Skip to content

Wiki

命令转发与常用控制接口

About 4 min read

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