Schrittmotorsteuerung
Diskrete Schritte, Zeitabstände der Schritte bestimmen Geschwindigkeit. $$ \vec F=m\cdot \vec a $$ Problem: Plötzliche Geschwindigkeitsänderung hat unendliche Beschleunigung zur Folge. Dabei können Schritte verloren gehen, unerwünschte Vibrationen in der Maschine ausgelöst werden etc.
Lösungsansatz: Vor Ecken wird langsam abgebremst und danach wieder beschleunigt (mit einer zu definierenden maximalen Beschleunigung).
Problem: Bei Polygonen ist jeder Punkt eine Ecke, was zu einer sehr langsamen Maschine führen würde.
Lösungsansatz: Kurven mit gemeinsamer Tangente in den Endpunkten.
Bezierkurven: Für die Schrittmotoren brauchen wir Zeitpunkte für die Schritte. Dazu muss letztlich die Gleichung $x=p_x(t)$ gelöst werden (Gleichung 3. Grades), wobei $x$ die nächste, durch Schritte vorgegebene $x$-Koordinate ist. Leider existiert diese nicht immer, z.B. wenn die Kurve vertikal ist. Es gäbe auch andere, iterative Ansätze, wo das nächste $t$ so bestimmt wird, dass sich eine Koordinaten um genau eine Schrittlänge unterscheidet.
Kurzum: Zum Nachfahren mit Schrittmotoren sind Bezierkurven mühsam.
Viel einfacher wäre es, Kreisbogen zu fahren (konstante Zentripetal-Beschleunigung). Tatsächlich wird das in G-Code normalerweise so gemacht: https://www.cnccookbook.com/cnc-g-code-arc-circle-g02-g03/
Wir werden uns nicht damit befassen, wie wir Bezierkurven allgemein möglichst gut durch Kreisbogen und Geradenstücke annähern können. Stattdessen untersuchen wir das inverse Problem:
Kreise mit kubischen Bezierkurven approximieren
Aufgabe: Finden Sie die Koordinaten von den 4 Kontrollpunkten einer kubischen Bezierkurve so, dass der Viertelkreisbogen des Einheitskreises im ersten Quadranten möglichst gut angenähert wird.
pts(r) := [[1,0],[1,r],[r,1],[0,1]]; p(t,r) := (1-t)^3*pts(r)[1]+3*(1-t)^2*t*pts(r)[2]+3*(1-t)*t^2*pts(r)[3]+t^3*pts(r)[4]; d(t,r):=(p(t,r).p(t,r))^0.5; define(d2(t,r),p(t,r).p(t,r)); solve(d2(0.5,r)=1,r); solve(d2dt(t,r)=0, t); tmax : rhs(solve(d2dt(t,r)=0, t)[2]); solve(d(tmax,r)-1 = 1-d(0.5,r),r); define(dtmax(r),d(tmax,r)); define(rdiff(r), float((dtmax(r)-1)-(1-d(0.5,r)))); load ("newton1"); ropt:newton(rdiff(r), r, 0.55,1.0e-17); 2.0-d(0.5,ropt); plot3d(d(t,r), [t,0,1],[r,0.55,0.555]);
Liefert ein optimales $r\approx 0.5519150244935106$ mit einer Abweichung von $\approx 1.000196076469877$. Siehe auch http://spencermortensen.com/articles/bezier-circle/ und https://pdfs.semanticscholar.org/1639/0db1a470bd13fe428e0896671a9a5745070a.pdf
Achterbahn mit Bezierkurven
- Modellierung in Blender
- Auslesen der Kurvendaten
- Berechnung der Geschwindigkeit
- Effektive Beschleunigung und daraus den Normalvektor zur Bahn
- Orthonormales Koordinatensystem zu jedem Bahnpunkt
- Längenparametrierung
- Bahnoptimierung (Annäherung an Kreisbogen, Minimierung der 3. Ableitung)