ROS与C++学习2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16481211/article/details/82493228

Logging(日志)

日志

ros有自身的话题机制,叫rosout,用于记录节点的日志消息。
日志消息是方便阅读的字符串内容,记录节点状态信息。
查看实时消息最好的方式是通过rqt_console GUI程序

日志语句

roscpp采用rosconsole包提供的客户端API。该API以一些rose_macros的形式:
rosconsole提供的日志语句的四种类型,5种不同的详细级别,用printf和stream-style格式。
(1)基础版
ROS_DEBUG(…)
ROS_DEBUG_STREAM(args)
基本版本只打印输出消息

#include<ros/console.h>
ROS_DEBUG("Hello %s","world");
ROS_DEBUG_STREAM("Hello"<<"world");

基本版本输出存储到了ros.< your_package_name>
(2)NAMED指定版本
ROS_DEBUG_NAMED(name,…)
ROS_DEBUG_STREAM_NAMED(name,args)
NAMED版本输出到日志,允许您根据其名称配置启用/禁用的不同日志记录语句。例如:

#include<ros/console.h>
ROS_DEBUG_NAMED("test_only","Hello %s","world");
ROS_DEBUG_STREAM_NAMED("test_only","Hello"<<"world");

它会输出到名叫ros.< you_package_name>.test_only中
有关此信息的更多信息可以在配置文件中获得。
(3)Conditional条件版
ROS_DEBUG_COND(cond, …)
ROS_DEBUG_STREAM_COND(cond, args)
conditional版本当条件为真是否就会输出日志信息。

#include <ros/console.h>
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");

(4)Conditional Named指定条件版

ROS_DEBUG_COND_NAMED(cond, name, …)
ROS_DEBUG_STREAM_COND_NAMED(cond, name, args)
指定条件版结合上面两种类型:

#include <ros/console.h>
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");

(5)Once [1.1+]
ROS_DEBUG_ONCE(…)
ROS_DEBUG_STREAM_ONCE(args)
ROS_DEBUG_ONCE_NAMED(name, …)
ROS_DEBUG_STREAM_ONCE_NAMED(name, args)

#include <ros/console.h>
for (int i = 0; i < 10; ++i)
{
  ROS_DEBUG_ONCE("This message will only print once");
}

(6)Throttle [1.1+]
ROS_DEBUG_THROTTLE(period, …)
ROS_DEBUG_STREAM_THROTTLE(period, args)
ROS_DEBUG_THROTTLE_NAMED(period, name, …)
ROS_DEBUG_STREAM_THROTTLE_NAMED(period, name, args)

while (true)
{
  ROS_DEBUG_THROTTLE(60, "This message will print every 60 seconds");
}

(7)Delayed throttle

(added in Indigo as of rosconsole version 1.11.11)
ROS_DEBUG_DELAYED_THROTTLE(period, …)
ROS_DEBUG_STREAM_DELAYED_THROTTLE(period, args)
ROS_DEBUG_DELAYED_THROTTLE_NAMED(period, name, …) ROS_DEBUG_STREAM_DELAYED_THROTTLE_NAMED(period, name, args)
这些宏会按一定间隔延迟发送日志

while (!ros::service::waitForService("add_two_ints", ros::Duration(0.1)) && ros::ok())
{
  // This message will print every 10 seconds.
  // The macro will have no effect the first 10 seconds.
  // In other words, if the service is not available, the message will be 
  // printed at times 10, 20, 30, ...
  ROS_DEBUG_DELAYED_THROTTLE(10, "Waiting for service 'add_two_ints'");
}

(8)Filter [1.1+]
ROS_DEBUG_FILTER(filter, …)
ROS_DEBUG_STREAM_FILTER(filter, args)
ROS_DEBUG_FILTER_NAMED(filter, name, …)
ROS_DEBUG_STREAM_FILTER_NAMED(filter, name, args)
过滤输出允许你使用自定义的过滤器,这些过滤器扩展自ros::console::FilterBase类,过滤器必需是指针类型。

日志级别

五种不同的详细级别,为:
DEBUG
INFO
WARN
ERROR
FATAL

设置日志级别

有三种方法设置日志级别:
第一个是通过配置文件设置所有节点的日志级别
第二个是在运行时,通过rqt_logger_level(以前叫rxloggerlevel)或rqt_console (以前叫rxconsole) 工具来设置日志级别
第三个通过 rosconsole API来设置:

#include <ros/console.h>
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
   ros::console::notifyLoggerLevelsChanged();
}

ROS roslaunch

roslaunch 用处:将多个rosnode 结合起来,一起运行。这样就不需要一个个的运行。

<launch>
      <arg name="a" default="1" />
      <arg name="b" default="2" />
  <node pkg="beginner_tutorials" name="add_two_ints_server" type="add_two_ints_server"/>
  <node pkg="beginner_tutorials" name="add_two_ints_client" type="add_two_ints_client" args="$(arg a) $(arg b)"/>
  <node name = "stage" pkg="stage_ros" type = "stageros" args="$(find stage_ros)/world/willow-erratic.world"/>
</launch>

launch文件为xml格式。
每个tag的格式至少包含下面三部分
1.pkg = “your package name”,

2.name = “your name”//一般为可执行文件的名称
可执行文件的名称是robot_cleaner_node

3.type =”可执行文件的名称”,
(即在CMakeList.txt中的add_executable(node_name src/c++file.cpp)中的node_name)
例如:add_executable(robot_cleaner_node src/robot_cleaner_move_rotate.cpp)中的robot_cleaner_node

此处的type是可执行文件的名称,而name则是可以任意给出的,它覆盖了原有文件中ros::init指定的node name。

4.(非必须)args 为运行时的参数
定义参数a,默认值为1,运行时可以重新赋值;
定义参数b,值为2,运行时不能赋值;
若赋值会出现错误:Invalid tag: cannot override arg ‘b’, which has already been set.

args=” ( a r g a ) (arg b)”:a,b作为参数传入节点,运行时可以将a重新赋值,不赋值使用默认值1.

( f i n d p a c k a g e n a m e ) p a c k a g e n a m e (find stage_ros)/world/willow-erratic.world” 表示 /opt/ros/indigo/share/stage_ros/world/willow-erratic.world
运行:1.(未定义arg时) roslaunch beginner_tutorials add_two.launch a:=4 b:=5
2.(定义arg后) roslaunch beginner_tutorials add_two.launch 或者roslaunch beginner_tutorials add_two.launch a:=4(只给a赋值,b不需要)

运行之后输出会保存在log文件中:例如log file: /home/server/.ros/log/e907e8c8-9be8-11e6-bf00-74d43562c7a3/add_two_ints_client-2*.log,并不会出现在控制台
要想输出在控制台,添加output属性

<node name = "my_stage" pkg = "my_stage" type = "my_stage"
output = "screen" />

5 若显示所有nodes的输出,用–screen命令行。
$ roslaunch –screen package_name launch_file_name
6

respawn="true"
eg:<node pkg="turtlesim" name="sim" type="turtlesim_node"  respawn="true"/>

代表当我们启动一个node时,roslaunch会监控它,当它关闭时,比如启动turtlesim节点,当我们关闭turtlesim窗口时,roslaunch会重新启动一个新的。
7

required="true"

此属性表示当这个节点退出后,roslaunch会关闭所有的节点,并退出。
8让一个节点在单独的终端窗口中启动:
roslaunch 使所有的节点都共用一个终端,要想节点有自己的终端可以使用

launch-prefix="xterm -e"

9 命名空间ns

ns="turtlesim1"

如果同一个节点使用这个属性可以创建了两个无关的节点。

<launch>
    <node
    name="turtlesim_node "
    pkg="turtlesim"
    type="turtlesim_node "
    ns="sim1"
    />
    <node
    pkg="turtlesim"
    type="turtle_teleop_key "
    name="teleop_key"
    required="true"
    launch −prefix="xterm −e"
    ns="sim1"
    />
    <node
    name="turtlesim_node "
    pkg="turtlesim"
    type="turtlesim_node "
    ns="sim2"
    />
    <node
    pkg="a gitr "
    type="pubvel"
    name="velocity_publisher "
    ns="sim2"
    />
</launch>

10.
remap :在launch文件中重新命名:使用 remap 元素
格式:< remap from=”original-name” to=”new-name” />
如果这个 remap 是 launch 元素的一个child(子类),与 node 元素同一层级, 并在 launch 元素内的最顶层。那么这个 remapping 将会作用于后续所有的节点。
将turtle1/pose 重新命名为tim
使用rosrun 命令rosrun turtlesim turtlesim_node turtle1/pose:=tim
使用roslaunch

<node pkg="turtlesim" type="turtlesim_node"
   name="turtlesim" >
   <remap from="turtle1/pose" to="tim" />
</node>

11.including
这个属性期望我们添加想要包含的文件的完整路径。但是大多数时候,include 元素使用一个 find 命令来搜索一个程序包,代替一个明确的完整路径:

<include file="$(find package-name)/launch-file-name" />

roslaunch 命令 将会在程序包(package)的子目录里搜索launch文件。 include 元素必须要指定文件的特定路径,你可以使用 find 来找到这个程序包,但是却不能在这个程序包目录里面自动的找到某个子目录里有launch文件。举例:

这样做是正确的:<include file = "find learning_tutrols"/launch/start_demo.launch" / >

这样做是错误的:<include file = "find learning_tutrols"/start_demo.launch" />

include 元素也支持 ns 属性,可以让这个文件里的内容推送到一个命名空间里面:

<include file=". . . " ns="namespace" />

12 .param 标签
wiki.ros.org/roslaunch/XML/param
定义了一个参数服务器上的参数,属性有
name : 参数名字
type :参数的类型,”str|int|double|bool”
value:参数的值,除了value还可以使用以下三种
textfile= ( f i n d p k g n a m e ) / p a t h / f i l e . t x t 访 使 (find pkg-name) 形式来。避免在另一台机器上找不到文件路径运行失败。
‘binfile=” ( f i n d p k g n a m e ) / p a t h / f i l e B a s e 64 X M L R P C c o m m a n d = (find pkg-name)/exe '$(find pkg-name)/arg.txt’”
parameter server 参数除了上述方法外,可以通过以下方式设置
命令行 rosparam set / rosparam get 设置
代码中
roscpp: ros::param::set / ros::param::get
rospy: set_param / get_param

13.rosparam 标签
wiki.ros.org/roslaunch/XML/rosparam
rosparam :可以使用从rosparam YAML文件加载,删除,dump ,ROS参数服务器参数
rosparam 参数:
command=”load|dump|delete” (optional, default=load)
file=”$(find pkg-name)/path/foo.yaml” (load or dump commands)
param=”param-name”
ns=”namespace” (optional)
subst_value=true|false (optional) 是否允许替换yaml文本中的参数

<rosparam command="load" file="$(find rosparam)/example.yaml" />//加载文件中的参数
<rosparam command="delete" param="my/param" />//删除参数

<arg name="whitelist" default="[3, 2]"/>
<rosparam param="whitelist" subst_value="True">$(arg whitelist)</rosparam> //替换

<rosparam param="a_list">[1, 2, 3, 4]</rosparam>
<rosparam>
  a: 1
  b: 2
</rosparam>

猜你喜欢

转载自blog.csdn.net/qq_16481211/article/details/82493228
今日推荐