ROS机器人操作系统:从入门到放弃(三)ROS中的launch文件

ROS中的launch文件

  • 1.launch文件简介
  • 2.运行launch文件
    • 借助package路径启动launch文件
    • 直接用绝对路径启动launch文件
    • 添加参数
  • 3.launch文件格式
    • node 标签
    • remap 标签
    • include 标签
    • arg 标签
      • 在命令行中赋值
      • 在launch文件中赋值
    • param 标签
    • rosparam 标签
    • group 标签
  • 4.编写launch文件实例
  • 在example1里边新建一个名为launch的文件夹
  • 编写launch文件
  • 运行launch文件

1.launch文件简介

从ROS的角度看,机器人系统就是一堆node和topic(再添加一些parameter,service等)构成的网络(rosgraph),其中每个node都可以完成一定的功能。通常一个机器人运行时要开启很多node,如果一个一个的启动,比较麻烦。通过launch文件以及roslaunch命令可以一次性启动多个node,并且可以设置丰富的参数。
roalaunch命令运行时首先会检测系统的rosmaster是否运行,如果已经启动,就用现有的rosmaster;如果没有启动,会先启动rosmaster,然后再执行lanunch文件中的设置,一次性把多个节点按照我们预先的配置启动起来。需要注意的是,launch文件不需要再编译,设置好之后可以直接用上述方式运行。

2.运行launch文件

借助package路径启动launch文件

$ roslaunch pkg_name launchfile_name.launch

直接用绝对路径启动launch文件

$ roslaunch path_to_launchfile

添加参数

arg:=value: 如果 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 命令提供路径

3.launch文件格式

launch文件本质上是一种xml文件,可以在头部添加,在某些编译器中可以高亮显示关键字,方便阅读。
与其它xml格式的文件类似,launch文件也是通过标签(tag)的方式书写,主要的tag如下:

<launch>                <!--根标签-->
<node>                  <!--需要启动的node及其参数-->
<include>               <!--包含其他launch-->
<machine>               <!--指定运行的机器-->
<env-loader>            <!--设置环境变量-->
<param>                 <!--定义参数到参数服务器-->
<rosparam>              <!--加载yaml文件中的参数到参数服务器-->
<arg>                   <!--定义变量-->
<remap>                 <!--设定 topic 映射-->
<group>                 <!--设定分组-->
</launch>               <!--根标签-->

node 标签

<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或者Julia编写的,就可能是.py或者.jl,如果是c++编写的,就会文件编译之后的可执行文件的名字。
name:是节点启动之后的名字,将覆盖节点中init()赋予节点的名称,每一个节点都要有自己独一无二的名字。
注意:roslaunch不能保证node的启动顺序,因此launch文件中所有的node都应该对启动顺序有鲁棒性。
实际上中除了pkg,type,name之外还可以设置更多参数,如下:

<launch>
    <node
        pkg=""
        type=""
        name=""  
        respawn="true" 
        required="true"
        launch-prefix="xterm -e"
        output="screen"
        ns="some_namespace"
    />
</launch>

respawn:若该节点关闭,是否自动重新启动。
required:若该节点关闭,是否关闭其他launch文件中的所有节点。
launch-prefix:是否新开一个窗口执行。例如,需要通过窗口进行机器人移动控制的时候,应该为控制node新开一个窗口;或者node有些信息输出,不希望与其他node信息混杂在一起的时候。
output:默认情况下,launch启动node的信息会存入log文件中:/.ros/log/run_id/node_name-number-stdout.log,可以通过此处参数设置,令信息显示在屏幕上。
ns:将node归入不同namespace,即在node name前边加ns指定的前缀。

remap 标签

经常作为node tag的子tag出现,可以用来修改topic。简单地说,remap的作用就是方便同一个node文件被应用到不同的环境中,用remap从外部修改一下topic即可,不需要改变源文件。
remap的常见格式如下:

<node pkg="some" type="some" name="some">
    <remap from="origin" to="new" />
</node>

注意:如果这个remap是launch元素的一个child(子类),与node元素同一层级,并在launch元素内的最顶层,那么这个remap将会作用于后续所有的节点。

include 标签

这个标签的作用是将另外一个launch文件添加到本launch文件中,类似launch文件中的嵌套。
基本格式:

<include file="path-to-launch-file" />

上边的文件路径可以给具体路径,但是一般来说为了程序的可移植性,最好借助find命令给出文件路径:

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

上述命令中,$(find package-name) 等价于本机中相应 package 的路径。这样即使换了其他机子,只要安装了同样的 package,就可以找到对应的路径。

有时,另一个 launch 引入的 node 可能需要统一命名,或者具有类似特征的 node 名字,比如 /vehicle1/gps, /vehicle1/lidar, /vehicle1/imu,即 node 具有统一的前缀,方便查找。这可以通过设置 ns (namespace)属性来实现,命令如下:

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

arg 标签

声明一个参数的存在(每一个argument必须给它分配一个value(赋值))

在命令行中赋值

$ roslaunch package-name launch-file-name arg-name:=arg-value

在launch文件中赋值

<arg name="arg-name" default="arg-value" /> 
<arg name="arg-name" value="arg-value" />

这两行的唯一不同是:命令行可以覆盖default的值,但是不能覆盖 value 。

param 标签

与 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 中

param 可以是在 global scope 中,它的 name 就是原本的 name,也可以在某个更小的 scope 中,比如 node,那么它在全局的名字就是 node/param 形式.
例如在 global scope 中定义如下 param:

<param name="publish_frequency" type="double" value="10.0" />

再在 node scope 中定义如下 param:

 <node name="node1" pkg="pkg1" type="exe1">
    <param name="param1" value="False"/>
 </node>

如果用 rosparam list列出server 中的 param,则有:

/publish_frequency
/node1/param1   # 自动加上了 namespace 前缀

rosparam 标签

param 只能对单个 param 操作,而且只有三种:value, textfile, command 形式,返回的是单个 param 的内容。
rosparam 则可以批量操作,还包括一些对参数设置的命令,如 dump, delete 等

  • 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.

group 标签

如果要对多个 node 进行同样的设置,比如都在同一个特定的 namespace,remap 相同的topic 等,可以用 tag。在 group 中可以使用所有常见的 tag 进行设置,例如:

<group ns="wg2">
    <remap from="chatter" to="talker"/> # 对该 group 中后续所有 node 都有效
    <node ... />
    <node ... >
        <remap from="chatter" to="talker1"/> # 各个 node 中可以重新设置 remap
    </node>
</group>

4.编写launch文件实例

在example1里边新建一个名为launch的文件夹

编写launch文件

在launch文件夹里边新建一个名为example1.launch的文件,输入以下内容:

<!--example1.launch -->
<launch>
  <node
    pkg="example1"
    type="talker"
    name="talker1"
    launch-prefix="xterm -e"
    output="screen"
    />
  <node
    pkg="example1"
    type="listener"
    name="listener1"
    launch-prefix="xterm -e"
    output="screen"
    />
</launch>

运行launch文件

$ roslaunch example1 example1.launch

运行之后就会看到新生成的两个终端

你可能感兴趣的:(ROS机器人操作系统:从入门到放弃(三)ROS中的launch文件)