硬件插件
Relevant source files
The following files were used as context for generating this wiki page:
目的与范围
本文说明 IB-Robot 用于连接实体机器人和仿真环境的硬件插件实现。硬件插件实现 ros2_control 硬件接口,提供统一抽象层,使同一套控制代码可以同时用于真实硬件和仿真。
本文聚焦两个主要硬件插件实现:
SO101SystemHardware: 使用 Feetech 舵机 SDK 的 SO-101 真实硬件插件。gz_ros2_control: 用于基于物理仿真的 Gazebo 仿真插件。
硬件插件架构
IB-Robot 中的硬件插件实现 ros2_control 的 SystemInterface,该接口定义由 rclcpp_lifecycle 框架管理的生命周期方法。系统会根据机器人配置 YAML 中的 hardware_plugin 字段动态加载这些插件。
硬件插件集成流程
下图展示 C++ 硬件插件如何把 ROS 2 control 框架桥接到实体 Feetech 电机总线。
系统名称 |
代码实体 |
|---|---|
硬件插件 |
|
舵机 SDK |
|
状态缓冲区 |
|
命令缓冲区 |
|
graph TB
subgraph "ros2_control Framework"
CM["ControllerManager"]
HWI["hardware_interface::SystemInterface"]
end
subgraph "so101_hardware_interface"
direction TB
PLUGIN["class SO101SystemHardware"]
INIT["on_init() / on_configure()"]
READ["read()"]
WRITE["write()"]
subgraph "Internal Buffers"
POS["hw_positions_"]
CMD["hw_commands_"]
end
end
subgraph "Feetech SDK (ftservo_sdk)"
SDK["class SMS_STS"]
SYNC_R["syncReadPacketRx()"]
SYNC_W["syncWritePosEx()"]
end
subgraph "Physical Layer"
BUS["Serial Bus (/dev/ttyACM0)"]
MOTORS["Feetech STS3215 Servos"]
end
CM -->|"calls"| HWI
HWI --> PLUGIN
PLUGIN -->|"loads calib_file"| INIT
PLUGIN -->|"fills"| POS
CMD -->|"reads from"| PLUGIN
READ -->|"get data"| SYNC_R
WRITE -->|"send data"| SYNC_W
SYNC_R <--> BUS
SYNC_W <--> BUS
BUS <--> MOTORS
来源: src/so101_hardware/package.xml:35-35, src/so101_hardware/CMakeLists.txt:46-60
SO101SystemHardware 插件
SO101SystemHardware 插件提供 ros2_control 与 Feetech 舵机之间的接口。它使用 C++ 实现,并通过 pluginlib 导出为 so101_hardware/SO101SystemHardware。
初始化与配置
在 on_init 期间,插件从 URDF/Hardware 描述解析参数,包括串口 port、calib_file 和 reset_positions。
在 on_configure 中,插件读取 JSON 标定文件并填充:
homing_offsets_range_mins_range_maxes_
电机通信(SMS_STS)
插件使用 Feetech SDK 中的 SMS_STS 类。该 SDK 在构建过程中作为 Git 子模块获取 src/so101_hardware/CMakeLists.txt:23-28,并编译为静态库 ftservo_sdk src/so101_hardware/CMakeLists.txt:32-38。
激活: 在
on_activate中,对每个电机 ID 执行 ping 以确认连通性,并提供 3 次重试机制。安全: 解锁 EPROM 写入标定参数(偏移和限位),然后重新上锁以持久化。
同步读写: 使用
syncReadPacketTx/Rx高效更新多电机状态,使用syncWritePosEx同时下发命令。
坐标转换
插件处理 ROS 弧度与 Feetech “ticks”(0-4095 范围)之间的转换。
Ticks 到弧度:
rad = (static_cast<double>(pos) - 2048.0) / TICKS_PER_RAD。弧度到 Ticks: 转换发生在
write()循环中,使用同一个TICKS_PER_RAD常量(4096.0 / 2π)。
标定与工具
IB-Robot 提供一组 Python 工具来管理硬件标定,这些工具对 C++ 插件正常工作至关重要。工具使用 lerobot.motors 库进行电机抽象。
标定数据流
下图把 Python 标定工具连接到底层 C++ 硬件接口使用的数据结构。
系统名称 |
代码实体 |
|---|---|
标定脚本 |
|
标定对象 |
|
迁移工具 |
|
检查工具 |
|
graph LR
subgraph "Python Toolset"
CALIB["scripts/calibrate_arm.py"]
TRANS["scripts/arm_calibration_transfer.py"]
CHECK["scripts/arm_calibration_checker.py"]
end
subgraph "Calibration Logic (so101_hardware.calibration)"
INTER["so101_hardware/calibration/interactive.py<br/>run_interactive_calibration()"]
MIGRATE["so101_hardware/calibration/transfer.py<br/>migrate_calibration_data()"]
VALID["so101_hardware/calibration/validation.py<br/>validate_calibration_data()"]
end
subgraph "Storage"
JSON["~/.calibrate/*.json"]
end
CALIB --> INTER
INTER -->|"Save"| JSON["save_calibration()"]
JSON -->|"Template"| TRANS
TRANS --> MIGRATE
MIGRATE --> VALID
VALID -->|"Save Finetuned"| JSON
JSON -->|"Load"| CHECK["load_calibration()"]
JSON -->|"Load"| CPP["SO101SystemHardware (C++)"]
来源: src/so101_hardware/so101_hardware/calibration/interactive.py:21-79, src/so101_hardware/so101_hardware/calibration/interactive.py:88-118, src/so101_hardware/so101_hardware/calibration/interactive.py:119-161, src/so101_hardware/so101_hardware/calibration/transfer.py:121-146, src/so101_hardware/so101_hardware/calibration/validation.py:18-59
关键工具
工具 |
用途 |
来源 |
|---|---|---|
|
运行交互式流程,通过释放扭矩查找回零偏移和物理范围,并把标定数据保存为 JSON 文件。 |
src/so101_hardware/so101_hardware/calibration/interactive.py:21-79 |
|
将旧版 LeRobot 标定文件(使用 |
src/so101_hardware/so101_hardware/calibration/transfer.py:13-22, src/so101_hardware/so101_hardware/calibration/transfer.py:38-63, src/so101_hardware/docs/tools/arm_calibration_transfer.md:1-10 |
|
重放固定姿态序列(30°、60°、90° 和夹爪检查)以验证装配精度。它加载标定数据并向硬件后端发送命令。 |
src/so101_hardware/scripts/arm_calibration_checker.py:9-14, src/so101_hardware/so101_hardware/calibration/checker.py:189-197, src/so101_hardware/test/test_checker.py:20-41 |
来源: src/so101_hardware/so101_hardware/calibration/interactive.py:21-79, src/so101_hardware/docs/tools/arm_calibration_checker.md:15-28
仿真后端
robot_config 启动系统会根据 use_sim 标志动态切换硬件后端。
Gazebo 集成(gz_ros2_control)
在 Gazebo 仿真中,系统使用 gz_ros2_control。启动构建器 generate_ros2_control_nodes 负责把 robot_description 注入 controller_manager。
URDF 生成:
description.py中的generate_robot_description处理 xacro,并为 Gazebo 环境注入相机传感器。控制器启动:
generate_controller_spawners创建节点,在仿真就绪后激活指定控制器,例如arm_position_controller。
硬件切换机制
选择逻辑位于 robot_config 启动构建器中:
模式 |
选择逻辑 |
插件 / 驱动 |
|---|---|---|
Real |
|
|
Sim |
|
|
Peripherals |
仿真中 |
|
故障排查
常见硬件问题
缺少标定文件: 如果插件因 “Calibration file not found” 失败,它会给出要运行的具体命令:
ros2 run so101_hardware calibrate_arm --arm follower --port /dev/ttyACM0。电机连接: 如果激活期间 ping 失败,插件会记录 “Motor ID X is NOT responding”。
Controller Manager 不匹配: 启动构建器使用临时 YAML 文件传递
robot_description,避免ros2_control_node与controller_manager服务之间的命名空间不匹配。