
Isaac LabとPPOで始めるUnitree G1のボトル把持・持ち上げ強化学習プロジェクト:Sim-to-Realで600mlボトルを実機把持・持ち上げ、PoCの完結
はじめに
前回の記事では、Isaac Lab上で構築したUnitree G1 Inspire Hand向けのボトル把持・持ち上げ強化学習について、simulationから実機deploymentの入口までを紹介しました。
前回までに確認できていた主な結果は以下です。
| Item | Result |
|---|---|
| Stage 1 modular evaluation | 768 / 768 |
| Stage 2 modular evaluation | 766 / 768 |
| Object-relative corrected integration | 748 / 768、97.40% |
| Practical asymmetric workspace | 648 / 768、84.375% |
| DGX Spark standalone inference | Passed |
| Real G1 state acquisition | Passed |
| Real Inspire Hand state acquisition | Passed |
| Real Stage -1 arm transition | Passed |
| First bounded Stage 2 command | Passed |
| Real object grasp / lift | Not yet tested |
前回の記事の最後では、実機G1上でtask-ready poseまで右腕を移動し、Stage 2 actorから生成されたbounded hand commandを送信するところまで確認していました。
しかし、実際のボトルを把持し、さらに内容物入りのボトルを持ち上げるところまでは到達していませんでした。
今週は、この最後のsim-to-real gapを埋めました。
最終的には、
Normal standing
↓
safe arm transition
↓
palm-left pregrasp
↓
Stage 2 RL-assisted grasp
↓
約600 mlの内容物入りPETボトルを保持
↓
two-stage lift
↓
実際にボトルがテーブルから離地
までを実機で確認しました。
本記事では、その過程で行った以下の内容をまとめます。
- Stage 2 policyを使った実機grasp
- Inspire Handの実機pre-shape調整
- 右手薬指故障というhardware constraintへの対応
- 空ボトルから約600 mlボトルへの段階的移行
- 実機でliftがほとんど発生しなかったfailure
- URDF joint limitの検証
- command targetとactual joint stateのtracking解析
- no-load / loaded conditionの比較
- steady-state tracking errorに対するmeasured compensation
- nominal 6 cmのtwo-stage lift
- 最終実機demo
- なぜ今回はStage 1 actorを実機で使用しなかったか
- 次のVisual Manipulation Projectへの接続
本記事の最終demoでは、約600 mlの内容物入りPETボトルを実際に把持し、テーブルから離地させるところまで確認しています。
一方で、安定したplace-backまで完成したわけではありません。下降・release時にはまだボトルを落としやすいため、demoでは安全のため人がボトルを受けています。
また、今回の最終実機PoCではボトル位置はmanual placementであり、camera-based autonomous manipulationではありません。
今回の実機PoCではStage 2だけを使用する
Simulationでは、最終的に以下のpipelineを構築していました。
Stage 0:
geometric coarse bias
↓
Stage 1:
learned safe approach
↓
controlled ingress
↓
Stage 2:
learned grasp residual
↓
lift
↓
retention
Stage 1にはmodel_149、Stage 2にはmodel_100を使用していました。
しかし、今回の実機PoCではStage 1 actorを直接使用しませんでした。
実機で使用したlearned policyはStage 2のmodel_100だけです。
理由は、Stage 1の役割が本質的に、
bottle position
↓
outer target
↓
right-arm approach
というobject-relative approachだからです。
現在の実機runtimeには、まだG1 cameraから取得した画像を使ってボトル位置をreal-timeに推定するperception pipelineがありません。
その状態でStage 1へnominal bottle positionを入力しても、「視覚を使った自律approach」にはなりません。
そこで今回のPoCでは、まずmanipulation部分だけを完成させることを優先しました。
manual bottle placement
↓
validated scripted arm approach
↓
Stage 2 RL-assisted grasp
↓
lift
つまり今回の実機結果は、
Stage 2 manipulation policyのsim-to-real PoC
として位置づけています。
Stage 1は使えなかったのではなく、次のプロジェクト(vision integration)で使用するために残しています。
実機Stage 2 Runtime
Stage 2 actorは前回と同じmodel_100です。
Network architectureは以下です。
input:
53D
network:
53
↓
256
↓
128
↓
64
↓
12
activation:
ELU
Stage 2はscripted grasp trajectory全体を置き換えるend-to-end policyではありません。
実際の構成は、
scripted calibrated grasp base
+
bounded Stage 2 learned residual
です。
つまり、
q_candidate
= q_base + residual_scale × actor_output
というhybrid構成です。
今回もStage 2はdeterministic inferenceで使用しています。
Residual scaleはsimulationと同様に0.08です。
また、closing方向についてはunilateral constraintを維持しました。
candidate
= max(candidate, base)
というsimulator-side conventionをreal motor-spaceへ変換しています。
したがって、policyが突然手を開く方向へ大きなcommandを出すことはありません。
Inspire Handの12D Simulation表現と6D実機Motor Space
Simulationで使用しているright handは12個のarticulated jointで表現されています。
一方、実機Inspire Handでは、右手を6D motor-spaceとして扱います。
今回使用したmotor orderは以下です。
0: pinky
1: ring
2: middle
3: index
4: thumb bend
5: thumb rotation
実機motor commandでは、
0:
close
1:
open
という方向です。
Stage 2 actorは12D targetを生成するため、実機では、
real motor-space q6
↓
simulator-side articulated q12
↓
Stage 2 actor
↓
12D candidate
↓
DFQ manifold projection
↓
real motor-space q6
というadapterを使用しています。
Pureにactor outputをmotorへ直接送信しているわけではありません。
使用したInspire Handの右手薬指が故障していた
今回使用した実機Inspire Handには、重要なhardware constraintがありました。
右手の薬指(ring finger)が故障しており、正常に独立制御できない状態でした。
そのため、最終demo動画を見ると、薬指だけが他の指と同じように開閉していないことが分かります。
これは、
Stage 2 policy failure
motor mapping failure
projection failure
による動作ではありません。
今回使用した実機hand固有のhardware故障です。
したがって、実機graspでは、
index
middle
pinky
thumb
を主に利用しながら、薬指が正常に独立制御できない状態のままgraspを成立させています。
Simulationでは5本の指が正常に動作するモデルを使用しているため、これは明確なsim-to-real差の一つです。
今回、この故障を補うためにpolicyを再学習することはしませんでした。
まず、
現在利用可能なhardware conditionのまま、既存Stage 2 policyとreal-world calibrationでどこまで成立するか
を確認する方針としました。
最終的には、このhardware constraintが存在する状態でも約600 mlのPETボトルを把持し、テーブルから離地させることができました。
実機Inspire HandではPre-shapeを再調整する必要があった
最初は、simulationで設計したpre-shapeをそのままprojectionして使用していました。
しかし実機では、grasp開始前の指が予想以上にcurlしていました。
特にpre-shape commandの一部だけを更新していたため、q0〜q3がstartup stateの影響を残していました。
そこで、pregraspでは右手6 motorに対してfull-open targetを明示的に与えるようにしました。
q0 = 1.0
q1 = 1.0
q2 = 1.0
q3 = 1.0
q4 = 1.0
q5 = 1.0
ただし、前述の通りring fingerについては実機側の故障により、command通りの独立した動作は行えません。
それでも、正常に動作する指についてはfull-open poseを使用することで、PETボトルへ横方向からapproachするときの指先干渉を大きく減らすことができました。
実機では、
simulator-side nominal poseより、実際に観測したhand geometryとhardware conditionを優先する
という方針を採用しました。
Wrist Orientationも実機で調整する
もう一つ重要だったのがwrist rollです。
最初に候補として、
1.20
0.90
0.60
0.35
0.16 rad
などを段階的に確認しました。
その後、さらにpalmをボトル側へ向けるため、最終的には、
right_wrist_roll = 0.0 rad
を使用しました。
今回の実機taskでは、
palm:
bottle側
fingers:
bottleの側面をwrap
thumb:
opposition
というgeometryを狙っています。
実機では数cmの位置差だけでなく、wrist orientationの小さな差もgrasp qualityへ大きく影響しました。
Startup TrajectoryとTableが干渉する
実機統合中には、policy以外のfailureも発生しました。
特に問題だったのがstartup trajectoryです。
Normal standingからtask-ready poseへ移動するために、Unitree native Right Hand Up動作からcaptureしたtrajectoryを使用していました。
このtrajectory自体はfree-spaceでは動作しました。
しかしFKを確認すると、途中のhand centerはtable topより低い高さのまま、かなり前方へ移動します。
そのため、
robot startup
+
table already present
という状態では、腕がtableへ干渉する可能性がありました。
実際にtableを押してしまうケースも確認しました。
そこで最終demoでは、
1. tableなしでstartup
2. right armをsafe outer poseまで移動
3. そこで5秒間停止
4. その間にtableとbottleを配置
5. 人がworkspaceから離れる
6. countdown終了後、自動的にingress
という構成にしました。
最初はterminalでCONTINUEを入力するoperator gateを使用していました。
しかしdemo撮影時にoperatorがPCとrobotの間を移動する必要があるため、最終版ではこれを廃止しました。
5
4
3
2
1
↓
automatic ingress
という5秒の固定windowにしています。
時間内に安全な配置が完了しない場合は、実行をabortします。
空ボトルから内容物入りPETボトルへ
実機testは一気に約600 mlへ進めたわけではありません。
最初は軽量なempty PET bottleを使用しました。
目的は、
arm geometry
hand geometry
finger closing direction
contact position
retention
を、payloadの影響を小さくした状態で確認することでした。
その後、
Stage 2 target
full-open pre-shape
wrist orientation
ingress depth
を調整し、最終的に約600 mlの内容物入りsealed PET bottleへ移行しました。
ここで重要なのは、simulationで使用した0.62 kg bottleと実物が完全に同一ではないことです。
Simulationはsimplified rigid bodyです。
実物では、
PET deformation
label friction
liquidによるmass distribution
grasp中の微小なslip
finger surface friction
などがあります。
したがって、
simulation:
0.62 kg success
と、
real:
approximately 600 ml filled PET success
は別の結果として扱っています。
Stage 2 RL-Assisted Graspを実物へ接続する
最終的なgraspでは、
full-open pre-shape
↓
50% deeper ingress
↓
Stage 2 model_100
↓
bounded final hand target
↓
grasp target latch
というsequenceを使用しました。
Simulationでも、一度retentionに成功した後にactor targetを更新し続けると、時間経過とともにbottleが傾き、slipするケースがありました。
そのため実機でも、grasp完了後はfinal hand targetをlatched targetとして保持しました。
Stage 2 grasp
↓
final hand target
↓
latch
↓
lift中も同じtargetを維持
つまりlift中にactorへ自由にhand targetを更新させるのではなく、成功したgrasp commandを固定しています。
これはsimulationで得たfailure analysisを、そのままreal runtimeのsupervisory controlへ反映した例です。
最初の約600 ml実機Grasp
この構成により、約600 mlの内容物入りPETボトルに対して、
side approach
↓
finger wrap
↓
thumb opposition
↓
retention
まで確認できました。
右手薬指は故障しているため、simulationと同じ5本指によるgraspではありません。
それでも、正常に動作する指とthumbを中心にgraspを成立させることができました。
ここで最初の大きなsim-to-real milestoneは達成しました。
しかし、次の問題が発生しました。
ボトルは持てるのに、ほとんど上へ持ち上がりませんでした。
Failure:+2 cm LiftをCommandしてもほとんど上がらない
当初のliftは、task-ready pose周辺で計測したlocal Cartesian-to-arm mappingを使用しました。
+Z方向の代表的なjoint correctionは以下です。
| Joint | +Z coefficient |
|---|---|
| right shoulder pitch | +0.1836 rad/m |
| right shoulder roll | -0.0313 rad/m |
| right shoulder yaw | +0.1120 rad/m |
| right elbow | -2.9553 rad/m |
+2 cmを要求すると、right elbowでは概ね、
-2.9553 × 0.02
≈ -0.0591 rad
のcommandになります。
Kinematic model上では問題ありません。
しかし実機では、commandしたほどarmが動いていませんでした。
最初は、
robotのjoint limitに近づいているのではないか
と疑いました。
URDF Joint Limitを確認する
公式G1 DFQ URDFからright arm joint limitを確認しました。
代表値は以下です。
| Joint | Lower | Upper |
|---|---|---|
| Shoulder pitch | -3.0892 | +2.6704 |
| Shoulder roll | -2.2515 | +1.5882 |
| Shoulder yaw | -2.6180 | +2.6180 |
| Elbow | -1.0472 | +2.0944 |
| Wrist roll | -1.9722 | +1.9722 |
| Wrist pitch | -1.6144 | +1.6144 |
| Wrist yaw | -1.6144 | +1.6144 |
当時のlift elbow targetは、
-0.062889 rad
でした。
一方、URDF lower limitは、
-1.0472 rad
です。
つまりlower limitまで、
approximately 0.984 rad
残っていました。
Shoulder jointsについても同様に十分なmarginがありました。
したがって、
liftできない原因はjoint-angle limitではない
ことが分かりました。
Commanded Joint TargetとActual Stateを比較する
次に、実機logから、
commanded target
vs
measured actual state
を比較しました。
約600 ml loaded runでは、lift前の代表値が以下でした。
Right Elbow
pregrasp command:
approximately -0.0038 rad
pregrasp actual:
approximately +0.0695 rad
error:
approximately +0.0733 rad
さらにlift topでは、
lift target:
-0.0629 rad
actual:
+0.0451 rad
error:
+0.1080 rad
となっていました。
つまり、
IK / Jacobian target
↓
q_target
↓
arm controller
↓
q_actual
の最後の部分で、大きなtracking errorが発生していました。
50% Deeper Ingressでも実際には50%動いていなかった
この結果はliftだけでなく、pregrasp geometryについても重要でした。
実機では「50% deeper ingress」を設定していました。
しかし肉眼では、50%にしてもhandが期待したほどボトル中心へ入りませんでした。
当初は、
50%
↓
70%
↓
100%
とcommandを増やすことも考えました。
しかしtracking logを見ると、問題はcommand fractionそのものではありませんでした。
例えばright elbowでは、
command:
approximately -0.0038 rad
actual:
approximately +0.068 rad
でした。
つまり、
50% commandを送っているが、実機はその50% targetまで到達していない
という状態でした。
ここで、単純にingress fractionだけを増やすのではなく、controller trackingそのものを調べることにしました。
No-Load Tracking Diagnostic
600 ml payloadが原因なのかを分離するため、同じarm targetを、
object:
none
table:
none
hand motion:
none
という条件で実行しました。
さらにpregrasp targetを10秒間保持し、0.5秒ごとにactual joint stateを記録しました。
結果は非常に明確でした。
Pregrasp
Right shoulder pitch:
target:
-0.299587
actual:
approximately -0.2407
error:
approximately +0.0589 rad
Right elbow:
target:
-0.003784
actual:
approximately +0.0674
error:
approximately +0.0712 rad
そして10秒間保持しても、
elbow error:
t = 0 s
approximately 0.07128
t = 5 s
approximately 0.07117
t = 10 s
approximately 0.07115
でした。
ほぼ変化していません。
つまり、
convergenceが遅いだけ
ではありませんでした。
一定のtracking offsetを持った状態でsteady stateになっていました。
Liftでも同じSteady-State Errorが発生する
No-load liftでも同様でした。
Right elbow:
target:
-0.062889
actual:
approximately +0.0215
error:
approximately +0.0844 rad
5秒保持しても、
0.0845
→
0.0844
→
0.0844
程度しか変化しませんでした。
ここまでで、
joint limit:
not the cause
insufficient waiting time:
not the cause
600 ml payload only:
not the cause
であることが分かりました。
No-loadでも明確なsteady-state tracking offsetが存在します。
Controller Packetも確認する
使用していたarm command packetも確認しました。
代表値は以下です。
Right Shoulder Pitch
kp:
90
kd:
3
tau:
0
Right Elbow
kp:
60
kd:
3
tau:
0
Arm weightは、
weight:
1.0
でした。
つまり、以前のlow-weight takeoverのように、
weight = 0.2
だからtargetへ到達しないという状態ではありません。
また、今回のPoCではKp / Kdを変更しませんでした。
実機のstiffnessを上げるよりも、まず現在のcontroller behaviorを計測し、その結果をtrajectory側へ反映する方針を取りました。
Payloadを追加するとLift Trackingはさらに悪化する
No-loadと約600 ml loaded conditionを比較すると、right elbow lift top errorは以下でした。
| Condition | Elbow top error |
|---|---|
| No load | approximately 0.0844 rad |
| Approximately 600 ml loaded | approximately 0.1080 rad |
差は、
approximately 0.0236 rad
です。
つまり、
no-loadでもtracking offsetが存在
+
payloadを持つとさらにtracking errorが増加
という結果でした。
この結果は、
kinematic targetが正しくても、実機actuator / controllerがそのtargetへ正確に到達するとは限らない
ことを示しています。
Simulationでは、
q_target
≈
q_actual
として扱える場合があります。
しかし実機では、
q_target
!=
q_actual
でした。
この差は、数cm単位のmanipulationでは無視できません。
Measured Tracking Compensation
そこで、実機で計測したsteady-state errorを使ってcommand targetを補正することにしました。
Errorを、
e
= q_actual - q_desired
とします。
今回は最初から100%補正せず、
alpha = 0.25
として、
q_command
= q_desired - alpha × e
というconservative compensationを試しました。
Pregrasp Compensation
No-load diagnosticで計測したerrorは、
shoulder pitch:
+0.058860 rad
elbow:
+0.071147 rad
でした。
25% compensationは、
shoulder pitch bias:
-0.014715 rad
elbow bias:
-0.017787 rad
です。
25% Compensationの実機結果
同じrun内で、まず補正なしbaselineを計測しました。
Before
shoulder pitch error:
approximately +0.05825 rad
elbow error:
approximately +0.07121 rad
25% compensation適用後は、
After
shoulder pitch error:
approximately +0.05329 rad
elbow error:
approximately +0.06327 rad
となりました。
両jointとも、actual stateがdesired pose方向へ移動しています。
特にliftでは改善がより明確でした。
No Compensation
elbow lift error:
approximately +0.08436 rad
25% Compensation
elbow lift error:
approximately +0.06201 rad
約26.5%減少しました。
また、actual elbow positionも、
approximately +0.0215 rad
から、
approximately -0.0009 rad
まで移動しました。
これにより、
command biasを使えばreal tracking errorを少なくできる
ことを実機で確認できました。
一方、responseは完全な1:1ではありませんでした。
そのため、この補正を理論的なinverse controllerとして扱うのではなく、
measured real-world calibration
として扱っています。
Loaded Condition用の追加Compensation
約600 ml loaded conditionでは、no-loadよりさらに、
approximately 0.023645 rad
のelbow errorが増加していました。
そこで最終runtimeでは、
no-load tracking compensation:
25%
additional loaded elbow compensation:
50% of measured incremental error
という構成を採用しました。
追加loaded biasは約、
-0.01182 rad
です。
Kp、Kd、arm weightは変更していません。
つまり、
controllerを強くする
のではなく、
actual robot responseを計測
↓
command trajectoryを調整
しています。
+3 cmでも実機Liftはまだ小さかった
最初の実機liftはnominal +2 cmでした。
Tracking compensation導入後、さらにnominal +3 cmへ拡張しました。
しかし、実際のdemoで見ると、まだ持ち上げ量は小さく、
graspは成功しているが、視覚的に明確なpick-and-liftとしては弱い
という結果でした。
ここで重要だったのは、
3 cm command
が、
actual 3 cm Cartesian lift
を意味するわけではないことです。
Local Jacobianはkinematic targetを生成していますが、real controller tracking errorが残っています。
したがって、最終的にはlift target自体をさらに拡張しました。
最終版はNominal 6 cmのTwo-Stage Lift
一度に大きなjoint targetへjumpするのではなく、最終demoではliftを2段階に分けました。
grasp
↓
Stage 1 lift:
nominal +3 cm
3.5 s
↓
0.75 s hold
↓
Stage 2 lift:
additional nominal +3 cm
3.5 s
↓
total nominal:
+6 cm
ここでいう6 cmはkinematic command上のnominal valueです。
実機で正確に6.0 cm上昇したことを主張するものではありません。
最終demoで確認したのは、
ボトルが明確にテーブルから離地した
という実機結果です。
Lift Guardrailも段階的に変更する
以前は、
MAX_LIFT_JOINT_DELTA_RAD:
0.070 rad
という独自のengineering guardrailを使用していました。
これはG1のhardware joint limitではありません。
6 cm liftでは、この値を単純に無効化するのではなく、
per-stage guardrail:
0.110 rad
total guardrail:
0.210 rad
と分離しました。
Right elbowのcommand deltaは、
Stage 1:
approximately -0.1038 rad
Stage 2:
approximately -0.0887 rad
Total:
approximately -0.1924 rad
でした。
最終elbow commandは、
approximately -0.2140 rad
です。
URDF lower limitは、
-1.0472 rad
なので、joint-angle limitまでは、
approximately 0.833 rad
残っています。
つまり、最終demoでもhardware joint-angle limitへ近づけたわけではありません。
Two-Stageにした理由
Two-stage liftには、単に高さを増やす以外にもメリットがありました。
grasp
↓
small lift
↓
short hold
↓
second lift
とすることで、
- 最初のliftでgraspが大きく崩れていないことを確認しやすい
- 1回のcommand displacementを小さくできる
- demo上もlift movementが視覚的に分かりやすい
- lower時も段階的なtrajectoryを構成できる
という利点があります。
最終runtimeではlower側も、
top
↓
intermediate lift pose
↓
pregrasp height
というtwo-stage trajectoryを実装しました。
ただし、現在のhardware / grasp conditionでは、下降中にボトルがslipする場合があります。
そのため、最終demoでは安定したautonomous place-backを成功結果として扱っていません。
最終Demo
最終的な実機sequenceは以下です。
Normal standing
↓
native safe raise
↓
move outward
↓
full-open Inspire Hand
↓
wrist roll = 0
↓
5-second table / bottle placement window
↓
fixed-wrist ingress
↓
50% deeper pregrasp
↓
measured tracking compensation
↓
Stage 2 model_100 RL-assisted grasp
↓
grasp target latch
↓
two-stage nominal +6 cm lift
↓
bottle leaves table
約600 mlの内容物入りPETボトルに対して、
Stage 2 model-derived grasp
bottle retention
visible upward motion
bottle bottom lift-off
を確認できました。
Demo動画
動画中では、右手の薬指が他の指と同じように動作していません。
これは今回使用したInspire Handの右手薬指が故障しており、正常に独立制御できないためです。Stage 2 policyが意図的に薬指を停止させているわけではありません。
このhardware constraintが存在する状態でも、正常に動作する指とthumbを用いて約600 mlのPETボトルを把持し、テーブルから離地させることができました。
このdemoでは、ボトルを持ち上げて離地させるところまでを成功結果としています。
一方、現在も下降・release時にはgraspが不安定になり、ボトルを落とす可能性があります。
そのため動画では、最終的に人がボトルを受けています。
本記事では、
pick:
demonstrated
lift-off:
demonstrated
stable autonomous place-back:
not established
と区別します。
最終実機Pipeline
今回のPoC最終版をまとめると、以下の構成です。
Real Stage -1:
native G1 trajectory
↓
safe outer pose
Manual perception substitute:
fixed bottle placement
↓
5-second insertion window
Geometric arm controller:
fixed-wrist ingress
↓
50% deeper pregrasp
↓
measured tracking compensation
Stage 2:
frozen model_100
↓
scripted base grasp
+ learned residual
↓
bounded real Inspire Hand target
↓
target latch
Lift:
measured local Cartesian-to-arm mapping
↓
real tracking compensation
↓
payload compensation
↓
two-stage nominal +6 cm lift
Pure end-to-end RLではありません。
今回も、
learned policy
+
geometric control
+
measured real-world calibration
+
supervisory control
を組み合わせたhybrid systemです。
なぜStage 1を最終Demoへ入れなかったか
SimulationではStage 1は非常に重要でした。
Stage 1の役割は、
current arm state
+
bottle-relative observation
↓
safe outer approach
です。
しかし実機でStage 1を正しく使用するには、
camera image
↓
bottle detection
↓
3D position estimation
↓
camera frame
↓
robot / task frame transform
↓
Stage 1 observation
が必要になります。
今回の実機PoCでは、このperception layerはまだ実装していません。
Bottle positionはmanual nominal placementです。
そのため、Stage 1へfake nominal observationを入力して動かすよりも、
Stage 2 manipulationのsim-to-real transferを先に完成させる
ことを選択しました。
結果として今回のfinal demoは、
Stage 1:
not used on real robot
Stage 2:
model_100 used on real robot
です。
これは今後の設計にも都合が良い結果でした。
今週遭遇した主なFailure
1. Simulationで3 cm上がるTargetでも実機で3 cm上がるとは限らない
Kinematic targetが正しくても、
q_target != q_actual
であれば、actual Cartesian poseも異なります。
Real manipulationでは、
IK accuracy
だけでなく、
controller tracking accuracy
も計測する必要があります。
2. 50% Ingress Commandは50% Actual Motionではなかった
Command fractionだけを見て、
50%では足りない
→ 100%にする
と判断すると、原因を誤ります。
今回の実際の問題は、targetそのものではなくtracking offsetでした。
3. 長くHoldしてもTracking Errorは消えなかった
10秒間のno-load holdで、
elbow error:
approximately 0.0713
→
approximately 0.0711 rad
でした。
つまり、単純にsettling timeを長くしても解決しませんでした。
4. Hardware Joint LimitとSoftware Guardrailを混同しない
当初使用していた、
MAX_LIFT_JOINT_DELTA_RAD = 0.070
は自分で設定したengineering guardrailです。
G1 elbowのURDF limit、
lower:
-1.0472 rad
とは全く別物です。
Debug時には、
hardware limit
controller behavior
software safety bound
trajectory design bound
を分離して考える必要があります。
5. PayloadによってTracking Behaviorが変わる
No-load elbow top error:
approximately 0.0844 rad
Loaded:
approximately 0.1080 rad
でした。
Real robotではobject massもcontroller responseへ影響します。
6. Measured Compensationは有効だが1:1ではない
25% command biasによってactual poseはdesired方向へ移動しました。
しかしpregraspでは、command biasに対するactual responseは完全な1:1ではありませんでした。
そのため、
measured error
↓
100% inverse compensation
と単純化せず、small bounded correctionとして段階的に使用しました。
7. Hardware FailureもSim-to-Real Gapの一部
Simulationではすべてのhand jointが正常に動作します。
しかし今回の実機Inspire Handでは右手薬指が故障しており、正常な独立制御ができませんでした。
それでも既存policyを即座に再学習するのではなく、
current hardware
↓
actual grasp geometry
↓
bounded calibration
の順で検証しました。
Real robotでは、simulationに存在しないhardware degradationもsystem designへ含める必要があります。
8. Startup PathもManipulation Systemの一部
Grasp policyだけが安全でも、そこへ到達するstartup trajectoryがtableに干渉すればsystemとして成立しません。
今回、native raise trajectoryがtable-safeではないことが分かり、
table absent during startup
↓
safe outer pose
↓
table insertion
というruntime-level workaroundを追加しました。
9. PASS Markerと実際のManipulation Successは別
Runtimeが、
PASS
を出しても、bottleが実際に持ち上がったことを保証しません。
最終的には、
robot log
+
joint state
+
visual observation
+
demo video
を合わせて判断しました。
特にreal-world roboticsでは、
software sequence completed
と、
physical task completed
を分離して記録する必要があります。
今回のSim-to-Realで最も重要だったこと
今回のPoCを通して最も大きかった学びは、
Simulationで正しいtargetを生成できることと、実機がそのtargetへ到達することは別問題
という点でした。
今回のfailure chainは、
simulation:
lift works
↓
offline IK:
lift target is valid
↓
URDF:
joint limits pass
↓
real robot:
lift is too small
↓
tracking diagnostic
↓
steady-state command / actual error discovered
↓
measured compensation
↓
larger two-stage lift
↓
real bottle lift-off
でした。
もし途中で、
RL policyが弱い
と判断してPPOを再学習していたら、問題の本質を見落としていた可能性があります。
今回は追加trainingではなく、
measurement
+
failure isolation
+
controller-level compensation
によって実機結果を改善しました。
これは前回のsimulation integrationで、
55.73% → 97.40%
へ改善したときと似ています。
そのときも問題はpolicy capacityではなくcoordinate semanticsでした。
今回も主な問題はpolicyそのものではなく、real-world control semanticsでした。
現在の到達点
Simulation
| Result | Value |
|---|---|
| Stage 1 modular | 768 / 768 |
| Stage 2 modular | 766 / 768 |
| Initial integrated RandPos | 428 / 768、55.73% |
| Object-relative corrected | 748 / 768、97.40% |
| Full ±5 cm square | 569 / 768、74.09% |
| Practical 10 cm × 8 cm workspace | 648 / 768、84.375% |
Deployment / Real Robot
| Item | Status |
|---|---|
| DGX Spark standalone Stage 1 actor | Passed |
| DGX Spark standalone Stage 2 actor | Passed |
| x86 / ARM64 numerical parity | Passed |
| G1 real state acquisition | Passed |
| Inspire Hand real state acquisition | Passed |
| Real Stage -1 | Passed |
| Full-open real pre-shape | Passed |
| Palm-left wrist calibration | Passed |
| Empty PET bottle grasp | Passed |
| Stage 2 model_100 real command | Passed |
| Approximately 600 ml filled PET grasp | Demonstrated |
| Loaded retention | Demonstrated |
| Real tracking diagnostic | Completed |
| Measured tracking compensation | Validated |
| Two-stage nominal +6 cm lift | Executed |
| Bottle lift-off | Demonstrated |
| Stable autonomous place-back | Not established |
| Camera-based autonomous approach | Not yet integrated |
| Real Stage 1 policy control | Not used in this PoC |
これでManipulation PoCはいったん完結
このプロジェクトでは、最初はIsaac Lab上で、
PET bottle
+
G1
+
Inspire Hand
+
PPO
を使ったgrasp / lift taskから始めました。
その後、
Mass Curriculum
Stage 1
Stage 2
controlled ingress
object-relative correction
Stage 0
randomized workspace evaluation
DGX Spark deployment
real G1 arm control
real Inspire Hand adapter
real grasp
tracking compensation
loaded lift
まで進みました。
最終的に、約600 mlの内容物入りPETボトルを実機G1で把持し、テーブルから持ち上げるdemoを残すことができました。
もちろん、robot manipulation systemとして完成したわけではありません。
現在も、
- manual bottle placement
- perceptionなし
- fixed standing
- predefined workspace
- autonomous place-back未完成
- contact force estimationなし
- Inspire Handはposition control
- 使用した実機Inspire Handの右手薬指が故障しており、独立制御不可
- Stage 1は実機未接続
という制約があります。
しかし、今回の目的は、
Simulation上で学習したRL policyを実機G1まで持っていき、実物体grasp / liftを成立させる
というPoCでした。
この目標については、ここで一度完結とします。
次は2つのProjectを統合する
今回の実習では、このManipulation Projectの前に、
「Unitree Go2とG1を活用したロボット目視検査エージェント」
も開発しました。
最初のProjectでは、
robot camera
↓
visual perception
↓
object / risk analysis
↓
agent
という、
robotが現実世界を見る
ための技術を扱いました。
一方、今回のProjectでは、
robot state
↓
approach
↓
RL grasp
↓
physical manipulation
という、
robotが現実世界へ働きかける
ための技術を扱いました。
実習最後のProjectでは、この2つを接続します。
目標とするpipelineは以下です。
G1 camera
↓
visual model
↓
bottle detection
↓
bottle position estimation
↓
camera-to-robot coordinate transform
↓
Stage 1 observation
↓
Stage 1 model_149
↓
automatic approach
↓
controlled ingress
↓
Stage 2 model_100
↓
automatic grasp
↓
lift
今回の実機PoCでStage 1を無理に使わなかった理由もここにあります。
Stage 1は本来、
「ボトルがどこにあるか」
というreal-world informationを受け取ってこそ意味があります。
次のProjectでは、最初のVisual Inspection Agentで得たcamera / vision側の知見を使って、このmissing perception layerを作ります。
そして、
Perception
+
Stage 1 approach
+
Stage 2 manipulation
を接続することで、
G1自身のcameraでボトルを見つけ、その位置を推定し、自動的にapproachして把持する
ところまで進める予定です。
まとめ
今回は、Isaac Lab上で学習したUnitree G1 Inspire Hand向けStage 2 policyを、実際のG1へ接続しました。
実機ではまず、full-open pre-shape、palm-left wrist orientation、safe outer approachを段階的に確認しました。
また、今回使用したInspire Handでは右手薬指が故障しており、独立して正常に制御できないというhardware constraintがありました。
それでも、Stage 2 model_100によるRL-assisted graspを実物PET bottleへ適用し、最終的には約600 mlの内容物入りPETボトルを把持できました。
一方、最初のliftは非常に小さく、nominal +2 cm / +3 cmのkinematic commandを与えても期待した高さまで上昇しませんでした。
URDF joint limitを確認した結果、joint-angle limitは原因ではありませんでした。
さらにno-load tracking diagnosticを行ったところ、10秒間targetを保持してもright elbowで約0.071 radのsteady-state tracking errorが残ることを確認しました。
Lift topでは、
no-load:
approximately 0.0844 rad error
approximately 600 ml loaded:
approximately 0.1080 rad error
となり、payloadによってtracking errorがさらに増加していました。
そこで、measured steady-state errorの25%をcommand biasとして使用しました。
その結果、lift時のright elbow errorは、
approximately 0.0844
→
approximately 0.0620 rad
まで改善しました。
最終demoでは、さらにloaded conditionの追加tracking errorを部分的に補正し、nominal +3 cmを2段階で実行するtwo-stage nominal +6 cm liftへ拡張しました。
その結果、実機G1が約600 mlの内容物入りPETボトルを把持し、実際にテーブルから離地させるdemoを記録できました。
今回の最終実機pipelineではStage 1 actorは使用していません。
Stage 1に必要なreal bottle positionをまだcameraから取得していないためです。
次のProjectでは、以前開発した「Unitree Go2とG1を活用したロボット目視検査エージェント」のvision技術と今回のmanipulation技術を統合します。
最終的には、
G1 camera
↓
visual model
↓
automatic bottle localization
↓
Stage 1
↓
Stage 2
↓
automatic grasp
というVisual Manipulation Pipelineの構築を目指します。
今回のPoCで最も重要だったのは、単にPPO policyを実機へ送ることではありませんでした。
policy
geometry
coordinate semantics
action mapping
controller tracking
payload
hardware condition
safety supervisor
を一つずつ実測し、simulationとreal robotの間にある差を切り分けることでした。
Simulationで高いsuccess rateを達成した後にも、多くのsim-to-real問題が残っていました。
しかし、それらを一つずつ分解したことで、最終的に実物の内容物入りPETボトルを持ち上げるところまで到達できました。
これで、
「Isaac LabとPPOで始めるUnitree G1のボトル把持・持ち上げ強化学習プロジェクト」
のManipulation PoCはいったん完結です。






