ROS 2 速查手册(进阶)
配套:ROS 2 Jazzy / Ubuntu 24.04
重点:C++ 工程结构、Composable Node、intra-process communication、QoS 实战、自定义 msg、Launch 阅读、TF2 编程、RViz2/Foxglove、Marker、rosbag 离线调试、ROS 环境变量与 systemd 部署。
1. 这份手册和基础版有什么区别?
基础版主要解决:
ROS 2 是什么?怎么创建 Node?怎么发布 Topic?怎么订阅 Topic?怎么编译?怎么 launch?怎么查 TF?这一份进一步解决:
为什么视觉项目要用 Composable Node?为什么图像传来传去会很慢?intra-process 到底是什么?怎么自己定义 msg?怎么看懂一个陌生的 launch?怎么在代码里真正使用 TF2?怎么把算法结果画到 RViz2?Foxglove 和 RViz2 怎么选?怎么用 rosbag 做离线算法开发?机器人开机后如何自动启动 ROS?2. ROS 2 C++ 工程结构
一个比较正规的 C++ ROS 2 Package 通常长这样:
my_package/├── CMakeLists.txt├── package.xml├── include/│ └── my_package/│ └── detector.hpp├── src/│ ├── detector.cpp│ └── detector_node.cpp├── config/│ └── detector.yaml├── launch/│ └── detector.launch.py└── rviz/ └── detector.rviz可以把它理解成:
package.xml ↓“我是谁?依赖谁?”
CMakeLists.txt ↓“我要怎么编译?”
include/ ↓“头文件”
src/ ↓“真正代码”
config/ ↓“参数”
launch/ ↓“怎么启动整个系统”
rviz/ ↓“怎么可视化”3. package.xml 和 CMakeLists.txt 的区别
package.xml
它更像:
项目的身份证 + 依赖清单
<package format="3"> <name>my_detector</name> <version>0.0.1</version>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend> <depend>sensor_msgs</depend> <depend>geometry_msgs</depend>
<export> <build_type>ament_cmake</build_type> </export></package>CMakeLists.txt
它更像:
告诉编译器“代码怎么变成程序”
cmake_minimum_required(VERSION 3.8)project(my_detector)
find_package(ament_cmake REQUIRED)find_package(rclcpp REQUIRED)find_package(sensor_msgs REQUIRED)find_package(geometry_msgs REQUIRED)
add_executable(detector_node src/detector_node.cpp)
ament_target_dependencies( detector_node rclcpp sensor_msgs geometry_msgs)
install( TARGETS detector_node DESTINATION lib/${PROJECT_NAME})
install( DIRECTORY config launch DESTINATION share/${PROJECT_NAME})
ament_package()记忆:
package.xml = “我需要谁”
CMakeLists.txt = “我怎么用这些东西编译”4. ROS 2 依赖为什么经常报错?
例如代码:
##include <sensor_msgs/msg/image.hpp>但编译报:
fatal error:sensor_msgs/msg/image.hpp: No such file or directory检查两层。
第一层:package.xml
<depend>sensor_msgs</depend>第二层:CMakeLists.txt
find_package(sensor_msgs REQUIRED)并且:
ament_target_dependencies( detector_node rclcpp sensor_msgs)所以:
package.xml ↓声明依赖
CMakeLists.txt ↓找到依赖 + 链接依赖5. --symlink-install
普通:
colcon build开发时推荐:
colcon build --symlink-install普通安装可以理解为:
源码 ↓复制 ↓install/symlink:
源码 ↓软链接 ↓install/对于 Python、配置文件等开发内容特别方便。
6. CMake Generator 改了为什么要删 build?
例如:
colcon build --cmake-args -G Ninja之前可能使用:
Unix MakefilesCMake 会把 generator 信息缓存到 build/。
所以切换:
Makefiles↔Ninja建议:
rm -rf build install logcolcon build记忆:
CMake 构建系统发生根本变化 → 清理旧缓存。
7. 自定义 Message
标准消息:
sensor_msgs/Imagegeometry_msgs/Posegeometry_msgs/Point解决的是通用问题。
视觉项目可能需要:
装甲板: 位置 置信度 类型 四角点 ID于是定义:
ArmorDetection.msg例如:
geometry_msgs/Point positionfloat32 confidenceuint8 armor_typestring text它相当于:
自己设计一种“数据包格式”。
8. msg 文件语法
最基本:
类型 名字例如:
float32 confidenceint32 idbool validstring name数组:
float32[] scoresgeometry_msgs/Point[] corners固定长度数组:
float32[4] values引用其他消息:
geometry_msgs/Point positionsensor_msgs/Image image9. 自定义 Message 的构建流程
假设:
autoaim_interfaces/└── msg/ └── ArmorDetection.msgCMake:
find_package(rosidl_default_generators REQUIRED)find_package(geometry_msgs REQUIRED)
rosidl_generate_interfaces( ${PROJECT_NAME} "msg/ArmorDetection.msg" DEPENDENCIES geometry_msgs)package.xml 中需要对应的接口生成和运行依赖,例如:
<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>rosidl_default_generators</build_depend><exec_depend>rosidl_default_runtime</exec_depend>
<depend>geometry_msgs</depend>
<member_of_group> rosidl_interface_packages</member_of_group>然后:
colcon build --packages-select autoaim_interfacessource install/setup.bash查看:
ros2 interface show autoaim_interfaces/msg/ArmorDetection10. 修改 msg 后为什么必须重新 build?
例如原来:
Point positionfloat confidence后来增加:
uint8 armor_type如果不重新构建:
代码 ↓仍然使用旧生成接口所以:
colcon build --packages-select autoaim_interfacessource install/setup.bash如果依赖它的包也需要重新构建:
colcon build经验:
改
.msg→ 先想到重新 build 接口包。
11. QoS:从“知道”进入“会排查”
QoS 可以理解成:
消息传输规则。
重要概念:
HistoryDepthReliabilityDurability12. History / Depth
例如:
Depth = 1可以简单理解为:
只保留最新的一条消息实时视觉:
Frame 1Frame 2Frame 3Frame 4如果算法处理很慢,不希望:
处理 Frame 1→ Frame 2→ Frame 3→ Frame 4最后虽然“每帧都处理了”,但处理的其实都是过去很久的数据。
实时视觉往往更关心:
“现在这一帧是什么?”
而不是:
“历史帧一帧都不能丢。”
13. Reliability
主要模式:
RELIABLEBEST_EFFORTRELIABLE
“尽量保证你收到”适合:
重要控制命令关键状态不能轻易丢的消息BEST_EFFORT
“能及时收到最好,丢一帧没关系”视觉图像通常更能接受这种思路。
例如:
30 FPS
Frame 100Frame 101Frame 102Frame 103Frame 104偶尔:
Frame 102 丢了通常仍然可以:
103104105继续处理。
14. QoS 不匹配是视觉项目经典问题
例如:
Camera PublisherReliability = BEST_EFFORT而:
Detector SubscriberReliability = RELIABLE两边 QoS 不兼容时:
Topic 明明存在Node 也存在但是收不到消息遇到:
“Topic 有,节点也有,但 callback 不触发。”
先检查:
ros2 topic info /camera/image_raw --verbose不要第一时间怀疑 OpenCV。
15. Composable Node:为什么视觉项目特别喜欢它?
普通 ROS 2:
camera_node ↓一个进程
detector_node ↓一个进程
locator_node ↓一个进程也就是:
Process AProcess BProcess CProcess D...每个进程都有:
自己的内存自己的运行环境自己的进程开销16. 图像为什么尤其怕进程间复制?
假设:
1280 × 1024 × 3约:
4 MB / frame如果:
Camera ↓Detector ↓Locator ↓Tracker每经过一个进程,可能涉及:
序列化 ↓复制 ↓反序列化 ↓下一进程如果:
30 FPS数据复制量很快就非常大。
所以视觉项目会特别关心:
不要无意义地复制图像。
17. Composable Node 是什么?
普通 Node:
Node ↓可执行文件 ↓独立进程Composable Node:
Node ↓可动态加载的类 ↓Container多个 Node:
Container Process ┌──────────────────────────┐ │ │ │ CameraNode │ │ DetectorNode │ │ LocatorNode │ │ TrackerNode │ │ │ └──────────────────────────┘类比:
普通模式:每个功能 = 一个 App
组件模式:一个 App = 一个容器功能 = App 里的插件18. 普通 Node 和组件 Node 的区别
普通:
int main(int argc, char** argv){ rclcpp::init(argc, argv);
rclcpp::spin( std::make_shared<CameraNode>() );
rclcpp::shutdown();}组件:
class CameraNode : public rclcpp::Node{public: explicit CameraNode( const rclcpp::NodeOptions& options) : Node("camera", options) { }};然后:
RCLCPP_COMPONENTS_REGISTER_NODE( CameraNode)重点:
组件通常没有自己的
main()。
19. CMake 如何注册组件?
普通:
add_executable(camera_node src/camera_node.cpp)组件:
find_package(rclcpp_components REQUIRED)
add_library( camera_node_component SHARED src/camera_node.cpp)
ament_target_dependencies( camera_node_component rclcpp rclcpp_components)
rclcpp_components_register_nodes( camera_node_component "autoaim_camera::CameraNode")本质:
.cpp ↓Shared Library ↓注册插件 ↓Container 动态加载20. Container
常见:
component_containercomponent_container_mt区别:
component_container ↓单线程
component_container_mt ↓多线程视觉项目通常更关注:
component_container_mt21. 为什么多线程 Container 对视觉有帮助?
假设:
Camera callback ↓Detector callback ↓Locator callback如果单线程:
Detector 推理 20ms
其他 callback ↓全部排队可能造成:
Camera ↓等待 ↓Detector ↓等待 ↓Locator多线程:
Thread 1 → CameraThread 2 → DetectorThread 3 → Locator可以更充分地并行执行。
注意:
多线程不等于自动变快。共享资源仍然需要考虑线程安全、锁和执行器行为。
22. intra-process communication
仅仅:
多个 Node ↓同一个进程并不意味着所有数据都完全不复制。
可以开启:
extra_arguments=[ { 'use_intra_process_comms': True }]核心思想:
普通通信:
Node A ↓序列化 ↓复制 ↓Node B
intra-process:
Node A ↓进程内部通信 ↓减少序列化/复制 ↓Node B对于:
4 MB 图像 × 高频率尤其有意义。
23. Composable Node + intra-process
可以记成:
Composable Node ↓解决“进程太多”
intra-process communication ↓减少同进程 Node 之间的数据复制组合起来:
Camera │ │ image ▼Detector │ │ detection ▼Locator │ ▼Tracker
全部在同一个 Container24. Component CLI
查看组件:
ros2 component list查看系统支持的组件类型:
ros2 component types手动加载:
ros2 component load /autoaim_container autoaim_camera autoaim_camera::CameraNode适合:
启动 Container ↓不重启整个系统 ↓临时加载某个 Node ↓测试25. 如何阅读一个陌生 Launch?
拿到:
autoaim_launcher.py推荐顺序:
① 找 Node / ComposableNode
② 看 package
③ 看 executable / plugin
④ 看 name
⑤ 看 parameters
⑥ 看 remappings
⑦ 看 namespace
⑧ 看 container
⑨ 画出 Topic 数据流最终把代码脑补成:
Camera │ ├── image_raw ──→ Detector │ ▼Detector │ └── detections ──→ Locator │ ▼ Tracker26. ComposableNode Launch 结构
典型:
ComposableNode( package='autoaim_camera',
plugin='autoaim_camera::CameraNode',
name='autoaim_camera',
parameters=[ camera_params_yaml ],
extra_arguments=[ { 'use_intra_process_comms': True } ],)重点看:
package ↓来自哪个 ROS Package
plugin ↓加载哪个 C++ 组件类
name ↓运行时 Node 名字
parameters ↓加载什么配置
extra_arguments ↓额外运行选项27. TF2:进入代码层
TF2 最核心的四个类:
| 类 | 用途 |
|---|---|
tf2_ros::Buffer | 保存 / 查询 TF |
tf2_ros::TransformListener | 接收 TF |
tf2_ros::TransformBroadcaster | 发布动态 TF |
tf2_ros::StaticTransformBroadcaster | 发布静态 TF |
常见初始化:
tf_buffer_ = std::make_shared<tf2_ros::Buffer>( get_clock() );
tf_listener_ = std::make_unique<tf2_ros::TransformListener>( *tf_buffer_ );28. lookupTransform
例如:
auto transform = tf_buffer_->lookupTransform( "gimbal_link", "camera_link", tf2::TimePointZero );最重要的是理解:
lookupTransform( target_frame, source_frame, time)也就是:
“我要把 source_frame 中的东西转换到 target_frame。”
29. TimePointZero
tf2::TimePointZero可以简单理解成:
使用最近可用的 TF。
视觉程序里经常:
lookupTransform( "gimbal_link", "camera_link", tf2::TimePointZero);如果任务严格依赖某一时刻的传感器数据,则应该认真处理时间戳,而不是永远使用最新 TF。
30. 查询前先 canTransform
直接:
lookupTransform(...)如果 TF 不存在可能抛异常。
更安全:
if (tf_buffer_->canTransform( "gimbal_link", "camera_link", tf2::TimePointZero)){ auto t = tf_buffer_->lookupTransform( "gimbal_link", "camera_link", tf2::TimePointZero );}实际工程还应考虑:
TF 是否刚刚启动TF 是否暂时还没收到时间戳是否匹配31. 直接变换一个 Point
例如相机检测到了:
camera_link:
x = 1.0y = 0.0z = 2.0建立:
geometry_msgs::msg::PointStamped camera_point;
camera_point.header.frame_id = "camera_link";
camera_point.point.x = 1.0;camera_point.point.y = 0.0;camera_point.point.z = 2.0;然后:
auto gimbal_point = tf_buffer_->transform( camera_point, "gimbal_link" );现在:
camera_point ↓TF2 ↓gimbal_point这就是视觉项目中“相机系位置 → 云台系位置”的核心操作。
32. 广播动态 TF
如果两个坐标系的关系会变化:
云台旋转 ↓camera 相对于 gimbal 的姿态变化可以:
tf2_ros::TransformBroadcaster broadcaster(this);
geometry_msgs::msg::TransformStamped t;
t.header.stamp = now();
t.header.frame_id = "gimbal_link";
t.child_frame_id = "camera_link";
t.transform.translation.x = 0.05;
t.transform.rotation.w = 1.0;
broadcaster.sendTransform(t);核心关系:
parent ↓child33. 广播静态 TF
例如相机牢牢安装在云台上:
gimbal │ │ 固定 ▼camera命令:
ros2 run tf2_ros static_transform_publisher 0.05 0 0.1 0 0 0 gimbal_link camera_link可以理解为:
x y z+yaw pitch roll+parent+child34. TF2 排错
Unknown frame
Unknown frame "camera_link"检查:
ros2 run tf2_ros tf2_echo camera_link gimbal_link如果都找不到:
frame 名字可能写错或者没人发布这个 frame刚启动就 TF 报错
可能只是:
Node 启动 ↓TF broadcaster 还没启动完成 ↓查询过早解决思路:
canTransform+重试TF Tree 断了
查看:
ros2 run tf2_tools view_frames寻找断开的 frame:
谁应该发布它?那个 Node 启动了吗?静态 TF 发布了吗?35. RViz2:把抽象数据变成可观察对象
启动:
rviz2核心价值:
把 ROS 中的坐标、图像、点云、轨迹、算法结果直接画出来。
36. Fixed Frame
RViz2:
Global Options ↓Fixed Frame例如:
gimbal_link可以理解成:
“我要站在哪个坐标系里观察整个机器人世界?”
如果 Fixed Frame 错了:
TFPointMarkerRobot可能:
不显示乱飞报 TF 错误37. RViz2 常用 Display
| Display | 用途 |
|---|---|
Image | 查看相机图像 |
TF | 查看所有坐标系 |
Marker | 查看单个 Marker |
MarkerArray | 查看多个调试对象 |
PointCloud2 | 查看点云 |
LaserScan | 查看激光雷达 |
RobotModel | 查看机器人模型 |
Path | 查看轨迹 |
Axes | 查看坐标轴 |
Grid | 查看参考网格 |
视觉开发最常用:
ImageTFMarkerArrayPointCloud238. Marker:给算法结果“画出来”
假设算法算出来:
目标位置:
x = 2.0y = 0.3z = 0.1单纯:
std::cout << x << y << z;很难直观看出:
到底算对没有?
如果画成 Marker:
机器人 │ │ ● ← 算法认为的目标 │ └────────────一眼就知道。
39. Marker 最重要的字段
visualization_msgs::msg::Marker m;Frame:
m.header.frame_id = "gimbal_link";命名空间:
m.ns = "locator";ID:
m.id = 0;类型:
m.type = visualization_msgs::msg::Marker::SPHERE;位置:
m.pose.position.x = 1.0;m.pose.position.y = 0.2;m.pose.position.z = 0.1;大小:
m.scale.x = 0.1;m.scale.y = 0.1;m.scale.z = 0.1;40. 常用 Marker 类型
ARROWCUBESPHERECYLINDERLINE_STRIPLINE_LISTTEXT_VIEW_FACING例如:
SPHERE ↓画一个目标点
ARROW ↓画方向
LINE_STRIP ↓画轨迹
TEXT_VIEW_FACING ↓显示文字41. Marker 生命周期
如果不断 ADD:
Marker 1Marker 2Marker 3Marker 4...可能留下大量历史残影。
可以设置:
m.lifetime = rclcpp::Duration( 0, 100 * 1000000 );类似:
100 ms 后自动消失实时视觉中很实用。
42. MarkerArray
如果一次要画:
20 个目标100 个轨迹点多个坐标轴可以:
visualization_msgs::msg::MarkerArray arr;
arr.markers.push_back(marker);
marker_pub_->publish(arr);适合批量发布调试信息。
43. 推荐的视觉调试习惯
不要只画:
算法最终结果最好同时画:
原始检测 ↓解算结果 ↓滤波结果 ↓预测结果例如:
点 ↓检测位置
另一个点 ↓滤波位置
箭头 ↓速度方向
线 ↓预测轨迹这样可以快速定位:
Detector 错?Locator 错?TF 错?Filter 错?44. Foxglove:现代化 ROS 可视化
Foxglove 可以理解成:
一个更现代、更适合数据分析的 ROS 可视化工具。
架构:
ROS 2 │ │ Topics ▼foxglove_bridge │ │ WebSocket ▼浏览器 / Foxglove App所以:
机器人上 ↓bridge
你的电脑 ↓Foxglove45. Foxglove Bridge
Ubuntu 24.04 + Jazzy:
sudo apt install -y ros-jazzy-foxglove-bridge启动:
ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765常用端口:
876546. Foxglove 常用面板
3D
看:
TFMarkerPointCloud机器人空间数据Image
看:
相机检测图像视觉处理结果Raw Messages
适合:
“这个 msg 到底发了什么?”直接查看完整字段。
Topic Metrics
适合查:
频率延迟数据流47. RViz2 vs Foxglove
| RViz2 | Foxglove | |
|---|---|---|
| 安装 | ROS 环境常自带 | 独立客户端/网页 |
| 3D | 强 | 强 |
| TF | 强 | 强 |
| Image | 强 | 强 |
| Raw Message | 一般 | 很方便 |
| Topic Metrics | 基础 | 很方便 |
| 布局 | 本地配置 | 更适合保存/分享 |
| 远程观察 | 不够方便 | 很方便 |
| 适合 | ROS 本机调试 | 综合数据分析 |
简单记:
本机快速调 ROS → RViz2
远程 / 数据分析 / 布局 → Foxglove48. rosbag:机器人开发的“录像机”
现场测试:
机器人 ↓相机 ↓Detector ↓真实数据如果每次改算法都重新跑机器人:
非常慢所以录制:
ros2 bag record -o bag/test01 /camera/image_raw /camera/camera_info /detections保存下来。
49. rosbag 回放
ros2 bag play bag/test01循环:
ros2 bag play bag/test01 --loop于是:
真实机器人 ↓一次录制 ↓rosbag ↓无限回放 ↓你的算法这意味着:
可以在没有机器人、没有相机的情况下反复调算法。
50. 推荐的视觉开发模式
第一阶段:
实车 ↓录制 rosbag ↓保存测试数据之后:
修改 Detector ↓rosbag play ↓测试再:
修改 Locator ↓rosbag play ↓测试再:
修改 Tracker ↓rosbag play ↓测试最终:
全部通过 ↓上真实机器人51. ROS_DOMAIN_ID
如果多台机器人同时运行:
Robot ARobot BRobot C不同机器人可以使用不同 Domain:
export ROS_DOMAIN_ID=10另一台:
export ROS_DOMAIN_ID=11理解为:
Domain 10 Robot A
Domain 11 Robot B达到网络隔离效果。
52. RMW_IMPLEMENTATION
ROS 2 通过 RMW 层连接底层通信实现。
查看:
echo $RMW_IMPLEMENTATION例如可能看到:
rmw_fastrtps_cpp不要为了“优化”就随意切换。
真实机器人系统通常应该:
团队统一 ↓RMW ↓统一部署53. 日志环境变量
例如:
echo $RCUTILS_CONSOLE_OUTPUT_FORMAT可以控制 ROS 日志输出格式。
部署时可能统一:
时间节点日志级别消息方便分析机器人运行日志。
54. systemd:让机器人开机自动运行
开发阶段:
ros2 launch ...每次手动运行。
真正部署机器人:
机器人上电 ↓Linux 启动 ↓systemd ↓ROS 2 launch ↓整套机器人程序自动启动55. systemd 服务的核心思想
典型:
[Unit]Description=AutoAim ROS2
[Service]User=robotGroup=dialoutEnvironmentFile=/path/to/robot.env
ExecStart=/path/to/start.sh
Restart=always
[Install]WantedBy=multi-user.target理解:
User ↓用谁运行
Group ↓例如串口权限
EnvironmentFile ↓读取机器人配置
ExecStart ↓启动命令
Restart=always ↓程序崩了自动重启56. systemd 常用命令
查看:
systemctl status autoaim.service启动:
sudo systemctl start autoaim.service停止:
sudo systemctl stop autoaim.service开机启动:
sudo systemctl enable autoaim.service取消:
sudo systemctl disable autoaim.service查看日志:
journalctl -u autoaim.service实时:
journalctl -u autoaim.service -f57. 一个完整的机器人系统
成熟 ROS 2 视觉系统可以理解为:
systemd │ ▼ ROS 2 launch │ ┌─────────┴─────────┐ │ │ Component Container Other Node │ ┌──────┼─────────┐ │ │ │ Camera Detector Locator │ │ │ └──────┴─────────┘ │ ▼ TF2 │ ▼ Tracker │ ▼ Controller │ ▼ Hardware同时:
Topics ↓rosbag ↓离线回放以及:
Topics ↓RViz2 / Foxglove ↓可视化调试58. 一张“工程化 ROS 2”心智地图
ROS 2 项目│├── Workspace│ ├── src│ ├── build│ ├── install│ └── log│├── Package│ ├── package.xml│ ├── CMakeLists.txt│ ├── src│ ├── include│ ├── config│ └── launch│├── Communication│ ├── Topic│ ├── Service│ └── Action│├── Configuration│ └── Parameter / YAML│├── Interface│ ├── msg│ ├── srv│ └── action│├── Performance│ ├── QoS│ ├── Component│ ├── Multi-thread│ └── Intra-process│├── Coordinate│ └── TF2│├── Visualization│ ├── RViz2│ ├── Foxglove│ └── Marker│├── Data│ └── rosbag│└── Deployment ├── Environment ├── ROS_DOMAIN_ID ├── RMW └── systemd59. 视觉项目排错顺序
没有图像
ros2 node listros2 topic listros2 topic type /camera/image_rawros2 topic info /camera/image_raw --verboseros2 topic hz /camera/image_raw顺序:
Node ↓Topic ↓Type ↓Publisher ↓QoS ↓Frequency检测结果没有
检查:
Camera ↓image_raw ↓Detector ↓detections分别:
ros2 topic hz /image_rawros2 topic hz /detections如果:
image_raw 正常detections 没有重点查:
DetectorQoScallback算法坐标位置不对
检查:
1. frame_id2. TF tree3. parent / child4. 相机外参5. 时间戳6. 坐标轴定义先:
ros2 run tf2_tools view_frames再:
ros2 run tf2_ros tf2_echo gimbal_link camera_link最后用 Marker 在 RViz2 里画出来。
60. 最重要的进阶命令
## Componentros2 component listros2 component types
## TFros2 run tf2_ros tf2_echo base_link camera_linkros2 run tf2_tools view_framesros2 run tf2_ros tf2_monitor
## Visualizationrviz2rqt_graph
## Bagros2 bag record -aros2 bag info <bag>ros2 bag play <bag>
## Parameterros2 param listros2 param get <node> <param>ros2 param dump <node>
## QoSros2 topic info /topic --verbose
## Systemsystemctl status <service>journalctl -u <service> -f61. 必须真正理解的 8 个关键词
① Composable Node
把 Node 变成可加载组件② Container
加载多个组件的进程③ Intra-process
减少同进程 Node 之间的数据复制④ QoS
规定消息怎么传⑤ Custom Message
定义属于自己项目的数据格式⑥ TF2
管理并转换坐标系⑦ Marker
把算法结果画出来⑧ rosbag
把机器人现场录下来,之后离线反复播放62. 最终把整个知识体系串起来
一个真实视觉项目可以是:
相机 │ │ Image ▼Camera Node │ │ /image_raw ▼Detector │ │ Custom Message ▼Locator │ │ camera frame ▼TF2 │ │ gimbal frame ▼Tracker │ │ prediction ▼Controller与此同时:
所有 Topic │ ├────────→ rosbag │ ├────────→ RViz2 │ └────────→ Foxglove性能方面:
CameraDetectorLocatorTracker │ ▼Composable Container │ ▼Multi-thread │ ▼Intra-process communication部署方面:
Linux ↓systemd ↓launch ↓ROS 2 system63. 一句话总结
基础 ROS 2 是“让节点通信起来”;进阶 ROS 2 是“让整个机器人系统跑得快、看得见、调得动、部署稳”。
对于机器人视觉,最重要的一条链是:
Topic ↓Custom Message ↓Composable Node ↓Intra-process ↓TF2 ↓Marker / RViz2 / Foxglove ↓rosbag ↓systemd这条链基本覆盖了从“写出一个 ROS 节点”到“把视觉算法部署到真实机器人”的关键工程能力。
参考资料
本手册根据浙江大学 RoboMaster Vision 的 ROS 2 基础培训页面整理,并刻意避开上一份基础速查手册已经详细介绍的内容:
- ROS 2 基础培训原文: https://hello-world-vision.github.io/Vision_Website/induction-training/07-ros2%E5%9F%BA%E7%A1%80/
- ROS 2 Jazzy 官方文档: https://docs.ros.org/en/jazzy/
- ROS 2 Composition: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Composition.html
- ROS 2 TF2: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Tf2/Tf2-Main.html
- ROS 2 RViz2: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/RViz/RViz-User-Guide.html
- Foxglove: https://foxglove.dev/
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或投喂支持!
无穷量?