博主提示:本文基于ROS Kinetic Kame,如有更新版本,可能存在细微差别,请以官方资料为准。若有大兄弟发现该文章有不妥之处,还请速速告知。
ROS中带有大量的功能强大的工具,帮助用户和开发人员进行可视化和代码调试工作,以便于检测和解决软硬件的问题。其中,包括日志系统、诊断信息、可视化以及检测工具。
1.调试ROS节点
调试程序在系统中有一个进程号(PID),可以用任何标准工具,如gdb,进行调试,同样也可以用valgrind检查内存泄露,或者callgrind分析算法性能。不过,实际中用的都会比较少,这里简单的说一下。
在用gdb调试节点时,唯一需要知道的是必须知道可执行节点的路径。节点的可执行文件在工作空间的devel/lib/<!packagge> 中。
启动roscore,在catkin_make、install后(不然无编译文件生成),首先必须到对应路径下:
$ cd ws/devel/lib/package
$ gdb out
gdb运行正常后,gdb的其他相关功能,help中有详细说明,不明白就找“谷哥”。
如果是在launch文件中启动gdb调试器,请参阅以下代码:
<launch>
<!-- launch-prefix="xterm -e gdb--args"这个启动前缀会创建一个调用gdb节点的新终端 -->
<!-- output="screen"使此节点在终端显示 -->
<node pkg="package" type="type1" name="nodename" launch-prefix="xterm -e gdb--args" output="screen"/>
</launch>
此外,还可以使用相同的属性把节点附加到诊断工具上。。例如,可以启动valgrind来检测程序的内存泄露情况,进行性能分析。
<launch>
<node pkg="package" type="type1" name="nodename" launch-prefix="valgrind" output="screen"/>
</launch>
2.日志信息
为了获取日志记录的函数和宏,用以下这个头文件:
#include <ros/ros.h>
此文件包括了以下的头文件
#include<ros/console.h>
如果想输出一个消息信息,可以按照以下的方式输出:
ROS_INFO("My INFO message.");
此时,终端中会对应的显示出消息的处理结果:
[INFO] [13567248907.8900943723465] : My INFO message.
所有输出的信息都包含有信息级别和时间戳(时间戳是以公历时间计时,代表自1970年1月1日以来的秒和纳秒计时)。
举个实际例子来说明:
float val = 1.23;
ROS_INFO("My INFO message with argument: %f", val);
此时终端会输出变量val对应的浮点值。
另外,前面的指令同样的相当于:
ROS_INFO_STREAM("My INFO message with argument: "<< val);
因为,C++STL流被*_STREAM函数支持,API会重新定向到cout/cerr、一个文件或者两者。(其实我也不太明白流的用法,偏工程的会用就行)
下面详细的介绍以下日记记录的标准级别,按照顺序是:
DEBUG 调试
INFO 信息
WARN 警告
ERROR 错误
FATAL 致命
每个消息级别用于不同的目的,在此,建议:
DEBUG 只有在调试时使用
INFO 说明有节点或者重要步骤在执行操作
WARN 提醒一些错误,或者不正常现象
ERROR 提示错误,但是不影响节点运行
FATAL 致命,此时节点停止运行
另外,在此补充几个会比较好用的函数:
(1)ROS_<!LEVEL>STREAM_NAMED(“namedmsg”,"My named <!LEVEL> Msg : val = " << val );
通过命名的消息,并且可以使用配置文件为每个命名的消息设置不同的初始日志级别。
(2)ROS<!LEVEL>_STREAM_COND(val < 0,“My conditioned <!LEVEL> Msg : val (” << val <<") " < 0 );
按照条件显示信息,如上就是当val < 0 时,才会输出信息。
另外有一种过滤信息,本质上与按条件显示相似,感兴趣的自己可以去查一查,这里就不赘述了,实用为主。
(3)单次、可调、组合显示输出次数
for(int i = 0; i < 10; i++ )
{
ROS_INFO_STREAM_ONCE("My Once INFO STREAM Msg : i = " << i);
}
这段代码只会显示一次信息,就是说在所有循环中只会输出一次信息。但是有时会需要以一定的频率来显示信息,这时候就可以参考下面的函数:
for(int i = 0; i < 10; i++ )
{
ROS_INFO_STREAM_THROTTLE(2, "My Throttle INFO STREAM Msg : i = " << i);
ros::Duration(1).sleep();
}
这段代码会每循环两次输出一次。
最后着重介绍一下rqt_console和rqt_logger_level,这两个可视化的工具很好用,具体自行百度有很多。
3.其他
节点相关
查询运行的节点 rosnode list
查看某个节点的详细信息 rosnode info /node
查询运行的话题 rostopic list
查看某个话题的消息类型 rostopic type /topic
查看话题发出的消息 rostopic echo /topic
查看消息具体格式 rosmsg show msg/…
发布消息主题 rostopic pub /topic msg [args]
服务相关
列出服务 rosservice list
输出服务信息 rosservice info /service
查看某个服务类型 rosservice type /service
(一般与 rossrv show一起使用,得到服务具体参数)
调用服务 rosservice call /service [args]
根据服务类型查询服务 rosservice find msg-type
参数相关
列出参数 rosparam list parameter
设置参数值 rosparam set parameter value
获取参数值 rosparam get parameter
从文件加载参数 rosparam load file
将参数保存到文件 rosparam dump file
删除参数 rosparam delete parameter
另外,有一些rqt的工具,
ROS日志 rqt_console
ROS系统状态 rqt_dep
ROS消息发布状态 rqt_publiser
ROS节点状态图 rqt_graph
设置动态参数 rqt_reconfigure(需要有对应的.cfg和.cpp文件)
诊断信息 rqt_runtime_monitor
绘制时间趋势曲线 rqt_plot或者rqt_gui
消息包记录 rosbag record /topic
消息包回放 rosbag play /topic
检车消息包 rosbag info /bagfile