07 · よくある問題と経験
本フローで実際に踏んだ落とし穴を、現象別にすばやく引ける形でまとめます。
環境系
| 現象 | 原因と解決策 |
|---|---|
uv sync が failed to persist temporary file ... os error 17(跨盘) を報告 | 本機の uv キャッシュディレクトリがドライブをまたぐ Windows の特例。すべての uv コマンドの前に export UV_CACHE_DIR='C:\Users\admin\AppData\Local\Temp\uv-cache' を追加 |
コンソールに libtorchcodec_core*.dll のロード失敗が数十行流れる | ノイズ警告:torchcodec のロード失敗後、自動的に pyav にフォールバックします。実測(smoke [5])では pyav で動画データセットのエンコード/デコードともに正常、状態データセットも動画データセットも影響を受けません |
python で Microsoft Store が開く | uv 管理の Python を使う;Store 版は使わない |
lerobot-train が accelerate is required but not installed を報告 | 初期インストール時に training extra が漏れています——01 の uv sync コマンドに --extra training を追加して再試行してください(01 の一度きりのインストールには含まれているため、01 どおりにインストールすれば発生しません) |
遠隔操作系
| 現象 | 原因と解決策 |
|---|---|
| キーボード制御が「とても遅い」 | --teleop.rate のデフォルト 60 単位/秒はやや保守的;150 に上げると操作感が正常(全行程約 1.3s) |
起動ログに clamped to be safe WARNING が流れる | 速度リミッタが追いつく過程の正常な出力で、到達すれば停止 |
| リーダーアームを中央にしてもシミュレーションアームが数度ずれる | キャリブレーション範囲の非対称による固定オフセット——so101_leader_trim で自動微調整(05) |
| 接続瞬間にアームが突然動く | 設計上の挙動:実機はトルクが入り中点/リーダーアーム姿勢へ移動;手元にスペースを空けておく |
| Ctrl-C 終了後にアームが柔らかくなって落下 | 正常:切断時にトルクを切るので、手で支える |
| 遠隔操作/録画中にタイピングするとアームが動く | キーボードリスニングはグローバルでキーを消費しません:どのウィンドウでマッピングキー(ピンインの字母を含む)を叩いてもキー入力キューに入ります。キーボードモードの遠隔操作/録画中はタイピングしない;リーダーアームモードではこの問題なし |
録画系
| 現象 | 原因と解決策 |
|---|---|
q で終了後、セッション中に押した字母が「一気にコマンドラインに吐き出される」 | Windows コンソールの入力バッファに溜まった分のエコー;ランチャーに drain_pending_keys() によるクリアを組み込み済み(古いセッションのみこの現象が発生) |
| あるエピソードの action span がすべて 0 | 空録画(人が動いていない)——録画前に少し動かすか、後からそのエピソードを削除 |
| エピソード冒頭 1 秒の誤差が大きい | 収束区間:録画開始瞬間にフォロワーアームがまだ初期姿勢で、リーダーアームは別の場所に止まっている;事前にリーダーアームを中位付近に置けば回避できる |
--dataset.root を親ディレクトリにするとデータセットが「見つからない」 | root はデータセットディレクトリそのもの;録画ごとに新しい root に変える |
Esc と q の違い | q は録画だけ停止;Esc はキーボード遠隔操作も切断。どちらもクリーンに終了できる(修正済み)が、q に慣れておく |
保存時に ValueError: You must add one or several frames... でプロセスがエラーを伴って終了 | エピソードの隙間に →/n を余計に押した(最も多いのは、保存 + 2 路動画エンコードの停止が数十秒続き、コンソールが固まったように見えて何度も連打したケース)。フラグが次のエピソード冒頭まで滞留して消費され → 0 フレームの空エピソードとなり、上流が空エピソードを保存する際にクラッシュ(lerobot の既知の境界)。保存済みエピソードは影響を受けず、データは無傷;セッションを開き直して続きを録画すればよい。対策済み(2026-10-16):record.py は各エピソード開始時に隙間期間に滞留した →/← フラグをクリアし(録画中のキーは通常どおり有効)、保存前に saving the episode + encoding videos now... のヒントを表示;回帰テストは smoke_test.py [7] |
録画開始瞬間の KeyError: 'wrist'(画像付きデータセット) | カメラの初回フレームがまだレンダリング完了する前に録画ループが観測を読んだ;修正済み(2026-10-16):ロボットプラグインの connect() が初回フレームの準備完了を待ってから返るように変更 |
動画付きスクリプトが BrokenProcessPool / Invalid argument: '<stdin>' を報告 | 動画エンコードはマルチプロセスプールを使い、子プロセスはファイルパスからエントリモジュールを再インポートする必要がある——録画スクリプトを python - <<EOF(stdin)で実行するとクラッシュする。スクリプトを実体の .py ファイルに保存してから実行すればよい(実体のエントリ record.py は影響なし) |
エピソード保存時に SvtMalloc[fatal]: allocate memory failed ... av.error.MemoryError: [Errno 12] ... 'avcodec_open2(libsvtav1)'、セッション全体が終了 | 上流デフォルトのエンコーダ libsvtav1 がデュアルカメラ(wrist+top)の 2 路エンコードを同時に開く際に、一度に大きなメモリ割り当てに失敗(シミュレーション + プレビューウィンドウの負荷下でより発生しやすい;2026-10-16 に実測で遭遇)。修正済み:record.py がデフォルトで --dataset.rgb_encoder.vcodec=h264 を注入(2 路 h264 同時エンコードは実測通過;明示的に vcodec を渡せば上書き可能)。保存済みエピソードは無損失;クラッシュによりデータセットディレクトリに tmp*/ と孤立 parquet が残ることがある(run2 の方法で整理) |
録画中に画面がカクつく(特に → を押した後)が、操作自体に遅延はない | カクつくのは保存/エンコードウィンドウ:エンコードプロセスがデフォルトで CPU を使い切り(2 路動画同時)、その間シミュレーションスレッドは 5 画面をレンダリングし続ける(内蔵 GPU ではより顕著)。制御ループ自体は影響を受けない——cadence の数値を基準にする(実測全編 29.97Hz、0 tick 予算超過)。緩和済み(2026-10-16):record.py のデフォルト --dataset.encoder_threads=2(各エンコードを 2 スレッドに制限);カメラプレビューウィンドウの更新を 15Hz に低減(--robot.preview_fps)。エピソードが短いほど保存ウィンドウの割合が大きく、カクつきを感じやすい;停止を完全に消したい場合は --dataset.streaming_encoding=true(録画しながらエンコード、上流推奨、実測待ち) |
エピソード保存時にエンコーダがメモリ割り当て失敗を報告し、セッション全体が終了(svtav1 の SvtMalloc、x264 の malloc ... failed、avcodec_open2 のエラーはすべてこの類) | 本機のシステムコミットメモリ(commit)が長期的に上限に迫っている(2026-10-16 実測 105.9GB / 119.7GB、29 日連続稼働)。保存のたびに 2 つのエンコードプロセスが新規起動し(それぞれ torch/av をロードするため commit スパイクが大きい)、限界寸前での同時起動が失敗を招く。緩和済み:record.py はエンコードに失敗時の自動リトライを 1 回追加(一過性の失敗でエピソードを失わない)、保存期間のログ氾濫も静音化(av.logging.set_libav_level + HF プログレスバー)。根治 = マシン再起動(長時間稼働で蓄積した commit/カーネルリークの解消;ユーザー空間プロセスは 27GB のみで、残りはカーネル/ドライバ層にあり殺せない);自己診断:Get-Counter '\Memory\Committed Bytes' vs '\Memory\Commit Limit' |
ハードウェア系
| 現象 | 原因と解決策 |
|---|---|
| COM ポート番号が前回と違う | ポート番号は抜き差し/ポート変更で変わるので、毎回まずポートを列挙して確認(03) |
| 読み取り専用チェックでサーボ欠落が提示される | 配線/給電の問題;まずドライバボードと配線順序を確認し、慌ててキャリブレーションしない |
shoulder_lift の方向が直感と逆(シミュレーション) | このモデルの正方向は下向きなので、マッピング前に符号を確認(02) |
設計説明(なぜこうしているか)
- MuJoCo はメッシュ頂点データを書き換える:
<mesh>ロード後、mjModel.mesh_vertに格納されるのはメッシュ自身の座標系での 頂点(原点は頂点重心に再設定され、軸は再配列される)であり、ファイルの元の座標ではありません——そのまま使ってバウンディングボックスを計算したり CAD 寸法を当てはめたりすると 誤った結果になります(レンダリング表示には影響しない)。CAD の真のジオメトリを得るには元ファイルを解析します(preview_mount.py/step_to_stl.pyのやり方)。一度ハマりました:ブラケットの実寸は 54.3 × 35.0 × 75.0 mm。 - MuJoCo カメラの画角方向はその座標系の −Z:
<camera>要素は自身の +Z(レンズ突出方向)を向きません。初版の カメラモジュールはレンズを +Z に作り、要素の向きを identity にした → 画面は実際には PCB の裏側から「逆さに見て」おり、レンズの向きと画面の方向 がちょうど逆でした(調整時に「回す方向と画面が合わない」の根源;2026-10-16 に赤/青板の対照レンダリングテストで特定)。 修正:カメラ要素を Y 軸周りに 180° 回転(view.quat = RPY(0,180,0)、preview_mount / adjust_camera / ロボットプラグイン の 3 箇所で統一);adjust_camera.pyに "sim_cam live view" リアルタイム画面ウィンドウを追加し、レンズ調整がその場で見たままに確認できるようになりました。 - 公式チュートリアル MJCF のグリッパは「鳥のくちばし式」点接触爪:2 枚の歯先が約 2.3 mm の点接触まで閉じ、実用的な把持面がほとんどありません。 系統的な物理実験(2026-10-16、数百組)の結論:ブロックを歯口付近の任意の位置に置いても、約 100° の閉じ掃引の中で 押し出され/楔で外され、掴み上げられません(16–34 mm のブロックすべて同様;機械的ストロークとトルク自体は正常)。「衝突パッチを補う」 方式で直さないこと——かつて両爪に歯板を補う案を試しました(把持は顕著に改善)が、それは実機に存在しないジオメトリであり、学習したポリシーがそれに 依存して sim2real の歪みを生むため、撤回済みです。正しい直し方は実機の爪ジオメトリで公式モデルの爪を置き換えること(例: menagerie の SO-ARM101 や自社 CAD の再構築)で、物理パラメータは実機と一致させるべきです。
- 公式デフォルトの接触パラメータは「柔らかすぎ」て物理的なめり込みを生む:
solrefの時定数デフォルトは 20 ms で、速い/薄い接触 (ブロックが薄い爪面に落ちる、閉じ掃引)では「力を発生する間もなく」互いにすり抜けます——症状は「ブロックが爪面を直接すり抜けて落ちる」。 修正(2026-10-16):接触パラメータを硬化——harden_mesh_contactsがコンパイル後にすべてのメッシュコリジョン体のsolrefを menagerie の歯面と同じ(0.01 s)に硬化し、ブロックの接触も同様に処理。純粋な物理忠実度の修正で、ジオメトリは一切追加しません。 - シミュレーションロボットは mujoco_menagerie の SO-ARM100 モデルに移行済み(2026-10-16):元チュートリアル zip の MJCF は キネマティクス演示品で、爪は掴めません;menagerie モデルは実機 CAD に基づいて処理されており——爪部に専用の衝突歯面と硬い接触パラメータがあり、 4 つの歯位置(浅→深)で実測すべて 34mm ブロックを突き止め + 掴み + 持ち上げ可能。移行の要点:モデルは
assets/menagerie_so_arm100/に vendored(Apache-2.0、LICENSE 同梱);関節マッピングと単位符号はMODEL_JOINTを参照(関節ごとに旧モデルの世界運動と照合して測定;wrist_roll の符号は実機遠隔操作での再確認待ち);モデルの Base は Z 軸周りに +90° 回転させて 作業正面を +x に向け;ブラケットは Fixed_Jaw(6 号サーボ)の側面に付け替え(まず解析検索で位置を特定し、2026-10-16 にユーザーが実機 写真と照合しながらadjust_mount.py --model menagerieで手動微調整して確定:[0.1, -0.7, 24.7]mm、RPY [0.34, -27.20, 89.51]°)。旧チュートリアルモデルとツールはそのまま残しており、いつでも比較できます。 - なぜ conda ではなく uv プロジェクト環境を使うのか:
.venvはプロジェクトと同じディレクトリにあり、uv.lockでバージョンを固定し、ディレクトリを削除すれば回収でき、 マシン上の conda 環境と完全に分離されています;uv runはアクティブな conda に何もインストールしません。本機のlerobotconda 環境 は別のリポジトリ副本(lerobot-main)を指しており、両者は互いに干渉しません。 - なぜプラグインをすべて
examples/so101_mujoco/に置くのか:公式の登録メカニズム(register_subclass)で接続し、 lerobot ソースコードの変更ゼロ;上流をアップグレードするときは再 sync するだけです。

