Für die Simulation Fahrbetrieb.
Inzwischen veraltete und obsolete Dokumentation, die nur noch verwirrt.
Im folgenden wird auf die zugrunde liegende Mathematik eingegangen. Dabei habe ich festgelegt, dass der Knickpunkt den Ursprung des fahrzeugbezogenen Koordinatensystems (x,y) darstellt und der hintere Fahrzeugteil die Ausrichtung (α) bestimmt. Das Koordinatensystem ist ein Linkssystem (wie bei allen Text- und grafischen Benutzeroberflächen außer OS/2 Presentation Manager). Das hat den Vorteil, dass ich nicht zwischen Canvas-, Maus- und Fahrzeugkoordinaten umrechnen muss, und dass positive Winkel nach rechts gehen, was IMHO viel natürlicher ist.
Bei Fahrzeugen liegt der Kurven-Mittelpunkt „Momentanpol“ rechnerisch in der Verlängerung der Achsen. Bei ungelenkt-mehrachsigen Fahrzeugen wie dem Muldenkipper gibt es bei den beiden (Hinter-)Achsen keinen Schnittpunkt, deshalb wird für das Maß b die Mitte zwischen den Achsen angenommen. Bei einem gewöhnlichen Fahrzeug (Auto) würde ich den mathematischen Kurvenradius auf die (Mitte der) Vorderachse legen. Bei einem knickgelenkten Fahrzeug gibt es jedoch 3 Kurvenradien. Der IMHO mathematisch wichtigste ist der am Knick rk. Im Bild ist der Lenkwinkel λ als lw eingezeichnet und die Herleitung von rb zu sehen:
rb = | a + b cos λ |
sin λ |
ra = | a cos λ + b |
sin λ |
rk = | √ |
sin λ |
Für kleine λ im Bogenmaß ist der gemeinsame Lenkradius r:
r ≈ | a + b |
λ |
„Gewöhnliche“ Fahrzeuge wie Fahrräder, Autos, Busse, Pferdekutschen und Handwagen verändern ihre Lage beim Lenken nicht. Dabei haben Pferdekutschen und Handwagen eine Drehschemel-Lenkung, Fahrräder, Motorräder und Dreiräder sind damit vergleichbar. Autos haben eine Einzelrad-Lenkung, wobei bei Bussen und einigen LKW mit mehrfacher Hinterachse auch eine Hinterachse mit gelenkt wird.
Knickgelenkte Fahrzeuge brechen beim Lenken aus. Zumindest wenn man den Fahrzeug-Ursprung auf den Knick legt. Legt man diesen auf die Verbindungsgerade zwischen Vorder- und Hinterachse, gibt es trotzdem einen (geringfügigen) Ausbruch durch das Verkürzen der Fahrzeug-Gesamtlänge und das Rollen der Räder zum Knick hin.
Beim Einlenken vollziehen die Räder eine Schleppkurve. Voraussetzung dafür ist ein Längsdifferenzial, welches das gegenseitige Abrollen erlaubt. Ohne Differenzial werden die Räder auf einer Geraden aufeinander zu gezerrt; beim gleichzeitigen Fahren oder bei Getriebespiel wird sich eine Mischform einstellen. Für das Berechnen der Schleppkurve hatte ich lange nach einer hinreichend performanten Lösung gesucht, die auch für 8-Bit-Mikrocontroller geeignet ist. Nun kann sie als gradweise Tabelle vorberechnet werden, nur unter Verwendung von Standard-Mathematik ohne weitere Interpolation, unter Annahme von gerader Radbewegung von einem Lenkwinkelgrad zum nächsten.
Das Bild zeigt einen (stark überhöhten) Iterationsschritt von einem Lenkwinkel zum nächsten. Dabei sind a, b und λ = lw die Achs-Teillängen und der Lenkwinkel. c ist die sich ergebende resultierende Achsabstand, f ist der Proportionalitätsfaktor der Rad-Längsbewegungen, typischerweise 1 für den Radlader und 2 für den Muldenkipper: Es wird davon ausgegangen, dass die Vorderachse die doppelte Längsbewegung wie die Doppel-Hinterachse vollzieht. Üm übrigen funktioniert die Rechnung auch dann, wenn a ≡ 0 vorliegt, die Knicklenkung zur Drehschemel-Lenkung „entartet“.
Als erstes wird der neue Achsabstand c gemäß Kosinussatz, aber für Außenwinkel, ermittelt. Davon wird stets nur das Quadrat benötigt:
c² = a² + b² + 2ab cos λ |
Als nächstes muss die Längsverkürzung d berechnet werden. Dazu wird der vorhergehende Lenkwinkel ¹λ (mit 0 beginnend) und Achsmittenabstand ¹c (mit a+b beginnend) herangezogen:
2d = | ¹c² – c² |
a + fb + fa cos ¹λ + b cos ¹λ |
Für diese Formel wurde der quadratische Term d²
mal benutzt und mal verworfen, es kommt augenscheinlich
(im Simulationsversuch unten) das gleiche heraus.
Nun muss die veränderte Lage des Knickpunkts berechnet werden.
Im Januar 2023 wurde dieser Algorithmus völlig neu aufgestellt,
und es wird mit den Achsmittelpunkten A und B gerechnet,
die sich um d bzw. f×d auf den Knickpunkt zubewegen.
Das erspart den Einsatz von Winkelfunktionen.
Mittels einer Kreisschnittberechnung (Point.moveToIntersect()
)
wird schließlich der neue Knickpunkt K ermittelt.
Für die Tabelle genügen schließlich:
x = K.x |
y = K.y |
α = atan2(K.y-B.y, K.x-B.x) |
Ziel ist, dass alle 20 ms die Inkremente i der Antriebsmotorumdrehung in eine aktualisierte Fahrzeugposition umgerechnet wird. Dazu gibt es einen Proportionalitätsfaktor k in m, der den Weg pro Inkrement festhält. Das Vorzeichen von i muss anhand der Servostellung ermittelt werden. Für Geradeausfahrt (Lenkwinkel λ ≡ 0) gilt:
w = ki |
x += w cos pos.α |
y += w sin pos.α |
Für Kurvenfahrten berechnet das JavaScript-Programm den Kreismittelpunkt an der Hinterachse (was es zur Visualisierung sowieso tut) und vollzieht eine Drehung an dieser Position. Der Kreismittelpunkt hat die Fahrzeugkoordinaten (mit dem Knick als Nullpunkt und dem Hinterteil auf der x-Achse) (-b,rb) mit rb wie oben. Der Verdrehwinkel µ (in rad) ist der Quotient aus Fahrstrecke und Kurvenradius. Es wird vernachlässigt, dass die Vorderräder eine andere Fahrstrecke abfahren.
Dazu wird das lokale Koordinatensystem am Drehpunkt zentriert, dann um µ verdreht und schließlich der Drehpunkt wiederhergestellt.
µ = | w |
rb | |
x += | –b cos α – rb sin α |
y += | –b sin α + rb cos α |
α += | µ |
x –= | –b cos α – rb sin α |
y –= | –b sin α + rb cos α |
Für das Mikrocontrollerprogramm erscheint die o.g. Rechnung mglw. zu aufwändig. Um mit einfachen Rechenoperationen auszukommen ist ein (lenkwinkelabhängiger) Punkt des Fahrzeugs erforderlich, bei dem die Längsachse des geradeausgerichteten Fahrzeugs das Lot zum Drehpunkt schneidet. Ein solcher Punkt wäre in der Lenkwinkel-Tabelle abzuspeichern. Ich nenne diesen hiermit Rechenpunkt R.
Um vom lokalen Koordinatenursprung zum Knickpunkt im geradeausgerichteten Zustand zu kommen müssen die für den gegebenen Lenkwinkel abgespeicherten Koordinaten (x,y,α) rückwärts angewendet werden, also nicht einfach subtrahieren sondern Koordinatendrehung ausführen. In der Formel heißt dieser Punkt fortan Q.
Q.x = P.x cos P.α – P.y sin P.α |
Q.y = P.x sin P.α + P.y cos P.α |
Q.α = P.α |
Die Koordinate des Drehpunktes ist im lokalen Koordinatensystem bekannt:
x = | –b |
y = | b cos λ + a |
sin λ |
Benötigt wird nun der Abstand (auf der Geradeausrichtgeraden) zwischen Q und R sowie der dazu senkrechte Abstand zwischen Drehpunkt (Momentanpol) und R, ein weiterer und kleinerer Kurvenradius. Die Animation zeigt nur die Konstruktionsgeraden; das Fahrzeug kann man sich allemal als „knickgelenktes Fahrrad, das niemals umfällt“ vorstellen.
Der Rechenpunkt R hat den Vorteil, für die nachfolgende Ausrichtprozedur ein geeigneter Ausgangspunkt zu sein. Für a ≡ 0 (Drehschemellenkung) fällt dieser Punkt mit der Hinterachse zusammen. Für a ≡ b besteht Symmetrie, und es sind Vereinfachungen möglich. Für den Allgemeinfall ist die Lage des Rechenpunktes von (a, b und) λ abhängig; dazu der sich ergebende Kurvenradius als Abstand zwischen Rechen- und Drehpunkt. Es ist fies, dass die Lage des Rechenpunktes von λ abhängt!! Daher wird für die folgende Ausrichtprozedur nur ein λ verwendet: Der maximale Lenkeinschlag.
Wie man an der nebenstehenden Simulation des Lenkvorgangs (nach rechts; das Fahrzeug steht mit der Front nach rechts) sieht, bewegt sich der Rechenpunkt R kaum und kann augenscheinlich im umgekehrten Verhältnis der Achsabstände a und b angenommen werden.
Diese neuen Erkenntnisse über den „Rechenpunkt“ lassen die JavaScript-Simulation falsch konstruiert erscheinen, und es erfolgt 2023 eine Umstellung vom Knick- zum Rechenpunkt. Für den Anwender auffallend ist dabei, dass beim Lenkvorgang der Ausrichtwinkel (in der Koordinatenanzeige) unverändert bleibt und das Auto nur noch in Längsrichtung „fährt“. Damit komme ich dem Ansatz von Felix Pfeiffer näher, der (unbewiesenermaßen) von einer (festen) Mitte zwischen den Mitten beider Achsmitten ausging.
Aus Sicht des Mikrocontrollers wird aus der Tabelle allenfalls C.x für die Längskorrektur benötigt sowie eine weitere Größe für die Verdrehung pro Radiant. (TODO!!) In diese fließt ein, dass der Kurvenradius der Räder größer ist als der Radius am Rechenpunkt. Besser: Werte aus experimentell aufgenommenen Kurvenradien.
Aus Sicht des Simulators wird weiterhin der Knickpunkt K und die Ausrichtung des Hinterteils α benötigt. Die Ausrichtung des Vorderteils ergibt sich schließlich daraus aus dem Lenkwinkel λ.
Der „Autopilot“ benötigt C.y (Kurvenradius am Rechenpunkt) und (vielleicht) C.x (Längskorrektur). Zur Kollisionsvermeidung werden zusätzlich noch sämtliche Fahrzeughauptabmessungen benötigt.
Ziel ist die Berechnung der Kurvensegmente, um das Fahrzeug von einer Startposition auf eine Ziellinie zu bringen. Im Normalfall genügen zwei Segmente mit jeweils maximalem Lenkeinschlag und damit bekanntem Kurvenradius. Am Ende muss das Fahrzeug geradeaus gelenkt auf der Ziellinie stehen. Diese Berechnung braucht nicht im 8-Bit-Mikrocontroller erfolgen.
Zunächst wird die Position des Fahrzeugs (x,y,α) (in der Praxis aus den 3D-Markern ermittelt) in das Koordinatensystem der Ziellinie, ebenfalls (x,y,α) überführt. Der erste Lenkeinschlag (rechts oder links) bei |α| ≤ -90° richtet sich nach der Seite: Bei y < 0 rechts, sonst links. Bei |α| > -90°, also wenn das Fahrzeug tendenziell verkehrt herum steht, andersherum.
Ein weiteres wichtiges Indiz ist die Lage des Drehzentrums bei sofortigem Lenkeinschlag, und zwar der zur Zielachse nähere (von beiden). Für die folgenden Abschnitte kommen nur Kreisbögen mit festem Radius r sowie Geradenabschnitte vor. Liegt das (erste) Drehzentrum mehr als r hinter dem Zielpunkt (also hinter der Y-Achse) wird vorwärts gefahren, sonst rückwärts. Ist der Abstand des Drehzentrums zur Ziellinie (X-Achse) größer als r erfolgt ein Abschnitt mit Geradeausfahrt in Y-Richtung, und der zweite Kreisbogen ist genau 90°: Ist |α| > -90°, dann mit gleicher Lenkrichtung, sonst mit wechselnder Lenkrichtung. Ansonsten (Normalfall) müssen 2 Kreisbögen tangential sowie stets mit wechselnder Lenkrichtung aneinandergesetzt werden, wobei der erste Bogen (|α| > -90°) auch länger als 180° werden kann (Fälle J und K).
Die verschiedenen Lösungen habe ich skizziert, wobei das Ziel das Erreichen der X-Achse mit Ausrichtung nach rechts ist, und das möglichst nahe am Ursprung.
Eine Rampenberechnung teilt ein Bewegungssegment in eine Beschleunigungsphase, eine Phase unbeschleunigter Bewegung (v konstant) und eine Abbremsphase auf. Die mittlere Phase unbeschleunigter Bewegung kann entfallen. Jede Phase wird in einen „Job“ übersetzt und dem Mikrocontroller übergeben. Mit dem „Tacho“ kann die Wegstrecke überprüft werden.
Das Erreichen des Zielpunktes ist eine simple Geradeausfahrt
vorwärts oder rückwärts.
In der Realität ist durch nochmaligen Abgleich mit 3D-Markern
die Lage zu prüfen und ggf. eine weitere Korrekturbewegung zu starten.
Auch die Simulation kann so verfahren, da die
Bewegungssegment-Abarbeitung (so wie's via requestAnimationFrame()
implementiert ist) unexakt ist.
Die Implementierung erwies sich schließlich als deutlich geradliniger: