ROS创建launch文件
01 launch文件启动
launch文件:通过XML文件实现多节点的配置和启动
launch文件可自动启动ROS Master,所以不用
roscore
了编写或修改launch文件后不需要再
catkin_make
编译启动launch文件:
roslaunch pkg_name launchfile_name.launch
也可以使用绝对路径启动launch文件:
roslaunch path_to_launchfile
添加参数的launch文件启动如下
roslaunch pkg_name launchfile_name model:=urdf/myfile.urdf # launch file 中有参数 “model” 需要赋值 # 或 roslaunch pkg_name launchfile_name model:='$(find urdf_pkg)/urdf/myfile.urdf' # 用 find 命令提供路径
常见参数:
screen
: 令 ros node 的信息(如果有的话)输出到屏幕上,而不是保存在某个 log 文件中,这样比较方便调试arg:=value
: 如果 launch 文件中有待赋值的变量,可以通过这种方式赋值
02 launch文件基本语法
<launch>
:launch文件中的根元素采用标签定义
launch文件语法与xml相同,其常用标签如下:
<launch> <!--根标签-->
<node> <!--需要启动的node及其参数-->
<include> <!--包含其他launch-->
<machine> <!--指定运行的机器-->
<env-loader> <!--设置环境变量-->
<param> <!--定义参数到参数服务器-->
<rosparam> <!--加载yaml文件中的参数到参数服务器-->
<arg> <!--定义变量-->
<remap> <!--设定 topic 映射-->
<group> <!--设定分组-->
</launch> <!--根标签-->
2.1 node标签
<node>
标签是launch文件最常使用的标签之一
<launch><node pkg="package_name" type="executable_file" name="node_name1"/><node pkg="another_package" type="another_executable" name="another_node"></node>
</launch>
pkg
:是节点所在的 package 名称type
:是 package 中的可执行文件,如果是 python编写的,就需要写出.py
后缀;如果是 c++ 编写的,则直接写可执行文件的名字就可以,不需要.cpp
后缀。name
:是节点启动之后的名字, 每一个节点都要有自己独一无二的名字。如果想启动两个相同的文件,可以在这里写两个不同的名字,这样就可以启动两个原名字相同的节点了(比如启动两个小乌龟),这也是使用launch文件的优势之一。
注意: roslaunch 不能保证 node 的启动顺序,因此 launch 文件中所有的 node 都应该对启动顺序有鲁棒性。
所以这也是手眼标定时,很多博主都说最好不要在一个launch文件中启动,分开启动的原因。
<node>
中除了 pkg
、 type
、name
之外还可以设置更多参数,如下:
<launch><nodepkg=""type=""name="" respawn="true" required="true"launch-prefix="xterm -e"output="screen"ns="some_namespace"args=""/>
</launch>
参数 | 作用 |
---|---|
pkg
|
表示该节点所在的功能包 |
type
|
该节点的实际名称,即开发时的名称。启动该节点的文件名,c++不需要加后缀。py需要加后缀 |
name
|
节点的名称,这里可以为节点重命名,这样就会覆盖掉原名字 |
respawn
|
若该节点意外关闭,是否自动重新启动 |
required
|
是否关闭其他所有launch启动的节点 |
launch-prefix
|
是否新开一个窗口执行。例如,需要通过窗口进行机器人移动控制的时候,应该为控制node新开一个窗口;或者当 node 有些信息输出,不希望与其他 node 信息混杂在一起的时候 |
output
|
默认情况下,launch 启动 node 的信息会存入下面的 log 文件中(/.ros/log/run_id/node_name-number-stdout.log ),可以通过此处参数设置,令信息显示在屏幕上,eg:output = “screen”
|
ns
|
将 node 归入不同的 namespace,即在 node name 前边加 ns 指定的前缀。为了实现这类操作,在 node 源文件中定义 node name 和 topic name 时要采用 relative name, 即不加slash符号 /
|
如果要设定节点的参数。还可以使用<args>
标签,其他可以和node一同使用的标签如下:
注意:
以下的这些可以单独作为标签使用,也就是放在<node>……</node>
中间,并使用<>
;
而上面的那些参数是放在<node……/>
中间,并且不必再使用尖括号了的
标签 | 作用 |
---|---|
<srgs>
|
设定该节点参数 |
<remap>
|
将topic映射为新的名字 |
<env>
|
让节点读入环境参数 |
<param>
|
设定该节点所需参数 |
2.2 include标签
这个标签的作用是将另外一个 launch
文件添加到另一个 launch
文件中,类似 launch
文件的嵌套。
include
的使用和c++和python的头文件类似。
node标签是启动一个节点,include标签是把另一个launch文件启动了(也就是启动一批节点)
<include>
基本格式:
<include file="$(find package-name)/launch-file-name" />
上边的文件路径可以给具体路径,但是一般来说为了程序的可移植性,最好借助 find
命令给出文件路径。
$(find package-name)
等价于电脑中相应 package
的路径。这样即使换了其他电脑,只要安装了同样的 package
,就可以找到对应的路径,也就是这样把一个绝对路径变为了类似于相对路径的形式。
如果有需要,include里面也可以加<arg>
标签,指定参数的值。
至于具体需要设定哪些参数,可以看看include
要启动的文件,设定了哪些args
关于arg
标签更详细的介绍可以看下一小节
<include file="$(find ur_robot_driver)/launch/ur3_bringup.launch"><arg name="limited" value="true" /><arg name="robot_ip" value="192.168.56.10" />
</include>
有时,另一个 launch
引入的 node
可能需要统一命名,或者具有类似特征的 node
名字,比如 /vehicle1/gps
, /vehicle1/lidar
, /vehicle1/imu
,即 node 具有统一的前缀,方便查找。这可以通过设置 ns (namespace)
属性来实现,命令如下:
<include file="$(find package-name)/launch-file-name " ns="namespace_name" />
2.3 remap标签
<remap>
经常作为node tag
的子tag
出现,可以用来修改topic
。
在很多rosnode
源文件中,可能并没有指定接收的或者发送的topic
,而仅仅是用 input_topic
和 output_topic
代替,这样在使用中需要将抽象的 topic
名字替换成具体场景中的 topic
名字。
简单地说, <remap>
的作用就是方便同一个 node
文件被应用到不同的环境中,用 remap
从外部修改一下 topic
即可,不需要改变源文件。
比如ur机械臂的仿真和控制实物这两个过程就可以通过remap
的命名,结合在一起。
remap
常见的使用格式如下:
<node pkg="some" type="some" name="some"><remap from="origin" to="new" />
</node>
2.4 arg标签
通过 <arg>
标签可以使参数重复使用,也便于多处同时修改。
<arg>
三种常用方法:
<arg name="foo">
:声明一个 arg,但不赋值。稍后可以通过命令行赋值,或者通过<include>
标签赋值。<arg name="foo" default="1">
:赋默认值。这个值可以被命令行和 tag 重写。<arg name="foo" value="1">
:赋固定值,这个值不可以被改写.
从命令行赋值:
roslaunch package_name file_name.launch arg1:=value1 arg2:=value2
如启动ur机械臂moveit时,如果是仿真,会在后面加sim:=true
,如果是驱动实物,则不需要加这个参数,因为它的default就是false
argument的继承问题:args类似于局部变量,argument不能传递给include元素里包含的子launch文件使用,它不能被包含的launch文件所 “继承” 。
解决这个问题的方法:在include
元素中插入arg
元素作为 include
元素的子类(children)
<include file="$(find ur_robot_driver)/launch/ur3_bringup.launch"><arg name="limited" value="true" /><arg name="robot_ip" value="192.168.56.10" /></include>
2.5 param标签
提到 param 首先要知道 parameter server(参数服务器), 它由 ROS Master 管理,提供了一个共享的字典 (dict) 类型数据。节点通过这个 server 存储、获取运行时所需的参数。
param server 设计时就不是针对高速存取的,因此一般只适合存放静态数据,例如配置参数.。
由于是全局可获取, 我们可以很容易的查看其中的 param 并且修改。
因为是全局的,param 的命名与 topic 和 node 相同,都是有 namespace hierarchy 结构的,这可以防止不同来源的名字冲突。它的存取也是体现了结构性,例如下边的 params:
/camera/left/name: leftcamera
/camera/left/exposure: 1
/camera/right/name: rightcamera
/camera/right/exposure: 1.1
对于上述数据的读取
# 如果读取参数 /camare/left/name 可以得到
leftcamera# 如果读取 param /camera/left可以得到 dict 为
{name: leftcamera, exposure: 1}#如果读取 param /camera,则得到 dict 为
{left: {name: leftcamera, exposure: 1}, right: {name: rightcamera, exposure: 1.1}}
与 arg 不同,param 是共享的,并且它的取值不仅限于 value,还可以是文件,甚至是一行命令。
<param name="param_name" type="type1" value="val"/> # type可以省略,系统自动判断
<param name="param_name" textfile="$(find pkg)/path/file"/> # 读取 file 存成 string
<param name="param_name" command="$(find pkg)/exe '$(find pkg)/arg.txt'"/>
实例:
<param name="param" type="yaml" command="cat '$(find pkg)/*.yaml'"/> # command 的结果存在 param 中
定义在<node>
下的<param>
,会加入node
的命名空间,例如:
<node name="node1" pkg="pkg1" type="exe1"><param name="param1" value="False"/>
</node>
rosparam list
列出:
/node1/param1 # 自动加上了 namespace 前缀
2.6 group标签
如果要对多个 node
进行同样的设置,比如都在同一个特定的 namespace
,remap
相同的topic
等,可以用 <group>
标签。在group
中可以使用所有常见的标签进行设置,例如
<group ns="wg2"><remap from="chatter" to="talker"/> # 对该 group 中后续所有 node 都有效<node ... /><node ... ><remap from="chatter" to="talker1"/> # 各个 node 中可以重新设置 remap</node>
</group>
03 一些概念
3.1 launch文件arg和param传参
ros传参主要有两种:
- 第一种是通过main函数的argc和argv变量;
- 第二种是通过参数服务器
在ros中我们可以在launch文件中使用args参数传递参数的值,这种是类比于“main函数通过argv变量传递参数给程序”
<arg name="a" default="1"/>
<arg name="b" default="5"/>
<node name="add_two_ints_client" pkg="beginner_tutorials" type="add_two_ints_client" args="$(arg a) $(arg b)" output="screen"/>
此外因为arg
的属性是default
,所以我们还可以在指令中修改参数的值(这正是arg传参的优势所在,可以不修改launch文件的情况下修改参数值,而通过命令行形式进行参数修改)
命令行指令:
roslaunch beginner_tutorials launch_file.launch a:=1 b:=2
参数服务器传参是通过 n.param<std::string>("n_arg",n_arg,"arg1")
语句来完成对变量n_arg的传参
类似的,launch文件的处理是<param>
标签
<node name="add_two_ints_client" pkg="beginner_tutorials" type="add_two_ints_client" output="screen"/>
<param name="n_arg" value="test"/>
如果想类似于args参数的在命令行中重新赋值,则执行下述指令:
roslaunch beginner_tutorials launch_file.launch arg_toparam:="best"
所以总结一下:
- args和param传参的方式不同,前者是通过main函数,后者是通过参数服务器
- args如果是default,则可以在命令行中重新赋值,而不必修改launch文件;如果是param,则需要在命令行中使用
arg_toparam
进行转换 - args可以理解为局部变量,而param是全局变量。
<arg>
标签给launch文件内部设置参数,通过标签设置的参数仅在launch文件内有效。 - param保存的值类型更多样,可以时value、文件或者命令
3.2 rosparam参数服务器
<param>
只能对单个 param
操作,而且只有三种:value
, textfile
, command
形式,返回的是单个 param
的内容。
<rosparam>
则可以批量操作,还包括一些对参数设置的命令,如 dump
, delete
等
<param>
标签可用于直接设置参数,也可以从文件中读取
<rosparam>
标签一般用于从yaml文件中读取并设置参数
load
:从yaml
文件中加载一批param
,格式如下:<rosparam command="load" file="$(find rosparam)/example.yaml" />
delete
:删除某个param
<rosparam command="delete" param="my_param" />
类似
<param>
的赋值操作<rosparam param="my_param">[1,2,3,4]</rosparam>
或者
<rosparam> a: 1 b: 2 </rosparam>
<rosparam>
标签也可以放在 <node>
标签 中, 此时 param
名字前边都加上 node
的 namespace
机器人的参数一般会提前设置好,这些参数都会放在 yaml
文件里,rosparam
命令的方便之处在于它可以直接读取 yaml 文件中的参数,而不必自己找第三方库去文件中读取。
04 参考
- http://wiki.ros.org/roslaunch/
- 古月居launch文件讲解:https://www.bilibili.com/video/BV1zt411G7Vn?p=19
- ROS 中的 launch 文件:https://www.jianshu.com/p/e55850b87c7d
- launch文件arg和param传参:https://zhuanlan.zhihu.com/p/157526418
ROS创建launch文件相关推荐
- linux开机启动roscore,树莓派ubuntuMate系统中开机自启动ROS的launch文件
0x00 为何需要开机自启动launch文件 在ROS开发后期阶段由于功能已经趋于稳定,因此就需要系统在一上电启动后就自动把ROS下的各节点程序加载运行,这样就省去了我们还得手动输入roslaunch ...
- ROS中launch文件的编写
ROS中launch文件的编写 launch文件介绍 ROS系统里的组成单位是节点(node),在启动ROS时需要启动所有的node,如果手动一一启动会是一项十分繁琐的事情,因此ROS通过launch ...
- ROS中launch文件使用笔记
1. 常用标签 <launch> <!--根标签--> <node> <!--需要启动的node及其参数--> <include> < ...
- ros中launch文件使用与虚拟机中使用Livox avia
在home目录创建工作空间,并创建src,将要安装的代码解压放在src中,编译ros项目 ROS入门(四)编译ROS程序包_小鱼儿飞呀飞的博客-CSDN博客_ros包编译 使用launch前要 `so ...
- Ros学习——launch文件解析
launch文件的重点是:节点(node)元素的集合. roslaunch 则是让所有的节点共享同一个终端. 1.标签(元素)说明 1. group标签 2. node标签 <group ns= ...
- ROS:launch文件的语法规范
在ROS应用中,一般涉及多个节点,而每个节点又有很多参数需要设置.为了方便.高效地操作多个节点,可以编写 .launch 文件,然后用roslaunch命令运行. 注意:存储启动文件的目录不一定必须命 ...
- ROS运行launch文件报错
报错内容 RLException: Invalid roslaunch XML syntax: no element found: line 1, column 0. 解决方法 将launch文件关闭 ...
- ROS实战篇(二)如何创建自定义的msg文件以及自己编写launch文件?
一.如何创建自定义的msg文件? msg文件介绍: 1.msg文件是用来描述ROS中自定义的消息类型的,可以被不同语言调用. 2.msg文件以 .msg 结尾,必须存放在软件包的msg文件夹下. 3. ...
- ROS系统 launch启动文件的使用方法
launch文件:通过XML文件实现多节点的配置和启动(可以自动启动ROS Master) 使用步骤 选定功能包右击 -> 添加 launch 文件夹 选定 launch 文件夹右击 -> ...
- ros launch文件编写和节点启动顺序控制
ROS可以通过launch文件进行节点的管理.初始参数的设置,但是launch文件不能指定节点的启动顺序,因此本文简单介绍下通过launch进行节点启动管理,通过shell来控制节点启动顺序. 1,我 ...
最新文章
- 使用Keil语言的嵌入式C编程教程(下)
- 从事仪表专业学c语言有用吗,仪器仪表工程就业方向
- LeetCode LFU Cache
- 高仿百思不得姐项目开发(粗略笔记,后期规范排版和更新)
- 【采用】风控模型评估方法以及大数据风控模型概念
- 问题解决: 解释器错误: 没有那个文件或目录
- COGS-363-土地购买-斜率优化
- 屏蔽浏览器退格键页面后退
- 为何boss上的HR要了简历就不回复了?
- 泰坦尼克号的数据分析
- 【aws smart home】Aleax skill环境搭建
- 【MOOC】华中科技大学计算机组成原理慕课答案-第二章-数据表示
- ThinkPHP3.1.3 { Fast Simple OOP PHP Framework } — [ WE CAN DO IT JUST THINK ] 报错解决办法。...
- 深入理解MVCC实现原理以及当前读和快照读存在的问题
- html5 画猫全过程svg入门
- java证书验证失败_使用certbot证书验证失败
- 【面试高频】Java设计原则总结
- [SOA介绍]什么是SOA
- 网页收藏栏小图标_如何设置在网页地址栏中的小图标
- 这么设置USB Copy数据就能轻松备份到NAS