İçeriğe geç

09 · Jacobian ve differential kinematics

Bölüm3 · Kinematics
Çalışma türüCPU · Mac ya da Colab CPU
Önkoşul08
Önce öğrenCalculus for Machine Learning · Linear Systems
Süre~45 dk
Kodexperiments/09-jacobians/experiment.py
Durum✅ tam

Bu derste yap

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

Tek bir matris joint hızlarını alet hızına çevirir; transpozu da alet kuvvetlerini joint torklarına geri çevirir.

SO-101’in omuz servosu gripper’daki 2 N’luk bir itmeyi tutmak için ne kadar tork ister? Joint’ler toplamda 1 rad/s ile dönerken gripper ne kadar hızlı hareket eder? İki sorunun cevabı aynı: her pozda değişen 6×5’lik bir matris. Menagerie modeli her servoyu 2,94 N m ile sınırlıyor (so101.xml içinde forcerange="-2.94 2.94"); bir yükün güvenli olup olmadığı yalnızca yüke değil, o matrise bağlı.

Bu matrisin tam doğru olması da gerekiyor: ders 10 onunla yüzlerce kez iterasyon yapıyor. Yaygın bir kısayol onu finite difference ile hesaplamaktır. Bu ders o kısayolun ne zaman doğru, ne zaman yanlış olduğunu ölçüyor.

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

1. Omuz, kol katlıyken de gerginken de aynı hızla dönüyor. Gripper ne zaman daha hızlı hareket eder?

  • Katlıyken, çünkü motor daha az yük taşır.
  • Gerginken, çünkü gripper omuz ekseninden daha uzaktadır.
  • İkisinde de aynı, çünkü joint hızı aynı.

Neden: Bir hinge’in sütunu a^×(p−o)\hat a \times (p - o); uzunluğu eksenden alete olan mesafeyle büyür, daha uzun bir anahtar gibi (Sade anlatımla).

2. Gripper’a dümdüz aşağı bastırıyorsun. Hangi joint bu baskıdan hiç tork hissetmez?

  • Ekseni dikey olan shoulder_pan.
  • Tabana en yakın joint olan shoulder_lift.
  • Hiçbiri; her joint bir kısmını hisseder.

Neden: Dikey bir kuvvetin dikey bir eksen etrafında momenti yoktur. Deney, Adım 3’te F=(0,0,−2)F = (0, 0, -2) N için J⊤FJ^\top F 0,0000 ile başlıyor.

Bir motoru biraz döndür ve gripper’ı izle: belli bir yöne, belli bir hızla biraz hareket eder. Bunu her motor için yap ve cevapları her motor için bir sütun olacak şekilde yaz. Bu tablo Jacobian’dır: “her motor biraz dönünce el hangi yöne ve ne hızla gider”. Birkaç motoru aynı anda döndürürsen elin hızı, her biri kendi motorunun hızıyla ölçeklenmiş bu sütunların toplamıdır. Tablo poza göre değişir, çünkü kaldıraç kolları değişir: kol gergin uzanmışken omuz eli, kol katlıyken olduğundan çok daha hızlı hareket ettirir.

Aynı tablo tersten okununca (transpose’u) kuvvet sorusunu cevaplar. Gripper’a bastır: her motor, baskı çarpı kendi kaldıraç kolu kadar bir tork hisseder; sütunu tam olarak bunu kodlar. Uzun bir kaldıraç torku büyütür, uzun bir anahtar gibi.

Tabloyu analitik olarak yazamıyorsan ölçebilirsin: bir joint’i küçük bir adım kadar oynat, aletin ne kadar gittiğine bak, böl. Bu bir finite difference’tır; ML’deki sayısal gradient kontrolüyle aynı numara. Adım çok büyükse hareketin eğriliği tahmini bozar; çok küçükse floating-point yuvarlaması bozar.

flowchart TD
    Q["şu anki poz q<br/>(joint açıları)"] -.-> J["Jacobian J(q)<br/>6 satır × 5 sütun,<br/>her joint için bir sütun"]
    QD["joint hızları q̇"] --> M1["J ile çarp"]
    J -.-> M1
    M1 --> V["alet hızı:<br/>doğrusal v, açısal ω"]
    F["aletteki kuvvet<br/>ve moment (F, M)"] --> M2["Jᵀ ile çarp"]
    J -.-> M2
    M2 --> T["joint torkları τ"]
