ポーズを一つずつ手作業でプログラムするのではなく、報酬と試行錯誤からタスクを自ら学習するロボットアーム。
従来の産業用ロボットは、すべての動作を人が手で教示します。私たちは、FR5アームが自ら物体を掴み、ビンに入れることを学習するシステムを構築しました — リアルな物理シミュレーション内で数千回練習し、成功するたびに報酬を得ます。学習した「スキル」は小さな標準ファイルとして書き出され、どこでも動作します。今日はWebブラウザ内でライブ動作し、明日は実機で動きます。
FR5が報酬と罰によって、検出した物体を掴み正しく置くことを学習 — 単一のGPUで訓練し、実機を駆動するために書き出します。
まず手書きのエキスパートを模倣し、その後強化学習で教師を超えていきます — 自分の教師よりうまく、しかも壊れずに。
訓練済みポリシーは、今まさに公開ブラウザデモでライブ動作しており、FAIRINO SDK経由で実機FR5へ移植できるよう構築されています。
75%の天井は過去2回の試みを退けてきました。今回それを突破し、85%以上の目標を運ではなく再現可能なレシピで達成しました。以下は、私たち自身のツールが自動要約した実験の推移です。
| 実行 | 変更 | 結果 |
|---|---|---|
| anchor5 | 完全な恒久模倣アンカー | 安定 83.2% |
| step2b | 研究提案のステップ毎報酬 | 崩壊 71.8→7.7% |
| phase2 | 研究提案 num_steps=200 | 頭打ち 74.3% |
| drcurric3 | DRカリキュラム(バグあり) | 崩壊 83.7→33.8% |
| drcurric4 | DRカリキュラム(修正済み) | 安定 79.9% |
| rkl_dr | Reverse-KL + DRカリキュラム | 安定 86.8% ✅ |
高フィデリティPhysXシミュレーションで — 85%以上のマイルストーン目標を余裕で超過。
訓練は安定。破滅的崩壊が中心的な失敗モードでしたが、今や解決済みです。
過去の書き出しを公式FAIRINO SimMachineで再生:最悪関節誤差0.0002°、リアリティギャップ警告ゼロ。
手書きの「エキスパート」スクリプトが約97%でピック&プレースします。ロボットはまずそれを模倣(行動クローニング)して基本動作を学びます。
次にシミュレーション内で練習し、タスク達成で報酬を得て、教師よりうまくできるよう学習します。
難所は、教師を忘れて崩壊することなく教師を超えて改善させること。「Reverse-KLアンカー」は教師の安全な挙動の範囲内に留めつつ、自身の動きを研ぎ澄まし教師を超えることを許します。これが天井を突破しました(83% → 86.8%)。
シミュレートしたモータダイナミクスを±20%ランダム化し、ポリシーが一つの正確な物理に依存しないようにします — ただし確実に掴めるようになった後でのみ。これが実機への移植準備を整えます。
訓練はNVIDIA Isaac Lab(v2.3.2)でのPPOです。ウォームスタートはスクリプト化エキスパートに対する行動クローニング。完全かつ恒久的なBCアンカー(--bc_floor 5.0 --bc_weight 5.0)が、過去の実行で見られた破滅的なポリシー崩壊を排除します。鍵となったのは、BC-MSE模倣損失をReverse-KLアンカー(train.py --anchor reverse_kl)に置き換えたこと:reverse-KLはモード探索的なので、ポリシーは教師の良いモードに集中しつつ、デモを超える自由を持ちます — これがMSEの課した模倣の天井を突破しました。
頑健性は成功ゲート付きDRカリキュラム(events_dr.py)から得られます:アクチュエータの剛性/減衰のランダム化(±20%)は、成功EMAが0.5を超えるまで無効のままで、その後ランプインします。初期のα=0早期リターンのバグ(drcurric3で見つかった3つのうちの1つ)がランダム化を完全に隠していました。評価は2,048並列エピソードで決定論的に行います。再現:tools/isaac_rl/train.py --anchor reverse_kl --bc_floor 5.0 --bc_weight 5.0 --init_std 0.05。
公開デモの訪問者は皆、実際のニューラルネットワークポリシーがシミュレートされたFR5のピック&プレースをリアルタイムで駆動する様子を見られます — インストール不要、どのブラウザでも。今回シーンを強化し(テーブル、グリッパー、仕分けビン、訓練と一致した配色)、実際の訓練環境のように見えます。
研究の推奨事項を意図的に現実に照らして検証し、通用しなかったものは捨てました。この厳密さこそが価値です — 最終的な数字が信頼できる理由です。
num_steps=200、研究の推奨) → 結果が悪化(74% 対 83%);価値推定はそもそもボトルネックではありませんでした。差し戻し。±20%のアクチュエータ・ダイナミクス・ランダム化のもとで訓練しており、一つの正確な物理モデルに依存しません — 頑健なsim-to-real移行の標準的手法です。
実FR5のダイナミクス(187°/s、428°/s²)は推測ではなく実コントローラから実測し、シミュレータに組み込み済み — シミュレーションが実機に忠実です。
書き出した軌道を公式FAIRINO SimMachine(実ファームウェア)で再生:最悪関節誤差0.0002°、リアリティギャップ警告ゼロ。
正直なスコープ。 RL訓練は実機到着まではシミュレーションのみ(約1か月)です。実機はFAIRINO Python SDKが駆動し、私たちのシステムは教示・検証・書き出し・QAを担います。残る作業はアルゴリズムのリスクではなく、ハードウェア統合です。
高フィデリティシミュレーションで。完全なドメインランダム化で訓練 → 実モータダイナミクスに頑健。これがマイルストーンであり、実機FR5用のポリシーです。
簡略化したブラウザシミュレーションで。より滑らかな公開デモが望まれた場合の即時ロールバックとして保持。
なぜギャップが? ブラウザデモは、実機には無い簡略化された瞬間移動の物理を使います。研究は明確でした:非現実的なブラウザシミュレーションで最良に見せようとすると、実機では悪化します(物理的に危険でガクガクしたコマンドを学習してしまう)。だからこそ86.8%のポリシーは、非現実的なブラウザシミュレーションではやや低い68.5%を正しく示します — そしてそれが正しいトレードオフです。ライブデモは現在86.8%のマイルストーンポリシーを動かしています。
新しい安全層が、力/トルク上限、既存の衝突e-stop、DCS立入禁止ゾーンを融合し、計画された動作を実行前にチェックします。失敗したピックは、損傷の後ではなく前に停止します。
手首カメラの経路(検出 → 物体が実際に保持されているか確認 → 空なら再試行)が実機向けに用意済み — 重要なハードウェア安全の基盤です。
実機化を担うチーム向けの、より深い運用FAQ。以下の各回答はtools/isaac_rl/内の実ファイルに対応します。
.ptファイル?2つの成果物、1つのネットワーク:
.pt(rsl_rl ActorCritic)。マイルストーンはcheckpoints/ppo_pick_rkl_dr_868.pt。.onnx。.ptからexport_onnx.pyで書き出し → exports/fr5_pick_rkl_dr.onnx、deploy/rl-policies/fr5_pick_policy.onnxとしてデプロイ。ONNXこそが製品です:単純なMLP、入力29個の浮動小数点 → 出力7個の浮動小数点、約5万パラメータ、193KB。ブラウザデモはONNXを動かし、実機も同じONNXを動かします。.ptはその訓練可能な形にすぎません。
.ptを読み込みモータ信号を計算する?ループはすでに存在します:reactive_runtime.py(FairinoServoJArmControllerクラス)。IPC上ではonnxruntime(.onnxを読み込む、.ptではない — Isaac/torch不要)とFAIRINO SDKでPythonを実行します。各制御ティック(約50Hz):
obs = observe() # 29個の数値(実機 + カメラ読み取りから) action = onnx_policy(obs) # 6関節のΔq (rad) + 1グリッパー move_to_delta(action) # q_next = GetActualJointPosDegree(1) + rad2deg(0.05·Δq) # robot.MoveJ(q_next) (M3コンベアではServoJストリーミング)
observe()は実機の読み取りから29個の数値を組み立てます:joint_pos = deg2rad(GetActualJointPosDegree(1)) − ready、joint_vel、グリッパー、YOLO(カメラ) → ハンドアイ → ベース座標系 のdetected_puck、tcp_to_puck、tcp_to_bin。
要点: ポリシーはモータ電流を出力しません。出力するのは関節位置の差分で、FAIRINOコントローラ自身のサーボループがそれをアクチュエータ信号に変換します。ポリシーは高レベルの反応的な関節プランナーです。
状態: この実機バックエンドはスタブです — 全メソッドがTODO M3(実機未到着、約1か月)。正確なSDK呼び出しはコード内に記述済み;検証用にはシミュレーションバックエンドが今日動きます。
両者は異なる役割で、補完的です:
SimMachineでは訓練できません:並列環境なし、GPU物理なし、ドメインランダム化なし — RLは何年もかかり、そもそも学習フレームワークではなくコントローラエミュレータです。よって:Isaac=学習、SimMachine=実ファームウェアでの検証。両方使いました — Isaacで訓練し、書き出しをSimMachineで再生(誤差0.0002°)。
scripted_expert.pyは手書きの状態機械(ML不使用):DiffIKのエンドエフェクタ経由点 — 接近 → 下降 → 把持 → 持ち上げ → 搬送 → 配置 — を関節差分に逆算。Isaac環境内で動作し約96.9%成功します。collect_demos.pyが成功エピソードごとの(観測, 行動)ペアをdemos/fr5_pick_demos.npzに記録。このバッファが教師データで、行動クローニング(bc_pretrain.py)がそれを模倣 → bc_init.pt、その後PPOが超えていきます。人による遠隔操作なし、実機データなし。
.pt?両方ともはい。仕分けは別のポリシー(ppo_sort_src.pt → fr5_sort_policy.onnx)で、32次元の観測(class_onehot(3) + tcp_to_correct_binを追加) — 29次元のピックネットワークでは文字通り動かせません。
そして今日時点で本当に弱いです:私たち自身のM2評価で約39.7%の正解仕分け。ニュアンス — ルーティングは完璧(誤仕分け0;常に正しいビンを狙う);失敗は配置完了で、これはReverse-KL修正前にピックを抑えていた、まさにその精度の天井です。だからあなたの経験は私たちのデータと一致します。
M1の勝ちレシピ(Reverse-KLアンカー + 密な段階的配置報酬 + DRカリキュラム)を適用した再訓練が必要 → より良い新しいfr5_sort_policy.onnxへ。M2は環境・エキスパート・BC・ベースラインPPOを出荷済み;85%以上への引き上げは、ピックで既に行ったのと同じ再訓練です — まだ未実施。
2つを混同しないこと:
tools/isaac_rl/train.py。作るのではなく、構造的な変更を加えて再実行(約25分)します:agents/rsl_rl_ppo_cfg.py内のより豊かな/再帰的(LSTM)アクター、加えてゴール近接カリキュラムと密な配置報酬。実機は不要。85%のM1目標を超えると収穫逓減 — だから「任意」。FairinoServoJArmControllerスタブを実装し、既存ONNXをデプロイし、実リアリティギャップを測定。質問2と7を参照。カメラは現在スタブの2つの経路を解放します:
detected_puckはシミュレーションの真値 + シミュレートしたYOLOノイズです。実機ではobserve()を次のように配線:カメラフレーム → YOLO11s(B6検出器、mAP50 0.986) → ハンドアイ変換(tools/vision/handeye.py) → ベース座標系。ハンドアイ校正はシミュレーションで0.07mmまで実証済み;実物のChArUcoボード撮影が1回必要です。confirm_grasp() — グリッパーを閉じた後、手首カメラで撮影し、物体が実際に爪の中にあるか確認し、空ならピックを再試行。これが「掴み損ねたのに気づかない」失敗モードを潰します。現在はTrue(保持と仮定)を返します。検出器とコード経路は存在します(B6ビジョン);実カメラ、ハンドアイ撮影、スタブ解除が必要です。
まず誤解を解きます:実機が自分で学習することはありません。 ロボット上で動く「ファインチューニングアプリ」は無く、アームが実機上で強化学習することもありません(実機学習は失敗=衝突や落下から学ぶため危険で、かつ遅すぎます)。学習はすべてIsaacシミュレーション内で行い、開発者がループを回します。 ロボットは常に、訓練済みの固定ポリシー(ONNX)を実行するだけです。
これは開発者が回すsim-to-real反復ループで、1サイクルあたり5ステップ。SimMachineに対して既に実証済みのワークフロー(Track FR5-CAL)と同じものです。
| # | ステップ | 担当 | 既存ツール |
|---|---|---|---|
| 1 | デプロイ — 86.8% ONNXを動かし、減速して実機ピックを実行 | 開発者 | reactive_runtime.py |
| 2 | 測定 — 実関節軌道 + 成功率を記録し、実際の動きをシミュレーション予測と比較 | ツールが算出 | realityGap.ts → gap_report.json |
| 3 | システム同定 — 実アームの真のダイナミクス(関節ごとの速度/加速度/減衰)を測定 | 開発者がスクリプト実行 | characterize.py |
| 4 | シミュレータを更新(実測ダイナミクスをscene.jsonに書き込み)し、868チェックポイントからtrain.pyを再実行(RTX 3060で約25分) | 開発者 + GPU | train.py |
| 5 | 再書き出し・再デプロイ・再測定。 実成功率が目標に達するまで反復 | 開発者 | export_onnx.py |
ロボットの担当は1〜2だけ(実行されて測定される)。学習はステップ4で、シミュレーション内・GPU上で、あなたが起動します。86.8%ポリシーは既に±20%のダイナミクスランダム化で訓練済みなので、初回デプロイでもそれなりに移行するはずです — ファインチューニングは残差ギャップを詰めるもので、ゼロからやり直すものではありません。
Robot.RPC("192.168.58.2"))、e-stopを配線。FairinoServoJArmControllerの3つのTODO M3メソッド(observe()、move_to_delta()、安全読み取り)を埋める — 正確なSDK呼び出しはドキュメント文字列に記述済み。observe()に配線;confirm_grasp()を有効化。これは予測であり、確約された日付ではありません。ハードウェアが予定どおり約1か月後に到着すると仮定しています。
| フェーズ | 作業 | 目安 |
|---|---|---|
| 0 | ハードウェア設置 + 接続 + ランタイムのスタブ解除 | 約1週間 |
| 1 | カメラ + ハンドアイ校正 + 把持確認 | 約1週間 |
| 2 | 初回デプロイ + ベースライン測定 + 安全検証 | 約1週間 |
| 3 | リアリティギャップ → システム同定 → ファインチューニングループ(1〜3サイクル) | 約2週間 |
| 4 | 頑健性 / エッジケース / 受け入れ / 文書化 | 約1〜2週間 |
→ ハードウェア到着後 約6〜8週間の立ち上げ、つまり本日から約3か月で、顧客に出荷可能な静的ピック&プレースに到達します。
ServoJストリーミングバックエンドが必要;これはより長い別トラックで、約3か月の静的ピックの数字には含まれません。これが「アルゴリズムのリスクではなく統合」である理由:ループ内の全ツールは既に存在し、シミュレーション/SimMachineでリハーサル済みです。未知数は実ギャップの大きさで、それが必要なファインチューニングのサイクル数(フェーズ3)を決めます。
A robot arm that learns the task itself from reward and practice, instead of being hand-programmed pose-by-pose.
Traditional industrial robots are taught every motion by hand. We built a system where the FR5 arm learns to pick an object and place it in a bin on its own — by practicing thousands of times in a realistic physics simulation and being rewarded when it succeeds. The trained "skill" then exports to a small standard file that can run anywhere, including live in a web browser today, and on the real robot tomorrow.
The FR5 learns, by reward and penalty, to pick a detected object and place it correctly — trained on a single GPU, then exported to drive the real arm.
It first imitates a hand-written expert, then improves past it through reinforcement learning — getting better than its own teacher without breaking.
The trained policy runs live in the public browser demo right now, and is built to transfer to the physical FR5 via the FAIRINO SDK.
The 75% ceiling had resisted two prior attempts. This session it broke, and the ≥85% target was reached not by luck but by a repeatable recipe. Below is the experiment progression, auto-summarized by our own tooling.
| Run | Change | Result |
|---|---|---|
| anchor5 | Full permanent imitation anchor | STABLE 83.2% |
| step2b | Research per-step reward | COLLAPSED 71.8→7.7% |
| phase2 | Research num_steps=200 | PLATEAU 74.3% |
| drcurric3 | DR curriculum (buggy) | COLLAPSED 83.7→33.8% |
| drcurric4 | DR curriculum (fixed) | STABLE 79.9% |
| rkl_dr | Reverse-KL + DR curriculum | STABLE 86.8% ✅ |
In high-fidelity PhysX simulation — comfortably over the ≥85% milestone target.
Training is stable. Catastrophic collapse was the central failure mode — now solved.
Earlier exports replayed on the official FAIRINO SimMachine: worst joint error 0.0002°, zero reality-gap warnings.
A hand-written "expert" script picks-and-places about 97% of the time. The robot first imitates it (behavior cloning) to learn the basic motion.
The robot then practices in simulation, getting rewarded for completing the task — and learning to do it better than the teacher.
The hard part is letting the robot improve past the teacher without forgetting it and collapsing. A "Reverse-KL anchor" keeps it within the teacher's safe behaviour while letting it sharpen its own moves and exceed the teacher. This is what broke the ceiling (83% → 86.8%).
We randomize the simulated motor dynamics (±20%) so the policy doesn't depend on one exact physics — but only after it can already grasp reliably. That's what makes it ready to transfer to the real robot.
Training is PPO in NVIDIA Isaac Lab (v2.3.2). The warm-start is behaviour-cloning against a scripted expert; a full, permanent BC anchor (--bc_floor 5.0 --bc_weight 5.0) eliminates the catastrophic policy collapse seen in prior runs. The key enabler is swapping the BC-MSE imitation loss for a Reverse-KL anchor (train.py --anchor reverse_kl): reverse-KL is mode-seeking, so the policy concentrates on the teacher's good modes while being free to exceed the demo — this broke the imitation ceiling that MSE imposed.
Robustness comes from a success-gated DR curriculum (events_dr.py): actuator stiffness/damping randomization (±20%) stays disabled until the success-EMA exceeds 0.5, then ramps in. An early α=0 early-return bug (one of three found in drcurric3) was masking the randomization entirely. Evaluation is deterministic over 2,048 parallel episodes. Reproduce with tools/isaac_rl/train.py --anchor reverse_kl --bc_floor 5.0 --bc_weight 5.0 --init_std 0.05.
Every visitor to the public demo sees the real neural-network policy driving the simulated FR5 pick-and-place in real time — no install, any browser. The scene was upgraded this session (table, gripper, sort bins, training-matched colors) so it looks like the actual training environment.
We deliberately tested the research recommendations against reality and discarded what didn't hold up. This rigor is the value — it's why the final number is trustworthy.
num_steps=200, a research recommendation) → made results worse (74% vs 83%); the value estimate was never our bottleneck. Reverted.Trained under ±20% actuator-dynamics randomization, so it doesn't depend on one exact physics model — the standard route to robust sim-to-real transfer.
Real FR5 dynamics (187°/s, 428°/s²) were measured from the real controller, not guessed, and baked into the simulator — so the sim is faithful to the arm.
Exported trajectories were replayed on the official FAIRINO SimMachine (real firmware): worst-case joint error 0.0002°, zero reality-gap warnings.
Honest scope. RL training is sim-only until the hardware lands (~1 month). The real robot is driven by the FAIRINO Python SDK; our system does the teaching, validation, export, and QA. The remaining work is hardware integration, not algorithmic risk.
In high-fidelity sim. Trained with full domain randomization → robust to real motor dynamics. This is the milestone and the policy for the actual FR5.
In the simplified browser sim. Retained as an instant rollback for a smoother public demo if ever preferred.
Why the gap? The browser demo uses a simplified, instant-motion physics the real robot doesn't have. Research was explicit: forcing the policy to look best in the unrealistic browser sim would make it worse on the real robot. So the 86.8% policy correctly shows a slightly lower 68.5% in the unrealistic browser sim — and that's the right trade-off. The live demo currently runs the 86.8% milestone policy.
A new safety layer fuses a force/torque limit, the existing collision e-stop, and DCS keep-out zones — and checks the planned motion before it executes. A failed pick stops before damage, not after.
A wrist-camera path (detect → confirm the object is actually held → retry if empty) is scaffolded for the real robot — critical hardware-safety groundwork.
A deeper, operator-facing FAQ for the team taking this to hardware. Every answer below maps to real files in tools/isaac_rl/.
.pt file?Two artifacts, one network:
.pt (the rsl_rl ActorCritic). The milestone is checkpoints/ppo_pick_rkl_dr_868.pt..onnx, exported from the .pt by export_onnx.py → exports/fr5_pick_rkl_dr.onnx, deployed as deploy/rl-policies/fr5_pick_policy.onnx.The ONNX is the product: a plain MLP, 29 input floats → 7 output floats, ~50k params, 193 KB. The browser demo runs the ONNX; the real robot will run the same ONNX. The .pt is just its trainable form.
.pt and compute the motor signal?The loop already exists: reactive_runtime.py (class FairinoServoJArmController). On the IPC you run Python with onnxruntime (which loads the .onnx, not the .pt — no Isaac/torch needed) plus the FAIRINO SDK. Every control tick (~50 Hz):
obs = observe() # 29 floats, from live robot + camera reads action = onnx_policy(obs) # 6 joint Δq (rad) + 1 gripper move_to_delta(action) # q_next = GetActualJointPosDegree(1) + rad2deg(0.05·Δq) # robot.MoveJ(q_next) (ServoJ streaming for M3 conveyor)
observe() assembles the 29 numbers from real reads: joint_pos = deg2rad(GetActualJointPosDegree(1)) − ready, joint_vel, gripper, detected_puck from YOLO(camera) → hand-eye → base frame, tcp_to_puck, tcp_to_bin.
Key point: the policy does not output motor currents. It outputs joint-position deltas; the FAIRINO controller's own servo loop converts those into actuator signals. The policy is a high-level reactive joint planner.
Status: this real-robot backend is a stub — every method is marked TODO M3 (no hardware yet, ~1 month). The exact SDK calls are written in the code; the sim backend runs today for validation.
They do different jobs and are complementary:
You can't train on SimMachine: no parallel envs, no GPU physics, no domain randomization — RL would take years, and it's a controller emulator, not a learning framework. So: Isaac = learn; SimMachine = verify on real firmware. We used both — trained in Isaac, replayed exports on SimMachine (0.0002° error).
scripted_expert.py is a hand-written state machine (no ML): DiffIK end-effector waypoints — approach → descend → grasp → lift → carry → place — inverted to joint deltas. It runs inside the Isaac env and succeeds ~96.9%. collect_demos.py records every successful episode's (observation, action) pairs into demos/fr5_pick_demos.npz. That buffer is the teacher data; behavior cloning (bc_pretrain.py) imitates it → bc_init.pt, then PPO improves past it. No human teleoperation, no real-robot data.
.pt?Yes to both. Sort is a separate policy (ppo_sort_src.pt → fr5_sort_policy.onnx) with a 32-dim observation (adds class_onehot(3) + tcp_to_correct_bin) — the 29-dim pick network literally cannot run it.
And it is genuinely weak today: ~39.7% correct-sort in our own M2 eval. The nuance — routing is perfect (0 mis-sorts; it always aims at the right bin); the failure is place-completion, the exact precision ceiling that capped pick before the Reverse-KL fix. So your experience matches our data.
It needs a retrain applying the M1 winning recipe (Reverse-KL anchor + dense graded-placement reward + DR curriculum) → a new, better fr5_sort_policy.onnx. M2 shipped the env, expert, BC, and a baseline PPO; lifting it to ≥85% is the same retrain we already did for pick — not yet done.
Don't conflate two things:
tools/isaac_rl/train.py on the RTX 3060 dev box. You don't create it; you re-run it (~25 min) with a structural change: a richer/recurrent (LSTM) actor in agents/rsl_rl_ppo_cfg.py, plus a goal-proximal curriculum and a dense place reward. No physical machine required. It's diminishing returns past the 85% M1 target — hence "optional."FairinoServoJArmController stub, deploy the existing ONNX, measure the real reality-gap. See questions 2 and 7.The camera unlocks two currently-stubbed paths:
detected_puck is sim ground-truth plus simulated YOLO noise. On hardware, wire observe() to: camera frame → YOLO11s (the B6 detector, mAP50 0.986) → hand-eye transform (tools/vision/handeye.py) → base frame. Hand-eye calibration is already proven in sim to 0.07 mm; it needs one real ChArUco-board capture.confirm_grasp() — after closing the gripper, capture the wrist cam, verify the object is actually in the jaws, and retry the pick if empty. This kills the "failed to pick, didn't notice" failure mode. It currently returns True (assume held).The detector and the code paths exist (B6 vision); they need the real camera, the hand-eye capture, and un-stubbing.
First, clear the misconception: the device does not learn by itself. There is no "fine-tune app" running on the robot, and the arm never does reinforcement learning on hardware (on-robot RL would be unsafe — it learns by failing, i.e. crashes and dropped parts — and far too slow). All learning happens in the Isaac simulation; the developer drives the loop. The robot only ever executes a fixed, already-trained policy (the ONNX).
It's a developer-run sim-to-real iteration loop, 5 steps per cycle — the same workflow already proven against the SimMachine (Track FR5-CAL).
| # | Step | Who | Existing tool |
|---|---|---|---|
| 1 | Deploy — run the 86.8% ONNX, do real picks at reduced speed | developer | reactive_runtime.py |
| 2 | Measure — record real joint trajectories + success rate; compare real motion vs the sim's prediction | tool computes it | realityGap.ts → gap_report.json |
| 3 | System-ID — measure the real arm's true dynamics (per-joint velocity/accel/damping) | developer runs a script | characterize.py |
| 4 | Update the simulator (write measured dynamics into scene.json), then re-run train.py warm-started from the 868 checkpoint (~25 min on the RTX 3060) | developer + GPU | train.py |
| 5 | Re-export, redeploy, re-measure. Repeat until real success ≥ target | developer | export_onnx.py |
The robot's contribution is only steps 1–2 (it executes and gets measured). The learning is step 4, in sim, on the GPU, kicked off by you. Because the 86.8% policy was already trained under ±20% dynamics randomization, the first deployment should transfer reasonably — fine-tuning closes the residual gap, it's not starting over.
Robot.RPC("192.168.58.2")), wire the e-stop.TODO M3 methods in FairinoServoJArmController (observe(), move_to_delta(), the safety reads) — the exact SDK calls are already written in the docstrings.observe(); enable confirm_grasp().This is a forecast, not a committed date. It assumes hardware arrives in ~1 month as planned.
| Phase | Work | Est. |
|---|---|---|
| 0 | Hardware install + connectivity + un-stub runtime | ~1 week |
| 1 | Camera + hand-eye calibration + grasp-confirmation | ~1 week |
| 2 | First deploy + baseline measure + safety validation | ~1 week |
| 3 | Reality-gap → System-ID → fine-tune loop (1–3 cycles) | ~2 weeks |
| 4 | Robustness / edge cases / acceptance / docs | ~1–2 weeks |
→ ~6–8 weeks of bring-up after hardware, so ≈ 3 months from today to a customer-shippable static pick-and-place.
ServoJ streaming backend on top of all the above; that's a longer, separate track, not part of the ~3-month static-pick number.The reason this is "integration, not algorithm risk": every tool in the loop already exists and was rehearsed in sim/SimMachine. The unknown is the size of the real gap, which sets how many fine-tune cycles (phase 3) you need.