Wiki
命令转发与常用控制接口
Existing English translations were reused. 19 current source blocks remain in Simplified Chinese, without triggering paid translation.
position、velocity、effort 是命令的物理含义;ForwardCommandController 主要负责把消息中的值交给指定接口。
1.示例 1:位置命令怎样进入接口
保持 mini 运行:
ros2 topic pub --once /forward_position_controller/commands \
std_msgs/msg/Float64MultiArray "{data: [0.3, -0.2]}"
ros2 topic echo /joint_states --once
1.1.对照源码阅读顺序
on_configure 创建 ~/commands 订阅
→ 回调将消息写入 realtime buffer
command_interface_configuration 返回 joints/interface_name
on_activate 取得并整理接口
update 从 realtime buffer 取消息
→ 检查数组长度
→ 对各命令接口 set_value
它没有在这里比较目标与关节反馈并为所有设备实现位置 PID。MiniSystem 的缓慢响应来自硬件模拟,而不是 ForwardCommandController 计算了电机力矩。
2.示例 2:认识三种接口
| 命令接口 | 旋转关节常用单位 | 下游通常要实现什么 |
|---|---|---|
| position | rad | 跟踪位置,常由驱动器内部完成 |
| velocity | rad/s | 跟踪角速度,常由驱动器速度环完成 |
| effort | N·m | 执行力矩或与设备协议映射 |
直线关节分别使用 m、m/s、N。电流不是通用意义上的 effort 数值,若协议传电流,需要根据电机与传动关系进行明确换算。
2.1.为什么不能只把 interface_name 改成 velocity
MiniSystem 只导出 position 命令接口。控制器若申请 joint1/velocity,会找不到资源。要改为速度控制,必须同时修改 URDF 声明、硬件导出、write 的语义,以及反馈更新算法。
下面是教学伪代码,不是可直接替换的完整插件:
velocity_command = 控制器目标角速度
write:向驱动器发送角速度
read:从编码器读 position 和 velocity
模拟时可用 position += velocity * dt
3.示例 3:用现成底盘练习速度接口
在DiffBot与差速底盘控制中运行的 DiffBot 提供轮子 velocity 命令与 position/velocity 状态。用那个完整实例学习速度模式,避免在当前双关节工程中只改一个字符串。
3.1.数组长度为什么重要
控制两个关节就需要两个目标。固定版本的 ForwardCommandController 在 update 中校验长度,错误时返回 ERROR。故意发送错误长度可能触发控制器错误处理,因此只在模拟工程中做,观察后查看状态并恢复或重启实例。
4.Summary of this section
选接口是在约定命令语义,选控制器是在约定目标如何变成接口值,选硬件后端是在约定接口值如何作用于设备。
源码:ros2_controllers/forward_command_controller/src/forward_controllers_base.cpp、ros2_controllers/position_controllers/src/joint_group_position_controller.cpp。位置组控制器复用了命令转发机制,读源码时留意继承与参数设置。
返回 Humble 总览 · 上一篇:状态广播与机器人显示 · 下一篇:Joint-Trajectory-Controller