ROS调试与运行
rqt工具
- rqt_console,rqt_logger_level
- rqt_plot
rqt_console,rqt_logger_level
- rqt_logger_level允许我们修改节点运行时输出信息的日志等级(logger levels)(包括 DEBUG、WARN、INFO和ERROR)
- 运行:
rosrun rqt_logger_level rqt_logger_level
操作小记
向test.cpp中添加从低到高四个等级的日志信息,INFO
、WARN
、ERROR
、FATAL
输入命令运行test_pkg_node节点:rosrun test_pkg test_pkg_node
打开rqt_logger_level界面,如下图所示
自行修改日志等级,观察消息输出情况
打开rqt_console界面,如下图所示
从图中可以看出系统输出了:info,warn,error,fatal等信息
Fatal是最高优先级,Debug是最低优先级。通过设置日志等级你可以获取该等级及其以上优先等级的所有日志消息。比如,将日志等级设为Warn时,你会得到Warn、Error和Fatal这三个等级的所有日志消息
将等级修改为Warn,观察到信息只输出Warn以上的信息,如下图所示
rqt_plot
- rqt_plot命令用于将话题的内容用曲线表达出来
- 输入命令打开rqt_plot工具:
rosrun rqt_plot rqt_plot
ROS参数服务器
-
rosparam
使得我们能够存储并操作ROS 参数服务器(Parameter Server)上的数据。 - 参数服务器能够存储整型、浮点、布尔、字符串、字典和列表等数据类型。
-
rosparam
使用YAML标记语言的语法。 - 一般而言,YAML的表述很自然:1 是整型, 1.0 是浮点型, one是字符串, true是布尔, [1, 2, 3]是整型列表, {a: b, c: d}是字典
-
rosparam
有很多指令可以用来操作参数-
rosparam set
:设置参数 -
rosparam get
:获取参数 -
rosparam load
:从文件读取参数 -
rosparam dump
:向文件中写入参数 -
rosparam delete
:删除参数 -
rosparam list
:列出参数名
-
操作小记
为了更加深刻的学习ROS参数,打开小乌龟程序:rosrun turtlesim turtlesim_node
查看当前系统中的参数服务器中的参数
现在我们修改背景颜色的红色通道:rosparam set /background_r 150
调用清除服务使得修改后的参数生效: rosservice call clear
显示参数服务器上的所有内容:rosparam get /
,而获取背景的绿色通道的值则用:rosparam get /background_g
现在我们将所有的参数写入params.yaml文件:rosparam dump params.yaml
保存成功后在home目录下可以查看到params.yaml文件
可以将yaml文件重载入服务器 ,打开params.yaml将background_r修改为130:rosparam load params.yaml copy
ROS launch
- 在ROS中一个节点程序一般只能完成功能单一的任务,但是一个完整的ROS机器人一般由很多个节点程序同时运行、相互协作才能完成复杂的任务,因此这就要求在启动机器人时就必须要启动很多个节点程序,一般的ROS机器人由十几个节点程序组成,复杂的几十个都有可能
- 这就要求我们必须高效率的启动很多节点,而不是通过
rosrun
命令来依次启动十几个节点程序,launch文件 就是为解决这个需求而生,launch文件就是一个xml格式的脚本文件,我们把需要启动的节点都写进launch文件中,这样我们就可以通过roslaunch工具来调用launch文件,执行这个脚本文件就一次性启动所有的节点程序
初始情况
接下来我们首先创建存放launch文件的软件包,然后编写一个简单的launch文件来一次性启动这两个节点
每个XML文件都必须要包含一个根元素,根元素由一对launch标签定义:<launch> … </launch>
<node pkg="package-name" type="executable-name" name="node-name" />
在节点标签末尾的斜杠“/” 是必须的,但很容易忘,你也可以这样显式地给出结束标签:<node pkg="…" type="…" name="…"> </node>
创建一个startup.launch,内容如下
- 在launch文件中,启动节点时name属性给节点指派了名称,它将覆盖任何通过调用
ros::int
来赋予节点的名称。 - 在默认状态下,从启动文件启动节点的标准输出被重定向到一个日志文件中,而不是在控制台显示。该日志文件的名称是:
~/.ros/log/run_id/node_name-number-stout.log
,其中,run_id
是节点管理器(master)启动时生成的一个唯一标示符。某个单独的节点在控制台中输出信息,只需在节点元素中配置:output="screen"
配置了该属性的节点会将标准输出显示在屏幕上而不是记录到日志文档。 - 接下来我们就可以将整个工作空间编译,这样我们就可以直接通过roslaunch命令来执行launch文件了roslaunch的用法是直接在终端中执行:
roslaunch package_name xxx.launch
- 编译后实际效果如下:
常见的节点属性
节点重生属性(respawn
)
当roslaunch开启所有nodes后,roslaunch会监视每个node,记录那些仍然活动的nodes。对于每个node,当其终止后,我们可以要求roslaunch重启该node,通过使用respawn属性
必要节点属性(required
)
当一个节点被声明为必要节点即 required="true"终止的时候,roslaunch 会终止所有其他活跃节点并退出。比如 在依赖激光雷达的机器人导航中,若激光雷达节点意外退出时,roslaunch将会终止其他节点然后退出
设定节点所需的参数(param
)
- 节点中的一些参数可以直接在launch文件中设定,这样就没有必要修改源码和编译了,每次只要修改一下launch文件就可以直接修改节点运行的参数。
-
<param>
标签定义了在参数服务器上设置的参数,放在<node>
标签中,在这种情况下,参数被当成了私有参数。 - 首先我们来修改launch文件中my_pkg节点的启动代码,增加相应的私有参数,如下图所示:
- 修改源码文件,获取当前节点的私有参数
- 当编译完成后,加载运行后的效果
包含其他launch文件(include)
- 在当前launch文件中调用另一个launch文件,方便代码的复用,可以使用包含(include)元素
<include file="$(find package-name)/launch-file-name">
- 由于直接输入路径信息很繁琐且容易出错,大多数包含元素都使用查找(
find
)命令搜索功能包的位置来替代直接输入绝对路径
- 编写测试源码
- 接下来编写third_pkg.launch文件
- 然后修改配置文件
- 然后修改robot_bringup软件包的launch文件,将third_pkg软件包的launch文件添加到总启动文件中
- 最后编译整个工作空间,当编译完成后,启动总launch文件来测试效果
- 编译完成后运行效果演示
- 编写launch时的注意事项
- roslaunch 不提供节点开始的顺序保证。这是特意的:没有办法知道哪个节点完全初始化了,所以启动代码必须在启动顺序上鲁棒性比较强。这个行为体现了ROS哲学:每一个节点与其他的节点都应该尽可能的独立、不相关,节点间耦合性尽可能低
- 在开始任何一个节点前,
roslaunch
将会确定roscore
是否已经在运行,如果没有则自动 启动它,因此在使用roslaunch
启动节点时不用再提前启动roscore
了 - 大多数 ROS 节点在启动时连接到master节点管理器上,如果没有在launch中配置该节点
respawn
属性为true运行中若连接中断,则不会尝试重新连接。因此如果roscore
被终止,当前运行的其他节点将无法建立新的连接,即使稍后重启roscore
也无济于事