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> 中除了 pkgtypename 之外还可以设置更多参数,如下:

<launch>
    <node
        pkg=""
        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_topicoutput_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 进行同样的设置,比如都在同一个特定的 namespaceremap 相同的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 名字前边都加上 nodenamespace


机器人的参数一般会提前设置好,这些参数都会放在 yaml 文件里,rosparam命令的方便之处在于它可以直接读取 yaml 文件中的参数,而不必自己找第三方库去文件中读取。

04 参考

  • 10
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建一个ROSlaunch文件,你可以按照以下步骤进行操作: 1. 首先,在你的ROS工作空间中找到你想要创建launch文件的功能包。可以使用命令`cd <workspace>/src/<package_name>`进入该功能包的目录。 2. 在功能包的目录下创建一个名为`launch`的文件夹。你可以使用命令`mkdir launch`来创建。 3. 进入`launch`文件夹,使用文本编辑器创建一个新的launch文件。你可以使用命令`touch <launch_file_name>.launch`来创建一个空的launch文件。 4. 打开这个新创建launch文件,并按照你的需求编写launch文件的内容。你可以参考ROSlaunch文件语法和示例来编写你的launch文件。在launch文件中,你可以指定要启动的节点、节点的参数配置以及节点之间的关系等。 5. 保存并关闭launch文件。 6. 现在,你可以使用`ros2 launch`命令来启动你的launch文件。使用命令`ros2 launch <package_name> <launch_file_name>`,将会启动整个系统,包括所有在launch文件中指定的节点和它们的配置。 总结起来,要创建一个ROSlaunch文件,你需要在功能包中创建一个名为`launch`的文件夹,并在其中创建一个launch文件。然后,按照你的需求编写launch文件的内容,并使用`ros2 launch`命令来启动该launch文件。 #### 引用[.reference_title] - *1* *3* [ROS2入门教程—创建一个launch文件](https://blog.csdn.net/qq_29923461/article/details/120404577)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [ROS学习(4)——launch文件的编写](https://blog.csdn.net/bulletstart/article/details/130794565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值