
Sim2Realを成功させる5つのテクニック|実機で動かない理由と対策
2026-08-08 ・ 実践
シミュレーションでは完璧に歩くのに、実機に載せた瞬間に転ぶ。ロボット開発者が必ず通るSim2Realギャップです。この記事では、その原因と実務で効く5つの対策をまとめます。
なぜギャップが生まれるのか
シミュレータは現実の近似にすぎません。ズレの主な発生源は4つです。
| ズレの原因 | 具体例 |
|---|---|
| 物理パラメータ | 摩擦係数、重量、慣性が現実と微妙に違う |
| 遅延 | 実機はセンサー読み取り〜モーター反応に数ms〜数十msかかる |
| センサーノイズ | シミュレータの観測は完璧、実機はブレる |
| 未モデル化要素 | ケーブルの張力、ギアのバックラッシュ、床のたわみ |
いちばん厄介なのは遅延
物理パラメータのズレは調整できますが、遅延は「未来を予測する」しかありません。シミュレータで遅延ゼロの前提で学習したAIは、実機で必ず振動します。
テクニック1: ドメインランダム化
最も効果が高く、最初にやるべき対策です。シミュレーション中に物理パラメータをわざとランダムに変動させます。
# 学習のたびにパラメータを揺らす
friction = np.random.uniform(0.5, 1.5) # 摩擦
mass_scale = np.random.uniform(0.8, 1.2) # 重量 ±20%
motor_delay = np.random.uniform(0, 0.03) # 遅延 0〜30ms
狙いは「正確なシミュレーション」ではなく**「どんな条件でも動くAI」**を作ること。現実がその変動範囲のどこかに収まっていれば、実機でも動きます。
ランダム化なし
- 1つの理想条件で最適化
- シミュレータ内では最高性能
- 実機で即転倒
ドメインランダム化
- 数千通りの条件で学習
- シミュレータ内の成績は少し落ちる
- 実機でも動く
シミュレータ内のスコアがわざと下がるのがポイントです。ここを我慢できるかが分かれ目になります。
テクニック2: システム同定(実機に合わせ込む)
実機で簡単な動作をさせ、その結果からシミュレータのパラメータを補正します。
# 実機で「関節を10度動かす」を実行し、応答を記録
# → シミュレータの応答と一致するようパラメータを最適化
ランダム化が「広く浅く」なら、こちらは「狭く深く」。両方やるのが最強で、システム同定で中心値を合わせ、その周辺をランダム化します。
テクニック3: 遅延をシミュレータに入れる
実機の遅延を測り、その分だけ観測を遅らせて学習します。
# 30ms前の観測を使って行動を決める(実機の遅延を再現)
delayed_obs = observation_buffer[-3] # 10msステップなら3つ前
これだけで実機の振動が劇的に減ります。測定は簡単(コマンドを送ってから動き出すまでを高速度カメラかログで計測)なので、費用対効果が非常に高い対策です。
テクニック4: 観測にノイズを足す
実機のセンサーはブレます。シミュレータの完璧な観測に慣れたAIは、ノイズで簡単に混乱します。
obs = true_state + np.random.normal(0, 0.01, size=obs_dim)
IMUや関節エンコーダの実測ノイズ幅を調べて、その程度を混ぜるのが定石です(センサー超入門)。
テクニック5: 段階的に移す
いきなり全力で動かさず、安全域から詰めていきます。
安全な実機移行
低速で
まず1/4の速度
吊るして
落下防止しながら
全力へ
徐々に本来の速度
ヒューマノイドの開発動画でロボットが吊り下げられているのは、この段階にいるからです。
デバッグの進め方
実機で動かないとき、闇雲にパラメータを触るのは時間の無駄です。順番に切り分けます。
- 同じ指令を入れて、動きが同じか → 違えばモーター/減速機の特性差
- センサー値がシミュレータと同じ範囲か → 違えば単位やキャリブレーションのミス
- 遅延はどれくらいか → 測って学習に反映
- それでもダメ → ランダム化の範囲を広げて再学習
まとめ
- Sim2Realギャップの原因は物理パラメータ・遅延・ノイズ・未モデル化要素
- 最優先はドメインランダム化。シミュレータ内のスコア低下を受け入れる
- 遅延の再現は費用対効果が最強
- システム同定で中心を合わせ、ランダム化で幅を持たせるのが王道
- 実機移行は低速・吊り下げから段階的に
次の一歩 🌸
学習側の話は強化学習でロボットを歩かせる、実機に載せるハード面はJetson Thor入門へどうぞ。
ゆるふわフィジカルAI