İçeriğe geç

13 · Trajectory generation

Bölüm4 · Dynamics ve control
Çalışma türüCPU · Mac ya da Colab CPU
Önkoşul10, 12
Önce öğrenCalculus for Machine Learning
Süre~45 dk
Kodexperiments/13-trajectory-generation/experiment.py
Durum✅ tam

Bu derste yap

Her adımı yapınca işaretle. Yalnız bu tarayıcıda saklanır.

Bir controller ona ne verirsen onu takip eder. Bir step verirsen sonsuz ivme üretmeye çalışır; yumuşak bir eğri verirsen torque küçük kalır.

Ders 12’de Unitree’nin gerçek robot için yazdığı ayağa kalkma örneği duruş pozunu tek seferde göndermiyordu: 2 ms’lik 500 ila 1000 tick süren fazlarla ona doğru interpolasyon yapıyordu (go2_stand_example.py). Robot arayüzleri daha da ileri gider: libfranka’nın rate_limiting.h dosyası, 1 ms’lik kontrol periyodunda joint başına en fazla 10 rad/s² ivme, 5000 rad/s³ jerk (ivmenin değişme hızı) ve 1000 N·m/s torque değişim hızı tanımlar ve komutları bu sınırlara kırpan limitRate fonksiyonları sunar (rate_limiting.h). Bir planner ya da IK solver sana nereye gideceğini söyler; trajectory generation ise referansın zamanda nasıl ilerleyeceğine karar verir. Bu seçim tepe torque’u, yapıyı sarsan jerk’ü ve takip hatasını (robotun referansının ne kadar gerisinde kaldığını) belirler. Bu ders üçünü de bir Panda üzerinde ölçüyor.

Okumadan önce · 2 soru. Önce tahmin et; nedenini ders anlatıyor.

1. Aynı quintic hareketi yarı sürede yapıyorsun. Referansın tepe ivmesine ve tepe jerk’üne ne olur?

  • İkisi de iki katına çıkar, çünkü her şey iki kat hızlı olur.
  • İvme ×4, jerk ×8.
  • İkisi de değişmez; onları yalnızca şekil belirler.

Neden: Zincir kuralıyla q¨∝1/T2\ddot q \propto 1/T^2 ve q...∝1/T3\dddot q \propto 1/T^3. B bölümü, quintic 1 s’den 0,5 s’ye - ivme 3,46 → 13,86 rad/s², jerk 35,8 → 284,6 rad/s³.

2. Hangi asansör yolculuğu daha yumuşak hissettirir: hızın sabit oranla artıp azaldığı mı, yoksa ivmenin kendisinin yavaşça başlayıp bittiği mi?

  • Sabit oranlı rampa, çünkü ivmesi daha düşüktür.
  • Aynı sürede biterlerse ikisi de aynı hissettirir.
  • İvmesi yavaşça başlayan: ivmedeki sıçrama hissettiğin sarsıntıdır (jerk).

Neden: Sade anlatımla: jerk ivmenin değişim hızıdır. Trapezoid’in ivmesi sıçrar (robot jerk’ü 1003 rad/s³), quintic’inki sıçramaz (35 rad/s³).

Controller referansını, yani şu an olması söylenen açıyı kovalar. Referans hedefe ışınlanırsa (step), controller oraya anında varmaya çalışır ve devasa bir tork ister. Trajectory ise referansı bir zaman çizelgesi olarak yazmaktır: başlangıç ile hedef arasında her tick’te her eklemin nerede olması gerektiği.

Bir asansör düşün. Ucuz bir asansör kalkarken ve dururken sarsar; iyi bir asansör harekete yumuşakça girer, sabit hızda gider ve yumuşakça çıkar. Sarsıntı olarak hissettiğin şey jerk’tür: ivmenin değişme hızı. Çizelgenin şekli buna karar verir:

  • linear: ilk andan itibaren sabit hız; hız iki uçta sıçrar;
  • trapezoid: hız artar, sabit gider, azalır; ivme köşelerde sıçrar;
  • cubic: hız yumuşaktır ama ivme başta ve sonda yine sıçrar;
  • quintic: konum, hız ve ivme başta ve sonda durağandır. Bu, minimum-jerk harekettir.

