ROS 使用记录(2) 日志系统与roslaunch

7 篇文章 0 订阅
本文深入介绍了ROS中的日志系统,包括C++和Python的日志支持、配置文件、logger命名、日志等级控制和输出格式。此外,还详细阐述了roslaunch的使用,如启动节点、设置参数、自动重启和rosout节点等功能,并提供了launch文件的常用标签和参数设置。
摘要由CSDN通过智能技术生成

0. 前言

1. 日志系统

  • 引入:

    • C++和Python都支持日志系统
    • 构建项目时不需要单独引入其他包
    • 对应的头文件是 #include <ros/console.h>,但直接使用 #include <ros/ros.h> 也可以。
  • 配置文件(config格式)

    • 默认配置文件路径 $ROS_ROOT/config/rosconsole.config
    • 自定义配置文件路径可通过环境变量 ROSCONSOLE_CONFIG_FILE 设置
    • 这两个配置文件有相同的格式
# Set the default ros output to warning and higher
log4j.logger.ros=WARN
# Override my package to output everything
log4j.logger.ros.my_package_name=DEBUG
  • ROS中为package指定环境变量可通过修改 launch 文件,如
<launch>
  <env name="ROSCONSOLE_CONFIG_FILE"
       value="$(find mypackage)/custom_rosconsole.conf"/>
  <node pkg="mypackage" type="mynode" name="mynode" output="screen"/>
</launch>
  • Logger 的命名方式
    • 有root logger,名字就是 ros,可通过环境变量 ROSCONSOLE_ROOT_LOGGER_NAME 修改
    • 默认情况下,某个package中logger的名字就是 ros.<package_name>,可通过环境变量 ROSCONSOLE_DEFAULT_NAME 修改。
    • 如果指定了名字(named variations),那么logger的名字就是 ros.<package_name>.<name>
  • 编译时删除日志,可通过设置宏 ROSCONSOLE_MIN_SEVERITY 实现,该宏的取值包括,低于这个等级的都删了
ROSCONSOLE_SEVERITY_DEBUG
ROSCONSOLE_SEVERITY_INFO
ROSCONSOLE_SEVERITY_WARN
ROSCONSOLE_SEVERITY_ERROR
ROSCONSOLE_SEVERITY_FATAL
ROSCONSOLE_SEVERITY_NONE
  • 改变最小输出日志等级
#include <ros/console.h>
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
   ros::console::notifyLoggerLevelsChanged();
}
  • 输出日志格式
    • 通过环境变量 ROSCONSOLE_FORMAT 设置日志等级,如 export ROSCONSOLE_FORMAT='[${severity}] [${time}]: ${message}'
    • 可选参数包括
      • 时间的格式是一串数字,没有任何意义……
      • Noetic版本(ubuntu20.04)才支持有意义的时间输出格式……
      • 。。。。。。。。。。。。。。。。。。。。。。。。。。。。真的劝退

image-20210901183626377

  • 输出位置选择
    • 可以是 stdout, stderr, log file, /rosout 节点

image-20210901193420532

  • 输出日志的方式
ROS_DEBUG("Hello %s", "World");
ROS_DEBUG_STREAM("Hello " << "World");

# 指定logger名字,lgger名字就是 ros.package_name.test_only
ROS_DEBUG_NAMED("test_only", "Hello %s", "World");
ROS_DEBUG_STREAM_NAMED("test_only", "Hello " << "World");

# 根据条件输出
ROS_DEBUG_COND(x < 0, "Uh oh, x = %d, this is bad", x);
ROS_DEBUG_STREAM_COND(x < 0, "Uh oh, x = " << x << ", this is bad");

# 融合前两个条件
ROS_DEBUG_COND_NAMED(x < 0, "test_only", "Uh oh, x = %d, this is bad", x);
ROS_DEBUG_STREAM_COND_NAMED(x < 0, "test_only", "Uh oh, x = " << x << ", this is bad");

# 只输出一次
ROS_DEBUG_ONCE("This message will only print once");

# 每多少次输出一次
ROS_DEBUG_THROTTLE(60, "This message will print every 60 seconds");
ROS_DEBUG_DELAYED_THROTTLE(10, "Waiting for service 'add_two_ints'");

