Tutorial · Mittelstufe · 40 Min.

Bewegungsprofile: Trapez- und S-Kurven-Beschleunigung

Warum ein Positionsbefehl Motoren springen und Maschinen schlagen lässt, wie ein Trapezprofil das behebt und was eine ruckbegrenzte S-Kurve an Zeit kostet.

Einführung

Einen Motor auf eine Position zu befehlen und er versucht, sofort dorthin zu kommen. Nicht schnell – sofort. Der Befehl enthält keine Information über Tempo – die einzige verfügbare Deutung lautet also „so schnell wie möglich“: und was danach geschieht, entscheidet, was zuerst ausgeht: Drehmoment, Stromgrenze, Traktion oder die Fähigkeit des Schrittmotors mitzuhalten.

Ein Bewegungsprofil ist die fehlende Information. Es verwandelt „fahr auf 100 mm“ in einen Fahrplan – wo die Achse zu jedem Augenblick zwischen jetzt und Ankunft sein soll –, und übergibt dem Regler ein Ziel, das sich mit Tempo bewegt, das die Maschine wirklich liefern kann.

Das ist der Unterschied zwischen einem Roboterarm, der ankommt, und einem, der ankommt und aufhört zu wackeln.

Was ein nackter Positionsbefehl wirklich verlangt

Einen Sprung betrachten: Bei t = 0 springt das Ziel von 0 mm auf 100 mm.

Um dem exakt zu folgen, bräuchte die Achse unendliche Geschwindigkeit, was unendliche Beschleunigung erfordert, was unendliche Kraft erfordert. Kann sie nicht – also gibt etwas nach:

  • Ein Schrittmotor wird mit Schrittrate befohlen, die sein Drehmoment bei dieser Drehzahl nicht erzeugen kann, verliert Schritte – und merkt es ungeregelt nicht. Position ist nun dauerhaft falsch. Warum das geschieht, und warum es immer vier Schritte auf einmal sind.
  • Ein DC-Motor mit PID-Schleife sieht einen riesigen Momentanfehler, sättigt seinen Ausgang, wickelt seinen Integralanteil auf und schwingt über.
  • Ein Servo knallt auf seine Maximalrate und kommt mit noch bewegtem Gesamtmechanismus an.

Keines davon sind Abstimmungsprobleme. Alle sind dasselbe Problem: Der Befehl war physisch unmöglich.

Das Trapezprofil

Die Lösung: Geschwindigkeit befehlen, und Geschwindigkeit mit Rate ändern, die der Motor durchhält. Mit konstanter Rate auf Marschtempo beschleunigen, halten, dann mit derselben Rate bremsen. Geschwindigkeit gegen Zeit geplottet ist ein Trapez – woher der Name kommt.

Drei Zahlen definieren es: die Strecke d, ein Toptempo v_max und eine Beschleunigung a.

t_accel = v_max / a                     time spent ramping
d_accel = v_max² / (2a)                 distance used by one ramp
t_total = v_max / a  +  d / v_max       whole move, if it reaches v_max

Für 100 mm Fahrt bei 100 mm/s mit a = 500 mm/s²: Jede Rampe dauert 0,2 s und deckt 10 mm ab, 80 mm Marsch bleiben übrig – gesamt 1,2 s.

Hier das Ganze als Zeitfunktion – die Position, der deine Regelschleife zum Augenblick t folgen sollte:

// Target position t seconds into a trapezoidal move of `d` mm.
float profilePosition(float t, float d, float vMax, float a) {
  float tAcc = vMax / a;
  float dAcc = vMax * vMax / (2 * a);

  if (2 * dAcc > d) {                      // too short to reach vMax
    float tPeak = sqrtf(d / a);            // triangular profile
    if (t >= 2 * tPeak) return d;
    if (t < tPeak) return 0.5f * a * t * t;
    float left = 2 * tPeak - t;
    return d - 0.5f * a * left * left;
  }

  float tCruise = (d - 2 * dAcc) / vMax;
  float tTotal  = 2 * tAcc + tCruise;
  if (t >= tTotal) return d;
  if (t < tAcc)           return 0.5f * a * t * t;
  if (t < tAcc + tCruise) return dAcc + vMax * (t - tAcc);

  float left = tTotal - t;
  return d - 0.5f * a * left * left;
}