Süre şekilden daha önemlidir: aynı hareketi yarı sürede yaparsan her ivme (ve tork) dört kat, her jerk sekiz kat büyür. İki seçim daha: eklem açılarında interpolasyon (ucuz, el bir eğri izler) ya da elin düz bir çizgi izlemesi (her noktada IK) ve feedforward eklenip eklenmeyeceği: planlanan ivmenin gerektirdiği torku önceden göndermek.

flowchart TD
    G["hedef eklem açıları<br/>planner ya da IK'dan"] --> TG["trajectory generator<br/>q_r(t) = q0 + s(t/T)·Δq"]
    TG --> R["q_r, q̇_r, q̈_r<br/>her 2 ms'de"]
    R --> PD["PD + yerçekimi<br/>q_r, q̇_r'yi takip eder"]
    R --> FF["feedforward<br/>M(q)·q̈_r"]
    PD --> S["topla, tork limitlerine kırp"]
    FF --> S
    S --> A["Panda"]
    A -- "ölçülen q, q̇" --> PD

Her hareket “başlangıç + yolun tamamlanan kesri × toplam değişim”dir; zamanla yalnızca s kesri değişir.

u = min(max(t / T, 0.0), 1.0) # normalised time, 0 at start, 1 at the end
s, sd, sdd = quintic_s(u), quintic_s1(u) / T, quintic_s2(u) / T**2 # fraction done and its time derivatives
q_ref, qd_ref, qdd_ref = q0 + s*dq, sd*dq, sdd*dq # per-joint reference [rad, rad/s, rad/s^2]
tau = g(q) + kp*(q_ref - q) + kd*(qd_ref - qd) # PD tracking + gravity (lesson 12)
tau += M(q) @ qdd_ref # optional feedforward (lesson 11's M)

| şekil | s(u)s(u) | sınır koşulları | tepe ∣q¨∣|\ddot q| | jerk | |---|---|---|---|---| | step | 1 | yok | ∞ | ∞ | | linear | uu | konum | ∞ (hız sıçrar) | ∞ | | trapezoidal velocity | T/3T/3 hızlan, sabit git, T/3T/3 yavaşla | konum, hız | 4,5 Δq/T24{,}5\,\Delta q/T^2 | ∞ (ivme sıçrar) | | cubic | 3u2−2u33u^2 - 2u^3 | konum, hız | 6 Δq/T26\,\Delta q/T^2 | uçlarda ∞ | | quintic | 10u3−15u4+6u510u^3 - 15u^4 + 6u^5 | konum, hız, ivme | 5,77 Δq/T25{,}77\,\Delta q/T^2 | 60 Δq/T360\,\Delta q/T^3 |

Burada q(t)=q0+s(t/T) Δqq(t) = q_0 + s(t/T)\,\Delta q, u=t/T∈[0,1]u = t/T \in [0,1] normalize zaman, s(u)s(u) ise s(0)=0s(0) = 0 ve s(1)=1s(1) = 1 olan time scaling’dir (Lynch & Park, böl. 9); q0q_0 başlangıç açıları, Δq\Delta q toplam değişim, TT süre, q¨\ddot q eklem ivmesi ve jerk q...\dddot q onun zaman türevidir. “Sınır koşulları”, şeklin iki uçta durağan yaptığı büyüklükleri listeler.

Linear, trapezoid, cubic ve quintic time scaling'lerin normalize zamana karşı konum, hız ve ivmesi. Yalnızca quintic hem sıfır hız hem sıfır ivmeyle başlayıp bitiyor; cubic'in ivmesi uçlarda 6'ya sıçrıyor, trapezoid'inki köşelerinde sıçrıyor.

Joint space ve Cartesian. Joint space interpolasyonu, iki uç da joint limitleri içindeyse limitler içinde kalır ama el bir eğri izler. Cartesian bir çizgi her waypoint’te IK ister (ders 10) ve singularity’lere ya da joint limitlerine takılabilir.

Feedforward. τ=g(q)+Kp(qr−q)+Kd(q˙r−q˙)\tau = g(q) + K_p(q_r - q) + K_d(\dot q_r - \dot q) biçimindeki bir takip controller’ı torku yalnızca bir hatadan üretir. Model terimi M(q)q¨rM(q)\ddot q_r‘yi (ders 11) eklemek ivmelendiren torku önceden sağlar; yumuşak bir referans q¨r\ddot q_r‘yi kullanılabilir ve sınırlı kılar.

Matematik ayrıntısı: quintic nereden geliyor, 1/T² ve 1/T³ yasaları

