從模擬到實機:Sim-to-Real 部署

2026-07-18
  • ros2
  • sim-to-real
  • deployment
  • hardware

問題定義

前面所有章節,從第 5 章的 Gazebo 模擬開始,大部分的開發跟測試都是在模擬環境裡完成的。模擬環境的價值在於快速迭代、零硬體風險,但模擬終究是對真實世界的簡化近似——這一節要處理的核心問題是:模擬裡調校好的系統,第一次真正接觸實體硬體時,該用什麼樣的心態與步驟,把「模擬裡沒暴露出來的問題」控制在可管理的範圍內,而不是直接把完整系統一次性丟上真實機器人測試。

核心概念說明

模擬與現實的落差來源

理解 Sim-to-Real 落差,先要清楚它具體來自哪裡:

  • 感測器雜訊與延遲:第 5.3 節提過模擬感測器會加上噪聲模型,但真實感測器的雜訊特性往往比簡化的高斯噪聲模型複雜得多(光線反射造成的系統性偏差、電磁干擾、硬體老化),而且真實感測器讀取與資料傳輸本身有非零延遲,這在即時控制迴路裡可能造成不可忽略的影響。
  • 致動器的非理想特性:模擬裡下達一個速度指令,通常假設致動器能立刻、精確地達成;真實馬達有反應時間、有最大加速度限制、可能有輕微的機械間隙(backlash),這些因素會讓實際執行結果跟指令之間存在模擬時沒有的落差。
  • 摩擦力與接觸力模型的簡化:第 5.1 節提過物理引擎用簡化的摩擦力模型計算碰撞與接觸,真實世界的摩擦力受表面材質、濕度、磨損程度等因素影響,遠比模擬模型複雜,這在牽涉精細接觸操作的任務(例如第 7.3 節的抓取,物體會不會打滑)特別容易暴露落差。

循序漸進:不要直接跳到完整系統測試

Sim-to-Real 轉移的核心原則,是把「從模擬到完整實機部署」這個大跳躍,拆成幾個風險遞增的中間步驟,每一步都先驗證沒有問題再往下走:

  1. 硬體單元測試:脫離完整系統,先單獨驗證每個硬體元件本身的行為是否符合預期(馬達轉動方向是否正確、感測器讀值是否合理),這一步甚至不需要跑任何規劃或控制演算法,純粹確認硬體介面本身正常。
  2. 開迴路驗證:用簡單、可預測的固定指令序列(例如「前進 0.5 秒然後停止」)驗證致動器的基本回應行為,不涉及任何感測器回饋或決策邏輯。
  3. 低速、受限環境的閉迴路測試:在模擬裡驗證過的完整系統(例如第 6 章的導航邏輯),先用明顯低於正常運作速度的參數、在一個空曠受控的場地測試,確認閉迴路控制不會出現不穩定或失控的行為。
  4. 逐步提升到正常運作參數:確認低速測試穩定後,才逐步把速度、複雜度提升到接近正式運作的水準。

實作範例:把第 6 章的導航系統從模擬過渡到實機的參數調整

延續第 6 章寫好的 Nav2 系統,示範第一次上機測試時,常見的參數保守化調整。

1. 降低速度限制,優先確保安全而非效率

yaml
controller_server:
  ros__parameters:
    FollowPath:
      max_vel_x: 0.15  # 模擬階段可能是 0.5,實機首次測試明顯調低
      max_vel_theta: 0.3
      acc_lim_x: 0.5   # 同樣調低加速度上限,避免急加速造成的機械衝擊或打滑

2. 放大代價地圖的膨脹半徑,換取更保守的安全餘裕

呼應第 6.3 節介紹的 inflation_layer,第一次實機測試時,故意設定比理論最小值更大的膨脹半徑,用犧牲一些路徑效率換取更大的安全邊界:

yaml
inflation_layer:
  inflation_radius: 0.5  # 模擬階段可能是 0.3,實機測試先保守一些

3. 在安全、可控的場地執行低速測試

bash
ros2 launch my_package nav2_bringup.launch.py params_file:=config/nav2_params_conservative.yaml

準備好物理層面的緊急停止手段(例如機器人上的實體急停開關,而不只是依賴軟體層面的邏輯),觀察機器人在這組保守參數下的實際行為:路徑跟隨是否平順、遇到障礙物的反應時間是否合理、有沒有出現模擬裡從未見過的異常抖動或偏移。

4. 記錄實機測試資料,跟模擬結果比對

用第 3.3 節介紹的 rosbag2,把實機測試過程的完整資料(感測器資料、控制指令、實際軌跡)錄下來:

bash
ros2 bag record -a -o real_world_test_01

