15 · Safety: limit'ler, torque cap, e-stop ve watchdog
| Bölüm | 4 · Dynamics ve control |
| Çalışma türü | CPU · Mac ya da Colab CPU |
| Önkoşul | 12 |
| Önce öğren | yok |
| Süre | ~40 dk |
| Kod | experiments/15-safety/experiment.py |
| Durum | ✅ tam |
Bu derste yap
Her adımı yapınca işaretle. Yalnız bu tarayıcıda saklanır.
Öğrenilmiş bir policy bir gün yanlış bir sayı gönderecek. Safety, o sayı ile motor arasında duran ve yanlış sayıyı ucuza getiren katmandır.
Problem
Bölüm başlığı “Problem”LeRobot’un SO-101 follower’ında, yorumuna göre “for safety purposes” var olan bir ayar var: max_relative_target, hedefin mevcut pozisyondan ne kadar uzak olabileceğini sınırlıyor ve varsayılan olarak kapalı (None) (config_so_follower.py). Aynı kod tabanı gripper’ın torque limit’ini “to avoid burnout” diye %50’ye ayarlıyor. İkisi de bir policy bir engelin yanında hatalı bir hedef verdiğinde ne olacağını söylemiyor. Bu ders bunu simülasyonda ölçüyor: tek bir hatalı komut, birkaç safeguard, her biriyle ve her biri olmadan kuvvetler.
Okumadan önce · 2 soru. Önce tahmin et; nedenini ders anlatıyor.
1. Bir eklemin motor torkuna cap koyuyorsun. Cap hangi zararı doğrudan sınırlar?
- Çarpmayı da itmeyi de eşit şekilde; kuvvet her durumda tork bölü kaldıraçtır.
- Engele kalıcı itmeyi; çarpmayı yalnızca dolaylı olarak, daha yavaş gelişle.
- Yalnızca çarpmayı; kol takılınca cap’in önemi kalmaz.
Neden: Durgun hâlde itme ‘dir; çarpma geliş hızına bağlıdır. A bölümü - 0,5 N·m cap 2,12 N itme ama yine de 21,34 N tepe veriyor.
2. Bir operatör bir eklemi hız komutlarıyla jog ediyor, sonra mesajlar gelmez oluyor. Watchdog yoksa kol ne yapar?
- Bir şey onu durdurana kadar son komut edilen hızla hareket etmeye devam eder.
- Yeni hedef almayan bir position servo gibi son pozisyonunu tutar.
- Düşer, çünkü servo torkunu kapatır.
Neden: “Dur” arayüze bağlıdır (Ana fikir). D bölümünde watchdog yokken kol son mesajdan sonra 19,57° gidiyor ve direğe 24,48 N ile çarpıyor.
Ana fikir
Bölüm başlığı “Ana fikir”Sade anlatımla
Bölüm başlığı “Sade anlatımla”Öğrenilmiş bir policy’ye yeni bir sürücünün arabasındakini ver. Konum limiti bir çittir: hedef güvenli aralığın dışına çıkmaz. Rate limit bir hız sınırlayıcıdır: hedef her kontrol tick’inde (komut döngüsünün bir turunda) yalnızca biraz ilerler. Torque cap kayan bir debriyajdır: hedef ne kadar yanlış olursa olsun motor daha sert itmez. Watchdog trendeki ölü adam pedalıdır: zamanında taze komut yoksa dur. E-stop fişi çeker, koruduğu yazılımdan bağımsız olarak.
Her katmanın ne yapabileceğine iki kural karar verir. Birincisi, bir limit zarar üzerinde değil, tek bir değişken üzerinde çalışır: torque cap kolun bir engele ne kadar sert itmeye devam ettiğini sınırlar, ama hızlı bir kol yine sert çarpar. İkincisi, “dur”un ne demek olduğu arayüze bağlıdır: yeni hedef almayan bir position servo son hedefi tutar; hız komutlarıyla sürülen bir kol hareket etmeye devam eder.
flowchart TD
P["policy çıktısı<br/>hedef açı"] --> WD["watchdog<br/>taze mesaj yok mu? tut"]
WD --> PL["konum limiti<br/>güvenli aralığa kırp"]
PL --> RL["relative-target limiti<br/>tick başına şimdiki ± δ"]
RL --> SV["servo PD döngüsü"]
SV --> TC["torque cap<br/>en fazla τmax"]
TC --> M["motor ve kol"]
ES["donanım E-stop<br/>gücü keser"] -.-> M
Güvenlik katmanları kod olarak
Bölüm başlığı “Güvenlik katmanları kod olarak”def safe_goal(target, q_now, t_now, t_last_msg): if t_now - t_last_msg > watchdog_timeout: # stale command: stop where you are return q_now goal = np.clip(target, q_min, q_max) # position limit return np.clip(goal, q_now - delta, q_now + delta) # relative-target limit: <= delta rad per tick# torque cap: set once, enforced by the actuator (MuJoCo: forcerange; STS3215: a register)| Formül | Neyi sınırlar |
|---|---|
| hedef | hedefin hızı: en fazla |
| kaldıracında bir engele kalıcı itme | |
| yol | watchdog devreye girene kadar kolun almaya devam ettiği yol |
| doğruysa, takılan bir servo rate limit’e rağmen cap’inde iter |
Burada şimdiki eklem açısı, hedefin tick başına izin verilen en büyük adımı, tick süresi (50 Hz’de 20 ms), torque cap, eklem ekseninden contact’a kaldıraç, contact kuvveti, eklem hızı, watchdog timeout’u ve servo’nun stiffness’ıdır (ders 12).
Matematik ayrıntısı: torque cap neden itmeyi sınırlar da çarpmayı sınırlamaz
Kalıcı itme. Kol direğe dayanıp durunca eklem torku contact momentini dengeler, ; cap’te saturation’dayken , hız ve contact modeli ne olursa olsun.
Çarpma. Kol eklem hızı ve inertia’sıyla gelir; stiffness’lı bir contact yayı ‘yi emer, yani tepe ve ile büyür. Torque cap bunu yalnızca dolaylı sınırlar (daha yavaş ivme); rate limit geliş hızını doğrudan sınırlar.
Rate limit ve takılan servo. Bir engele karşı konum değişmeyi bırakır, hedef önde kalır ve servo komut eder; olduğunda cap bunu ‘a kırpar.
Daha derine: LeRobot robots/utils.py (ensure_safe_goal_position); MuJoCo Modeling · actuators ve forcerange; Lynch & Park, Modern Robotics, böl. 11.
Sıfırdan yaz
Bölüm başlığı “Sıfırdan yaz”Dört katmanı yaklaşık 50 satır NumPy ile yazıp Deney’in komut döngüsüne koyacaksın. Hakem MuJoCo: aynı servo torkları ve katmanların döngüdeyken aynı tablolar. Bitmiş fonksiyonlar physai/safety.py içinde; uv run python experiments/15-safety/build.py beş adımı yaklaşık 2 s’de koşar (çıktı build_output.txt içinde).
Adım 1 · Hedefi kırp
Bölüm başlığı “Adım 1 · Hedefi kırp”def clamp_goal(target, q_now, q_min=None, q_max=None, delta=None): """Position limit, then relative-target limit: the goal stays in [q_min, q_max] and within delta of q_now.""" goal = target if q_min is not None or q_max is not None: goal = np.clip(goal, q_min, q_max) # a fence around the safe range if delta is not None: goal = np.clip(goal, q_now - delta, q_now + delta) # at most delta ahead of where the joint is now return goalÖnce çit, sonra eklemin şu anki yerine göre adım. Kontrol: dört elle hesaplanmış durum, sonra 100.000 rastgele hedef, “mevcut pozisyon artı kırpılmış fark” kuralına karşı:
== Step 1. The goal clamp: position limit 0.3 rad, relative-target limit 0.02 rad == target q_now goal 1.20 0.00 0.020 1.20 0.29 0.300 0.25 0.24 0.250 -1.00 -0.10 -0.120100000 random: max |goal - q_now| = 0.0200 rad, outside range: 0, vs present + clip(diff): 1.7e-18goal speed bound delta / tick = 1.00 rad/sİkinci satırda çit kazanıyor (0,31 değil 0,300). 1,00 rad/s’lik sınır eklem için değil hedef için geçerli: Adım 3 1,82 rad/s ölçüyor.
Adım 2 · Torku sınırla
Bölüm başlığı “Adım 2 · Torku sınırla”def servo_torque(goal, q, qd, kp, kv, tau_max): """A position servo with a torque cap: kp (goal - q) - kv qd, clipped to +-tau_max.""" return np.clip(kp * (goal - q) - kv * qd, -tau_max, tau_max)MuJoCo’nun position actuator’ı ctrl’ü ctrlrange’e kırptıktan sonra gainprm[0]·ctrl + biasprm[1]·q + biasprm[2]·qdot hesaplar (biasprm = (0, −kp, −kv)) ve sonucu forcerange’e kırpar. Kontrol , ve aralıkları modelden okur; hedefler joint aralığının çok dışına çıkar:
== Step 2. The capped servo vs MuJoCo's position actuator (SO-101, 2000 random states) ==kp = 998.22, kv = 2.731, cap = 2.94 N m, pan ctrlrange = [-1.920, 1.920] radcap 2.94 N m: max |ours - MuJoCo| = 2.3e-13 N m; cap reached at an error of 2.95 mradcap 0.50 N m: max |ours - MuJoCo| = 2.2e-14 N m; cap reached at an error of 0.50 mradDuran bir eklem 2,94 N·m’lik cap’e 2,95 mrad hatada ulaşıyor; yani her hatalı komutta itmeyi gain’ler değil cap belirler.
Adım 3 · Katmanları döngüye koy
Bölüm başlığı “Adım 3 · Katmanları döngüye koy”Döngüde:
lim = (-q_lim, q_lim) if q_lim is not None else (None, None)d.ctrl[pan] = clamp_goal(target, d.qpos[0], *lim, delta) # every tickm.actuator_forcerange[pan] = [-cap, cap] # once, before the runKontrol A bölümünü senin katmanlarınla ve Deney’in döngüsüyle yeniden koşar, sonra contact kaldıracı ‘yi ölçer:
== Step 3. Part A with our layers in the loop (bad command: pan target 0 -> 1.2 rad at t = 0.1 s) ==safeguard peak N push N speed tau max |ours - Exp.|none 125.98 14.33 4.49 2.94 0.0e+00limit 0.3 0.00 0.00 4.02 2.94 0.0e+00delta 0.02 45.82 14.48 1.82 2.94 0.0e+00cap 0.5 21.34 2.12 0.75 0.50 0.0e+00all three 0.00 0.00 0.75 0.50 0.0e+00steady push vs tau_max / r (r = lever of the post contacts about the pan axis): cap 2.94: r = 22.5 cm, tau_max / r = 13.07 N, push 14.33 N cap 1.00: r = 22.5 cm, tau_max / r = 4.44 N, push 4.34 N cap 0.50: r = 22.6 cm, tau_max / r = 2.22 N, push 2.12 Nstall test: kp * 0.005 = 4.99 N m >= 2.94 N mA bölümünün tablosu, bit bit aynı. = 22,5 cm ile , ölçülen 2,12 ve 4,34 N’a karşı 2,22 ve 4,44 N, tam cap’te 14,33’e karşı 13,07 N öngörüyor: formül contact’taki sürtünme kuvvetlerini yok sayıyor, oysa onlar da eksen etrafında moment taşıyor. Ve 4,99 N·m ≥ 2,94 N·m: C bölümünün en sıkı δ’sı bile itmeyi sınırlayamaz.
Adım 4 · Watchdog
Bölüm başlığı “Adım 4 · Watchdog”class Watchdog: """Expires when no fresh command has arrived for longer than `timeout` seconds."""
def __init__(self, timeout): self.timeout, self.last = timeout, None
def feed(self, t): """Call whenever a fresh command arrives at time t.""" self.last = t
def expired(self, t): return self.last is not None and t - self.last > self.timeoutHer mesajda besle; sessiz bir tick’te süresi dolmuş watchdog hızı sıfırlar ve mevcut açıyı tutar:
if msg is not None: wd.feed(t)elif wd.expired(t) and v_cmd != 0.0: v_cmd, target = 0.0, d.qpos[0] # stale command: stop and hold here== Step 4. Watchdog: jog at 1 rad/s, the last message at t = 0.18 s (part D) == timeout s stopped after s travel deg peak N max |ours - Exp.| none 0.350 19.57 24.48 0.0e+00 0.5 0.350 19.57 24.48 0.0e+00 0.2 0.230 11.61 0.00 0.0e+00 0.05 0.090 3.58 0.00 0.0e+00Yine D bölümünün satırları: 0,5 s, kolun direğe ulaşması için gereken 0,350 s’den uzun.
Adım 5 · E-stop latch’i
Bölüm başlığı “Adım 5 · E-stop latch’i”class EStop: """A latch: one press stops the robot until someone resets it after the cause is gone."""
def __init__(self): self.tripped = False
def update(self, pressed): """Call every tick with the button (or fault) state; returns True while the stop is active.""" self.tripped = self.tripped or bool(pressed) return self.tripped
def reset(self, pressed): """Clear the latch, but only if the button is released.""" if not pressed: self.tripped = False return self.trippedSeken bir buton ya da bir tick için kaybolan bir arıza kolu yeniden başlatmamalı; reset ancak buton bırakılınca işler. Kontrol bir tick boyunca basar, sonra E bölümünü latch ile yeniden koşar:
== Step 5. E-stop latch, then part E: stop a 1 rad/s jog at t = 0.2 s ==pressed for one tick: active [False, True, True, True]; reset while pressed: True; after release: Falsestop travel deg stopped after s gripper drop cm max |ours - Exp.|hold 0.15 0.030 0.02 0.0e+00torque off 1.53 0.124 11.74 0.0e+00Latch durup durmamaya karar verir; nasıl durulacağı E bölümünün seçimidir. Gerçek bir E-stop ayrıca motor gücünü donanımda keser.
Elinde kalan
Bölüm başlığı “Elinde kalan”physai.safety artık clamp_goal, servo_torque, Watchdog ve EStop içeriyor; ders 40 gerçek SO-101’i bunların arkasında koşar, ders 41 bunları bir modelin çıktısıyla servo’lar arasına koyar. Test: uv run pytest tests/test_15_safety.py.
Kütüphaneyle kullan
Bölüm başlığı “Kütüphaneyle kullan”MuJoCo’da iki katman mj_step içinde uygulanan model özellikleridir, “torque off” ise bir flag’dir:
m.actuator_ctrlrange[pan] = [-0.3, 0.3] # position limit on the goal (needs ctrllimited)m.actuator_forcerange[pan] = [-0.5, 0.5] # torque cap (needs forcelimited)m.opt.disableflags |= mujoco.mjtDisableBit.mjDSBL_ACTUATION # every actuator stops producing force== Use it. The position limit and the cap as model attributes (MuJoCo clamps inside mj_step) ==actuator_ctrlrange = [-0.3, 0.3]: peak 0.00 N, push 0.00 N; vs our layer 0.0e+00actuator_forcerange = [-0.5, 0.5]: peak 21.34 N, push 2.12 N; vs our layer 0.0e+00Adım limiti, watchdog ve latch senin döngünde yaşar; simülasyonda da robotta da.
| Katman | physai | MuJoCo | LeRobot SO-101 follower | libfranka |
|---|---|---|---|---|
| konum limiti | clamp_goal(q_min, q_max) | actuator ctrlrange + ctrllimited | ||
| adım limiti | clamp_goal(delta), mevcut açıya göre | max_relative_target → ensure_safe_goal_position, Present_Position’a göre | limitRate(max_derivatives, commanded, last_commanded), son komuta göre | |
| torque cap | servo_torque(tau_max) | actuator forcerange + forcelimited; joint actuatorfrcrange | gripper Max_Torque_Limit 500 | |
| torque off | mjDSBL_ACTUATION | disable_torque_on_disconnect |
Kaynaklar: MuJoCo XML reference; LeRobot robots/utils.py, so_follower.py; libfranka rate_limiting.h.
Üç tuzak:
- Mevcut açıya mı, son komuta mı göre? LeRobot her gönderimden önce
Present_Position’ı okuyup ona göre kırpar,clamp_goalgibi. Son komuta göre çalışan bir limiter (libfranka’nınlimitRate’i) eklem takılıyken hedefi ilerletmeye devam eder; engel kalkınca kol yetişmek için sıçrar. - Birimler. SO-101 follower beş gövde eklemini varsayılan olarak dereceye (
use_degrees = True), gripper’ı 0–100’e normalize eder; yanimax_relative_target = 0.020,02 rad değil 0,02° demektir. Ayrıcaensure_safe_goal_positionisinstance(max_relative_target, float)diye bakar:5gibi bir tamsayıTypeErrorfırlatır. - Bir flag limiti kapatabilir.
ctrlrangeyalnızcactrllimitedaçıkken ve globalclampctrlflag’i kapatılmamışken kırpar; yoksa konum limiti sessizce ortadan kalkar.
Yazdıktan sonra · 2 soru.
1. Sıfırdan yaz, Adım 2’de SO-101 servo’su ( = 998,22) 2,94 N·m’lik cap’ine 2,95 mrad hatada ulaşıyor. Hatalı bir komut için bundan ne çıkar?
- Servo hatayla orantılı iter, yani daha büyük bir hatalı komut daha sert iter.
- İtmeyi sınırlamanın en iyi yolu ‘yi düşürmektir.
- Neredeyse her hatalı komut servo’yu saturation’a sokar; itmeyi gain’ler değil cap belirler.
Neden: Adım 2 MuJoCo’nun actuator’ıyla 2,3e-13 N·m’ye kadar örtüşüyor ve 2,95 mrad eşiğini gösteriyor; Adım 3 de cap’i izleyen itmeler ölçüyor (0,5 N·m’de 2,12 N, 1,0 N·m’de 4,34 N).
2. LeRobot’un varsayılan SO-101 follower ayarlarıyla max_relative_target = 0.02 yapıyorsun. Neyi sınırlar?
- Her gövde ekleminin hedefini son komuttan 0,02 rad uzağa.
- Her gövde ekleminin hedefini mevcut pozisyondan 0,02° uzağa.
- Eklem hızını 0,02 rad/s’ye.
Neden: Kütüphaneyle kullan, tuzaklar - follower varsayılan olarak derece kullanır (use_degrees = True) ve ensure_safe_goal_position, clamp_goal gibi mevcut pozisyona (Present_Position) göre kırpar.
Kurulum. SO-101 (Menagerie scene.xml), her joint modelin STS3215 position servo’su ( = 998,22, = 2,731, cap ±2,94 N·m; ders 12). Timestep 2 ms, komut döngüsü 50 Hz. Kol pozu: shoulder_lift −0,5, elbow 0,5, wrist 0,8 rad; gripper frame’i (29,4; −0,1; 12,8) cm’de. Sabit bir direk (2 × 2 × 20 cm) gripper’ın savrulma yolunda, pan ≈ 0,6 rad’da duruyor. Döngü Sıfırdan yaz’ın Adım 3’ü; script: experiments/15-safety/experiment.py. MuJoCo 3.17.0, NumPy 2.5.4, Python 3.14, Apple M5, deterministik, ~3 s.
A. Tek bir hatalı komut. t = 0,1 s’de shoulder_pan hedefi 0 → 1,2 rad sıçrıyor. Tahmin et: hangi tek safeguard çarpmayı engeller, hangisi yalnızca yumuşatır?
| safeguard | direkteki tepe kuvvet | kalıcı itme kuvveti | tepe pan hızı | tepe tork |
|---|---|---|---|---|
| yok | 125,98 N | 14,33 N | 4,49 rad/s | 2,94 N·m |
| joint limit |pan| ≤ 0,3 rad | 0,00 | 0,00 | 4,02 | 2,94 |
| relative target ≤ 0,02 rad/tick | 45,82 | 14,48 | 1,82 | 2,94 |
| torque cap 0,5 N·m | 21,34 | 2,12 | 0,75 | 0,50 |
| üçü birden | 0,00 | 0,00 | 0,75 | 0,50 |
Contact’ı yalnızca position limit engelliyor, o da yalnızca engelin nerede olduğunu bildiğimiz için. Rate limit çarpmayı azaltıyor (45,82’ye karşı 125,98 N) ama kalıcı itmeyi azaltmıyor. Torque cap ikisini de azaltıyor.
B. Torque cap sweep’i (aynı hatalı komut, başka hiçbir şey yok):
| cap [N·m] | 2,94 | 2,00 | 1,00 | 0,50 | 0,25 | 0,10 |
|---|---|---|---|---|---|---|
| tepe kuvvet [N] | 125,98 | 69,79 | 37,96 | 21,34 | 8,57 | 0,00 |
| kalıcı itme [N] | 14,33 | 8,73 | 4,34 | 2,12 | 1,48 | 0,00 |
| tepe hız [rad/s] | 4,49 | 3,16 | 1,58 | 0,75 | 0,33 | 0,08 |
Cap hızı da sınırlıyor; 0,10 N·m’de kol 2 s içinde direğe ulaşmıyor. 0,5 ile 2 N·m arasında kalıcı itme cap ile neredeyse orantılı (2,12, 4,34, 8,73 N): yaklaşık 23 cm’lik bir kaldıraçla (Adım 3 22,5 cm ölçüyor).
C. Relative-target limit δ sweep’i (hedef her 20 ms’de mevcut ± δ’ya kırpılıyor):
| δ [rad] | yok | 0,2 | 0,05 | 0,02 | 0,01 | 0,005 |
|---|---|---|---|---|---|---|
| çarpma anındaki hız [rad/s] | 4,494 | 4,494 | 2,866 | 1,513 | 0,929 | 0,359 |
| tepe kuvvet [N] | 125,98 | 125,98 | 72,94 | 45,82 | 21,39 | 17,17 |
| kalıcı itme [N] | 14,33 | 14,33 | 13,54 | 14,48 | 14,67 | 13,54 |

