学会使用日志(log)系统,做ROS大型项目的主治医生

通过显示进程的运行状态是好的习惯,但需要确定这样做不会影响到软件的运行效率和输出的清晰度。ROS 日志 (log) 系统的功能就是让进程生成一些日志消息,显示在屏幕上、发送到特定 topic 或者储存在特定 log 文档中,以方便调试、记录、报警等。下面简单介绍如何生成和查看日志消息。

日志消息

在ROS中,有一个特殊的话题叫作/rosout,它承载着所有节点的所有日志消息。/rosout消息的类型是rosgraph_msgs/Log:

rosgraph_msgs/Log消息用来让各个节点发布日志消息,这样一来就能让网络上的任何一个人都看到。可以认为/rosout是一个加强版的print():他不是向终端输出字符串,可以将字符串和元数据放到一个消息中,发送到网络上的任何一个人。ROS节点应该向/rosout发布日志消息,这样一来这些消息就能被所有人看到。rospy客户端提供了多个函数来发布rosgraph_msgs/Log消息:

1
2
if battery_voltage < 11.0:
rospy.logwarn('Battery voltage low: %f'%(battery_voltage))

rospy.logwarn()函数实现了三件事请:

  1. 输出一个格式化的字符串到终端
  2. 输出更详细的警告到日志文档中,这个文档一般在~/.ros/log中
  3. 构建并发布一条消息到/rosout话题,其中包括警告以及节点元数据

日志等级

ROS有5个日志记录标准级别,这些名称是输出信息的函数的一部分,他们遵循以下语法:
ROS_<LEVEL>[_<OTHER>]
每个消息级别用于不同的目的:

  • DEBUG(调试):只在调试时用,此消息不出现在部署的应用中,仅用于测试。
  • INFO(信息):标准消息,说明重要步骤或节点所正在执行的操作。
  • WARN(警告):提醒一些错误,缺失或者不正常,但进程仍能运行。
  • ERROR(错误):提示错误,尽管节点仍可在这里恢复,但对节点的行为设置了一定期望。
  • FATAR(致命):这些消息通常表示阻止节点继续运行的错误。

生成基本的日志消息

由五个 C++ 宏来产生日志消息,每个宏对应一个级别:

1
2
3
4
5
ROS_DEBUG_STREAM(message);  
ROS_INFO_STREAM(message);
ROS_WARN_STREAM(message);
ROS_ERROR_STREAM(message);
ROS_FATAL_STREAM(message);

编写如下 C++ 进程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

int (int argc,char **argv)
{
ros::init(argc,argv,"count_and_log");
ros::NodeHandle nh;
ros::Rate.rate(10);
for(int i=1;ros::ok();i++){
ROS_DEBUG_STREAM("Counted?to?"<<i);
if((i%3)==0){
ROS_INFO_STREAM(I<<"?is?divisible?by?3.");
}
if((i%5)==0){
ROS_INFO_STREAM(I<<大专栏  ROS中的日志(log)消息"string">"?is?divisible?by?5.");
}
if((i%10)==0){
ROS_INFO_STREAM(I<<"?is?divisible?by?10.");
}
if((i%20)==0){
ROS_INFO_STREAM(I<<"?is?divisible?by?20.");
}
rate.sleep();
}
}

编译、执行之后结果如下:

生成一次性日志消息

ROS 提供了可以仅仅生成一次日志消息的宏:

1
2
3
4
5
ROS_DEBUG_STREAM_ONCE(message);  
ROS_INFO_STREAM_ONCE (message);
ROS_WARN_STREAM_ONCE (message);
ROS_ERROR_STREAM_ONCE (message);
ROS_FATAL_STREAM_ONCE (message);

将上述 C++ 进程中的 log 命令替换一下,得到如下的执行结果:

可以看到每个日志只生成了一次。

生成频率受控的日志消息

1
2
3
4
5
ROS_DEBUG_STREAM_THROTTLE(interval, message);  
ROS_INFO_STREAM_THROTTLE(interval, message);
ROS_WARN_STREAM_THROTTLE(interval, message);
ROS_ERROR_STREAM_THROTTLE(interval, messge);
ROS_FATAL_STREAM_THROTTLE(interval, message);

参数 interval 是 double 型,表示相邻日志消息出现的最小时间间隔,以秒为单位。得到如下的执行结果:

查看日志消息

日志消息有三个不同的输出目的地,包括屏幕、rosout topic、log 文档。其中发布到 rosout topic 的 msg 类型是 rosgraph_msgs/Log。除了 topic echo,还可以通过 rqt_console 查看日志消息:

启用和禁用日志消息

ROS 默认只处理 INFO 或者更高级别消息,DEBUG 级别的消息会被忽略。可以通过命令行设置显示的日志级别:
rosservice call /node-name/set_logger_level package-name level

其中:

  • set_logger_level服务由各个节点自动提供;
  • node-name 期望设置日志级别的节点名称;
  • package-name 拥有这个节点的 package 名称;
  • level 是五个级别中的一个。

另外也可以通过图形接口设置日志级别:
rqt_logger_level

图中列出了节点列表、日志记录器列表、日志级别列表。在图中操作与 rosservice 命令的效果一致。
另外,也可以在 C++ 进程中设置日志级别。ROS node 改变自身日志级别最直接的方式是使用 log4cxx 提供的接口:

1
2
3
4
#include <log4cxx/logger.h>
log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->setLevel(
ros::console::g_level_lookup[ros::console::levels::Debug]);
ros::console::notifyLoggerLevelsChanged();

其中 Debug 可以替换为 Info、Warn、Error、Fatal。

后记

对于大型ROS项目的调试必须要利用到日志系统,所有成熟的框架都为开发者提供了代码进程的调试工具,学会这些工具能够很大程度上帮助我们少走弯路节省时间,所以我们要能够利用这些辅助工具来作为开发过程中的左膀右臂,达到事半功倍的效果。

ROS中的日志(log)消息的更多相关文章

  1. spring boot中配置日志log和热部署

    Java的日志有很多 个人强烈不推荐log4j ,推荐log4j2和logback 在高并发,多线程的环境下log4j1 的性能和log4j2相比可以用junk来形容  对就是junk.log4j2的 ...

  2. ROS中发布IMU传感器消息

    下面使用SYD Dynamics的9轴AHRS(Attitude and heading reference system),来发布sensor_msgs/Imu类型的消息. 将传感器用USB转串口接 ...

  3. Android NDK开发 Jni中打日志LOG(二)

    HelloJni.c文件中,加入头文件和函数声明.最终文件如下: #include <jni.h> #include <string.h> #include<androi ...

  4. ROS中发布激光扫描消息

    激光雷达工作时会先在当前位置发出激光并接收反射光束,解析得到距离信息,而后激光发射器会转过一个角度分辨率对应的角度再次重复这个过程.限于物理及机械方面的限制,激光雷达通常会有一部分“盲区”.使用激光雷 ...

  5. 对比几种在ROS中常用的几种SLAM算法

    在此因为要总结写一个文档,所以查阅资料,将总结的内容记录下来,欢迎大家指正! 文章将介绍使用的基于机器人操作系统(ROS)框架工作的SLAM算法. 在ROS中提供的五种基于2D激光的SLAM算法分别是 ...

  6. mysql中slow query log慢日志查询分析

    在mysql中slow query log是一个非常重要的功能,我们可以开启mysql的slow query log功能,这样就可以分析每条sql执行的状态与性能从而进行优化了. 一.慢查询日志 配置 ...

  7. Expo大作战(六)--expo开发模式,expo中exp命令行工具,expo中如何查看日志log,expo中的调试方式

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,将全部来与官网 我猜去全部机翻+个人 ...

  8. java中的日志组件-log4j

    1.为什么使用日志组件 Log4J是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台.文件.CUI组件.NT的事件记录器:还可以控制每一 ...

  9. hadoop集群中的日志文件

    hadoop存在多种日志文件,其中master上的日志文件记录全面信息,包括slave上的jobtracker与datanode也会将错误信息写到master中.而slave中的日志主要记录完成的ta ...

随机推荐

  1. 题解 P1082 【同余方程】

    题目 这里给出非递归的 exgcd 做法 [基础] ( 只需要非递归的同学麻烦跳过 ) 由于欧几里德算法 ( 又名辗转相除法 ) 可以帮助我们求出最大公约数,并且提出对于 \(\forall a,b\ ...

  2. leetcode算法题121-123 --78 --python版本

    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 实例输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作,不能 ...

  3. 关于PHP索引数组unset某key后json_encode相关问题踩坑记录

    <?php $a = [1,2,3]; var_dump(json_encode($a)); #string(7) "[1,2,3]" unset($a[0]); var_d ...

  4. 转载:Apache优化:修改最大并发连接数

    本文转自:https://blog.csdn.net/bjash/article/details/50394894 Apache是一个跨平台的web服务器,由于其简单.稳定安全的特性,被广泛应用于计算 ...

  5. shell 实现war包的配置更新和自动发布

    此脚本主要用来实现非maven tomcat项目的war包手动发布, 1.将测试war包上传至指定目录 2.备份目前生产代码 3.自动配置文件替换 4.新版本代码的发布 #!/bin/bash ### ...

  6. ThreeJS 阴影条纹BUG

    ThreeJS 开启阴影正确做法: 1. 渲染器启用阴影 renderer.shadowMap.enabled = true;2. 灯光产生阴影 light.castShadow = true;3. ...

  7. LaunchPad(思维)

    链接:https://ac.nowcoder.com/acm/contest/3665/D来源:牛客网 题目描述 Hery is a boy with strong practical abiliti ...

  8. sudo输入密码

    网易云音乐, 启动问题. 修改 .desktop 文件 Exec=sh /home/xyq/.music.sh # ~/.music.sh echo 密码 | sudo -S netease-clou ...

  9. 67)vector的begin() end() 和 front() back()的区别 rbegin() rend()

    1) ·············· 2)`````````v1.begin() 和v1.end()  是作为迭代器v1的 第一个位置  和 最后一个元素的下一个位置. `````````````v1. ...

  10. Electron基础 - 如何创建模态窗体

    在开发桌面端应用我们常常需要弹出一个提示窗体或者对话框,而提示窗体和对话框和普通窗体的区别是,在提示框出现时,其它窗体就被锁定了,必须要等到提示框被正确关闭时其它窗体才能“解锁”,这种类型的窗体叫做模 ...