import numpy as np
def hinge_column(axis, o, p): # axis: joint axis (unit, world), o: point on the axis, p: tool point
jp = np.cross(axis, p - o) # tool linear velocity per 1 rad/s of this joint (m/s)
jr = axis # tool angular velocity per 1 rad/s of this joint (rad/s)
return np.r_[jp, jr]
J = np.column_stack([hinge_column(a, o, p) for a, o in zip(axes, origins)]) # 6 x n
twist = J @ qdot # [v; w]: tool velocity for joint speeds qdot
tau = J.T @ np.r_[F, M] # joint torques for the tool to push with force F and moment M
def fd_column(tool_pos, q, i, eps=1e-5): # central difference for column i (position rows)
dq = np.zeros_like(q)
dq[i] = eps
return (tool_pos(q + dq) - tool_pos(q - dq)) / (2 * eps)
BüyüklükFormül
Hız haritası[vω]=J(q) q˙=[Jp(q)Jr(q)]q˙,J∈R6×n\begin{bmatrix} v \\ \omega \end{bmatrix} = J(q)\,\dot q = \begin{bmatrix} J_p(q) \\ J_r(q) \end{bmatrix}\dot q ,\qquad J \in \mathbb R^{6\times n}
Bir hinge’in ii. sütunuJp,i=a^i×(p−oi)J_{p,i} = \hat a_i \times (p - o_i),  Jr,i=a^i\ J_{r,i} = \hat a_i
Statik kuvvet haritasıτ=J⊤[FM]\tau = J^\top \begin{bmatrix} F \\ M \end{bmatrix}
İleri farkx(q+εei)−x(q)ε\frac{x(q + \varepsilon e_i) - x(q)}{\varepsilon}, hata O(ε)O(\varepsilon)
Merkezi farkx(q+εei)−x(q−εei)2ε\frac{x(q+\varepsilon e_i) - x(q-\varepsilon e_i)}{2\varepsilon}, hata O(ε2)O(\varepsilon^2)

qq ve q˙\dot q joint açıları ve hızlarıdır; vv ve ω\omega aletin world koordinatlarındaki doğrusal ve açısal hızıdır; JpJ_p ve JrJ_r, JJ‘nin üç konum ve üç rotation satırıdır; a^i\hat a_i, ii. hinge’in world koordinatlarındaki birim ekseni, oio_i bu eksen üzerindeki herhangi bir noktadır; pp alet noktasıdır; FF ve MM aletin çevreye uyguladığı kuvvet ve momenttir; τ\tau joint torklarının vektörüdür; x(q)x(q) alet konumu, eie_i ii. joint’in birim vektörü, ε\varepsilon adımdır.

Bu geometric Jacobian’dır (Lynch & Park, Modern Robotics, Böl. 5). MuJoCo onu mj_jac (bir body’ye bağlı herhangi bir world noktası), mj_jacBody ve mj_jacSite ile döndürür (API reference). Alete bastıran bir dış wrench (kuvvet artı moment) (F,M)(F, M), −J⊤[F;M]-J^\top[F;M] ile tutulur.

Matematik ayrıntısı: sütun formülü, virtual work ve en iyi finite difference adımı

Bir hinge’in sütunu. ii. hinge’i 1 rad/s ile döndürmek, ondan sonraki her şeyi oio_i‘den geçen a^i\hat a_i ekseni etrafında döndürür. oo‘dan geçen bir doğru etrafında ω\omega açısal hızıyla dönen rigid bir cisim üzerindeki pp noktası ω×(p−o)\omega \times (p - o) hızıyla hareket eder; bu da Jp,i=a^i×(p−oi)J_{p,i} = \hat a_i \times (p - o_i) ve Jr,i=a^iJ_{r,i} = \hat a_i verir.

Virtual work ile statik kuvvet haritası. Dengede joint’lerin verdiği güç aletin aktardığı güce eşittir: her q˙\dot q için τ⊤q˙=[F;M]⊤[v;ω]=[F;M]⊤Jq˙\tau^\top \dot q = [F; M]^\top [v; \omega] = [F; M]^\top J\dot q, dolayısıyla τ=J⊤[F;M]\tau = J^\top [F; M]. Sürtünme, boşluk ve yerçekimi ek terimlerdir (yerçekimi Boz bölümünde giriyor).

Finite difference hatası. Taylor açılımı ileri fark için ε\varepsilon mertebesinde, merkezi fark için ε2\varepsilon^2 mertebesinde bir truncation hatası verir. Floating-point yuvarlaması yaklaşık ϵmach∣x∣/ε\epsilon_{\text{mach}}\lvert x\rvert/\varepsilon kadar hata ekler; ϵmach\epsilon_{\text{mach}} machine epsilon’dur (bir double’ın göreli hassasiyeti). Toplamı en küçük yapmak, ileri fark için kabaca ϵmach\sqrt{\epsilon_{\text{mach}}}, merkezi fark için ϵmach3\sqrt[3]{\epsilon_{\text{mach}}} civarında bir en iyi adım verir.

Rotation sütunları özeldir. Bir hinge’i ε\varepsilon kadar oynatmak aleti tam olarak o hinge’in ekseni etrafında ε\varepsilon kadar döndürür; orientation fark oranında truncation hatası yoktur, yalnızca yuvarlama vardır (Deney, Adım 2).

Daha derine: AIEFS Calculus for Machine Learning, Linear Systems; Lynch & Park, Modern Robotics, Böl. 5 “Velocity Kinematics and Statics”.

Şimdi SO-101’in Jacobian’ını ders 08’in üzerine yaklaşık 30 satır NumPy ile kendin yazacaksın ve her adımı MuJoCo ile karşılaştıracaksın. Ders 08’den elinde chain_from_mujoco ve fk var; fk her hinge’in dünyadaki eksenini a^i\hat a_i, üzerindeki bir noktayı oio_i ve alet noktasını pp döndürüyor: sütun formülünün ihtiyaç duyduğu üç şey tam olarak bunlar. MuJoCo’dan yeni hiçbir şey gelmiyor.

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

Ana fikir’deki formül, tek bir hinge için: doğrusal kısım eksen ile eksenden alete uzanan kaldıracın çapraz çarpımı, açısal kısım eksenin kendisi.

def hinge_column(axis, o, p):
"""Tool twist per 1 rad/s of one hinge: linear part a x (p - o), angular part a."""
return np.r_[np.cross(axis, p - o), axis]
chain = chain_from_mujoco(m, "gripperframe") # lesson 08
axes, anchors, p = fk(chain, Q0)
col = hinge_column(axes[1], anchors[1], p) # shoulder_lift
== Step 1. One hinge column at q = (0, -0.6, 0.9, 0.4, 0.3) ==
shoulder_lift column, ours: -0.0198 0.0000 -0.2193 0.0000 1.0000 0.0000
shoulder_lift column, MuJoCo: -0.0198 0.0000 -0.2193 0.0000 1.0000 0.0000
lever |a x (p - o)| = 0.2202 m, max difference 8.3e-17

Lift sütunu rad/s başına (−0,0198,0,−0,2193)(-0{,}0198, 0, -0{,}2193) m/s: lift’i döndürmek aleti çoğunlukla dümdüz aşağı, 0,2202 m’lik bir kaldıracın hızıyla hareket ettirir.

Her hinge için bir sütun, yan yana; fk’nın zaten döndürdüğü eksen ve noktalarla:

def jacobian(chain, q):
"""Geometric Jacobian (6 x n) of the tool point: rows 0-2 linear, rows 3-5 angular, world frame."""
axes, anchors, p = fk(chain, q)
return np.column_stack([hinge_column(a, o, p) for a, o in zip(axes, anchors)])
== Step 2. Jacobian from hinge columns vs mj_jacSite (50 poses) ==
max entry error: linear rows 3.9e-16, angular rows 1.0e-15

JJ elindeyken Problem bölümündeki iki soru birer satır:

J = jacobian(chain, Q0)
speed = np.linalg.norm(J[:3] @ (np.ones(5) / np.sqrt(5))) # tool speed, every joint at 1/sqrt(5) rad/s
tau = J[:3].T @ np.array([0, 0, -2.0]) # torques for a 2 N push down
== Step 3. Use it at q = (0, -0.6, 0.9, 0.4, 0.3) ==
tool speed for every joint at 1/sqrt(5) rad/s: 0.312 m/s
F = [0, 0, -2.0] N -> J^T F = 0.0000 0.4385 0.5194 0.2586 0.0042 N m
F = [2.0, 0, 0] N -> J^T F = 0.0052 -0.0397 -0.2571 -0.1873 -0.0036 N m
F = [0, 1.5, 0] N -> J^T F = -0.3745 0.0000 0.0000 0.0000 0.0175 N m

Aşağı baskı için lift torku, 2 N çarpı Adım 1’deki lift sütununun dikey girdisi. Deney’in Adım 3 tablosuyla karşılaştır: servo lift’te 0,4383 N m tuttu, burada 0,4385 N m çıkıyor. Aradaki 0,0002 bir hata değil. Servo’lar yük altında biraz esner, kol biraz farklı bir pozda oturur ve JJ poza bağlıdır; oturmuş pozda ikisi 4,2e-14 farkla aynı. Pan girdisinin sıfır olmasının sebebini ilk alıştırma soruyor.

Öğrenilmiş bir modelinki dahil her Jacobian’a uygulayabileceğin test: her joint’i biraz oynat ve kendi forward kinematics’inin farkını al.

def fd_jacobian(tool_pos, q, eps=1e-5):
"""Position rows of the Jacobian by central differences of any function q -> tool position."""
cols = []
for i in range(len(q)):
dq = np.zeros(len(q))
dq[i] = eps
cols.append((tool_pos(q + dq) - tool_pos(q - dq)) / (2 * eps))
return np.column_stack(cols)
== Step 4. Central differences of our FK vs our analytic Jacobian (eps = 1e-5) ==
median max entry error: 4.7e-12

Deney’deki ε sweep’inin mj_jacSite’a karşı ε = 1e-5’te merkezi farklar için bulduğu hata bu (5,6e-12); bu kez kendi matrisine karşı.

physai.kinematics artık hinge_column, jacobian ve fd_jacobian de içeriyor. Ders 10 inverse kinematics’i, ders 14 bir task-space controller’ı bunların üzerine kuruyor. tests/test_09_jacobians.py bunları MuJoCo’ya sabitliyor; bir şey değiştirdikten sonra uv run pytest tests/test_09_jacobians.py çalıştır.

Pratikte aynı matrisi kütüphaneden istersin. MuJoCo’da bu üç çağrı, ve ikincisi kolayca unutulur:

mujoco.mj_kinematics(m, d)
mujoco.mj_comPos(m, d) # mj_jac* reads data that only mj_comPos fills
jacp, jacr = np.zeros((3, m.nv)), np.zeros((3, m.nv))
mujoco.mj_jacSite(m, d, jacp, jacr, site_id)
J = np.r_[jacp, jacr] # equals jacobian(chain, q) to 1e-15 (Build it, Step 2)

Başka araçlar aynı bilgiyi farklı konvansiyonlarla döndürür. Sayıları karıştırmadan önce hangisinin elinde olduğuna bak:

AraçÇağrıSatır sırasıHangi noktanın hızı, hangi eksenlerde
physaijacobian(chain, q)önce doğrusal, sonra açısalalet noktası, dünya eksenleri
MuJoComj_jacSite(m, d, jacp, jacr, site)iki ayrı 3 × nv dizisite, dünya eksenleri
PinocchiocomputeFrameJacobian(model, data, q, frame_id, LOCAL_WORLD_ALIGNED)önce doğrusal, sonra açısalframe orijini, dünya eksenleri (yukarıdakiyle aynı); LOCAL frame’in kendi eksenlerini kullanır
Modern Roboticsspace Jacobian JsJ_s, body Jacobian JbJ_bönce açısal, sonra doğrusalJsJ_s: gövdenin space-frame orijinindeki noktası; JbJ_b: body frame orijini, gövde eksenleri

Saatlere mal olan üç tuzak:

  • Sütunlar serbestlik dereceleridir. MuJoCo Jacobian’larının m.nq (konum) değil m.nv (hız) kadar sütunu vardır. Modelde free ya da ball joint olduğu anda ikisi ayrılır (quaternion’ın 4 sayısı ama 3 dönme hızı vardır); bkz. ders 36.
  • Quaternion sırası. MuJoCo (w,x,y,z)(w, x, y, z) saklar; SciPy’ın Rotation.from_quat’ı scalar_first=True vermezsen (x,y,z,w)(x, y, z, w) bekler.
  • Bayat veri. mj_jacSite son mj_kinematics/mj_forward’ın hesapladığı konumları okur; qpos’u değiştirip yeniden hesaplamayı unutursan hiçbir hata almadan bir önceki pozun Jacobian’ını alırsın.