Sınır koşullarından polinomlar. Bir cubic’in dört katsayısı vardır; iki uçta ss ve s˙\dot s için yeter: s(0)=0s(0)=0, s(1)=1s(1)=1, s′(0)=s′(1)=0s'(0)=s'(1)=0 koşulları 3u2−2u33u^2 - 2u^3 verir. İvmesi s′′=6−12us'' = 6 - 12u uçlarda ±6\pm 6‘dır ve orada durağan haldeki sıfırdan sıçrar. Bir quintic’in altı katsayısı vardır; s′′(0)=s′′(1)=0s''(0) = s''(1) = 0 eklenince 10u3−15u4+6u510u^3 - 15u^4 + 6u^5 çıkar. İvmesi s′′=60u−180u2+120u3s'' = 60u - 180u^2 + 120u^3, u=(3−3)/6u = (3-\sqrt3)/6‘da 103/3≈5,7710\sqrt3/3 \approx 5{,}77 değeriyle tepe yapar; jerk’ü s′′′=60−360u+360u2s''' = 60 - 360u + 360u^2 uçlarda en büyüktür: 60.

Minimum jerk. ∫01(s′′′)2 du\int_0^1 (s''')^2\,du‘yu küçültmek, Euler–Lagrange denklemiyle s(6)=0s^{(6)} = 0 verir: beşinci dereceden bir polinom. İki uçta durağanlıkla tam olarak yukarıdaki quintic’tir (Flash & Hogan 1985).

Süreyle ölçekleme. Zincir kuralıyla q˙=Δq s′(u)/T\dot q = \Delta q\, s'(u)/T, q¨=Δq s′′(u)/T2\ddot q = \Delta q\, s''(u)/T^2, q...=Δq s′′′(u)/T3\dddot q = \Delta q\, s'''(u)/T^3. Şekil tablodaki sabitleri, süre ise TT‘nin kuvvetlerini belirler. Eklem torku ≈Mq¨\approx M\ddot q + yerçekimi; TT‘yi yarıya indirmek torkun dinamik kısmını dört katına çıkarır.

Sıçrama neden sonsuz jerk demek. İvme sonlu bir miktar sıfır zamanda değişirse türevi bir sivri tepedir (2 ms’lik bir simülasyonda: değişimin 2 ms’ye bölümü); deneydeki robot jerk sütunlarının ölçtüğü budur.

Daha derine: Calculus for Machine Learning (türev, zincir kuralı); Lynch & Park, Modern Robotics, böl. 9; T. Flash, N. Hogan, doi:10.1523/JNEUROSCI.05-07-01688.1985.

Şimdi time scaling’leri yaklaşık 40 satır NumPy ile kendin yazacaksın, polinomları kopyalamak yerine türetecek ve formül tablosunun her sayısını kontrol edeceksin; sonra sonucu ders 11’in mass matrix’iyle Deney’in Panda’sında takip edeceksin.

Adımları kendi dosyana yaz (örneğin scratch/my_trajectory.py) ve her adımdan sonra çalıştır. Bitmiş fonksiyonlar physai/trajectory.py içinde; uv run python experiments/13-trajectory-generation/build.py beş adımı kontrolleriyle birlikte koşturur (çıktı build_output.txt dosyasında).

“uu‘da rr. türev vv‘ye eşit” türündeki her koşul katsayılarda bir doğrusal denklemdir, çünkü drduruk=k!(k−r)!uk−r\frac{d^r}{du^r}u^k = \frac{k!}{(k-r)!}u^{k-r}. Katsayı sayısı kadar koşul, tek bir solve:

def poly_from_boundary(conds, degree):
"""Coefficients c (s = sum_k c_k u^k) that meet every condition (u, derivative order, value)."""
A = [[factorial(k) / factorial(k - r) * u ** (k - r) if k >= r else 0.0 for k in range(degree + 1)]
for u, r, _ in conds]
return np.linalg.solve(np.array(A), np.array([v for _, _, v in conds], dtype=float))
def poly_eval(c, u, order=0):
"""The order-th derivative of the polynomial with coefficients c, at u."""
return P.polyval(u, P.polyder(c, order))
REST = [(0, 0, 0.0), (1, 0, 1.0), (0, 1, 0.0), (1, 1, 0.0)] # s(0) = 0, s(1) = 1, at rest at both ends
CUBIC = poly_from_boundary(REST, 3)
QUINTIC = poly_from_boundary(REST + [(0, 2, 0.0), (1, 2, 0.0)], 5) # ... and zero acceleration at both ends
== Step 1. Coefficients from boundary conditions (c0 + c1 u + c2 u^2 + ...) ==
cubic (s, s' at both ends): 0.00 0.00 3.00 -2.00
quintic (s, s', s'' at both ends): 0.00 0.00 0.00 10.00 -15.00 6.00
max diff to 3u^2 - 2u^3: 0.0e+00, to 10u^3 - 15u^4 + 6u^5: 1.1e-14
one more pair (zero jerk at both ends) gives degree 7: 0 0 0 0 35 -84 70 -20

Ders kitabındaki polinomlar kendiliğinden çıkıyor; bir çift koşul daha ailenin bir sonraki üyesini veriyor (35u4−84u5+70u6−20u735u^4 - 84u^5 + 70u^6 - 20u^7, uçlarda jerk de sıfır).

Her şekil normalize zamanda ss, s′s' ve s′′s'' döndürür:

def cubic(u):
"""Cubic time scaling 3u^2 - 2u^3: s, ds/du, d2s/du2."""
return poly_eval(CUBIC, u), poly_eval(CUBIC, u, 1), poly_eval(CUBIC, u, 2)
def quintic(u):
"""Quintic (minimum-jerk) time scaling 10u^3 - 15u^4 + 6u^5: s, ds/du, d2s/du2."""
return poly_eval(QUINTIC, u), poly_eval(QUINTIC, u, 1), poly_eval(QUINTIC, u, 2)
== Step 2. Peaks of the normalised shapes (100001 points on [0, 1]) ==
shape max ds/du max d2s/du2 at u max |d3s/du3| inside
cubic 1.5000 6.0000 0.0000 12.0000
quintic 1.8750 5.7735 0.2113 60.0000
formulas: cubic 1.5, 6 at u = 0; quintic 1.875, 10 sqrt(3)/3 = 5.7735 at u = (3 - sqrt(3))/6 = 0.2113, jerk 60

Her değer matematik ayrıntısındaki kapalı formlarla örtüşüyor: cubic’in ivmesi uçlarda tepe yapıyor (6), quintic’inki u=0,2113u = 0{,}2113‘te (103/310\sqrt3/3 = 5,7735) ve quintic’in jerk’ü uçlarda 60. Cubic’in jerk’ü içeride sabit 12, ama ivmesi u=0u = 0‘da 0’dan 6’ya sıçrıyor: tablodaki ”∞” bu sıçrama.

Trapezoid parça parça tanımlıdır: bir parabol, bir doğru, bir parabol. İvmesi aa, s(1)=1s(1) = 1‘den çıkar:

def trapezoid(u, ta=1 / 3):
"""Trapezoidal velocity: accelerate for ta, cruise, decelerate for ta. Returns s, ds/du, d2s/du2."""
a = 1 / (ta * (1 - ta)) # the acceleration that makes s(1) = 1
if u < ta:
return 0.5 * a * u ** 2, a * u, a
if u <= 1 - ta:
return 0.5 * a * ta ** 2 + a * ta * (u - ta), a * ta, 0.0
return 1 - 0.5 * a * (1 - u) ** 2, a * (1 - u), -a
== Step 3. The trapezoid (ta = 1/3) ==
s(1) = 1.000000, peak ds/du = 1.5000, peak |d2s/du2| = 4.5000
max |s - integral of ds/du| = 1.0e-10 (s is continuous; d2s/du2 jumps 0 -> 4.5)

Zincir kuralı s(u)s(u)‘yu bir eklem referansına çevirir: her türev için TT‘ye böl. Hareketin dışında referans durağandır:

def joint_reference(shape, t, T, q0, dq):
"""Reference angle, speed and acceleration at time t of the move q0 -> q0 + dq lasting T seconds."""
s, s1, s2 = shape(min(max(t / T, 0.0), 1.0))
if not 0.0 < t < T: # at rest before and after the move
s1 = s2 = 0.0
return q0 + s * dq, s1 / T * dq, s2 / T ** 2 * dq
== Step 4. Reference peaks of the Panda move (largest joint 0.6 rad) ==
T (s) shape exact acc 2 ms acc exact jerk 2 ms jerk
0.25 cubic 57.60 56.68 inf inf
0.25 quintic 55.43 55.41 2304.00 2249.00
0.50 cubic 14.40 14.28 inf inf
0.50 quintic 13.86 13.86 288.00 284.55
1.00 cubic 3.60 3.59 inf inf
1.00 quintic 3.46 3.46 36.00 35.78
2.00 cubic 0.90 0.90 inf inf
2.00 quintic 0.87 0.87 4.50 4.49
1.00 trapezoid 2.70 2.70

“Exact” sütunları formül tablosunun 0,6 rad ile çarpımı: ivme için 1/T21/T^2, jerk için 1/T31/T^3. Deney’in tablosu “2 ms” sütunlarını içeriyor, çünkü referansı kontrol hızında örnekliyor ve t=0t = 0‘da durağan sayıyor: cubic’in ilk örneği 2 ms’de, orada s′′=6−12⋅0,002s'' = 6 - 12 \cdot 0{,}002, bu yüzden 3,60 yerine 3,59; quintic’in jerk’ü ise 2 ms’lik bir sonlu fark, 36,00 yerine 35,78. T = 0,25 s’de farklar büyüyor (56,68’e karşı 57,60, 2249,00’a karşı 2304,00), çünkü 2 ms o zaman hareketin daha büyük bir payı.

joint_reference’ı Deney’in controller’ına ver ve ders 11’deki mass_matrix ile M(q)q¨rM(q)\ddot q_r‘yi ekle:

q_ref, qd_ref, qdd_ref = joint_reference(quintic, d.time, 1.0, Q0, DQ)
tau = d.qfrc_bias[:7] + KP * (q_ref - d.qpos[:7]) + KD * (qd_ref - d.qvel[:7])
tau = tau + mass_matrix(tree, d.qpos)[:7, :7] @ qdd_ref - d.qfrc_passive[:7] # feedforward
== Step 5. Track the quintic on the Panda (T = 1 s, the Experiment's PD + qfrc_bias) ==
PD + gravity tracking error 1.32 deg, robot peak jerk 35 rad/s^3
PD + M qdd_ref - passive tracking error 0.01 deg, robot peak jerk 48 rad/s^3

Deney’in quintic satırları, 1,32° ve 0,01°, senin referansından ve senin mass matrix’inden.

physai.trajectory artık poly_from_boundary, poly_eval, cubic, quintic, trapezoid ve joint_reference içeriyor. Ders 14 contact hedefini aynı quintic ile rampalıyor. tests/test_13_trajectory_generation.py bunları kapalı formlara karşı kontrol ediyor; bir şey değiştirdikten sonra uv run pytest tests/test_13_trajectory_generation.py çalıştır.

MuJoCo’nun bir trajectory generator’ı yok: hesapladığın referans neyse onu simüle eder. Noktadan noktaya bir hareket için SciPy’ın spline’ları aynı eğrileri verir:

from scipy.interpolate import CubicSpline, make_interp_spline
cs = CubicSpline([0, T], [q0, q1], bc_type="clamped") # zero speed at both ends: the cubic
qs = make_interp_spline([0, T], [q0, q1], k=5,
bc_type=([(1, 0.0), (2, 0.0)], [(1, 0.0), (2, 0.0)])) # + zero acceleration: the quintic
q, qd, qdd = qs(t), qs(t, 1), qs(t, 2)
== Use it. SciPy splines through the two end points (T = 1 s, 0 -> 0.6 rad) ==
CubicSpline(bc_type='clamped') vs cubic: max diff 3.3e-16 rad
make_interp_spline(k=5, zero speed and acceleration) vs quintic: max diff 1.5e-15 rad, peak jerk 36.00 rad/s^3

İkiden fazla noktayla aynı çağrılar bütün ara noktalardan geçen yumuşak bir eğri verir; tek hareketlik formüller bunu yapamaz.

AraçÇağrıŞekil
physaijoint_reference(quintic, t, T, q0, dq)tt anında qq, q˙\dot q, q¨\ddot q
SciPyCubicSpline(t, q, bc_type="clamped"), make_interp_spline(t, q, k=5, bc_type=...)ara noktalardan geçen parçalı polinomlar; spline(t, n) nn. türevi verir
Modern Robotics koduCubicTimeScaling(Tf, t), QuinticTimeScaling(Tf, t), JointTrajectory(thetastart, thetaend, Tf, N, method)yalnız s(t)s(t) ve NN örneklenmiş eklem vektörü (core.py)
libfrankalimitRate(...)komut edilen hızı, ivmeyi ve jerk’ü robotun sınırlarına kırpar (rate_limiting.h)

Üç tuzak:

  • Normalize ve gerçek zaman. s′(u)s'(u), uu birimi başınadır; eklem hızı s′(u) Δq/Ts'(u)\,\Delta q / T‘dir. Bir 1/T1/T‘yi unutmak en yaygın hata ve T = 0,25 s’de 4 kat fark eder.
  • Örneklenmiş tepeler tepe değildir. Kontrol hızında bir limite karşı kontrol edilen referans, iki örnek arasında olan bir sıçramayı kaçırabilir (Adım 4: 3,60’a karşı 3,59).
  • Kırpmak yumuşatmak değildir. Bir rate limiter her komutu geçerli tutar ama sıçrayan bir referansı farklı, planlanmamış bir harekete çevirir; baştan yumuşak bir referans planla.

Yazdıktan sonra · 2 soru.

1. Sıfırdan yaz, Adım 1 quintic’in katsayılarını nasıl buluyor?

  • Altı sınır koşulundan (iki uçta s, s’, s”), her biri bir doğrusal denklem, birlikte çözülerek.
  • Deney’in ölçtüğü joint açılarına polinom uydurarak.
  • Cubic’in integralini bir kez daha alarak.

Neden: poly_from_boundary 0, 0, 0, 10, −15, 6 döndürür; bir çift koşul daha (sıfır jerk) 7. derece 35u⁴ − 84u⁵ + 70u⁶ − 20u⁷ biçimini verir.

2. Formül T = 1 s’de cubic’in tepe ivmesini 3,60 rad/s² veriyor, Deney’in tablosu 3,59. Neden (Sıfırdan yaz, Adım 4)?

  • Panda’nın tork limitleri ivmeyi kırpıyor.
  • Deney referansı 2 ms’de bir örnekliyor ve t = 0’da durağan sayıyor; ilk örneği 2 ms’de, orada s” = 6 − 12·0,002.
  • Deney’de cubic’in katsayıları yuvarlanmış.

Neden: Quintic’in jerk’ü için de sebep aynı, 36,00 yerine 35,78: 2 ms’lik finite difference. T = 0,25 s’de fark büyüyor (56,68’e karşı 57,60).

Kurulum. Panda (Menagerie), home keyframe’inden başlıyor, joint hareketi Δq\Delta q = (0,6, 0,4, −0,4, 0,5, 0,5, −0,4, 0,6) rad. Modelin yerleşik position actuator’ları kapatıldı (actuator_gainprm ve actuator_biasprm 0 yapıldı); torque’lar qfrc_applied’a yazılıyor ve modelin sınırlarında kırpılıyor (joint 1–4 için 87 N·m, joint 5–7 için 12 N·m). Controller ve fizik 2 ms’de çalışıyor:

s, sd, sdd = profile(kind, d.time, T)
q_ref, qd_ref = Q0 + s * DQ, sd * DQ
tau = d.qfrc_bias[:7] + KP * (q_ref - q) + KD * (qd_ref - qd) # PD + gravity/Coriolis
tau = np.clip(tau, -lim, lim)

Kp = (600, 600, 600, 600, 250, 150, 50), Kd = (50, 50, 50, 50, 20, 12, 4). “Robot” sütunları simülasyonda qacc’den ölçülüyor; robot jerk’ü onun 2 ms’deki sonlu farkı. “Saturation’daki adımlar”, herhangi bir joint torkunun limitinde kırpıldığı kontrol adımlarının payıdır. Tam script: experiments/13-trajectory-generation/experiment.py. MuJoCo 3.17.0, NumPy 2.5.4, Python 3.14, Apple M5, deterministik, ~4 s.

Tahmin et. Hangi şeklin takip hatası en küçük? Hangisinin jerk’ü en küçük?

A. Beş şekil, T = 1 s (referans değerleri en büyük joint için, 0,6 rad; hata = hareket boyunca en büyük ∣qr−q∣|q_r - q|):

şekilref. tepe ivme [rad/s²]ref. tepe jerk [rad/s³]robot tepe ivmerobot tepe jerktakip hatasısaturation’daki adımlar
step∞∞739,217502534,35°%5,5
linear∞∞220,91104750,78°%0,0
trapezoid2,70∞3,010031,08°%0,0
cubic3,59∞3,613371,05°%0,0
quintic3,4635,783,7351,32°%0,0
quintic + Mq¨rM\ddot q_r − passive3,4635,783,5480,01°%0,0
  • Step, adımların %5,5’inde torque’u saturation’a sokuyor ve kendi referansının 34,35° gerisinde kalıyor; robotun ivmesi 739,2 rad/s²’ye çıkıyor.
  • Jerk süreklilikle gelir. İvmesi sıçrayan her şekil (linear, trapezoid, cubic) 1003–110475 rad/s³ robot jerk’ü üretiyor; quintic 35 rad/s³ üretiyor ve referansıyla (35,78) uyuşuyor. Esnek uzuvları, dişli kutularını ve gripper’daki nesneyi titreten şey jerk’tür.
  • Yumuşak şekillerin takip hatası yaklaşık 1° ve onu şekil belirlemiyor. En kötü joint, modelin pasif damping’inin (1 N·m·s/rad) ve ataletin karşılanmadığı joint 7 (Kp 50). Model feedforward’ı Mq¨rM\ddot q_r‘yi eklemek ve qfrc_passive’i iptal etmek hatayı 0,01°‘ye düşürüyor. Jerk’ü şekil belirler; takip hatasını model belirler.

B. Süre sweep’i (aynı hareket):

T [s]şekilref. tepe ivmeref. tepe jerkrobot tepe jerkhata
0,25cubic56,68∞213114,46°
0,25quintic55,412249,021075,52°
0,50cubic14,28∞53172,16°
0,50quintic13,86284,62342,73°
1,00cubic3,59∞13371,05°
1,00quintic3,4635,8351,32°
2,00cubic0,90∞3350,52°
2,00quintic0,874,540,65°

İvme 1/T21/T^2 ile ölçekleniyor (56,68 → 14,28 → 3,59 → 0,90, her yarılanmada 4 kat), quintic’in jerk’ü 1/T31/T^3 ile (2249,0 → 284,6 → 35,8 → 4,5, 8 kat), yalnız PD ile takip hatası ise kabaca 1/T1/T ile. Her sürede cubic’in robot jerk’ü quintic’inkinin bir mertebe ya da daha fazla üstünde (0,25 s’de 21311’e karşı 2107 rad/s³, 2 s’de 335’e karşı 4).

C. Joint space mi, Kartezyen mi? Tool centre point, sabit oryantasyonla yy boyunca 50 cm ilerliyor; uçlar A ve B IK çözümleri (IK kalıntısı 0,001 mm’nin altında):

interpolasyonçizgiden en büyük uzaklıkel yolujoint yolu
joint space (qq‘da quintic)5,38 cm51,53 cm1,089 rad
Kartezyen (her ara noktada IK)0,00 cm50,00 cm1,256 rad

Aynı uçlar, aynı zamanlama: joint space yolu çizgiden 5,38 cm sapıyor. Kalabalık bir sahnede bir kutunun kenarına çarpmaya yeter; boş alanda ise önemsiz, orada joint space daha ucuz (1,089’a karşı 1,256 rad joint hareketi) ve yol ortasında asla singularity’ye girmez.

Hareketi kısalt. T = 0,25 s’de referans, 0,6 rad’lık joint hareketi için 55,41 rad/s² (quintic) istiyor; yumuşak quintic bile artık 2107 rad/s³ robot jerk’ü ve 5,52° takip hatası üretiyor. Uca git, T → 0, step’i elde edersin: torque saturation (adımların %5,5’i), 739,2 rad/s² ivme ve 34,35° gecikme. Mekanizma controller değil, ölçekleme yasası: hiçbir gain ayarı actuator’ların veremeyeceği ivmeyi üretemez ve torque kırpıldığında PD’nin özenle ayarlanmış damping’i ortadan kalkar.

  • Panda / FR3 sınıfı. libfranka’nın rate limiter sabitleri (10 rad/s² joint ivmesi, 5000 rad/s³ jerk, 1 ms periyot; rate_limiting.h) sıçrayan her referans tarafından ihlal edilir. Bizim sweep’imizde T = 0,5 s’de hem cubic hem quintic 10 rad/s²’yi aşıyor (14,28 ve 13,86) ve cubic’in ivme süreksizliği her sürede sınırsız jerk veriyor. 1 s’lik bir quintic iki sınırın da içinde kalıyor (3,46 rad/s², 35,78 rad/s³). Bu karşılaştırmalar simüle ettiğimiz referansları kullanıyor; burada hiçbir şey bir Panda’da koşturulmadı.
  • Go2. SDK ayağa kalkma örneğinin parça parça doğrusal rampası (ders 12) “linear” satırıdır: konum adımları sınırlı, ama her ara noktada hız sıçrıyor.
  • SO-101. Servolar hedef konumları kontrol döngüsünün hızında alır. Ham hedefler üreten 30 Hz’lik bir policy fiilen bir merdiven gönderiyor; hedefler arasında interpolasyonun gerçek kolda jerk’ü azaltıp azaltmadığı henüz ölçülmedi.

Hızlı kontrol · 2 soru. Bir cevaba tıkla.

1. T = 1 s’de en düşük referans tepe ivmesi trapezoid’de (2,70 rad/s²). Panda neden yine de onunla quintic’e göre çok daha fazla jerk görüyor?

  • İvmesi köşelerde sıçrıyor; sıfır ivmeyle başlayıp biten yalnızca quintic.
  • Sabit hız fazı PD gain’leri için fazla hızlı.
  • Step gibi joint torque’larını saturation’a sokuyor.

Neden: Jerk ivmenin sürekliliğini izler - A bölümünde robot jerk’ü trapezoid için 1003 rad/s³, quintic için 35; ikisinde de saturation’daki adımlar %0,0.

2. T = 1 s’de bütün yumuşak şekiller yaklaşık 1° hatayla takip ediyor. Quintic’in hatasını 0,01°‘ye ne indirdi?

  • Cubic’ten quintic’e geçmek.
  • Hareketi iki kat uzatmak.
  • Model feedforward’ı Mq¨rM\ddot q_r‘yi eklemek ve qfrc_passive’i iptal etmek.

Neden: Jerk’ü şekil, takip hatasını model belirler. A bölümü - quintic 1,32°, quintic + feedforward 0,01°; T’yi iki katına çıkarmak yalnızca 0,65°‘ye indiriyor (B bölümü).

  1. Kolay. Bir quintic bir joint’i 2 s’de 1 rad hareket ettiriyor. Tepe ivmesi ve tepe jerk’ü nedir?
  2. Orta. A bölümünde linear profil, referans ivmesi sonsuz olduğu hâlde neden en küçük takip hatasına (0,78°) sahip?
  3. Zor. experiment.py’de cubic ve trapezoid’e M(q)q¨r−M(q)\ddot q_r - qfrc_passive feedforward’ı ekle. Koşturmadan önce tahmin et: onların takip hatası da ~0,01°‘ye düşer mi? Robot jerk’leri değişir mi?
  1. Tepe ivme 5,77⋅1/22≈1,445{,}77 \cdot 1 / 2^2 \approx 1{,}44 rad/s²; tepe jerk 60⋅1/23=7,560 \cdot 1 / 2^3 = 7{,}5 rad/s³ (tablodaki formüllerden).
  2. Tepe hızı (Δq/T\Delta q/T) tüm şekillerin en düşüğü ve ivmesi iki an dışında sıfır; bu, modellenmemiş damping torque’unun en küçük olmasıyla tutarlı. Sonsuz ivme yalnızca başta ve sonda iki kısa sıçrama olarak görünüyor (robot tepesi 220,9 rad/s²).
  3. Burada hesaplanmadı; koştur.
  • Zaman ölçekleme fiziği belirler: ivmeler 1/T21/T^2, jerk’ler 1/T31/T^3 ile ölçeklenir; bir step Panda’nın torque’unu saturation’a sokar ve 34,35° geride kalır.
  • Jerk’ü ivmenin sürekliliği belirler: T = 1 s’de quintic 35 rad/s³, trapezoid ve cubic 1003–1337 rad/s³. Takip hatasını model belirler: feedforward onu 1,32°‘den 0,01°‘ye indirir.
  • Joint space interpolasyonu düz çizgiden sapar (burada 50 cm’de 5,38 cm); Kartezyen interpolasyonu yalnızca yolun önemli olduğu yerde kullan.

Sonraki: ders 14 · Operational-space ve impedance control.

Kaynaklar: