İçeriğe geç

16 · Grasping ve scripted pick-and-place

Bölüm4 · Dynamics ve control
Çalışma türüCPU · Mac ya da Colab CPU
Önkoşul10, 13
Önce öğrenyok
Süre~60 dk
Kodexperiments/16-grasping-and-pick-place/experiment.py
Durum✅ tam

Bu derste yap

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

Bir grasp, yükü sürtünme taşıyabildiğinde tutar. Pick-and-place’teki geri kalan her şey (IK, trajectory’ler, state machine) iki çeneyi bunun doğru olduğu yere koymak için vardır.

Bölüm 7 policy’leri demonstration’lardan eğitiyor ve en ucuzları zaten çalışan bir script’ten gelir. Simülasyonda scripted bir pick’i taklit etmek kolaydır: çeneler kapanınca küpü gripper’a weld et, her deneme “başarılı” olsun. Fiziksel soru şu: gerçek bir contact modeliyle ve hiçbir bağlantı olmadan, bir SO-101 3 cm’lik bir küpü ne zaman kaldırır, ne zaman sıkıştırıp fırlatır, düşürür ya da hiç kapanamaz? Cevap ders 04’ün friction cone’undan geliyor ve 240 simüle edilmiş grasp üzerinde ölçülüyor.

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

1. Bir küpü karşılıklı iki yüzünden iki parmak ucuyla sıkıştırıp kaldırıyorsun. Ağırlığını ne taşır?

  • Sıkmanın kendisi, çünkü normal kuvvetler yukarı bakar.
  • Hiçbir şey; küpü parmakların şekli tutar.
  • Parmak uçlarındaki sürtünme, en fazla μ çarpı toplam sıkma.

Neden: Çeneler yatay bastırır; yukarı yalnızca sürtünme etki eder, μ(N1+N2)≥mg\mu(N_1+N_2) \ge mg. Sıfırdan yaz, Adım 2 - tutulan 0,4 kg’lık küpe gelen contact kuvvetleri yukarı doğru 3,924 N ediyor, tam mgmg.

2. Kaygan bir küpte daha güçlü bir çene grasp’i her zaman daha güvenilir yapar mı?

  • Hayır; çeneler hâlâ hareket ederken sert sıkmak küpü fırlatabilir.
  • Evet; daha fazla sıkma her zaman daha fazla sürtünme demektir.
  • Evet, friction-cone oranı 1’in üstünde olduğu sürece.

Neden: Ana fikir’deki ıslak sabun. μ = 0,05’te B bölümü - 2,94 N·m cap (oran 15,11) 7/10 tuttu ve 3 küpü fırlattı, 1,0 N·m cap 10/10 tuttu.

Bir küpü iki parmağının arasında sıkıştır: onu alttan hiçbir şey tutmaz, bütün ağırlığı parmak uçlarındaki sürtünme taşır, en fazla tutunma katsayısı × sıkma kadar. Daha ağır bir küp kayıp düşer. Islak bir sabun düşük sürtünmeli durumdur: daha sert sıkarsın, parmakların hâlâ hareket ederken sıkarsan sabun fırlar gider.

Script’li bir pick-and-place, bir trafik ışığı gibi küçük bir state machine’dir: her state’in bir eylemi (kol hedefi, çene açık ya da kapalı) ve bir çıkış koşulu (bir timer ya da algılanan bir şey) vardır. Script açık çeneleri küpün üstüne getirir, indirir, sensörler grasp’in oluştuğunu söyleyene kadar kapatır, kaldırır ve tutar.

stateDiagram-v2
    [*] --> settle
    settle --> pre: 0,3 s
    pre --> down: 1,2 s
    down --> close: 0,8 s
    close --> lift: iki çene de değiyor, çene hızı 0,1 s boyunca 0,05 rad/s altında
    close --> lift: timeout 4 s (yine de kaldır)
    lift --> hold: 1,0 s
    hold --> [*]: 0,8 s, sonra başarı testi
ratio = mu * (N1 + N2) / (m * g) # N1, N2: normal forces of the two jaws (mj_contactForce)
holds = ratio >= 1.0 # below 1 the cube slides out of the jaws
state = "settle"
while state != "done":
command_arm_and_jaw(state) # IK + min-jerk target, jaw open or closed
if state == "close": # sensed, not timed (timeout 4 s)
if both_jaws_touch() and jaw_still(speed=0.05, for_s=0.1) or timed_out(4.0):
state = "lift"
elif time_in_state() >= DURATION[state]:
state = NEXT[state] # settle -> pre -> down -> close; lift -> hold -> done
FormülNe söylüyor
μ (N1+N2)  ≥  mg\mu\,(N_1 + N_2) \;\ge\; m gsürtünme ağırlığı taşıyabilir (Lynch & Park, bölüm 12)
μ(N1+N2)mg≥1\dfrac{\mu (N_1 + N_2)}{m g} \ge 1aynısı oran olarak: friction-cone payı
mmax⁡=μ(N1+N2)/gm_{\max} = \mu (N_1+N_2)/gverilen bir sıkmanın kaldırabileceği en ağır küp

Burada μ\mu çene–küp sürtünme katsayısı, N1,N2N_1, N_2 iki çenenin küpe uyguladığı normal kuvvetler, mm küpün kütlesi ve gg = 9,81 m/s²’dir. Grasp antipodal’dır: iki contact normali birbirine bakar, çeneler yatay bastırır ve yukarı doğru yalnızca sürtünme etki eder.

Gripper ve sürtünme. SO-101’de sabit bir çene ve menteşeli, hareketli bir çene (gripper joint’i) var; bir STS3215 position servo ile sürülüyor. 3 cm’lik bir küpte kapalı limite komutlanan servo torque cap’ine ulaşana kadar iter; sıkmayı cap ve çene kolu belirler. Çene pad’lerinin sürtünmesi 1, priority’si 1; küpe priority 2 veriliyor ki MuJoCo’nun kullandığı onun μ’sü olsun (Kütüphaneyle kullan).

State’ler. pre açık çeneleri küp merkezinin 5,5 cm üstüne, down merkezin 4 mm altına götürür, close kol dururken çeneyi 0,3 s’de kapatır, lift merkezin 7 cm üstüne çıkar. Kol hedefleri 5 kol joint’i üzerinde damped-least-squares IK’dan gelir (ders 10) ve ders 13’ün quintic’iyle harmanlanır. Başarı, fiziksel olarak: sonda küpün altı yerden ≥ 4 cm yukarıda ve iki çeneye de değiyor.

Matematik ayrıntısı: friction cone, sıkma ve kaldırmanın neden biraz fazlasını istediği

Coulomb sürtünmesi. Her contact’ta teğetsel kuvvet en fazla μNi\mu N_i‘dir (ders 04). İki teğetsel kuvvet ağırlığı taşır, ft,1+ft,2=mgf_{t,1} + f_{t,2} = mg ve her biri ft,i≤μNif_{t,i} \le \mu N_i; buradan μ(N1+N2)≥mg\mu(N_1 + N_2) \ge mg.

Torque cap’ten sıkma. Takılan bir servo cap’i τmax⁡\tau_{\max} ile iter; rjr_j çene kolunda hareketli çene yaklaşık τmax⁡/rj\tau_{\max}/r_j ile bastırır, küp dengede kalsın diye sabit çene de aynı kuvvetle karşılık verir. Yani N1+N2≈2τmax⁡/rjN_1 + N_2 \approx 2\tau_{\max}/r_j: kuvvet çeneler arasında bölünmez.

Kaldırma. Küpü yukarı aa ivmesiyle hızlandırmak μ(N1+N2)≥m(g+a)\mu(N_1+N_2) \ge m(g + a) ister, durağan oran 1’den biraz fazlasını. Kapanma sırasında çene küpü yana iter; o anda bir contact kuvveti cone’unun dışına çıkarsa küp, durağan test devreye girmeden kayıp gider.

Daha derine: ders 04 · Friction; Lynch & Park, Modern Robotics, bölüm 12; MuJoCo Modeling · contact parametreleri.