Yazdıktan sonra · 2 soru.

1. Sıfırdan yaz, Adım 1: q = (0, −0,6, 0,9, 0,4, 0,3)‘te shoulder_lift sütununun doğrusal kısmının uzunluğu 0,2202 m. Bu sayı ne?

  • Lift’in 1 rad/s’si başına alet hızı (m/s): lift ekseninden alete olan kaldıraç.
  • MJCF dosyasındaki üst kol link’inin uzunluğu.
  • Elle yazılan sütunun yuvarlama hatası.

Neden: ∣a^×(p−o)∣|\hat a \times (p - o)| eksenden alet noktasına olan mesafedir; sütun MuJoCo’nunkiyle 8,3e-17 farkla örtüşür ve 2 N çarpı dikey girdisi 0,2193, Adım 3’teki 0,4385 N m’yi verir.

2. Sıfırdan yaz, Adım 3 2 N aşağı baskı için lift’te J⊤FJ^\top F = 0,4385 N m veriyor; Deney’deki servo 0,4383 N m tuttu. Fark neden?

  • Elle yazılan Jacobian’da bir hata.
  • Transpose’taki float yuvarlaması.
  • Servo’lar yük altında biraz esner, kol biraz farklı bir pozda oturur ve JJ poza bağlıdır.

Neden: Adım 3 JJ‘yi komut verilen pozda hesaplar; Deney oturmuş pozda karşılaştırır ve orada J⊤FJ^\top F ile servo torku 4,2e-14 farkla aynıdır. Elle yazılan JJ verilen her pozda mj_jacSite ile 1,0e-15 farkla örtüşür (Adım 2).

Script: experiments/09-jacobians/experiment.py. MuJoCo 3.17.0, NumPy 2.5.4, Apple Silicon Mac (Apple M5), deterministik, birkaç saniye.

mujoco.mj_kinematics(m, d)
mujoco.mj_comPos(m, d) # fills the data mj_jac* reads
jp, jr = np.zeros((3, m.nv)), np.zeros((3, m.nv))
mujoco.mj_jacSite(m, d, jp, jr, site_id) # 3 x nv each, world frame

Önce tahmin et. Daha küçük bir finite difference adımı her zaman daha mı iyi? Hangi adımı seçerdin?

Adım 1 · hız haritası. 50 rastgele poz, rastgele birim joint hızları. Tahmin edilen Jq˙J\dot q ile site’ın 10−610^{-6} s’deki gerçek hareketi: en büyük bağıl hata 7,9e-07 (doğrusal) ve 3,8e-07 (açısal). Her joint 1/51/\sqrt5 rad/s’de (∣q˙∣=1\lvert\dot q\rvert = 1) iken medyan site hızı 0,306 m/s.

Adım 2 · ε adımı sweep’i. 50 pozun medyanı; mj_jacSite’a göre en büyük eleman hatası. Orientation farkları mju_subQuat ile alınıp world frame’ine döndürülüyor.

ε (rad)ileri JpJ_pileri JrJ_rmerkezi JpJ_pmerkezi JrJ_r
1e-11,2e-024,8e-154,2e-042,6e-15
1e-31,2e-044,5e-134,2e-082,5e-13
1e-51,2e-064,7e-115,6e-122,3e-11
1e-71,2e-084,5e-094,7e-102,3e-09
1e-89,8e-094,4e-084,9e-092,3e-08
1e-109,5e-074,4e-064,3e-072,2e-06
1e-128,9e-054,6e-044,7e-052,4e-04
1e-148,3e-034,5e-024,5e-032,6e-02

Öteleme hatası V biçiminde. Minimumun sağında truncation (ε’un her on kat büyümesinde hata ileri farkta 10 kat, merkezi farkta 100 kat artıyor); solunda yuvarlama (ε’un her on kat küçülmesinde hata 10 kat artıyor). En iyi ileri adım 1e-8 (hata 9,8e-09), en iyi merkezi adım 1e-5 (hata 5,6e-12). Karşılaştırma için ϵmach=\sqrt{\epsilon_{\text{mach}}} = 1,5e-08 ve ϵmach3=\sqrt[3]{\epsilon_{\text{mach}}} = 6,1e-06.