Beachte, was diese Funktion nicht ist: kein Regler. Sie erzeugt einen Sollwert. Was du hattest – Schrittmotor-Schrittplaner, PID-Schleife, Servoschreiben – folgt weiter. Das Profil ändert nur, wem gefolgt wird.

Die verlangte Bewegung ist nicht immer die bekommene

Dieser 2 * dAcc > d-Ast ist der Fall, den Leute zuerst treffen und fehldiagnostizieren.

Ist die Bewegung kürzer als die Strecke, die zum Hoch- und wieder Herunterbeschleunigen nötig ist, erreicht die Achse nie das konfigurierte Tempo. Sie rampt hoch, trifft die Halbzeit und rampt sofort herunter – ein Dreieck, kein Trapez.

Die Schwelle lautet d < v_max² / a. Für die Zahlen oben sind das 20 mm – jede Bewegung kürzer als 20 mm deckelt also unter 100 mm/s, egal was man setzt.

Ein Plot von Geschwindigkeit gegen Zeit für drei Bewegungen unter denselben Profileinstellungen von 500 mm/s Quadrat und 100 mm/s Toptempo. Eine 8-mm-Bewegung bildet ein Dreieck mit Spitze 63 mm/s nach 0,25 Sekunden und berührt nie das als Strichellinie gezeigte konfigurierte Toptempo. Eine 20-mm-Bewegung erreicht gerade 100 mm/s an ihrer Spitze. Eine 60-mm-Bewegung bildet ein Trapez mit klarer Marschphase und dauert 0,80 Sekunden.
Unter 20 mm geht dieser Achse die Strecke aus, bevor ihr die Rampe ausgeht. Das Tempolimit zu erhöhen bewirkt bei diesen Bewegungen nichts – nur Beschleunigung zu erhöhen tut es. SVG herunterladen

Darum ändert v_max zu erhöhen an einer Maschine mit vielen kurzen Bewegungen nichts Messbares. Die Bewegungen waren nie tempobegrenzt; sie waren beschleunigungsbegrenzt. Ein 3D-Drucker mit dichtem Infill ist das Alltagsbeispiel.

Die Ecken sind weiter unstetig

Das Trapezprofil behebte Geschwindigkeit. Beschleunigung ansehen und das Problem ist nur gewandert.

Bei t = 0 springt Beschleunigung instant von 0 auf 500 mm/s². Oben auf der Rampe fällt sie instant auf 0 zurück. Jedes davon ist ein Sprung in Beschleunigung – und die Änderungsrate von Beschleunigung ist Ruck: Ein Sprung in Beschleunigung ist also ein unendlicher Ruckimpuls.

Unendlich ist keine Zahl, die eine Maschine erzeugen kann. Was sie stattdessen erzeugt:

  • Einen hörbaren Schlag zu Beginn und Ende jeder Rampe.
  • Klingeln – Riemen dehnen sich, Kupplungen winden sich auf, und die Struktur hat Nachgiebigkeit: Eine plötzliche Kraftänderung regt sie also an und sie schwingt danach. Auf einem Drucker ist das das Ghosting neben scharfen Merkmalen.
  • Drehmomentspitzen, die Stromgrenzen auslösen, die die Durchschnittszahl für in Ordnung erklärte.
