Wiki
狀態接口與命令接口源碼
本文由簡體中文內容確定性轉換,並受版本化術語表保護。
接口句柄是這套框架最容易“能用卻説不清”的部分。本節沿着變量地址理解控制器與硬件如何共享數據。
1.示例 1:普通 C++ 中的最小句柄
保存為 /tmp/interface_handle.cpp:
#include <iostream>
struct Handle {
double * value;
double get_value() const {return *value;}
void set_value(double input) {*value = input;}
};
int main()
{
double command = 0.0;
Handle hardware_handle{&command};
Handle controller_handle = hardware_handle;
controller_handle.set_value(0.5);
std::cout << "hardware sees " << hardware_handle.get_value() << '\n';
}
g++ -std=c++17 /tmp/interface_handle.cpp -o /tmp/interface_handle
/tmp/interface_handle
1.1.運行輸出
hardware sees 0.5
複製句柄沒有複製底層 command 變量。兩個句柄都引用同一個地址。這個小程序只解釋共享存儲,不包含框架的資源借用和生命週期管理。
2.示例 2:回到 MiniSystem 的導出函數
從零編寫模擬硬件插件這一行把成員元素地址交給接口:
result.emplace_back(info_.joints[i].name, "position", &command_[i]);
接口全名由關節名和接口類型組成,例如 joint1/position。控制器通過借出的命令句柄執行 set_value,最終改變 command_[i];write 再讀取 command_[i]。
controller.command_interfaces_[k]
→ LoanedCommandInterface
→ CommandInterface
→ 指向 MiniSystem::command_[i] 的地址
2.1.為什麼不能返回局部變量地址
函數返回以後局部變量生命週期結束,句柄保存的地址失效。之後可能讀到隨機值、崩潰,或者偶爾看起來正常。
2.2.為什麼 vector 不能隨意擴容
vector 擴容可能搬遷元素。舊地址仍留在句柄裏,成員對象本身還活着也不能保證舊地址有效。因此本教程只在 on_init 分配大小;配置與激活階段通過逐元素複製更新值。
3.示例 3:觀察接口借用與釋放
保持 mini.launch.py 運行,在另一個終端執行:
ros2 control list_hardware_interfaces
ros2 control set_controller_state forward_position_controller inactive
ros2 control list_hardware_interfaces
ros2 control set_controller_state forward_position_controller active
ros2 control list_hardware_interfaces
3.1.預期現象
停用前命令接口 claimed;停用後接口釋放;重新激活後再次 claimed。狀態接口可以供多個讀取者使用,而同一個命令接口通常只能交給一個控制器寫入。
注意:釋放控制器句柄不等於物理設備已經斷電。設備怎樣停止屬於硬件實現與驅動器協議。
4.關鍵類型與函數
| 類型或函數 | 作用 |
|---|---|
| StateInterface | 反饋接口的名字和存儲位置 |
| CommandInterface | 命令接口的名字和存儲位置 |
| LoanedCommandInterface | 帶資源歸還機制的借用句柄 |
| get_value() | 讀取句柄關聯的值 |
| set_value(value) | 寫入命令句柄關聯的值 |
| claim_command_interface(key) | 按完整名稱申請獨佔命令資源 |
這些訪問不通過 ROS Topic 傳送每一個 double。硬件插件和控制器通常處在同一個管理器進程中,以接口句柄交換數據。
5.對應底層源碼
依次閲讀 ros2_control/hardware_interface/include/hardware_interface/handle.hpp、ros2_control/hardware_interface/include/hardware_interface/loaned_command_interface.hpp、ros2_control/hardware_interface/src/resource_manager.cpp 中的 claim_command_interface()。注意資源歸還回調與接口占用記錄。
返回 Humble 總覽 · 上一篇:從零編寫模擬硬件插件 · 下一篇:硬件與控制器生命週期