调试ROS节点
使用gdb调试ros节点
需要知道可执行节点的路径。一般为工作空间中的devel/lib/<package_name>/目录下。如果运行过catkin_make install命令,则在
install/lib/<package_name>/目录下。
运行:gdb <node_name>
节点启动时调用gdb调试器
需要一个启动文件
<launch>
<node pkg ="chapter3_tutorials" type ="example1" name="example1"/>
</launch>
要在节点启动时调用gdb调试器,需要添加 launch-prefix="xterm -e gdb --args", 如下
<launch>
<node pkg ="chapter3_tutorials" type ="example1" name="example1"
launch-prefix="xterm -e gdb --args"/>
</launch>
节点启动时调用valgrind
<launch>
<node pkg ="chapter3_tutorials" type ="example1" name="example1"
output="screen"
launch-prefix="valgrind"/>
</launch>
设置节点core 文件转储
1. 取消core文件大小限制
ulimit -c unlimted
2. 为了创建core文件转储,必须将core文件名设置为默认使用的进程pid,否则无法创建,因为在$ROS_HOME 已有一个core 目录会防止core文件转储。因此,为了创建core文件转存的名称和路径为 $ROS_HOME/core.PID,必须运行如下命令:
echo 1 | sudo tee /proc/sys/kernel/core_user_pid
日志信息
输出日志信息
头文件:#include <ros/ros.h>
ROS_INFO("My info message.")
ROS_INFO("My infomessage with argument: %f", val)/* 相当于printf */
ROS_INFO_STREAM("My infomessage with argument: " << val) /* 相当于cout */
日志级别
DEBUG
INFO
WARN
ERROR
FATAL
为特定节点配置调试信息级别
默认情况下,系统会显示INFO及更高级别的调试信息,并使用ROS默认级别来过滤特定节点输出的信息。可通过三种方式实现:
1. 编译时设定(不推荐,需要修改源代码);
<ros/console.h>中加入
#define ROSCONSOLE_MIN_SEVERITY ROSCONSOLE_SEVERITY_ERROR /* 默认为DEBUG级 */
或者在CMakeLists.txt中使用以下代码设置包中所有节点的宏:
add_definations(-DROSCONSOLE_MIN_SEVERITY=ROSCONSOLE_SEVERITY_ERROR)
2. 用配置文件进行更改;
roscd 到功能包目录,创建文件夹config,config文件chapter3_tutorials.config
roscd chapter3_tutorials
mkdir config
cd config
touch chapter3_tutorials.config
echo ’log4j.logger.ros.chapter3_tutorials=ERROR' > chapter3_tutorials.config
然后设置 ROSCONSOLE_CONFIG_FILE环境变量指向刚才新建的配置文件。可以使用一个启动文件来替代配置环境变量,但这样会直接运行节点。因此可以用env字段扩展launch文件:
<launch>
<!-- Logger config -->
<env name ="ROSCONSOLE_CONFIG_FILE"
value="$(find chapter3_tutorials)/config/chapter3_tutorials.config"/>
<!-- Example 1 -->
<node pkg ="chapter3_tutorials" type ="example1" name="example1"
output="screen"/>
</launch>
3. 动态修改。
信息命名
ROS_INFO_STREAM_NAMED(
"named_msg",
"My named INFO stream message; val = " << val);
通过命名的消息,可以使用配置文件对每个命名的消息设置不同的初始日志级别:
log4j.logger.ros.chapter3_tutorials.named_msg=ERROR
按条件显示信息
ROS_INFO_STREAM_COND[_NAMED](
val < 0.,
[“named_msg”,]
"My conditional INFO stream message; val (" << val << ") < 0");
过滤信息
过滤信息本质上与按条件显示信息类似,但它允许我们指定一个用户自定义的过滤器。这个过滤器继承自ros::console::FilteBase 结构体。并将过滤器指针传递给ROS_<LEVEL>[_STREAM]_FILTER[_NAMED]为格式的宏的的哥参数:
struct MyLowerFilter:public ros::console::FilterBase {
MyLowerFilter(const double& val):value(val) {}
inline virtual bool isEnabled() {return value < 0.;}
double value;
};
MyLowerFilter filer_lower(val);
ROS_INFO_STREAM_FILTER(&filter_lower,
“My filter INFO stream message; val (" << val << ") < 0"
);
显示信息的方式---单次、可调、组合
只显示一次:ROS_INFO_STREAM_ONCE_NAMED
可调:ROS_INFO_STREAM_THROTTLE_NAMED(period, "named_msg", "message i " << i);
隔 period 个循环打印一次。
动态加载节点(nodelet) 日志信息:
将ROS_*改成NODELET_*.
修改调试级别
rosrun rqt_console rqt_console 查看日志信息
rosrun rqt_logger_level rqt_logger_level :设置日志记录器的严重级别。