2. roslaunch

  • roslaunch 的作用就是:

    • 启动多个节点
    • 在参数服务器设置参数
    • 可自动重启节点
    • 自动启动 roscore
  • 启动命令是:roslaunch package_name file.launch

  • 在xml文件中支持很多 substitution args

    • 不知道该怎么翻译,在ROSLaunch节点启动前解析,用于指定一些参数
    • $(env ENVIRONMENT_VARIABLE):指定环境变量,替换对应参数
    • $(optenv ENVIRONMENT_VARIABLE):如果设置了环境变量,就用环境变量取值,替换对应参数,如果环境变量没有数值,就默认为空
    • $(optenv ENVIRONMENT_VARIABLE default_value):设置了环境变量默认值,其他的效果与上一个命令相同
    • $(find pkg):寻找一个package的相对路径,常用语替代硬编码的路径。
    • $(anon name):对一个字符串生成一个anonymous id,同样字符串反复生成结果相同。
    • $(arg foo):寻找同一个launch文件中的 <arg> 对应内容
    • $(eval <expression>):kinetic中新增,解析python表达式,如 "$(eval arg('foo') + env('PATH') + 'bar' + find('pkg')"
    • $(dirname):lunar中新增,获取当前launch文件所在路径
  • if/unless 语法

<group if="$(arg foo)">
  <!-- stuff that will only be evaluated if foo is true -->
</group>

<param name="foo" value="bar" unless="$(arg foo)" />  <!-- This param won't be set when "unless" condition is met -->
  • 常用标签很多,简单浏览一遍,主要靠后面细看

    • <launch>:launch文件的根元素,其他元素都包含在这个元素中

    • <node>:指定要启动的ROS节点,注意,包括重启节点选项

    • <machine>:指定节点运行的机器

    • <include>:导入其他launch xml文件

    • <remap>:单独针对对某个节点,重命名topic名字(应该不止针对topic,不过没细看,具体可以参考文档

      • <remap from="/different_topic" to="/needed_topic"/>
    • <env>:为节点设置环境变量,只能在 launch/include/node/machine 中使用

      • 环境变量相关文档,没细看
    • <param>:设置 Parameter Server 中的参数

      • lunar 中新增了解析 yaml 文件的功能,没细看。
    • <rosparam>:使用 rosparam 功能

    • <group>:将一系列node组合起来,一起配置

    • <test>:与node类似,只不过该node用于测试,是 rostest 的一部分

    • <arg>

  • 官网中的实例一

    • 最简单的实例,启动一个node。
    • name应该是随便取名,pkg就是包名,type就是二进制程序名。
    • 为什么有name?猜测就是某个二进制程序可以同时启动多次,每次启动的name必须不同
<launch>
  <node name="talker" pkg="rospy_tutorials" type="talker" />
</launch>
  • 官网中的实例二
    • 设置了需要启动的机器信息
    • 同时启动多个节点
<launch>
  <!-- local machine already has a definition by default.
       This tag overrides the default definition with
       specific ROS_ROOT and ROS_PACKAGE_PATH values -->
  <machine name="local_alt" address="localhost" default="true" ros-root="/u/user/ros/ros/" ros-package-path="/u/user/ros/ros-pkg" />
  <!-- a basic listener node -->
  <node name="listener-1" pkg="rospy_tutorials" type="listener" />
  <!-- pass args to the listener node -->
  <node name="listener-2" pkg="rospy_tutorials" type="listener" args="-foo arg2" />
  <!-- a respawn-able listener node -->
  <node name="listener-3" pkg="rospy_tutorials" type="listener" respawn="true" />
  <!-- start listener node in the 'wg1' namespace -->
  <node ns="wg1" name="listener-wg1" pkg="rospy_tutorials" type="listener" respawn="true" />
  <!-- start a group of nodes in the 'wg2' namespace -->
  <group ns="wg2">
    <!-- remap applies to all future statements in this scope. -->
    <remap from="chatter" to="hello"/>
    <node pkg="rospy_tutorials" type="listener" name="listener" args="--test" respawn="true" />
    <node pkg="rospy_tutorials" type="talker" name="talker">
      <!-- set a private parameter for the node -->
      <param name="talker_1_param" value="a value" />
      <!-- nodes can have their own remap args -->
      <remap from="chatter" to="hello-1"/>
      <!-- you can set environment variables for a node -->
      <env name="ENV_EXAMPLE" value="some value" />
    </node>
  </group>
</launch>
  • 官网中的实例三
    • 设置参数实例
<launch>
  <param name="somestring1" value="bar" />
  <!-- force to string instead of integer -->
  <param name="somestring2" value="10" type="str" />

  <param name="someinteger1" value="1" type="int" />
  <param name="someinteger2" value="2" />

  <param name="somefloat1" value="3.14159" type="double" />
  <param name="somefloat2" value="3.0" />

  <!-- you can set parameters in child namespaces -->
  <param name="wg/childparam" value="a child namespace parameter" />

  <!-- upload the contents of a file to the server -->
  <param name="configfile" textfile="$(find roslaunch)/example.xml" />
  <!-- upload the contents of a file as base64 binary to the server -->
  <param name="binaryfile" binfile="$(find roslaunch)/example.xml" />
</launch>
  • C++ 代码中如何读取参数?
ros::init(argc, argv, "param");
ros::NodeHandle nh;
std::string config_path;
n.param<std::string>("configfile", config_path, "");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值