3、调试工具链:RViz2可视化、rqt_graph节点图、ros2 topic/param/service命令行工具
调试感知模块,说白了就是跟数据打交道。你想想看,激光雷达点云进来了,经过预处理、分割、聚类、跟踪,最后输出目标列表——这中间任何一个环节出问题,结果都会跑偏。那怎么定位问题?靠猜吗?当然不是。Autoware 给我们配了一套非常趁手的调试工具链,今天我就带你挨个捋一遍。
核心工具链一览:
- RViz2 —— 可视化调试,看数据长什么样
- rqt_graph —— 节点拓扑图,看数据怎么流
- ros2 topic / param / service —— 命令行三板斧,看数据是什么
3.1 RViz2:让数据「看得见」
RViz2 是 ROS2 的标配可视化工具。我个人习惯一启动 Autoware 就把 RViz2 打开,哪怕暂时不看,也挂着。为什么?因为很多时候问题不是「算错了」,而是「数据根本没来」。你盯着终端日志看半天,不如在 RViz2 里扫一眼——点云有没有?包围框有没有?一目了然。
我的小技巧:在 RViz2 左侧面板的「Displays」里,把常用的显示项(比如 /perception/pointcloud_map、/perception/objects)保存成一个配置文件。下次启动直接 rviz2 -d my_perception.rviz,省得每次重新配。
RViz2 里最常用的几个显示插件:
- PointCloud2 —— 看激光雷达原始点云,检查有没有畸变或丢帧
- MarkerArray —— 看检测框、跟踪轨迹,我经常用它来对比算法输出和真值
- Path —— 看规划路径,但感知调试里偶尔也用来显示车道线
- TF —— 看坐标系变换,这个特别重要。我记得有一次调试,检测框一直飘,最后发现是 lidar_frame 到 base_link 的 TF 没发布
注意:RViz2 默认只显示当前时间戳附近的数据。如果你在回放 rosbag,记得把「Time」面板里的「Wall Clock」改成「ROS Time」,否则你什么都看不到。这个坑我踩过不止一次。
3.2 rqt_graph:看清数据「怎么流」
rqt_graph 是个被很多人低估的工具。说白了,它就是一张节点和话题的关系图。你运行 rqt_graph,系统会自动绘制出当前所有节点之间的数据流向。
什么时候用?举个例子。你发现感知模块没有输出目标,但不确定是检测节点没启动,还是检测节点发布了但跟踪节点没收到。这时候打开 rqt_graph,一眼就能看出来——如果检测节点和跟踪节点之间没有连线,那肯定是话题名对不上,或者节点根本没跑起来。
实战经验:我曾经遇到一个情况,感知模块偶尔会漏掉正前方的车辆。查了半天代码没找到原因,最后打开 rqt_graph 发现,某个节点的输出话题在特定条件下会断开连接。嗯,这种「间歇性断连」的问题,光看日志根本发现不了。
rqt_graph 的几个实用操作:
- 勾选「Hide Debug」—— 隐藏 /rosout 等调试话题,让图更干净
- 勾选「Dead Sinks」—— 显示没有订阅者的发布者,帮你发现「发了没人收」的话题
- 勾选「Leaf Topics」—— 只显示终端话题,适合快速定位输出端
3.3 ros2 命令行工具:三板斧搞定数据探查
命令行工具是调试的「最后一道防线」。当 RViz2 里看不到数据,rqt_graph 又看不出问题时,就该掏出这三板斧了。
3.3.1 ros2 topic
最常用的三个子命令:
| 命令 | 作用 | 我的用法 |
|---|---|---|
ros2 topic list |
列出所有话题 | 先跑一遍,确认感知模块的话题都在 |
ros2 topic echo /topic_name |
打印话题数据 | 看检测结果的具体字段,比如置信度、尺寸 |
ros2 topic hz /topic_name |
查看发布频率 | 检查点云是否掉帧,正常应该是 10Hz |
ros2 topic bw /topic_name |
查看带宽 | 怀疑数据量太大时用,比如全分辨率点云 |
避坑指南:我曾经用 ros2 topic echo 看检测结果,发现某个目标的置信度一直是 0.99,但实际那个位置根本没有障碍物。后来才发现,是检测节点的后处理逻辑里写死了置信度——这种「假阳性」问题,光看可视化很难发现,但 echo 出来一看数据就露馅了。
3.3.2 ros2 param
感知模块的参数非常多——比如聚类阈值、检测置信度阈值、跟踪生命周期等等。调试的时候经常需要临时改参数看看效果,总不能每次都改配置文件然后重启节点吧?
ros2 param 就是干这个的:
# 查看节点所有参数
ros2 param list /perception/detection_node
# 获取某个参数的值
ros2 param get /perception/detection_node score_threshold
# 临时修改参数(运行时生效)
ros2 param set /perception/detection_node score_threshold 0.5
注意,不是所有参数都支持运行时修改。这取决于节点实现——如果节点没有实现参数回调,改了也没用。我一般先 param get 看看当前值,再 param set 试试,如果没反应,那就只能改配置文件重启了。
3.3.3 ros2 service
Service 是 ROS2 里的请求-响应机制。感知模块里常见的 service 有:
- 重置节点状态 —— 比如清空跟踪器的历史轨迹
- 触发一次检测 —— 用于单步调试
- 保存当前帧数据 —— 用于离线分析
调用方式很简单:
# 列出所有 service
ros2 service list
# 查看 service 类型
ros2 service type /perception/detection_node/reset
# 调用 service
ros2 service call /perception/detection_node/reset std_srvs/srv/Empty
注意:调用 service 之前,最好先用 ros2 service type 确认一下请求和响应的格式。我见过有人直接拿 Empty 去调一个需要传参数的 service,结果节点直接崩了。
3.4 三个工具怎么配合?
我一般按这个流程来:
- 先开 RViz2 —— 看整体效果,有没有明显的异常(比如检测框乱跳、点云缺失)
- 再开 rqt_graph —— 如果 RViz2 里数据不对,查节点拓扑,看是不是话题断连
- 最后上命令行 —— 如果拓扑没问题,用 topic echo 看具体数据,用 param 调参数,用 service 触发重置
这套流程我用了好几年,基本上 80% 的问题都能在十分钟内定位到根因。剩下的 20%,嗯,那就得打开源码一行一行看了——但那是另一个话题了。