Grasp testini, sıkma formülünü ve pick state machine’ini yaklaşık 90 satır NumPy ile yazıp Deney’in SO-101’ini onlarla süreceksin; hakemler MuJoCo’nun contact kuvvetleri ve SciPy. Bitmiş fonksiyonlar physai/grasp.py içinde; uv run python experiments/16-grasping-and-pick-place/build.py beş adımı yaklaşık 5 s’de koşar (çıktı build_output.txt içinde).

def cone_ratio(mu, normal_forces, mass, g=9.81):
"""Friction-cone margin of an antipodal grasp: mu (N1 + N2) / (m g). Below 1 the object slides out."""
return mu * np.sum(normal_forces) / (mass * g)
def max_mass(mu, normal_forces, g=9.81):
"""The heaviest object this squeeze can hold by friction alone."""
return mu * np.sum(normal_forces) / g

Kontrol, A–C bölümlerinin oran sütunlarını output.txt’de basılı sıkma değerlerinden yeniden hesaplar:

== Step 1. The friction-cone ratio from the Experiment's own squeeze forces (output.txt) ==
part A: 6 rows, max |ours - printed ratio| = 0.01
part B: 4 rows, max |ours - printed ratio| = 0.00
part C: 8 rows, max |ours - printed ratio| = 0.00
max_mass: mu 0.05, 12.74 N -> 0.065 kg; mu 0.3, 16.25 N -> 0.497 kg

0,01, basılı sıkmanın yuvarlanmasından geliyor. μ = 0,3’te 16,25 N durağan hâlde 0,497 kg tutabilirdi, ama C bölümü 0,45 kg’ı düşürüyor: kaldırma daha fazlasını ister (Adım 5).

def cone_use(f_contact, mu):
"""How much of its friction cone a contact uses: |tangential| / (mu * normal), from a contact-frame
force (normal, tangent1, tangent2), the order mj_contactForce returns. Above 1 it slides."""
f = np.asarray(f_contact, float)
return np.hypot(f[1], f[2]) / (mu * f[0])

Kontrol, bütün çene contact’ları üzerinden küpe gelen dikey kuvveti toplar ve her contact’ın cone’unun ne kadarını kullandığına bakar:

== Step 2. Inside a held grasp (end of the hold, cube in the air) ==
case contacts sum Fz N m g N max cone use
mu 1.0, 30 g 18 0.294 0.294 0.037
mu 0.3, 0.4 kg 7 3.924 3.924 1.000

Ağırlığı tam olarak yalnızca sürtünme taşıyor. 30 g ve μ = 1’de en çok yüklenen contact cone’unun %3,7’sini kullanıyor; 0,4 kg ve μ = 0,3’te (oran 1,24) bazı contact’lar sınırda (1,000), geri kalanını diğerleri taşıyor.

def squeeze_from_cap(tau_max, r_jaw):
"""Squeeze of a stalled parallel jaw: the moving jaw presses tau/r, the fixed jaw pushes back as hard,
so N1 + N2 = 2 tau / r (the force is not split between the jaws)."""
return 2 * tau_max / r_jaw

Çene kolu rr ölçülüyor: hareketli çene contact’larının menteşe etrafındaki moment kolu, normal kuvvetle ağırlıklı. Çenenin statik sürtünmesi, onun τ\tau‘nun o kayıp kadar altında ya da üstünde bastırmasına izin verir:

== Step 3. Squeeze from the jaw torque cap (mu = 0.05, 30 g, nominal position) ==
jaw friction loss 0.052 N m; band = 2 (tau +- loss) / r
cap N m r_jaw cm 2 tau / r N band N squeeze N N fixed / N moving
1.00 7.37 27.13 [25.72, 28.54] 26.12 1.002
0.50 7.42 13.47 [12.07, 14.87] 12.66 1.001
0.30 7.44 8.07 [6.67, 9.47] 6.68 1.004

Sıkma her cap’te bandın içinde ve çeneler eşit bastırıyor (oran 1,00): her biri yaklaşık τ/r\tau/r taşıyor, toplam 2τ/r2\tau/r. Bunlar nominal pozisyonda tek pick’ler; tablolar 10 pozisyonun ortalaması.