Vier gestapelte Plots gegen Zeit im Vergleich von Trapez- und S-Kurven-Profil für dieselbe 100-mm-Bewegung. Position: Beide sind weiche S-Formen bis 100 mm, die S-Kurve leicht dahinter. Geschwindigkeit: Das Trapez hat gerade Rampen und scharfe Ecken, die S-Kurve abgerundete Ecken und endet 0,1 Sekunden später. Beschleunigung: Das Trapez ist eine Rechteckwelle, die instant zwischen plus und minus 500 schaltet, die S-Kurve ein Trapez, das dazwischen rampt. Ruck: Die S-Kurve ist eine begrenzte Rechteckwelle, während das Trapezprofil als vier unbegrenzte Impulspfeile an den Ecken gezeichnet ist.
Dieselbe Bewegung unter beiden Profilen. Jede Zeile ist die Ableitung der darüber – und die Unstetigkeit verschwindet beim Differenzieren nicht: Sie wandert nur den Stapel hinunter, bis sie Impuls wird. SVG herunterladen

Die S-Kurve

Ein S-Kurven-Profil begrenzt Ruck wie Beschleunigung. Statt auf volle Beschleunigung zu springen, rampt es hinein über eine Ruckzeit t_j = a_max / j_max, hält, rampt dann hinaus. Die Geschwindigkeitskurve bekommt abgerundete Ecken – woher der Name –, und Beschleunigung wird ein eigenes Trapez.

Eine volle S-Kurven-Bewegung hat sieben Phasen: Ruck hoch, Beschleunigung halten, Ruck herunter, Marsch, und das Spiegelbild zum Stoppen.

Was es kostet: exakt ein t_j

Das lohnt Auswendiglernen – denn es macht den Tausch konkret.

Wenn beide Profile dasselbe v_max und dasselbe a_max erreichen, dauert die S-Kurven-Bewegung um exakt t_j länger – eine Ruckzeit, nicht zwei, und egal wie weit die Bewegung ist:

trapezoidal   T = v_max/a + d/v_max
S-curve       T = v_max/a + d/v_max + t_j          where t_j = a_max / j_max

Für die durchgerechnete Bewegung: Aus 1,2 s werden 1,3 s. 8 % Aufschlag auf diese Bewegung, und ein kleinerer Prozentsatz auf längere – im Tausch gegen begrenzten Ruck.

Der Grund, warum es eine und nicht zwei sind: Das Beschleunigungssegment der S-Kurve ist länger, deckt also vor Marsch mehr Strecke ab – die Marschphase schrumpft also und gibt den Großteil der Zeit zurück. Nur die Ruckzeit selbst ist uneinbringlich.

Darin versteckt sich eine Zwangsbedingung. Die Beschleunigung erreicht a_max nur, wenn v_max ≥ a_max² / j_max. Darunter erreicht die Bewegung volle Beschleunigung ebenfalls nie – und man bekommt ein Dreiecksbeschleunigungsprofil: dieselbe „Strecke ausgegangen“-Geschichte, eine Ableitung höher.

„Ruck“ in Druckerfirmware ist kein Ruck

Wissenswert, bevor man irgendetwas abstimmt – denn das Vokabular täuscht aktiv.

Klassisches Marlins DEFAULT_XJERK ist nicht die Ableitung von Beschleunigung. Es ist die maximale instantane Geschwindigkeitsänderung, die an einer Stoßstelle zweier Bewegungen erlaubt ist, in mm/s – eine Kurvengenehmigung, die den Planer eine Ecke nehmen lässt, ohne auf null zu bremsen. Nützlich, aber eine andere Größe mit falschem Namen und falschen Einheiten.

Neueres Marlin nutzt stattdessen standardmäßig Junction Deviation – was die Ecke als Kreisbogen gegebener Abweichung in mm modelliert. Klipper nutzt square_corner_velocity – das Tempo, mit dem eine 90°-Ecke genommen wird. Alle drei sind Antworten auf „wie stoppe ich nicht an jeder Ecke?“, und keine ist eine Ruckgrenze im physikalischen Sinn.

Sagt ein Forenbeitrag also, deinen Ruck zu senken, um Klingeln zu stoppen, prüfen, welche Größe gemeint ist. Kurventempo zu senken verringert Kurvenschock; es begrenzt kein da/dt in einer einzelnen Bewegung.

Dein PID ist wahrscheinlich in Ordnung

