跳到正文

Wiki

ros2_control整體工作過程

約 3 分鐘閱讀

本文由簡體中文內容確定性轉換,並受版本化術語表保護。

先理解“目標、反饋、迴圈”,再記住管理器和外掛的類名。

1.示例 1:普通程式中的控制週期

1.1.程式目標

模擬位置裝置:讀取上一次命令作用後的狀態,更新本輪命令,再交給裝置。儲存為 /tmp/jazzy_cycle.cpp:

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>
int main()
{
  double feedback = 0.0;
  double applied = 0.0;
  const double target = 0.5;
  auto next = std::chrono::steady_clock::now();
  for (int cycle = 0; cycle < 100; ++cycle) {
    feedback += (1.0 - std::exp(-0.01 / 0.2)) * (applied - feedback); // read
    const double command = target; // update
    applied = command; // write
    if (cycle % 20 == 0) {
      std::cout << cycle << " feedback=" << feedback << " command=" << command << '\n';
    }
    next += std::chrono::milliseconds(10);
    std::this_thread::sleep_until(next);
  }
}
g++ -std=c++17 /tmp/jazzy_cycle.cpp -o /tmp/jazzy_cycle
/tmp/jazzy_cycle

1.2.執行輸出與執行順序

第一輪反饋仍為零,之後逐漸靠近 0.5。read 在本輪 write 之前,因此它不能讀到尚未發生的裝置響應。這裡的一階公式只表示教學模型,不含真實電機與碰撞。

2.把程式對應到框架

概念 對應職責
ControllerManager 管理控制器和排程
ResourceManager 管理硬體元件、介面和資源借用
硬體外掛 read/write 將裝置資料與框架介面連線
控制器 update 由目標與反饋計算介面命令
URDF 宣告模型、硬體後端與介面
YAML、launch、spawner 提供配置並啟動這些元件

3.示例 2:收到訊息後發生什麼

ROS 订阅回调收到目标
  → 保存最新完整目标
控制循环 read 获取反馈
  → update 读取目标并设置命令接口
  → write 下发目标
下一轮 read 获取新的反馈

訊息回撥和控制迴圈是不同執行路徑。訊息頻率不等於 update_rate,回撥也不應該直接承擔整個裝置控制迴圈。

3.1.本節需要注意的點

position 命令表示目標位置,state 表示反饋;真實裝置可能延遲、跟蹤失敗或限幅。把命令直接當成反饋,會失去檢查裝置行為的依據。

旋轉關節的位置和速度通常為 rad、rad/s;直線關節為 m、m/s。傳輸協議中的編碼器數值、rpm 和電流要在裝置適配層明確換算。

原始碼入口:ros2_control/controller_manager/src/ros2_control_node.cpp。找到控制執行緒和 Executor,觀察 read、update、write 與 spin 各自執行在哪裡。


返回 Jazzy 總覽 · 上一篇:環境準備與原始碼地圖 · 下一篇:執行第一個RRBot例項