Log eksenlerde, adım boyuna göre finite difference Jacobian hatası. Translation sütunlarında iki yöntem de V çiziyor: ileri fark 1e-8 rad civarında, merkezi fark 1e-5 rad civarında en iyi; daha küçük adımlarda ikisi de kötüleşiyor. Rotation sütunlarında hata yalnızca adım küçüldükçe büyüyor.

Rotation sütunlarında hiç truncation hatası yok: bir hinge’i ε kadar oynatmak site’ı tam olarak o hinge’in ekseni etrafında ε kadar döndürür; fark oranı kesindir, geriye yalnızca yuvarlama kalır (ε = 0,1’de 4,8e-15, ε küçüldükçe büyüyor).

Adım 3 · simülasyonda τ = Jᵀ F doğrulaması. Yalnızca dış kuvvet etki etsin diye yerçekimi ve joint friction loss kapatıldı. Kol position servo’larıyla (komut edilen açıya doğru geri iten motorlar) bir pozu tutuyor; gripper site’ına xfrc_applied ile sabit bir kuvvet uygulanıyor (kuvvet artı r×Fr\times F momenti, çünkü xfrc_applied body’nin kütle merkezinde etki eder). 20 s’lik simülasyondan sonra joint’ler duruyor (en büyük |q̇| = 8,5e-15 rad/s) ve servo torkları J⊤FJ^\top F ile karşılaştırılıyor:

site’taki F (N)J⊤FJ^\top F (N m), joint 1–5servo torku (N m), işaret çevrilmişen büyük fark
(0, 0, −2)0,0000, 0,4383, 0,5191, 0,2584, 0,00420,0000, 0,4383, 0,5191, 0,2584, 0,00424,2e-14
(2, 0, 0)0,0052, −0,0395, −0,2569, −0,1872, −0,0036aynı7,1e-14
(0, 1,5, 0)−0,3745, −0,0000, −0,0001, −0,0001, 0,0175aynı7,2e-14
(1, −1, 1)0,2523, −0,2390, −0,3882, −0,2229, −0,0156aynı1,6e-13

Servo’lar tam olarak −J⊤F-J^\top F‘ye oturuyor. Yana doğru bir itme (0, 1,5, 0) N neredeyse yalnızca pan joint’ini yüklüyor; aşağı doğru itme üç pitch joint’ini yüklüyor.

Uç yükünü bir servo doyana kadar artır. Yerçekimi açıkken servo’lar, aşağı doğru bir ff uç kuvveti için τ=g(q)−f Jp⊤(−z^)\tau = g(q) - f\,J_p^\top(-\hat z) sağlamak zorunda. Her joint için modelin 2,94 N m limitini alarak:

Poz (rad)lift ekseni → uç (m)yerçekimi torku, lift / elbow (N m)en büyük ek uç yüküsınırlayan joint
yakın (0, −1,5, 1,5, 0,5, 0)0,172−0,059 / −0,4698,81 Nelbow_flex
orta (0, −0,6, 0,9, 0,4, 0)0,220−0,281 / −0,4439,61 Nelbow_flex
gergin (0, 1,3, −1,3, 0, 0)0,411−0,909 / −0,4834,95 Nshoulder_lift

Sonra gergin durum, kuvvet bu limitin bir kesrine ayarlanarak 5 s simüle ediliyor:

uç kuvveti (N)× limit5 s sonra uç düşüşülift servo torku
0,000,00,5 mm−0,909 N m
2,480,51,2 mm−1,925 N m
4,460,91,8 mm−2,737 N m
5,451,1147,4 mm−2,940 N m
7,431,5179,7 mm−2,940 N m