def minjerk(u):
"""Minimum-jerk blend 0 -> 1 over u in [0, 1]: zero velocity and acceleration at both ends."""
u = min(1.0, max(0.0, u))
return u ** 3 * (10 - 15 * u + 6 * u * u)
class PickMachine:
"""settle -> pre -> down -> close -> lift -> hold -> done. Timed states end after their duration;
close ends on a sensed condition: both jaws touch and the jaw is still for `still_time` (or a timeout)."""
NEXT = dict(settle="pre", pre="down", down="close", close="lift", lift="hold", hold="done")
MOVES = dict(settle=("home", "home"), pre=("home", "pre"), down=("pre", "down"),
lift=("down", "lift"), hold=("lift", "lift"))
def __init__(self, durations, close_timeout=4.0, still_speed=0.05, still_time=0.1, t0=0.0):
self.dur, self.timeout = durations, close_timeout
self.still_speed, self.still_time = still_speed, still_time
self.state, self.t_state, self.still_since, self.close_s = "settle", t0, None, float("nan")
def command(self, now, poses, jaw_open, jaw_closed):
"""Arm joint targets and jaw target for this step: min-jerk between poses; in close, a jaw ramp."""
t = now - self.t_state
if self.state == "close":
u = minjerk(t / self.dur["close_ramp"])
return poses["down"], jaw_open + u * (jaw_closed - jaw_open)
a, b = self.MOVES[self.state]
q = poses[a] + minjerk(t / self.dur[self.state]) * (poses[b] - poses[a])
return q, jaw_open if self.state in ("settle", "pre", "down") else jaw_closed
def update(self, now, both_touch=False, jaw_speed=0.0):
"""Call after every physics step with what the sensors say; returns the (possibly new) state."""
t = now - self.t_state
if self.state == "close":
settled = both_touch and abs(jaw_speed) < self.still_speed and t > self.dur["close_ramp"]
if not settled:
self.still_since = None
elif self.still_since is None:
self.still_since = now
if self.still_since is not None and now - self.still_since >= self.still_time:
self.close_s = t # the grip formed: lift
self.state, self.t_state = "lift", now
elif t > self.timeout:
self.state, self.t_state = "lift", now # lift anyway; the success test will tell
elif t >= self.dur[self.state] - 1e-9:
self.state, self.t_state = self.NEXT[self.state], now
return self.state

Döngü hedefleri sorar, MuJoCo’yu adımlar ve çenelerin algıladığını bildirir:

while sm.state != "done":
d.ctrl[arm], d.ctrl[jaw] = sm.command(d.time, poses, G_OPEN, G_CLOSE)
mujoco.mj_step(m, d)
nf, nm = jaw_contacts(m, d) # normal force from each jaw (mj_contactForce)
sm.update(d.time, nf > 0 and nm > 0, d.qvel[jaw_dof])

Aynı başlangıçtan Deney’in scripted_pick’ine karşı kontrol:

== Step 4. Our state machine vs the Experiment's scripted_pick (nominal pick) ==
minjerk: s(0.5) = 0.500, peak speed 1.8750 (15/8 = 1.875), |v|, |a| at the ends < 6e-04 (finite differences)
ours: held, lift 7.37 cm, jaw forces 39.84 / 39.83 N, close 0.474 s, 2287 steps
Exp.: success True, lift 7.37 cm, jaw forces 39.84 / 39.83 N, close 0.474 s, 2287 steps; max |qpos ours - Exp.| = 0.0e+00

2287 adım boyunca son bitine kadar aynı; blend durgun başlıyor ve durgun bitiyor.

def pick_outcome(lift, touches_both, closed, min_lift=0.04):
"""Physical success test: lifted at least min_lift (m) and still in both jaws; else why it failed."""
if lift >= min_lift and touches_both:
return "held"
return "dropped" if closed else "not closed"
def wilson(k, n, z=1.96):
"""Wilson 95 % interval for a success rate of k out of n trials."""
p = k / n
den = 1 + z * z / n
c = (p + z * z / (2 * n)) / den
h = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / den
return max(0.0, c - h), min(1.0, c + h)