事後可以離線比對「模擬環境下同樣路徑的執行軌跡」跟「實機測試錄下來的實際軌跡」之間的差異,這種比對能幫助具體定位落差發生在哪個環節(是感測器讀值本身跟模擬時的分布不同,還是控制指令的執行結果偏離預期)。

常見錯誤與除錯技巧

錯誤一:實機上機器人的移動軌跡明顯偏離規劃路徑,即使在模擬裡完全正常

現象:規劃出的路徑筆直,但機器人實際走出來的軌跡持續往一側偏移。

原因:常見原因是里程計(odometry)的校正跟真實硬體的實際特性不一致——例如輪子的實際直徑跟程式碼裡設定的參數有些微差異,或兩個輪子的摩擦特性不完全對稱,這類「模擬裡完美對稱、真實硬體有製造公差」的落差,會讓里程計計算出來的位移,跟機器人實際移動的距離有系統性偏差,長時間累積後造成明顯偏移。

排除方式:執行一段簡單的校正流程——讓機器人執行一段已知距離的直線移動,比較里程計回報的位移量跟實際量測到的位移量,計算出校正係數,調整里程計計算參數(例如輪子有效直徑)直到兩者吻合,這是實機部署輪型機器人時常見的必要校正步驟,模擬環境完全不需要考慮這個問題。

錯誤二:低速測試一切正常,但速度提升到接近正式運作參數後,系統開始出現不穩定的抖動

原因:這通常代表控制器的參數(例如 PID 增益,如果控制迴路用了這類參數)是針對模擬環境的理想動態特性調校的,模擬裡的致動延遲、感測器延遲相對較低或較一致,真實硬體在較高速度下,延遲與雜訊的影響會被放大,原本在模擬與低速測試下穩定的控制參數,可能在真實高速動態下逼近甚至超出穩定邊界。

排除方式:不要跳過中間的速度階段,逐步、小幅度地提升速度參數,每次提升後都留時間觀察系統反應是否仍然穩定,一旦出現抖動徵兆就先退回上一個確認穩定的速度水準,重新檢視控制器參數是否需要針對真實硬體的動態特性重新調校,而不是照搬模擬階段調好的參數。

小結

Sim-to-Real 落差主要來自感測器雜訊、致動器非理想特性、摩擦力模型簡化這幾個模擬難以完全複現的因素,循序漸進——先硬體單元測試、再開迴路驗證、再低速閉迴路測試、最後逐步提升到正常參數——是控制這個轉移過程風險的核心原則。到這裡,第 10 章部署與進階主題(容器化、即時系統、安全機制、Sim-to-Real)已經涵蓋了把一個在開發環境裡調校好的系統,可靠、安全地交付到正式運作環境的完整考量。整個 ROS2 課程的核心知識體系到這裡告一段落,最後的收尾專案會把前面所有章節學到的東西,串成一個完整、可展示的自主導航機器人專案。

延伸閱讀

常見問題

faq_01.log
模擬裡表現完美的系統,換到實機為什麼常常直接失效,而不是表現得『差一點』?
因為很多在模擬裡被隱性忽略或簡化的因素(感測器雜訊、致動器的反應延遲、摩擦力的非線性特性),在真實世界裡不是『數值上有一點誤差』,而是可能觸發演算法完全沒有被設計來處理的情境——例如一個沒有做雜訊容忍設計的濾波器,遇到真實感測器的雜訊可能直接發散,這種失效模式不是『準確度下降』,而是『整個邏輯鏈條崩潰』,這也是為什麼 Sim-to-Real 轉移需要循序漸進、每一步都驗證,而不是直接一次到位切換到完整實機測試。
faq_02.log
有沒有辦法讓模擬環境更接近真實世界,減少 Sim-to-Real 的落差?
有,這個方向的技術統稱域隨機化(domain randomization)——刻意在模擬裡加入隨機變化的雜訊、摩擦係數、感測器延遲等參數,讓演算法在訓練或測試階段就被迫適應各種變化範圍,而不是只在單一組『乾淨』的理想參數下驗證過。這能有效降低 Sim-to-Real 落差,但無法完全消除,實機驗證步驟仍然是必要的,不能純粹依賴這種技術而跳過實機測試。
faq_03.log
第一次上機測試,應該找什麼樣的場地跟測試方式?
找一個空曠、可控、萬一系統行為異常也不會造成危險或財物損失的場地,並且準備好能立即介入的物理緊急停止手段(而不是只依賴軟體層面的緊急停止邏輯,因為軟體本身也可能是故障來源之一)。第一次測試的目標不是驗證完整功能,而是驗證『系統不會做出危險或失控的行為』這個最低限度的安全底線,功能完整性可以在確認安全無虞之後,再逐步擴大測試範圍。