Entwickler-Ecke
Sonstiges (.NET) - [C#] Modell Panzer Lenkung Problem ?
MCPC10 - Mo 04.01.16 20:16
Titel: [C#] Modell Panzer Lenkung Problem ?
Hallo erstmal :),
Ich hoffe das ich hier richtig bin für meine Frage :)
Also ich habe das Problem das ich einen Panzer per Lenkrad über USB ansteuern möchte (Arduino) über C# und SharpDX komm ich an die Daten des Lenkrades und kann diese auch soweit interpretieren auch Serial Communication funktioniert mit dem Arduino bestens aber derzeit funktioniert die Lenkung nur wenn der Panzer ausreichend schnell ist. Hier ein bisschen Code dazu:
int leftTrackSpeed = lenkradWert * (sollGeschwindigkeit/32767)
Wie gesagt das Problem liegt daran, das wenn ich keine Geschwindigkeit habe die Lenkung nicht funktioniert. Wenn der Panzer sehr langsam ist, lenkt der extrem langsam, was nicht wirklich Realistisch ist :(.
Ich hoffe einer oder mehrere von euch können mir bei diesem Problem helfen.
Bei Fragen, bin ich gerne zu euren Diensten ;)
Danke :)
Ralf Jansen - Mo 04.01.16 21:14
Das drumherum kann ich nicht beurteilen aber alleine deine Zeile Code hat ein Problem.
lenkradWert und sollGeschwindigkeit sind vermutlich Integer und bei einer Division Integer/Integer kommt natürlich am Ende wieder ein Integer raus.
Bedeutet jeder Wert zwischen 0 und 32766 für sollGeschwindigkeit wird den Ausdruck zu 0 werden lassen. Auch 32766/32767 ist in Integermathematik 0 (halt mit Rest 32766 der hier aber unter den Tisch fällt).
Zum Beispiel ein (unter obiger Annahme das die Variablen Integer sind)
C#-Quelltext
1:
| int leftTrackSpeed = (int)((double)lenkradWert * (sollGeschwindigkeit / 32767.0)); |
sollte näher am gewünschten sein.
MCPC10 - Mo 04.01.16 22:05
Ralf Jansen hat folgendes geschrieben : |
Das drumherum kann ich nicht beurteilen aber alleine deine Zeile Code hat ein Problem.
lenkradWert und sollGeschwindigkeit sind vermutlich Integer und bei einer Division Integer/Integer kommt natürlich am Ende wieder ein Integer raus.
Bedeutet jeder Wert zwischen 0 und 32766 für sollGeschwindigkeit wird den Ausdruck zu 0 werden lassen. Auch 32766/32767 ist in Integermathematik 0 (halt mit Rest 32766 der hier aber unter den Tisch fällt).
Zum Beispiel ein (unter obiger Annahme das die Variablen Integer sind)
C#-Quelltext 1:
| int leftTrackSpeed = (int)((double)lenkradWert * (sollGeschwindigkeit / 32767.0)); |
sollte näher am gewünschten sein. |
Also das was ich dahin geschrieben habe ist nur eine Vereinfachung des Codes denn ich selber benutze derzeit :)
Noch Wichtig da ich über Arduino Arbeite (H-Brücke), ist 255 die maxGeschwindigkeit und sie ändert sich je nach Gas bis 0. :)
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| sollGeschwindigkeit = Convert.ToInt16(BremseGas() * (maxGeschwindigkeit / 32767f)); Beschleunigungskontrolle();
if (lenkrad > 0) { rightTrackSpeed = Convert.ToInt16(geschwindigkeit - lenkrad); leftTrackSpeed = geschwindigkeit; } else if (lenkrad < 0) { leftTrackSpeed = Convert.ToInt16(geschwindigkeit - (lenkrad *-1)); rightTrackSpeed = geschwindigkeit; } else { rightTrackSpeed = geschwindigkeit; leftTrackSpeed = geschwindigkeit; } |
Aber trotzdem DANKE !
icho2099 - Di 05.01.16 09:55
Da du nur die innere Kette verlangsamt, ohne die äußere zu beschleunigen, muss sich dein Fzg so verhalten.
Dem Lenkeinschlag sollte eine Drehgeschwindigkeit zugeordnet werden, und dann zu der Sollgeschwindigkeit addiert/subtrahiert (außen/innen) werden.
Das erlaubt dann auch Drehen auf der Stelle.
Mit einer nicht linearen Zuordnung Lenkeinschlag/Drehgeschwindigkeit wird das dann auch
Feinfühlig.
MCPC10 - Di 05.01.16 18:25
icho2099 hat folgendes geschrieben : |
Da du nur die innere Kette verlangsamt, ohne die äußere zu beschleunigen, muss sich dein Fzg so verhalten.
Dem Lenkeinschlag sollte eine Drehgeschwindigkeit zugeordnet werden, und dann zu der Sollgeschwindigkeit addiert/subtrahiert (außen/innen) werden.
Das erlaubt dann auch Drehen auf der Stelle.
Mit einer nicht linearen Zuordnung Lenkeinschlag/Drehgeschwindigkeit wird das dann auch
Feinfühlig. |
Also die Idee gefällt mir aber wenn ich 255 als max Wert habe und wenn ich das Gas durchdrücke kann keine Lenkung mehr dazu tun (denn Arduino 255 = Motordrehzahl am Limit) oder wie meinst du es. Danke nochmal ;)
C#-Quelltext
1: 2: 3:
| lenkrad = lenkung * (255/32767f);
leftTrackSpeed = (gas + lenkrad) * (255/512f); |
Meinst du so oder verstehe ich was falsch (Code aus den Gedanken, kann Fehler enthalten) :)
Danke nochmal !
icho2099 - Di 05.01.16 23:53
Natürlich musst du den Wertebereich für die Stellgrößen begrenzen. Und am Limit ist am Limit.
Dann geht kein Addieren mehr, aber Subtrahieren auf der Innenseite geht immer noch.
Also zunächst alle Werte berechnen, dann auf den Bereich der Stellgrößen skalieren und ggf.
am Limit abschneiden.
Ich würde den Range der Lenkung, also die Steigung der Funktion
Lenkeinschlag-->Drehgeschwindigkeit, von der Sollgeschwindigkeit abhängig machen. Damit erreichst du bei hoher Geschwindigkeit kleinere Lenkwirkung und verhinderst Überschläge.
Und ein kleiner Totbereich um den Lenkeinschlag 0 herum verhindert das Zappeln bei Geradeausfahrt.
MCPC10 - Mi 06.01.16 14:41
icho2099 hat folgendes geschrieben : |
Natürlich musst du den Wertebereich für die Stellgrößen begrenzen. Und am Limit ist am Limit.
Dann geht kein Addieren mehr, aber Subtrahieren auf der Innenseite geht immer noch.
Also zunächst alle Werte berechnen, dann auf den Bereich der Stellgrößen skalieren und ggf.
am Limit abschneiden.
Ich würde den Range der Lenkung, also die Steigung der Funktion
Lenkeinschlag-->Drehgeschwindigkeit, von der Sollgeschwindigkeit abhängig machen. Damit erreichst du bei hoher Geschwindigkeit kleinere Lenkwirkung und verhinderst Überschläge.
Und ein kleiner Totbereich um den Lenkeinschlag 0 herum verhindert das Zappeln bei Geradeausfahrt. |
Haste auch eine Idee wie ich das schreiben soll, also ein Code Beispiel, denn ich verstehe noch nicht wie ich das Programmieren soll. :)
Danke :)
icho2099 - Fr 08.01.16 16:02
Hallo,
weil C jetzt nicht so meins ist, hab ich was in Delphi gebastelt.
Vielleicht hilft dir das ja, guckst du Anhang.
Ein paar Konstante und globale Variable:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| Const cLEmin = 0; cLEmax = 4095; cLEOffset = 2047; cLETh = 16; cGmin = 0; cGmax = 4095; cGOffset = 2047; cGTh = 16;
Var fLE : Integer; fLEAdapt : Boolean; fG : Integer; fVL : Integer; fVR : Integer; |
Und dann wie du die Werte für die beiden Antriebe berechnen kannst.
Die Skalierung auf 8-Bit 0..255 oder -127..128 kriegst du sicher auch
alleine hin.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| Procedure tForm1.DoIt; Var V : Integer; k : Double; begin fLE := fLE - cLEOffset; If (fLE > -cLETh) AND (fLE < cLETh) then fLE := 0 else If (fLE < 0) then fLE := fLE + cLETh else fLE := fLE - cLETh;
V := fG - cGOffset; If (V > -cGTh) AND (V < cGTh) then V := 0 else If (V < 0) then V := V + cGTh else V := V - cGTh;
If fLEAdapt then begin k := 1 - (Abs(V) / (cGmax-cGOffset)); fLE := Round(fLE * k); end;
fVL := V + fLE; fVR := V - fLE;
LblVL.Caption := IntToStr(fVL); LblVR.Caption := IntToStr(fVR);
end; |
Der Rest ist nur schmückendes Beiwerk.
Moderiert von
Th69: Code- durch Delphi-Tags ersetzt
MCPC10 - Di 19.01.16 18:23
So, hallo erstmal und danke für deinen Beitrag, hatte wegen der Schule (und Après Ski :) ) bis jetzt nicht wirklich Zeit gehabt ;)
Da ich Delphi nicht kenne, kann ich nicht wirklich viel mit dem Source anfangen aber deine Software sieht extrem "Geil" aus :)
Ich versuche mal zu verstehen wie das geht aber wie gesagt Delphi war mir bis jetzt, noch unbekannt :).
Moderiert von
Th69: Full-Quotes entfernt.
MCPC10 - Mo 22.02.16 22:02
Konnte deinen Source jetzt endlich lesen :) und in meinen C# Source einfügen. Wenn jemand interesse an Code hat dann bitte melden.
Habe jetzt noch eine andere frage, wenn jemand eine idee hat wie man eine bessere Geschwindigkeitskonrolle macht wäre ich ihm dankbar, denn derzeit nutze ich die Zei t aber das ist noch nicht so optimal den ich will das wenn man die Bremse drückt der "Motor" schneller abbremsen tut und das er auch langsam anfährt.
Danke nochmal für den Delphi Code und ich würde mich sehr freuen wenn mir jemand mit der Geschwindigkeitskonrolle helfen könnte. :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!