1. Aufgabe
Gegeben sind eine zurückzulegende Entfernung ⟪s_"req"⟫ und symmetrische Maximalwerte für Geschwindigkeit ⟪v_("max")⟫, Beschleunigung ⟪a_("max")⟫ und Ruck ⟪j_("max")⟫.
Gesucht ist eine Trajektorie minimaler Zeitdauer, die aus vollständigem Stillstand (⟪v=0⟫, ⟪a=0⟫ und ⟪j=0⟫) startet, die Entfernung ⟪s_"req"⟫ zurücklegt und mit vollständigem Stillstand endet unter Einhaltung von ⟪v_("max")⟫, ⟪a_("max")⟫ und ⟪j_("max")⟫.
2. Vorbereitungen
(Kann möglicherweise weg.)
- Beschleunigung ⟪a(t)⟫, Geschwindigkeit ⟪v(t)⟫ und Position ⟪s(t)⟫
einer Bewegung mit konstem Jerk ⟪j⟫ sind:
⟪{: ( a(t), = , a_0 + j * t ) :}⟫
⟪{: ( v(t), = , v_0 + int_(u=0)^t a(u) \ du ), ( , = , v_0 + int_(u=0)^t (a_0 + j u) \ du ), ( , = , v_0 + int_(u=0)^t a_0 \ du + int_(u=0)^t j u \ du ), ( , = , v_0 + a_0 t + j/2 t^2 ) :}⟫
⟪{: ( s(t), = , s_0 + int_(u=0)^t v(u) \ du ), ( , = , s_0 + int_(u=0)^t (v_0 + a_0 u + j/2 u^2 ) \ du ), ( , = , s_0 + int_(u=0)^t v_0 \ du + int_(u=0)^t a_0 u \ du + int_(u=0)^t j/2 u^2 \ du ), ( , = , s_0 + v_0 t + a_0/2 t^2 + j/6 t^3 ) :}⟫
3. Lösung
Die Lösung besteht aus bis zu 7 Phasen:
- Wir erhöhen über die Zeitdauer ⟪t_1⟫ die Beschleunigung linear mit ⟪+j_("max")⟫ von ⟪0⟫
auf ⟪+a_1⟫.
Dabei nimmt die Geschwindigkeit quadratisch zu bis zum Wert ⟪v_1⟫. - Wir halten für eine Zeitdauer ⟪t_2⟫ die Beschleunigung auf konstant ⟪a_1⟫.
Dabei nimmt die Geschwindigkeit linear um insgesamt ⟪v_2=t_2*a_1⟫ zu. - Wir reduzieren über die Zeitdauer ⟪t_1⟫ die Beschleunigung linear mit ⟪-j_("max")⟫ von
⟪+a_1⟫ auf ⟪0⟫.
Dabei erreicht die Geschwindigkeit den Wert ⟪v_3 = 2*v_1+v_2⟫. - Wir fahren über die Zeitdauer ⟪t_3⟫ mit der konstanten Geschwindigkeit ⟪v_3⟫.
- Wir reduzieren über die Zeitdauer ⟪t_1⟫ die Beschleunigung linear mit ⟪-j_("max")⟫ von ⟪0⟫
auf ⟪-a_1⟫.
Dabei nimmt die Geschwindigkeit quadratisch um den Betrag ⟪v_1⟫ ab. - Wir halten für eine Zeitdauer ⟪t_2⟫ die Beschleunigung auf konstant ⟪-a_1⟫.
Dabei nimmt die Geschwindigkeit linear um insgesamt ⟪v_2⟫ ab. - Wir erhöhen über die Zeitdauer ⟪t_1⟫ die Beschleunigung linear mit ⟪+j_("max")⟫ von ⟪-a_1⟫
auf ⟪0⟫.
Dabei erreicht die Geschwindigkeit den Wert ⟪0⟫.
Die zurückgelegte Strecke entspricht der Gesamtfläche unter der Geschwindigkeitskurve; Zur Veranschaulichung der Berechnung sind Teilflächen mit Großbuchstaben bezeichnet. Wegen der Symmetrie der Randbedingungen finden wir nur 3 Zeitdauern und nur 7 unterschiedliche Teilflächen. Außerdem gilt ⟪A+F=C⟫.
3.1. Bestimmung von t1
Zur Erreichung der Zeitoptimalität wählen wir zuerst ⟪t_1⟫ innerhalb der Vorgaben maximal, danach ⟪t_2⟫ und zuletzt ⟪t_3⟫ Außerdem nutzen wir immer dem maximalen Ruck, also ⟪j in {-j_("max"), 0, +j_("max")}⟫.
Für ⟪t_1⟫ gelten folgende Bedingungen:
- Die maximale Beschleunigung.
⟪ a(t_1) le a_("max") ⟫
Mit ⟪a(t_1) = j_"max"*t_1⟫ ergibt sich:
⟪(1.1)⟫ ⟪{: ( j_"max"*t_1 , le a_("max") ), ( t_1 , le a_("max")/j_("max") ) :}⟫
- Die maximale Geschwindigkeit.
Mit ⟪v(t_1) = j_"max"/2 * t_1^2⟫ ergibt sich:
⟪(1.2)⟫ ⟪{: ( 2 * v_1 = 2 * v(t_1) , le v_("max") ), ( 2 * j_"max"/2 * t_1^2 , le v_("max") ), ( t_1^2 , le v_("max")/j_("max") ), ( t_1 , le sqrt( v_("max")/j_("max") ) ) :}⟫
- Die geforderte Strecke.
Die zurückgelegte Strecke entspricht der Fläche unter der Kurve der Geschwindigkeit ⟪f=v(t)⟫.
Bei der Berechnung des maximalen Wertes für ⟪t_1⟫ rechnen wir mit ⟪t_2=t_3=0⟫: Die Flächen B, D, E und G sind dann 0, und für die von Start bis Stopp zurückgelegte Strecke ⟪s_1⟫ gilt:⟪ s_1 = 2 * ( A + C + F ) ⟫
Aus Symmetriegründen gilt ⟪A + F = C⟫, und damit ergit sich:
⟪ s_1 = 2 * ( C + C ) = 4 * C ⟫
Mit ⟪C = v_1*t_1⟫ und und ⟪v_1 = j_"max"/2 * t_1^2⟫ berechnen wir:⟪(1.3)⟫ ⟪{: ( s_1 , le s_"req" ), ( 4 * C , le s_"req" ), ( 4 * v_1 * t_1 , le s_"req" ), ( 4 * j_"max"/2 * t_1^2 * t_1 , le s_"req" ), ( 2 * j_"max" * t_1^3 , le s_"req" ), ( t_1^3 , le s_"req" / (2*j_"max") ), ( t_1 , le root(3)( s_"req" / (2*j_"max") ) ) :}⟫
Damit ergibt sich:
⟪(1.4)⟫ ⟪{: ( t_1 := min{ a_("max")/j_("max"), sqrt( v_("max")/j_("max")), root(3)(s_"req" / (2*j_"max"))} ), ( a_1 := j_"max" * t_1 ), ( v_1 := j_"max"/2 * t_1^2 ), ( s_1 := 4 * v_1 * t_1 ) :}⟫
3.2. Bestimmung von t2
Für ⟪t_2⟫ gelten folgende Bedingungen:
- Die maximale Geschwindigkeit.
Mit ⟪v_2 = a_1 * t_2⟫ ergibt sich:
⟪(2.1)⟫ ⟪{: ( 2 * v_1 + v_2 , le v_"max" ), ( v_2 , le v_"max" - 2 * v_1 ), ( a_1 * t_2 , le v_"max" - 2 * v_1 ), ( t_2 , le ( v_"max" - 2 * v_1 ) / a_1 ) :}⟫
- Die geforderte Strecke.
Bei der Berechnung des maximalen Wertes für ⟪t_2⟫ rechnen wir mit ⟪t_3=0⟫. Die von ⟪t_2⟫ abhängige Strecke ergibt sich zu:
⟪ s_2 = 2 * ( B + D + E ) ⟫
wobei:
⟪{: ( B , = , v_1 * t_2 ), ( D , = , 1/2 * v_2 * t_2 ), ( , = , 1/2 * a_1 * t_2 * t_2 ), ( , = , a_1/2 * t_2^2 ), ( E , = , v_2 * t_1 ), ( , = , a_1 * t_2 * t_1 ), ( , = , a_1 * t_1 * t_2 ) :}⟫
Wir setzen ein und lösen nach ⟪t_2⟫ auf:
⟪(2.2)⟫ ⟪{: ( s_1 + s_2 , le s_"req" ), ( s_2 , le s_"req" - s_1 ), ( 2 * ( B + D + E ) , le s_"req" - s_1 ), ( 2 v_1 * t_2 + a_1 * t_2^2 + 2 a_1 t_1 * t_2 , le s_"req" - s_1 ), ( 2 v_1/a_1 * t_2 + t_2^2 + 2 t_1 * t_2 , le ( s_"req" - s_1 ) / a_1 ), ( t_2^2 + 2 (v_1/a_1 + t_1) * t_2 , le ( s_"req" - s_1 ) / a_1 ), ( t_2^2 + 2 underbrace(( t_1/2 + t_1 ))_q * t_2 , le ( s_"req" - s_1 ) / a_1 ), ( t_2^2 + 2 * t_2 * q , le ( s_"req" - s_1 ) / a_1 ), ( t_2^2 + 2 * t_2 * q + q^2 , le ( s_"req" - s_1 ) / a_1 + q^2 ), ( ( t_2 + q )^2 , le ( s_"req" - s_1 ) / a_1 + q^2 ), ( t_2 + q , le sqrt( ( s_"req" - s_1 ) / a_1 + q^2 ) ), ( t_2 , le sqrt( ( s_"req" - s_1 ) / a_1 + q^2 ) - q ) :}⟫
Damit ergibt sich:
⟪(2.3)⟫ ⟪{: ( q := 3/2 t_1 ), ( t_2 := min{ (v_"max" - 2 * v_1) / a_1, sqrt( ( s_"req" - s_1 ) / a_1 + q^2 ) - q } ), ( s_2 := 2 * v_1 * t_2 + a_1 * t_2^2 + 2 * a_1 * t_1 * t_2 ), ( v_2 := a_1 * t_2 ), ( v_3 := 2 * v_1 + v_2 ) :}⟫
3.3. Bestimmung von t3
Die von ⟪t_3⟫ abhängige Strecke ergibt sich zu:
⟪ s_3 = G = v_3 * t_3 ⟫
Um das Ziel zu erreichen, muss gelten:
⟪ s_1 + s_2 + s_3 = s_"req" ⟫
Wir setzen ein und lösen auf:
⟪(3.1)⟫ ⟪{: ( s_1 + s_2 + s_3 , = s_"req" ), ( s_3 , = s_"req" - s_1 - s_2 ), ( v_3 * t_3 , = s_"req" - s_1 - s_2 ), ( t_3 , = (s_"req" - s_1 - s_2 ) / v_3 ) :}⟫
4. Lösungsalgorithmus
Bei ⟪s_"req"<0⟫ wird mit ⟪abs(s_"req")⟫ gerechnet und dann der Jerk jeweils mit
umgekehrten Vorzeichen benutzt.
Der Fall ⟪s_"req"=0⟫ muss gesondert behandelt werden, da dann auch ⟪a_1=0⟫ und ⟪v_3=0⟫ gelten
und durch diese Werte geteilt wird.
function solve( sreq, vmax, amax, jmax ){ sreq := abs( sreq ) if( sreq == 0 ) return [0, 0, 0] t1_limit_a := amax/jmax t1_limit_v := sqrt( vmax/jmax ) t1_limit_s := cbrt( sreq / (2*jmax) ) t1 := min( t1_limit_a, t1_limit_v, t1_limit_s ) a1 := jmax * t1 v1 := jmax/2 * t1*t1 s1 := 4 * v1 * t1 q := 1.5 * t1 t2_limit_v := ( vmax - 2*v1 ) / a1 t2_limit_s := sqrt( (sreq - s1) / a1 + q*q ) - q t2 := min( t2_limit_v, t2_limit_s ) v2 := a1*t2 v3 := 2*v1 + v2 s2 := 2*v1*t2 + a1*t2*t2 + 2*a1*t1*t2 t3 := (sreq - s1 - s2) / v3 return [t1, t2, t3] }
Die sieben Phasen sind dann:
# | t | j |
---|---|---|
1 | t1 | +signum(sreq) * jmax |
2 | t2 | 0 |
3 | t1 | -signum(sreq) * jmax |
4 | t3 | 0 |
5 | t1 | -signum(sreq) * jmax |
6 | t2 | 0 |
7 | t1 | +signum(sreq) * jmax |
Es gibt eine Implementierung in JavaScript mit Beispielaufgaben.