Skip to content

Wiki

ros2_control整体工作过程

About 3 min read

Existing English translations were reused. 15 current source blocks remain in Simplified Chinese, without triggering paid translation.

先理解“目标、反馈、循环”,再记住管理器和插件的类名。

1.示例 1:普通程序中的控制周期

1.1.Program Objectives

模拟位置设备:读取上一次命令作用后的状态,更新本轮命令,再交给设备。保存为 /tmp/jazzy_cycle.cpp:

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>
int main()
{
  double feedback = 0.0;
  double applied = 0.0;
  const double target = 0.5;
  auto next = std::chrono::steady_clock::now();
  for (int cycle = 0; cycle < 100; ++cycle) {
    feedback += (1.0 - std::exp(-0.01 / 0.2)) * (applied - feedback); // read
    const double command = target; // update
    applied = command; // write
    if (cycle % 20 == 0) {
      std::cout << cycle << " feedback=" << feedback << " command=" << command << '\n';
    }
    next += std::chrono::milliseconds(10);
    std::this_thread::sleep_until(next);
  }
}
g++ -std=c++17 /tmp/jazzy_cycle.cpp -o /tmp/jazzy_cycle
/tmp/jazzy_cycle

1.2.运行输出与执行顺序

第一轮反馈仍为零,之后逐渐靠近 0.5。read 在本轮 write 之前,因此它不能读到尚未发生的设备响应。这里的一阶公式只表示教学模型,不含真实电机与碰撞。

2.把程序对应到框架

概念 对应职责
ControllerManager 管理控制器和调度
ResourceManager 管理硬件组件、接口和资源借用
硬件插件 read/write 将设备数据与框架接口连接
控制器 update 由目标与反馈计算接口命令
URDF 声明模型、硬件后端与接口
YAML、launch、spawner 提供配置并启动这些组件

3.示例 2:收到消息后发生什么

ROS 订阅回调收到目标
  → 保存最新完整目标
控制循环 read 获取反馈
  → update 读取目标并设置命令接口
  → write 下发目标
下一轮 read 获取新的反馈

消息回调和控制循环是不同执行路径。消息频率不等于 update_rate,回调也不应该直接承担整个设备控制循环。

3.1.本节需要注意的点

position 命令表示目标位置,state 表示反馈;真实设备可能延迟、跟踪失败或限幅。把命令直接当成反馈,会失去检查设备行为的依据。

旋转关节的位置和速度通常为 rad、rad/s;直线关节为 m、m/s。传输协议中的编码器数值、rpm 和电流要在设备适配层明确换算。

源码入口:ros2_control/controller_manager/src/ros2_control_node.cpp。找到控制线程和 Executor,观察 read、update、write 与 spin 各自运行在哪里。


返回 Jazzy 总览 · 上一篇:环境准备与源码地图 · 下一篇:运行第一个RRBot实例