继"ROS2 Jazzy + C++ 实战路线------进阶学习3"继续学习
核心架构:
ROS2
│
controller_manager
│
┌─────────┴─────────┐
↓ ↓
joint_state_broadcaster trajectory_controller
│ │
└─────────┬─────────┘
↓
Hardware
↓
EtherCAT
↓
Motor Driver
↓
Motor
ros2_control 是你从"会 ROS2"走向"机器人控制系统工程"的关键一步。
ros2_control = ROS2 和机器人底层硬件之间的一套标准控制框架。
你可以把它理解成一个"翻译层"。
上层说:
左膝关节 → 转到某个位置
底层电机驱动器理解的是:
CAN / EtherCAT / UDP / 串口
ros2_control 就负责把两边连接起来。
ROS2
│
↓
controller_manager
│
┌──────────┴──────────┐
↓ ↓
Controller Controller
│ │
└──────────┬──────────┘
↓
Hardware Interface
↓
真实机器人硬件
↓
EtherCAT / CAN
↓
电机驱动器
↓
电机
1. Controller
Controller 就是:
控制器。
例如你想控制机器人关节位置:
目标位置
↓
Position Controller
↓
关节
或者:
目标轨迹
↓
Trajectory Controller
↓
多个关节
所以 Controller 是:
决定"机器人应该怎么运动"的软件模块。
2. Hardware Interface
Hardware Interface 可以理解成:
ROS2 和真实机器人硬件之间的接口。
例如:
ROS2
↓
Hardware Interface
↓
EtherCAT
↓
电机驱动器
它负责两件事情:
写给硬件
command
例如:
目标位置
目标速度
目标力矩
从硬件读回来
state
例如:
实际位置
实际速度
实际力矩
所以你可以简单记:
Command
↓
ROS2 → 电机
State
↑
电机 → ROS2
3. Command Interface 和 State Interface
这是 ros2_control 最重要的概念之一。
State Interface
机器人现在是什么状态?
例如:
position
velocity
effort
也就是:
电机现在在哪里?
电机现在多快?
电机现在输出多大力?
Command Interface
我要机器人变成什么状态?
例如:
position command
velocity command
effort command
所以直接记:
State Interface
↑
│
机器人实际状态
Command Interface
↓
│
给机器人目标
4. controller_manager
名字其实已经告诉你了:
管理 Controller。
比如系统里有:
joint_state_broadcaster
joint_trajectory_controller
controller_manager 负责:
加载
启动
停止
切换
管理
所以:
controller_manager
│
├── controller A
├── controller B
└── controller C
你可以把它理解成:
控制器的总管。
5. joint_state_broadcaster
这个名字第一次看很长。
拆开:
joint_state
= 关节状态
broadcaster
= 广播出去
所以:
joint_state_broadcaster 主要负责把硬件读取到的关节状态发布到 ROS2。
例如:
编码器
↓
Hardware Interface
↓
joint_state_broadcaster
↓
/joint_states
其他 ROS2 节点就可以订阅。
6. joint_trajectory_controller
这个你以后做机器人动作控制会经常遇到。
它主要处理:
一组关节按照给定轨迹运动。
例如:
时间 膝关节
0s 0°
1s 20°
2s 40°
3s 30°
这不是简单的:
"去 40°"
而是:
按照轨迹运动
因此:
Trajectory
↓
joint_trajectory_controller
↓
多个 Joint
这时候你就已经开始接近:
完整机器人运动控制系统 了。
7. ros2_control 和 URDF 还有一个关键关系
刚才我们学了:
URDF / Xacro
它描述:
机器人有什么关节
关节叫什么
关节怎么连接
而 ros2_control 需要知道:
这个关节有什么控制接口
这个关节有什么状态接口
硬件怎么连接
所以最终经常看到:
URDF / Xacro
↓
ros2_control 配置
↓
Hardware Interface
↓
Controller
ROS2
│
┌────────────┼────────────┐
↓ ↓ ↓
Topic Service Action
│
↓
Node
│
↓
数据通信
机器人模型:
URDF / Xacro
↓
TF2
↓
RViz2
机器人控制:
Controller
↓
controller_manager
↓
ros2_control
↓
Hardware Interface
↓
EtherCAT / CAN
↓
Motor
8. QoS
全称:
Quality of Service
中文可以理解为:
通信质量策略。
QoS 最重要的几个概念:
Reliability
Durability
History
Depth
不要一上来背全部 QoS 参数。
1. Reliability:可靠性
最容易理解。
有两个主要选择:
Reliable
Best Effort
Reliable
意思:
尽量保证消息送到。
类似:
"这条消息一定尽量给你送过去。"
如果网络出现问题,会尝试处理。
适合:
重要控制信息
关键状态信息
Best Effort
意思:
能送就送,丢了就算了。
例如:
摄像头
↓
30 FPS
↓
丢一帧
↓
下一帧马上来了
通常没必要为了这一帧影响整个系统。
所以传感器数据经常会看到:
Best Effort
2. History
就是:
消息保留多少历史。
例如:
History = Keep Last
Depth = 10
可以理解成:
只保留最近 10 条消息
如果:
1
2
3
4
...
10
11
来了以后:
1
就可能被挤掉。
3. Depth
Depth 就是:
队列深度 。
例如:
Depth = 10
就是:
┌────┬────┬────┬────┬────┐
│ 6 │ 7 │ 8 │ 9 │ 10 │
└────┴────┴────┴────┴────┘
↓
最新数据
9. QoS 最重要的一个坑
这也是你以后实际调 ROS2 最容易遇到的问题之一:
Publisher 和 Subscriber 的 QoS 不匹配,可能导致收不到数据。
例如:
Publisher
Reliable
但是:
Subscriber
Best Effort
两边 QoS 如果不兼容:
Publisher
X
Subscriber
你可能看到:
Topic 明明存在
ros2 topic list 能看到
但是就是收不到数据
这时候不要马上怀疑:
代码写错了
Topic 名字错了
先检查:
ros2 topic info /xxx
以及:
ros2 topic info /xxx --verbose
ROS2
│
┌─────────────┴─────────────┐
↓ ↓
Node Node
│ │
└─────── Topic ─────────────┘
│
QoS
│
┌─────────────┼─────────────┐
↓ ↓ ↓
Reliability History Depth
│
↓
Reliable / Best Effort
这就完整了。
| 概念 | 大白话 |
|---|---|
| Reliability | 丢了要不要尽量保证送到 |
| History | 保存消息的策略 |
| Depth | 队列存多少条 |
| QoS | 整体通信策略 |
最重要的是:
Publisher 和 Subscriber 的 QoS 要能够匹配。
ROS2
│
┌──────┴──────┐
│ │
Node Node
│ │
└─── Topic ───┘
│
QoS
│
┌────────────┼────────────┐
↓ ↓ ↓
Reliability History Depth
│
┌────┴────┐
↓ ↓
Reliable Best Effort