Grad 3 Rest-to-Rest-Solver

Geschrieben von am .

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.)

  1. 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:

A B C C B A D E G E D F F t1 t2 t1 t3 t1 t2 t1 f=v(t) f=a(t) v1 v2 v1 v3 +a1 -a1
Zeichnung 1
  1. 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⟫.
  2. 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.
  3. 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⟫.
  4. Wir fahren über die Zeitdauer ⟪t_3⟫ mit der konstanten Geschwindigkeit ⟪v_3⟫.
  5. 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.
  6. Wir halten für eine Zeitdauer ⟪t_2⟫ die Beschleunigung auf konstant ⟪-a_1⟫.
    Dabei nimmt die Geschwindigkeit linear um insgesamt ⟪v_2⟫ ab.
  7. 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:

  1. 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") ) :}⟫

  2. 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") ) ) :}⟫

  3. 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:

  1. 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 ) :}⟫

  2. 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.