Kontrol üç sweep satırını senin machine’inle yeniden koşar ve Wilson aralığını SciPy’ınkiyle karşılaştırır:

== Step 5. Three sweep rows rerun with our machine (10 positions, seed 0) ==
row held / not closed / dropped squeeze N ratio Wilson 95% vs SciPy
A mu 0.03 2 / 8 / 0 12.29 1.25 [0.06, 0.51] 5.6e-06
C 0.4 kg 10 / 0 / 0 16.25 1.24 [0.72, 1.00] 7.4e-06
C 0.45 kg 0 / 0 / 10 16.47 1.12 [0.00, 0.28] 7.4e-06

A ve C bölümleri, sayısı sayısına. SciPy zz = 1,95996… kullanıyor, sen 1,96; 1e-5 oradan.

physai.grasp artık cone_ratio, max_mass, cone_use, squeeze_from_cap, minjerk, PickMachine, pick_outcome, wilson içeriyor. Ders 26 demonstration’ları scripted pick ile kaydeder, ders 25 başarı oranlarını Wilson aralıklarıyla raporlar. Test: uv run pytest tests/test_16_grasping_and_pick_place.py.

Contact fiziğine MuJoCo karar verir; senin kodun onu ayarlar ve okur:

geom.priority = 2; geom.friction = [mu, 0.03, 0.003]; geom.condim = 4 # MjSpec: whose mu counts, sliding + torsion
m.opt.cone # 1 = elliptic in the SO-101 model, 0 = pyramidal
mujoco.mj_contactForce(m, d, k, f6) # contact k: f6[:3] = (normal, tangent1, tangent2), then torques
on_geom2 = d.contact[k].frame.reshape(3, 3).T @ f6[:3] # world frame; normal points geom1 -> geom2
ci = scipy.stats.binomtest(k, n).proportion_ci(method="wilson")
Parçaphysai / bu dersMuJoCoSciPy
geçerli sürtünme katsayısıcone_ratio’daki μpriority’si yüksek geom, yoksa friction’ın eleman bazında maksimumu
contact kuvveticone_use(f) girdisi, (normal, t1, t2)mj_contactForce, contact frame’i, önce normal
başarı aralığıwilson(k, n)binomtest(k, n).proportion_ci(method="wilson")

Kaynaklar: MuJoCo Modeling · contact, mjContact, mj_contactForce; SciPy binomtest.

Üç tuzak:

  • İşaret ve frame. mj_contactForce contact frame’inde verir ve frame’in normali geom1’den geom2’ye bakar: küp geom1 ise işareti çevir (Adım 2).
  • Pyramidal cone’ların daha çok satırı var. cone="pyramidal" ile efc_force contact başına (normal, teğetler) değil 2(condim−1)2(\text{condim} - 1) piramit kenarı kuvveti tutar; kuvvetleri mj_contactForce üzerinden oku.
  • SciPy’ın varsayılan aralığı Wilson değil. proportion_ci() varsayılan olarak method="exact" (Clopper–Pearson, daha geniş) kullanır; tablolarla eşleşmesi için method="wilson" ver.

Yazdıktan sonra · 2 soru.

1. Takılan çene servo’su hareketli çeneyi küpe yaklaşık τmax⁡/rj\tau_{\max}/r_j ile bastırıyor. Toplam sıkma N1+N2N_1 + N_2 ne olur?

  • Yaklaşık τmax⁡/rj\tau_{\max}/r_j; iki çene arasında bölünür.
  • Yaklaşık 2τmax⁡/rj2\tau_{\max}/r_j, çünkü sabit çene de aynı kuvvetle karşılık verir.
  • μ’ye bağlıdır, çünkü sürtünme normal kuvvete eklenir.