Limitin altında kol yaklaşık bir milimetre sarkıyor (sonlu servo stiffness’ı). Limitin yüzde on üstünde lift servo’su −2,940 N m’de kırpılıyor ve kol 147,4 mm düşüyor. Kolu 0,220 m’den 0,411 m’ye uzatmak güvenli yükü kabaca yarıya indirdi: limiti yük değil, Jacobian belirliyor.

  • 2,94 N m’lik forcerange bir model parametresidir. MJCF yorumu, position gain’lerinin ve kuvvetlerin servo proportional gain’i 16 varsayılarak hesaplandığını ve bunların LeRobot’taki servo gain’lerinin “not a 1-to-1 mapping” olduğunu söylüyor (so101.xml). Yük tablosunu bir donanım değeri gibi okuma. Gerçek kolda henüz ölçülmedi. Prosedür: gergin pozda gripper’a bilinen ağırlıklar as, joint torkunu kaydet (örneğin sürücün sunuyorsa servo’nun akım okumasından) ve J⊤FJ^\top F‘ye fit et.
  • Donanımda statik harita ayrıca joint sürtünmesini (modelin frictionloss’u, Deney’in Adım 3’ünde kapatıldı), dişli boşluğunu ve kablo kuvvetlerini taşır; τ=J⊤F\tau = J^\top F‘nin ancak bunlar kadar tutmasını bekle.
  • Jacobian’ı yine de finite difference ile hesaplıyorsan (örneğin öğrenilmiş bir modelin etrafında), 1e-8 değil, 1e-5 rad civarında ε ile merkezi fark kullan.

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

1. Konum Jacobian’ını finite difference ile hesaplıyorsun. Daha küçük ε adımı her zaman daha mı doğru?

  • Evet; truncation hatası ε ile düşer, yani double’ın izin verdiği en küçük adım en iyisidir.
  • Evet, ama yalnızca merkezi farklar için.
  • Hayır; en iyi adımın altında yuvarlama hatası baskın çıkar, yani hata eğrisi V biçimindedir.

Neden: Adım 2 tablosu, en iyi ileri adım 1e-8 (hata 9,8e-09), en iyi merkezi adım 1e-5 (hata 5,6e-12); 1e-14’te merkezi hata 4,5e-03.

2. Modelin servo’ları orta pozda 9,61 N ek uç yükü tutarken gergin pozda yalnızca 4,95 N tutuyor. Neden?

  • Kol gerginken servo kuvvet limiti daha düşüktür.
  • Lift ekseninden uca kaldıraç 0,220’den 0,411 m’ye çıkıyor ve τ=J⊤F\tau = J^\top F bu kaldıraçla ölçekleniyor.
  • Gergin pozda Jacobian singular olduğu için uca hiç tork ulaşmaz.

Neden: Boz bölümünde her joint’in limiti aynı, 2,94 N m; gergin pozda yalnız yerçekimi lift’te −0,909 N m alıyor ve ilk doyan shoulder_lift oluyor.

  1. Kolay. F=(0,0,−2)F = (0, 0, -2) N için J⊤FJ^\top F‘nin ilk elemanı neden tam 0,0000?
  2. Orta. Hangi poz, aşağı doğru uç kuvvetinin newton’u başına shoulder lift torkunu en büyük yapar? “Lift ekseni → uç” sütunuyla savun, sonra mj_jacSite ile kontrol et.
  3. Zor. ε sweep’ini float32’de tekrarla (farkı almadan önce konumları np.float32’ye çevir). En iyi adımlar nereye kayar, neden?
  1. Joint 1’in (pan) ekseni düşey; düşey bir kuvvetin düşey bir eksen etrafında momenti yoktur, yani a^1⋅(r×F)=0\hat a_1 \cdot (r \times F) = 0.
  2. Tamamen gergin yatay poz: newton başına lift torku, lift ekseninden uca yatay mesafeye eşittir; script çıktısında gergin pozda 0,410 N m/N. Diğer pozları script ile kontrol et.
  3. Burada hesaplanmadı. Minimumların daha büyük ε’a, ϵ32≈1,2×10−7\epsilon_{32} \approx 1{,}2\times10^{-7} (float32 machine epsilon) ile ϵ32\sqrt{\epsilon_{32}} ve ϵ323\sqrt[3]{\epsilon_{32}} civarına kaymasını bekle.
  • mj_jacSite geometric Jacobian’ı verir; Jq˙J\dot q gerçek site hızıyla 7,9e-07 bağıl hatayla tuttu.
  • Finite difference’ın en iyi bir adımı vardır: bu sweep’te 1e-8 (ileri, 9,8e-09) ve 1e-5 (merkezi, 5,6e-12); daha küçüğü daha kötü.
  • τ=J⊤F\tau = J^\top F simülasyonda 1,6e-13 N m’ye kadar tuttu; 0,411 m’lik kolda modelin servo’ları yalnızca 4,95 N uç yükü taşıyor.

Sonraki: ders 10 · Inverse kinematics ve singularity.

Kaynaklar