Daha küçük δ çarpma hızını ve tepeyi düşürüyor, ama kalıcı itme 14 N civarında kalıyor: kol durunca hedef hâlâ mevcut + δ, ve buradaki her δ için ≥ 2,94 N·m (998,22 × 0,005 ≈ 5 N·m).
D. Watchdog. Operatör shoulder_pan’ı velocity komutlarıyla 1 rad/s’de jog ediyor (hedef tick başına ilerliyor). Son mesaj t = 0,18 s’de geliyor (pan 0,185 rad); bir watchdog mevcut pozisyonu tutana kadar controller o hızı kullanıyor.
| timeout | son mesajdan sonra durdu | sonrasındaki en büyük hareket | direkteki tepe kuvvet |
|---|---|---|---|
| yok | 0,350 s (direk durdurdu) | 19,57° | 24,48 N |
| 1 s | 0,350 s | 19,57° | 24,48 N |
| 0,5 s | 0,350 s | 19,57° | 24,48 N |
| 0,2 s | 0,230 s | 11,61° | 0,00 |
| 0,1 s | 0,130 s | 5,88° | 0,00 |
| 0,05 s | 0,090 s | 3,58° | 0,00 |
Watchdog ancak kol engele ulaşmadan tetiklenirse işe yarar: burada 0,5 s ve 1 s fazla yavaş.
E. İki durma yolu, t = 0,2 s’deki aynı 1 rad/s jog’dan:
| durma | durmadan sonraki en büyük pan hareketi | pan şu süre sonra durdu | gripper düşüşü |
|---|---|---|---|
| pozisyonu tut (hedef := mevcut) | 0,15° | 0,030 s | 0,02 cm |
| torque off (actuation kapalı) | 1,53° | 0,124 s | 11,74 cm |
Torque off pan joint’ini yalnızca sürtünmeyle durduruyor ve omzu yerçekimine bırakıyor: gripper 11,74 cm düşüyor, 12,8 cm’den yere. Tutmak daha hızlı durduruyor ve kolu yukarıda tutuyor, ama çalışan bir controller ister.
Tek koruma olarak rate limiter’ı kullan. Cömert: tick başına δ = 0,2 rad 10 rad/s demek, servo’nun hiç ulaşmadığı bir hız (4,494 rad/s); koşu limiter yokmuş gibi (125,98 N). Sıkı: δ = 0,005 rad çarpmayı 17,17 N’ye indiriyor, yine de kol hatalı komut sürdükçe 13,54 N ile itiyor. Rate limit bir contact-force limit’i değildir; o iş torque cap’in (B) ya da engellerin yerini bilen bir modelin (A).
Gerçek robotta
Bölüm başlığı “Gerçek robotta”- SO-101 / LeRobot.
max_relative_targetvarsayılan olarak kapalı (Kütüphaneyle kullan). Bağlanırken LeRobot her STS3215’e position-mode P/I/D katsayılarını 16/0/32 olarak yazıyor ve yalnızca gripper içinMax_Torque_Limit500,Protection_Current250 veOverload_Torque25 ayarlıyor (so_follower.py).disable_torque_on_disconnect = True, bağlantı kopmasını E bölümünün “torque off”u yapıyor: kolun düşmesini bekle. - Gerçek kolda ölçülmedi. Buradaki çarpma kuvvetleri MuJoCo’nun contact modeline ve 2 ms’lik adıma bağlı. Prosedür: direğin yerine bir mutfak terazisi ya da kuvvet sensörü koy, düşürülmüş torque limit’iyle ona yavaşça jog et (step değil), tepeyi kaydet; en düşük limit’le başla ve yola asla elini koyma. Donanım E-stop’u yukarıdaki tüm yazılım katmanlarından ayrıdır.
Kendini dene
Bölüm başlığı “Kendini dene”Hızlı kontrol · 2 soru. Bir cevaba tıkla.
1. Sıkı bir relative-target limit (δ = 0,005 rad/tick) direğe çarpmayı 17,17 N’ye indiriyor. Kol neden sonrasında yine de 13,54 N ile itmeye devam ediyor?
- Kol durunca hedef δ kadar önde kalıyor ve (yaklaşık 5 N·m) 2,94 N·m’lik cap’in üstünde; servo cap’inde itiyor.
- Rate limit yalnızca kol serbestçe hareket ederken geçerli.
- Yerçekimi kolu direğe doğru çekiyor.
Neden: C bölümü - kalıcı itme her δ için 14 N civarında kalıyor (998,22 × 0,005 ≈ 5 N·m ≥ 2,94 N·m). Rate limit itmeyi değil, çarpma anındaki hızı sınırlar.
2. 0,5 s timeout’lu bir watchdog 1 rad/s’lik bir jog’u koruyor ama kol yine de direğe çarpıyor. Neden?
- Watchdog torku kesiyor, kol da direğe düşüyor.
- Watchdog’lar yalnızca position komutlarıyla çalışır.
- Kol son mesajdan 0,350 s sonra direğe ulaşıyor, timeout tetiklenmeden önce.
Neden: D bölümü - watchdog ancak kol bir şeye ulaşmadan tetiklenirse işe yarar; 0,2 s ve daha kısası direkten kaçındı (0,00 N), 0,5 s ve 1 s 24,48 N verdi.
- Kolay. Torque cap 1,0 N·m ve kol 23 cm iken hangi kalıcı itme kuvvetini beklersin? B bölümüyle karşılaştır.
- Orta. A bölümünde δ = 0,02 rad/tick neden 20 ms’de 0,02 rad’ın ima ettiği 1 rad/s’nin üstünde, 1,82 rad/s’lik bir tepe pan hızı veriyor?
- Zor. Hıza bağlı bir torque cap ekle (0,2 rad/s altında tam cap, üstünde 0,5 N·m) ve A bölümünü yeniden koş. Önce çarpma tepesini ve kalıcı itmeyi tahmin et.
Cevaplar
Bölüm başlığı “Cevaplar”- N; B bölümü 4,34 N ölçüyor.
- Hedef mevcut pozisyona göre ve her 20 ms’de güncelleniyor. Bir tick içinde servo δ kadar hata görüyor ve ≈ 20 N·m, 2,94 N·m’lik cap’ini aşıyor; bu yüzden tam torkla ivmeleniyor, hedefi geçiyor ve frenliyor; hız δ/Δt = 1 rad/s civarında, üstüne çıkan tepelerle salınıyor.
- Burada hesaplanmadı; koş ve gör.
Akılda kalanlar ve kaynaklar
Bölüm başlığı “Akılda kalanlar ve kaynaklar”- Her safeguard bir değişkeni sınırlar: position limit bilinen çarpışmaları engeller (0 N), torque cap itmeyi sınırlar (0,5 N·m’de 14,33 → 2,12 N), rate limit çarpma hızını sınırlar (4,494 → 0,359 rad/s) ama itmeyi sınırlamaz.
- Watchdog, kol herhangi bir şeye ulaşmadan tetiklenmeli: burada 0,05–0,2 s direkten kaçındı, 0,5 s kaçınamadı.
- “Dur” bir tasarım kararıdır: pozisyonu tutmak 0,030 s’de durduruyor; torque off gripper’ı 11,74 cm düşürüyor.
Sonraki: ders 16 · Grasping ve scripted pick-and-place.
Kaynaklar:
- LeRobot
config_so_follower.py,so_follower.py,robots/utils.py(Apache-2.0, 27.10.2026’da okundu). - libfranka
rate_limiting.h. - MuJoCo Modeling · actuator’lar ve
forcerange, XML reference,mj_contactForce; Menagerierobotstudio_so101. - Lynch & Park, Modern Robotics, bölüm 11.
- Ölçülen tüm sayılar:
experiments/15-safety/output.txtvebuild_output.txt.