Neden: Sıfırdan yaz, Adım 3 - iki çene eşit bastırıyor (0,5 N·m’de sabit / hareketli 1,001) ve 12,66 N’luk sıkma, rr = 7,42 cm ile 2(τ±kayıp)/r2(\tau \pm \text{kayıp})/r = [12,07, 14,87] N bandının içinde.

2. C bölümünün 10/10’unu scipy.stats.binomtest(10, 10).proportion_ci() ile raporluyorsun ve tablonun [0,72, 1,00]‘ından farklı bir aralık alıyorsun. Neden?

  • SciPy 1,96 yerine zz = 1,95996 kullanıyor, bu da sınırı gözle görülür kaydırıyor.
  • Varsayılan yöntem "exact" (Clopper–Pearson) ve daha geniş; method="wilson" ver.
  • SciPy başarı sayısını değil, başarısızlık sayısını bekliyor.

Neden: Kütüphaneyle kullan, tuzaklar. method="wilson" ile Adım 5 SciPy’la 7,4e-06’ya kadar örtüşüyor; zz farkı yalnızca o son 1e-5’i açıklıyor.

Pick, Bölüm 7’nin demonstration kaydetmek için import ettiği tek bir fonksiyon:

def scripted_pick(model, data, cube_pos, record=False):
"""Runs settle -> pre -> down -> close -> lift -> hold in (model, data).
Returns success, lift_cm, squeeze_N, close_s, ... and with record=True the
per-step (time, state, qpos, ctrl) trajectory."""

Kurulum: SO-101 (Menagerie scene.xml, timestep 2 ms), 3 cm küp, condim 4, küp sürtünmesi μ, kütle m, çene torque cap’i τ (varsayılan 2,94 N·m). Her sweep değeri (22, 0) cm çevresindeki 2 × 2 cm’lik bir karede düzgün dağılmış 10 küp pozisyonuyla koşuluyor, seed 0. Script: experiments/16-grasping-and-pick-place/experiment.py. MuJoCo 3.17.0, NumPy 2.5.4, Python 3.14, Apple M5, deterministik, ~30 s.

Nominal pick (μ 1,0, 30 g, varsayılan cap): başarılı, küpün altı 7,37 cm’de, IK hatası 0,18 mm, çene kuvvetleri 39,84 / 39,83 N, kaydedilen 2287 adım. 0,29 N’luk bir küpe yaklaşık 80 N’luk sıkma sürtünmeyi hiç sınamaz; bu yüzden A ve C bölümleri 0,5 N·m’lik cap kullanıyor.

Tahmin et: τ = 0,5 N·m’de sıkma yaklaşık 13 N, yani 30 g için cone μ ≈ 0,02’nin altında bozulur. Ölçülen sınır orada mı çıkacak?

A. Sürtünme sweep’i (30 g, τ = 0,5 N·m). “close” = close state’inde geçen süre, “sıkma” = state bittiğindeki N1+N2N_1 + N_2 (çenenin kapandığı denemeler üzerinden ortalama). “Wilson %95”, n’de k ile tutarlı gerçek başarı oranları aralığıdır; 10 denemeyle geniştir. “Fırladı”: küp 30 cm’den uzakta kaldı.

μbaşarıWilson %95closesıkmaμ(N1+N2)/mg\mu(N_1+N_2)/mgtuttu / kapanmadı / düşürdü; fırladı
0,0050/10[0,00, 0,28]–––0 / 10 / 0; 10
0,010/10[0,00, 0,28]–––0 / 10 / 0; 10
0,0150/10[0,00, 0,28]–––0 / 10 / 0; 10
0,020/10[0,00, 0,28]1,59 s14,21 N0,970 / 9 / 1; 8
0,032/10[0,06, 0,51]1,6212,291,252 / 8 / 0; 7
0,0510/10[0,72, 1,00]1,6312,742,1610 / 0 / 0; 0
0,110/10[0,72, 1,00]1,6313,264,5110 / 0 / 0; 0
0,310/10[0,72, 1,00]1,5814,2414,5210 / 0 / 0; 0
1,010/10[0,72, 1,00]1,5614,9150,6510 / 0 / 0; 0

