ROS学习笔记六:xxx.launch文件详解
每当我们需要运行一个ROS节点或工具时,都需要打开一个新的终端运行一个命令。当系统中的节点数量不断增加时,每个节点一个终端的模式会变得非常麻烦。那么有没有一种方式可以一次性启动所有节点呢?答案当然是肯定的。
启动文件(Launch File)便是ROS中一种同时启动多个节点的途径,还可以自动启动ROSMaster节点管理器,而且可以实现每个节点的各种配置,为多个节点的操作提供了很大便利。
一、基本元素
首先来看一个简单的launch文件:
<launch>
<node name="sim1" pkg="turtlesim" type="turtlesim_node"/>
<node name="sim2" pkg="turtlesim" type="turtlesim_node"/>
</launch>
这是一个简单而完整的launch文件,采用XML的形式进行描述,包含一个根元素<launch>和两个节点元素<node>。
1.1 launch
XML文件必须要包含一个根元素,launch文件中的根元素采用<launch>标签定义,文件中的其他内容都必须包含在这个标签之中:
<launch>
……
……
……
</launch>
1.2 node
启动文件的核心是启动ROS节点,采用<node>标签定义,语法如下:
<node name="node-name" pkg="package-name" type="executable-name"/>
从上边的定义规则可以看出,在启动文件中启动一个节点需要三个属性:name、pkg和type。其中name属性用来定义节点运行的名称,将覆盖节点中ros::init()定义的节点名称;pkg属性定义节点所在的功能包名称,type属性定义节点的可执行文件名称,这两个属性等同于在终端中使用rosrun命令执行节点时的输入参数。这是三个最常用的属性,在某些情况下,我们还有可能用到以下属性:
| 属性 | 属性作用 |
|---|---|
output="screen" |
终端输出转储在当前的控制台上,而不是在日志文件中 |
respawn="true" |
当roslaunch启动完所有该启动的节点之后,会监测每一个节点,保证它们正常的运行状态。对于任意节点,当它终止时,roslaunch 会将该节点重启 |
required="true" |
当被此属性标记的节点终止时,roslaunch会将其他的节点一并终止。注意此属性不可以与respawn="true"一起描述同一个节点 |
ns = "NAME_SPACE" |
这个属性可以让你在自定义的命名空间里运行节点 |
args = "arguments" |
节点需要的输入参数 |
实际应用中的launch文件往往会更加复杂,使用的标签也会更多,例如一个启动机器人的launch文件如下:
<launch>
<node pkg="mrobot_bringup" type="mrobot_bringup" name="mrobot_bringup" output="screen" />
<arg name="urdf_file" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot_with_rplidar.urdf.xacro'" />
<param name="robot_description" command="$(arg urdf_file)" />
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="state_publisher">
<param name="publish_frequency" type="double" value="5.0" />
</node>
<node name="base2laser" pkg="tf" type="static_transform_publisher" args="0 0 0 0 0 0 1 /base_link /laser 50"/>
<node pkg="robot_pose_ekf" type="robot_pose_ekf" name="robot_pose_ekf">
<remap from="robot_pose_ekf/odom_combined" to="odom_combined"/>
<param name="freq" value="10.0"/>
<param name="sensor_timeout" value="1.0"/>
<param name="publish_tf" value="true"/>
<param name="odom_used" value="true"/>
<param name="imu_used" value="false"/>
<param name="vo_used" value="false"/>
<param name="output_frame" value="odom"/>
</node>
<include file="$(find mrobot_bringup)/launch/rplidar.launch" />
</launch>
目前,我们只关注其中的标签元素,除了上边介绍的<launch>和<node>,这里还出现了<arg>、<param>、<remap>,这些都是常用的标签元素。
二、参数设置
为了方便设置和修改,launch文件支持参数设置的功能,类似于编程语言中的变量声明。关于参数设置的标签元素有两个:<param>、<arg>,一个代表parameter,另一个代表argument。这两个标签元素翻译成中文都是“参数”的意思,但是这两个“参数”的意义是完全不同的。
2.1 param
parameter是ROS系统运行中的参数,存储在参数服务器中。在launch文件中可以通过<param>元素加载parameter。launch文件执行后,parameter就加载到ROS的参数服务器上了。
每个活跃的节点都可以通过 ros::param::get()接口来获取parameter的值,用户也可以在终端中通过rosparam命令获得parameter的值。
比如现在在参数服务器中添加一个名为demo_param,值为666的参数
<param name="demo_param" type="int" value="666"/>
运行launch文件后,demo_param这个parameter的值就设置为666,并且加载到ROS参数服务器上了。但是在很多复杂的系统中,参数的数量很多,如果这样一个一个的设置会非常麻烦,ROS也为我们提供了另外一种类似的参数加载方式——<rosparam>:
<rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam>可以帮助我们将一个yaml格式文件中的参数全部加载到ROS参数服务器中,需要设置command属性为“load”,还可以选择设置命名空间“ns”。
2.2 arg
arg标签用来在launch文件中定义参数,arg和param在ROS里有根本性的区别,就像局部变量和全局变量的区别一样。arg不储存在参数服务器中,不能提供给节点使用,只能在launch文件中使用。param则是储存在参数服务器中,可以被节点使用。
<arg name="demo"/>
像上面这样,就简单地声明了一个参数,名叫demo,但是声明不等于定义,我们需要给他赋值,在赋值之后参数才能够发挥作用。
<arg name="demo1" value="666"/>
<arg name="demo2" default="666"/>
以上是两种简单的赋值方法,两者的区别是使用后者赋值的参数可以在命令行中像下面这样被修改,前者则不行。
roslaunch demo demo.launch demo:2=6666
launch文件中需要使用到argarg-name时,可以使用如下方式调用:
<arg name="arg-name" value="666"/>
<param name="foo" value="$(arg arg-name)" />
<node name="node" pkg="package" type="type "args="$(arg arg-name)" />
当$(arg arg_name)出现在launch文件任意位置时,将会自动替代为所给参数的值。
三、重映射机制
ROS的设计目标是提高代码的复用率,所以ROS社区中的很多功能包我们都可以拿来直接使用,而不需要关注功能包的内部实现。那么问题就来了,别人功能包的接口不一定和我们的系统兼容呀?
ROS提供一种重映射的机制,简单来说就是取别名,类似于C++中的别名机制,我们不需要修改别人功能包的接口,只需要将接口名称重映射一下,取个别名,我们的系统就认识了(接口的数据类型必须相同)。launch文件中的<remap>标签顾名思义重映射,emap标签里包含一个original-name和一个new-name,及原名称和新名称。
比如turtlebot的键盘控制节点,发布的速度控制指令话题可能是/turtlebot/cmd_vel,但是我们自己的机器人订阅的速度控制话题是/cmd_vel,这个时候使用<remap>就可以轻松解决问题,将/turtlebot /cmd_vel重映射为/cmd_vel,我们的机器人就可以接收到速度控制指令了:
<remap from="/turtlebot/cmd_vel" to="/cmd_vel"/>
重映射机制在ROS中的使用非常广泛,也非常重要,方法不止这一种,也可以在终端rosrun命令中实现重映射,大家一定要理解好这种机制。
四、嵌套复用
在复杂的系统当中,launch文件往往有很多,这些launch文件之间也会存在依赖关系。如果需要直接复用一个已有launch文件中的内容,可以使用<include>标签包含其他launch文件,这和C语言中的include几乎是一样的。
<include file="$(find demo)/launch/demo.launch" ns="demo_namespace"/>
| 属性 | 属性作用 |
|---|---|
file ="$(find pkg-name)/path/filename.xml" |
指明我们想要包含进来的文件 |
ns="NAME_SPACE" |
相对NAME_SPACE命名空间导入文件 |
总而言之,launch是ROS框架中非常实用、灵活的功能,它类似于一种高级编程语言,可以帮助我们管理启动系统时的方方面面。在使用ROS的过程中,很多情况下我们并不需要编写大量代码,仅需要使用已有的功能包,编辑一下launch文件,就可以完成很多机器人功能。
五、拓展说明
使用
roslaunch命令 和 使用rosrun命令 单独运行每个节点之间的重要区别
默认情况下,roslaunch 命令 从启动节点开始,标准输出信息会重定向到一个日志文件中,而不会像 rosrun 命令那样,将 log 信息显示在终端(console)上。日志文件所在路径: ∼/.ros/log/run_id/node_name-number-stdout.log
Q: 如何将标准输出信息显示在终端(console)上?
A: 在 node 元素中使用 output 属性:output=”screen”。
扩展: node 元素的 output 属性只能影响这个节点自己。除了 output 属性,我们可以使用 roslaunch命令行工具的 –screen 命令行选项强制性的在终端的窗口中显示所有节点的输出信息。
$ roslaunch --screen package-name launch-file-name
参考:
ROS学习笔记六:xxx.launch文件详解的更多相关文章
- Docker学习(六)——Dockerfile文件详解
Docker学习(六)--Dockerfile文件详解 一.环境介绍 1.Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下,可以为Dockerfile父目录的子目录 ...
- 小程序学习笔记二:页面文件详解之 .json文件
页面配置文件—— pageName.json 每一个小程序页面可以使用.json文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项. 页面的 ...
- 小程序学习笔记三:页面文件详解之视图层WXML、WXS、WXSS文件
视图层:Pages主要有 wxml页面文件和模板文件.wxs脚本文件.wxss样式文件:component是抽取出来的业务单元,同样拥有wxml页面文件和模板文件.wxs脚本文件.wxss样式文件 ...
- IP地址和子网划分学习笔记之《IP地址详解》
2018-05-03 18:47:37 在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
- 云时代架构阅读笔记六——Java内存模型详解(二)
承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...
- linux命令学习笔记(25):linux文件属性详解
Linux 文件或目录的属性主要包括:文件或目录的节点.种类.权限模式.链接数量.所归属的用户和用户组. 最近访问或修改的时间等内容.具体情况如下: 命令: ls -lih 输出: [root@loc ...
- Java学习笔记 线程池使用及详解
有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...
- Mybatis学习(三)————— 映射文件详解
前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输 ...
随机推荐
- Nexus搭建Maven私有仓库
原文:http://blog.csdn.net/rickyit/article/details/54927101 前言 Nexus Repository Manager is a Javaapplic ...
- 临远大神,你为啥要建立一个 TASK表。HumanTaskDTO
临远大神,你为啥要建立一个 TASK表.HumanTaskDTO HumanTask这张表的作用是什么. 为了实现理想中的任务中心.TaskCenter. 首先,工作流可能会完全不包含任何人工节点,全 ...
- RHEL 启动系统及故障排除
一:Linux的启动过程: 开机加电自检->MBR引导(boot loader占446字节,分区列表64字节,magic占2字节)-->grub菜单(MBR是grub的第一个字段,第二个字 ...
- MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍
近期有个开发团队抱怨我们平台包括的mysql cluster不行,总是报mysql的"heartbeat Error".分析了他们收集的日志.没有发现mysql cluster节点 ...
- 同步定制 Unity团队 程序的C#文件模板
孙广东 2015.7.30 就是把程序制定好的模板(不论什么人能够更改并同步git)放到,unity项目的Editor 目录下, 当程序新建一个C#脚本后就是这个模板了. "81-C# ...
- Random产生随机数问题
昨天在开发时发现这个问题,在同一个for循环内,通过Random多次产生随机数得到的随机数竟是一样的!以前还真没发现这个问题. 以下是简化的代码,如果将random定义在for循环外面则不会有问题(猜 ...
- 【iOS系列】-UINavigationController的使用(Segue传递数据)
[iOS系列]-UINavigationController的使用 UINavigationController是以以栈(先进后出)的形式保存子控制器, 常用属性: UINavigationItem有 ...
- (2)MyEclipse怎么关联本地Tomcat服务器
1,在MyEclipse中点击服务器按钮: 2,选择“Configure Server” 3,在弹出面板中选择 [Servers]-[Tomcat]-[对应版本的服务器] 5,看上图,先选择Enabl ...
- mysql06---权限控制
mysql权限管理: mysql的权限控制,首先在user表判断有没有权限连,连上后看有没有全局权限.然后看db表有哪些库级别的权限.然后看tables_priv表有哪些表级别的权限.最后还可以看有哪 ...
- C # 踩坑记录(20190603)
由于公司战略层需求,需要学习c#,在此仅记录相关问题,以便后期回顾. 学习路线 .NET 框架学习与C # 的关系 Visual Studio 简介及相关帮助网站(msdn) Main 方法及&quo ...