Hat man eine geregelte Achse, die bei jeder Bewegung überschwingt und schwingt, lautet der Instinkt: verstimmen – Kp senken, D dazu, dem Überschwingen kämpfen.

Erst den Sollwert profilieren versuchen.

Ein Sprungeingang verlangt von einem PID-Regler unendlichen Ausgang. Sein Fehlerterm startet bei voller Bewegungsstrecke, der D-Term sieht einen instantanen Sprung, und der I-Term summiert auf, während der Ausgang sättigt und die Achse nicht antworten kann. Verstimmen macht den Regler überall träge, um einen unmöglichen Augenblick zu überleben.

Mit Profil bleibt der Fehler die ganze Bewegung klein – denn das Ziel liegt dort, wo die Achse wirklich sein kann. Dieselben Verstärkungen, die gegen einen Sprung unbrauchbar waren, sind gegen eine Rampe oft wohlgesittet – und nun korrigiert der Regler nur noch Last und Reibung, wofür er da ist. Den Unterschied kann man im PID-Simulator beobachten, indem man einen Sprungsollwert gegen einen graduellen vergleicht.

Wo du dem auf einem echten Roboter begegnest

  • Schrittmotoren. AccelSteppers setMaxSpeed() und setAcceleration() liefern ein Trapezprofil und sonst nichts. Keine S-Kurven-Option; dafür erzeugt man den Sollwert selbst.
  • Hobbyservos. Ein SG90 hat einen internen Regler, den man weder sieht noch abstimmt – Profilieren heißt also, den befohlenen Winkel graduell zu schreiten statt das Ziel in einem Aufruf zu schreiben: dieselbe Idee von außen angewandt.
  • DC-Motoren mit Encodern. Den Positionssollwert profilieren und die Encoder-PID folgen lassen. Das ist die Anordnung, wo Profilieren am besten zahlt.
  • Mobile Roboter. Dieselbe Grenze gilt für linear.x auf einer cmd_vel-Brücke: Ein Geschwindigkeitsstufensprung lässt die Räder rutschen, was Odometrie korrumpiert. Den Twist ratenbegrenzen.
  • Drucker und CNC. Marlin, Klipper und GRBL planen alle Trapezbewegungen mit Kurvenregel dazwischen.

Wenn es schiefgeht

Symptom Meist
Schrittmotor verliert unter Last lautlos Position Kein Profil – Befehlsrate übersteigt Anzugsdrehmoment
Maschine schlägt zu Bewegungsbeginn und -ende Trapezruckimpuls; braucht S-Kurve oder niedrigere Beschleunigung
Klingeln neben scharfen Merkmalen Strukturresonanz, von Beschleunigungssprüngen angeregt
Kurze Bewegungen ignorieren die Tempoeinstellung Dreiecksprofil – beschleunigungsbegrenzt, nicht tempobegrenzt
Überschwingen und Schwingen bei jeder Bewegung Sprungsollwert in geschlossene Schleife; vor Verstimmen profilieren
Beschleunigung zu erhöhen hilft, dann plötzlich nicht Nun drehmomentbegrenzt statt profilbegrenzt
Odometrie driftet bei Starts stark Radschlupf aus Geschwindigkeitssprung; Befehl ratenbegrenzen

Profilieren ist die billigste große Verbesserung, die den meisten Hobbybewegungssystemen offensteht – denn es kostet eine Funktion und keine Hardware. Der Roboterarmsimulator ist ein guter Ort zu sehen, warum es am Ende eines langen Glieds zählt, wo ein kleiner Beschleunigungsschritt an der Basis zum sichtbaren Wackeln am Greifer wird. Am mobilen Roboter ist dasselbe Profil das, was einen Pfadfolger für eine Ecke schärfer als sein Wenderadius langsamer werden lässt, statt ihr nicht zu folgen.

Den Graphen erkunden

Teil dieser Bauprojekte

Projekte und Lernpfade, die dieses Tutorial enthalten.

Weiterführende Literatur

Quellen