Sınır μ = 0,03 ile 0,05 arasında, tahmine yakın; ama altındaki başarısızlıklar kaldırmadan sonraki düşürmeler değil. μ ≤ 0,03’teki 48 başarısız denemenin 47’sinde çene hiç oturmadı: küp çeneler kapanırken onları terk etti (45’i fırladı). Düşük sürtünme, ağırlık önem kazanmadan, sıkma anında başarısız oluyor. Fırlama mesafeleri MuJoCo’nun çok düşük μ’deki soft contact’ını yansıtıyor, gerçek hızları değil.

B. Çene torque cap’i (30 g, μ = 0,05):

τ [N·m]başarıclosesıkmaorantuttu / kapanmadı / düşürdü; fırladı
2,947/100,96 s88,93 N15,117 / 1 / 2; 3
1,010/100,9127,234,6310 / 0 / 0; 0
0,510/101,6312,742,1610 / 0 / 0; 0
0,310/102,657,041,2010 / 0 / 0; 0
0,20/10–––0 / 10 / 0; 5
0,150/10–––0 / 10 / 0; 0
0,10/10–––0 / 10 / 0; 0

Sıkma cap ile kabaca orantılı artıyor (7,04 → 12,74 → 27,23 N; Adım 3). 0,3 N·m’nin altında çene damping’ine (0,60 N·m·s/rad) ve friction loss’una (0,052 N·m) karşı o kadar yavaş kapanıyor ki 4 s’lik timeout içinde hiç oturmuyor (cap düştükçe close süresi 0,91 → 1,63 → 2,65 s). 2,94 N·m’de 10 küpün 3’ü fırlatılıyor: daha fazla kuvvet her zaman daha iyi grasp demek değil.

C. Kütle sweep’i (μ = 0,3, τ = 0,5 N·m):

m [kg]0,030,10,20,30,40,450,50,7
başarı10/1010/1010/1010/1010/100/100/100/10
sıkma [N]14,2414,9515,5215,8716,2516,4716,6116,90
μ(N1+N2)/mg\mu(N_1+N_2)/mg14,524,572,371,621,241,121,020,74
sonuçtuttututtututtututtututtudüşürdüdüşürdüdüşürdü

Solda: μ başına A bölümü sonuçları; μ = 0,03'e kadar çene çoğunlukla hiç oturmuyor, 0,05'ten itibaren 10'u da tutuluyor. Sağda: friction-cone oranına karşı C bölümü başarısı; 1,24 ve üstü başarılı, 1,12 ve altı başarısız, 1 sınırının hemen üstünde.

Burada hikâyenin tamamı cone: ortalama oranı ≥ 1,24 olan her kütle bütün denemelerde tutuyor, oranı ≤ 1,12 olan her kütle kaldırma sırasında düşüyor. Sınır 1’in biraz üstünde: küpü yukarı ivmelendirmek için gereken ek kuvvet.

μ’yü düşür (A bölümü) ya da kütleyi artır (C bölümü); grasp iki şekilde bozulur. Ağır küp, oran ≤ 1,12: cone’un öngördüğü gibi kaldırma sırasında çenelerin arasından aşağı kayıyor. Kaygan küp, μ ≤ 0,015: her değerdeki 10 küpün hepsi çene kapanırken dışarı atılıyor. Statik oranın 1,25 olduğu μ = 0,03’te bile 10 grasp’ten 8’i hiç oluşmuyor. Son grasp üzerindeki cone kontrolü gerekli ama yeterli değil: kapanma da contact’ları cone’larının içinde tutmalı.

  • SO-101 / LeRobot. Bağlanırken LeRobot gripper servo’sunu Max_Torque_Limit 500, Protection_Current 250 ve Overload_Torque 25 ile sınırlıyor (so_follower.py). Bunların çenede kaç newton-metre olduğu orada belgelenmemiş; Menagerie’deki 2,94 N·m’lik cap bir model parametresi, ölçüm değil.
  • Gerçek kolda henüz ölçülmedi. Prosedür: iki yüzey bitişinde tartılmış 3 cm’lik küpler; scripted pick’i (kalibrasyondan gelen joint offset’leriyle) sabit pozisyonlarda küp başına 20 kez koş; aynı fiziksel testle puanla (≥ 4 cm kalktı, 1 s tutuldu); k/n’yi Wilson aralığıyla raporla.
  • Sim-to-real farkları. Gerçek sürtünme statik ve kinetik arasında farklıdır, toz ve aşınmayla değişir (MuJoCo’da tek μ var), pad’ler deforme olur. Sınırın kaymasını bekle; yöntem taşınır.

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

1. C bölümünde 0,45 kg’lık bir küpün friction-cone oranı 1,12, yani 1’in üstünde; ama 10 kaldırmanın hepsinde düşüyor. Neden?

  • Kaldırma küpü yukarı ivmelendirir; bu, μ(N1+N2)≥m(g+a)\mu(N_1+N_2) \ge m(g + a) ister, yani statik testten biraz fazlasını.
  • Çene ağır bir küpün üzerine hiç kapanmaz.
  • Oran yanlış μ ile hesaplanıyor, çünkü çene pedlerinin priority’si var.

Neden: Oranı ≥ 1,24 olan her kütle tuttu, ≤ 1,12 olan her kütle kaldırma sırasında düştü (C bölümü). Küpe priority 2 verildi, yani geçerli olan onun μ’sü.

2. μ ≤ 0,03’te (30 g, cap 0,5 N·m) neredeyse her grasp başarısız. Ne zaman başarısız oluyor?

  • Kaldırmadan sonra, küp çenelerin arasından aşağı kayınca.
  • down state’inde, açık çeneler küpü devirince.
  • Çeneler kapanırken; küp, kavrama oluşmadan onları terk ediyor.

Neden: μ ≤ 0,03’teki 48 başarısız denemenin 47’sinde çene küpe hiç oturmadı (A bölümü). Son grasp üzerindeki cone kontrolü gerekli ama yeterli değil.

  1. Kolay. Sıkma N1+N2N_1 + N_2 = 12,74 N ve μ = 0,05 iken cone koşulunun izin verdiği en ağır küp kaç kg?
  2. Orta. Script close’u neden sabit 0,6 s sonra değil de algılanan bir koşulla bitiriyor? B bölümünün close sürelerini kullan.
  3. Zor. close state’i, çene rampası başladığından beri küpün 5 mm’den fazla hareket etmediğini de kontrol etsin; ettiyse iptal etsin (yeniden aç, yeniden yaklaş). A bölümünü yeniden koş. Önce tahmin et: μ = 0,03’teki başarı artar mı?
  1. m≤μ(N1+N2)/g=0,05⋅12,74/9,81≈0,065m \le \mu (N_1+N_2)/g = 0{,}05 \cdot 12{,}74 / 9{,}81 \approx 0{,}065 kg.
  2. Close süresi 0,91 s (τ 1,0 N·m) ile 2,65 s (τ 0,3 N·m) arasında değişiyor. Sabit 0,6 s hepsinden kısa; yani çene oturmadan kaldırır. En yavaş cap’e yetecek bir timer ise hızlı cap’lerde zaman kaybettirir.
  3. Burada hesaplanmadı; koş ve gör.
  • Friction cone kaldırmayı öngörüyor: sıkma ölçüldüğünde, oranı ≥ 1,24 olanlar 50/50 denemede tuttu, oranı ≤ 1,12 olanlar 30/30 denemede düşürdü (C bölümü).
  • Düşük μ’de grasp daha erken, kapanma sırasında bozuluyor (μ ≤ 0,03’te 48 başarısızlığın 47’si); sıkma çene cap’iyle ölçekleniyor ve fazla düşük bir cap 4 s içinde hiç kapanmıyor.
  • scripted_pick (ve physai.grasp.PickMachine) fiziksel olarak doğrulanmış bir demonstration üreticisi: state machine, IK, min-jerk, algılanan bir close koşulu, weld yok.

Sonraki: Bölüm 5 · ders 17 · Sensor’ler, noise ve filtering; demonstration’lar ders 26’da kullanılıyor.

Kaynaklar: