roslaunch文件格式解析

374 阅读10分钟

roslaunch文件格式解析

roslaunch是ros中重要的概念,ros机器人系统是机器人系统就是一堆 node 和 topic (再添加一些 parameter, service 等)构成的网络(rosgraph),其中每个 node 都可以完成一定的功能。

使用ros launch可以一次性启动多个node相互关联并设置丰富的参数,是一种较好的结构。roslaunch 可以让所有的节点共享同一个终端。

一些网站

blog.csdn.net/qq_33444963… ROS笔记(一)xxx.launch文件详解

ros官方教程http://wiki.ros.org/ROS/Tutorials/Roslaunch%20tips%20for%20larger%20projects

关于ros的一些基本概念

Quick Overview of Graph Concepts 官方的一些解释

  • Nodes: A node is an executable that uses ROS to communicate with other nodes.
  • Messages: ROS data type used when subscribing or publishing to a topic.
  • Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages.
  • Master: Name service for ROS (i.e. helps nodes find each other)
  • rosout: ROS equivalent of stdout/stderr
  • roscore: Master + rosout + parameter server (parameter server will be introduced later)

ROS Node(节点)实际上只是ROS包中的一个可执行文件。ROS节点使用ROSclient(客户端)库与其他节点通信。节点可以publish or subscribe(发布或订阅)Topic(主题)。节点还可以提供或使用Service(服务)。

ROS client(客户端)库允许以不同编程语言编写的节点进行通信:

  • rospy = python client library python语言
  • roscpp = c++ client library C++语言

使用rosnode list可以查看当前运行的结点

ROS Topic(话题) 结点之间利用rostopic 话题进行通信 一个结点发布(publish)一个话题,另一个结点接收(subscribe)同样的话题来进行通信

可以利用rqt_graph来展示结点和话题之间的关系

rostopic命令可以让你了解关于topic的信息

  • rostopic bw     display bandwidth used by topic
    rostopic echo   print messages to screen
    rostopic hz     display publishing rate of topic    
    rostopic list   print information about active topics
    rostopic pub    publish data to topic
    rostopic type   print topic type
    

ROS Service

服务是节点相互通信的另一种方式。服务允许节点发送request请求并接收 response响应

rosservice命令可以了解ROS的 client/service框架

rosservice list         print information about active services
rosservice call         call the service with the provided args
rosservice type         print service type
rosservice find         find services by service type
rosservice uri          print service ROSRPC uri

rosparam

rosparam允许您在ROS[Parameter Server](wiki.ros.org/Parameter Server)上存储和操作数据。参数服务器可以存储整数、浮点、布尔、字典和列表。rosparam使用YAML标记语言进行语法。1是整数,1.0是浮点,1是字符串,true是布尔值,[1,2,3]是整数列表,{a:b,c:d}是字典。rosparam有许多可用于参数的命令,如下所示:用法:

rosparam set            set parameter
rosparam get            get parameter
rosparam load           load parameters from file
rosparam dump           dump parameters to file
rosparam delete         delete parameter
rosparam list           list parameter names

roslauch

原文 ros官方教程http://wiki.ros.org/ROS/Tutorials/Roslaunch%20tips%20for%20larger%20projects

使用2dnav_pr2包作为案例研究:

介绍:

机器人上的大型应用通常涉及多个互连节点,每个节点都有许多参数。二维导航就是一个很好的例子。2dnav_pr2应用程序由移动_基础节点本身、定位、地平面过滤、基础控制器和地图服务器组成。总的来说,还有几百个ROS参数影响这些节点的行为。最后,还有一些限制,例如,为了提高效率,地平面滤波应与倾斜激光器在同一台机器上运行。
roslaunch文件允许我们说出所有这些。给定一个正在运行的机器人,启动文件2dnav_pr2。2dnav_pr2软件包中的启动将提供机器人导航所需的一切。在本教程中,我们将介绍此启动文件以及使用的各种功能。
我们还希望roslaunch文件尽可能可重用。在这种情况下,可以在物理上完全相同的机器人之间移动,而无需更改启动文件。即使是从机器人移动到模拟器这样的改变,也只需几次改变即可完成。

roslaunch可以很好的做到这一点。

顶层组织结构 Top-level organization

这里有一个样例文件 (你可以在这个文件夹下找到

rospack find 2dnav_pr2/move_base/2dnav_pr2.launch”).

<launch>
  <group name="wg">
    <include file="$(find pr2_alpha)/$(env ROBOT).machine" />
    <include file="$(find 2dnav_pr2)/config/new_amcl_node.xml" />
    <include file="$(find 2dnav_pr2)/config/base_odom_teleop.xml" />
    <include file="$(find 2dnav_pr2)/config/lasers_and_filters.xml" />
    <include file="$(find 2dnav_pr2)/config/map_server.xml" />
    <include file="$(find 2dnav_pr2)/config/ground_plane.xml" />

    <!-- The navigation stack and associated parameters -->
    <include file="$(find 2dnav_pr2)/move_base/move_base.xml" />
  </group>
</launch>

此文件包括一组其他文件。每个包含的文件都包含与系统某个部分有关的节点和参数(可能还有嵌套的包含),例如定位、传感器处理和路径规划。

Tips:lauch文件应该简短,包括与应用程序子组件对应的其他文件的include,以及通常更改的ROS参数。

使用launch文件要考虑多方面,利用要在PR2 机器人上进行控制,首先需要运行一个roscore,然后启动一个特定于robot的启动文件,如pre。在pr2_alpha包中启动,然后启动2dnav_pr2.launch 可以使用一个launch文件来完成以上的工作而不是一个一个运行文件

这样做由如下的优缺点

优点:我们可以不用打开那么多的终端和launch文件
缺点:启动机器人启动文件将启动一个持续约一分钟的校准阶段。如果2dnav_pr2.launch文件包含机器人launch,那么每次我们杀死roslaunch进程(使用control-c)并将其恢复时,都会再次进行校准。
CON:一些2d导航节点要求在开始之前已经完成校准。Roslaunch在此时不能提供对节点启动顺序或时间的任何控制。理想的解决方案是通过等待校准完成,使节点按顺序地工作,但在此之前,将东西放入两个启动文件中,允许我们启动机器人,等待校准完成,然后启动2dnav。
因此,对于是否将内容拆分为多个启动文件,没有统一的答案。这里,决定使用两个不同的启动文件。
TIPs:在决定应用程序需要多少launch文件时,请注意权衡。

不同机器人的标签和环境变量Machine tags and Environment Variables

我们希望控制哪些节点在哪些机器上运行,以实现负载平衡和带宽管理。例如,我们希望amcl节点与基础激光器在同一台机器上运行。同时,为了可重用性,我们不想将机器名硬编码到roslaunch文件中。Roslaunch用 machine tags.处理这个问题。
第一个包括

<include file="$(find pr2_alpha)/$(env ROBOT).machine" />

关于这个文件,首先要注意的是使用env substitution参数来使用环境变量ROBOT的值。例如,可以用如下的命令

export ROBOT=pre

在roslaunch进行运行前会进行预处理。机器标签会被包含
Tips:使用env substitution参数允许启动文件的某些部分依赖于环境变量。
接下来,让我们看一个示例机器文件:pre。pr2_alpha包中的命名。

<launch>
  <machine name="c1" address="pre1" ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" default="true" />
  <machine name="c2" address="pre2" ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" />
</launch>

这两句话在逻辑机器名“c1”和“c2”与实际主机名(如“pre2”)之间建立映射。允许控制您登录的用户(假设您具有适当的ssh凭据)。
一旦定义了映射,就可以在启动节点时使用它。例如,包含的文件config/new_amcl_节点。2dnav_pr2包中的xml包含行<node

<node pkg="amcl" type="amcl" name="amcl" machine="c1">

这将导致amcl节点在逻辑名称为c1的机器上运行(查看其他启动文件,您将看到大多数激光传感器处理都放在这台机器上)。
当在一个新的机器人上运行时,比如说一个被称为prf的机器人,我们只需要改变机器人的环境变量。然后将加载相应的机器文件(pr2_alpha包中的prf.machine)。我们甚至可以通过将ROBOT设置为sim来在模拟器上运行。查看文件sim。在pr2_alpha包中,我们看到它只是将所有逻辑机器名映射到localhost。
Tips:使用机器标签来平衡负载和控制哪些节点运行在同一台机器上,并考虑机器文件名取决于环境变量的可重用性。

参数、命名空间和yaml文件Parameters, namespaces, and yaml files

下面看文件move_base。xml。以下是该文件的一部分:

<node pkg="move_base" type="move_base" name="move_base" machine="c2">
  <remap from="odom" to="pr2_base_odometry/odom" />
  <param name="controller_frequency" value="10.0" />
  <param name="footprint_padding" value="0.015" />
  <param name="controller_patience" value="15.0" />
  <param name="clearing_radius" value="0.59" />
  <rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
  <rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
  <rosparam file="$(find 2dnav_pr2)/move_base/local_costmap_params.yaml" command="load" />
  <rosparam file="$(find 2dnav_pr2)/move_base/global_costmap_params.yaml" command="load" />
  <rosparam file="$(find 2dnav_pr2)/move_base/navfn_params.yaml" command="load" />
  <rosparam file="$(find 2dnav_pr2)/move_base/base_local_planner_params.yaml" command="load" />
</node>

此片段启动move_base节点。包含的第一个元素是重新映射。Move_base设计用于接收话题topic为“odom”的里程计。对于pr2,里程计在pr2_base_里程计话题topic上发布,因此我们重新映射了它。

Tips:当给定类型的信息在不同的情况下发布在不同的话题topic上时,使用话题重映射topic remapping

然后是一堆标记。请注意,这些参数位于node元素内部(因为它们位于末尾的之前),因此它们将是私有参数。例如,第一个选项将move_base/controller_频率设置为10.0。
在元素之后,有一些元素。这些文件以yaml格式读取参数数据,yaml是一种人类可读的格式,允许复杂的数据结构。这是costmap_common_参数的一部分。由第一个元素加载的yaml文件:

raytrace_range: 3.0
footprint: [[-0.325, -0.325], [-0.325, 0.325], [0.325, 0.325], [0.46, 0.0], [0.325, -0.325]]
inflation_radius: 0.55

# BEGIN VOXEL STUFF
observation_sources: base_scan_marking base_scan tilt_scan ground_object_cloud

base_scan_marking: {sensor_frame: base_laser, topic: /base_scan_marking, data_type: PointCloud, expected_update_rate: 0.2,
  observation_persistence: 0.0, marking: true, clearing: false, min_obstacle_height: 0.08, max_obstacle_height: 2.0}

我们看到yaml允许向量之类的东西(对于footprint参数)。它还允许将一些参数放入嵌套的命名空间中。例如,base_scan_marking/sensor_frame设置为base_laser。请注意,这些名称空间相对于yaml文件自己的名称空间,反过来,由于节点元素包含该rosparam,因此参数的完全限定名为*/move_base/global_costmap/base_scan_marking/sensor_frame*.。
move_base中的下一行。xml是:

<rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />

与前面的元素不同,此元素没有ns属性。因此,yaml文件的名称空间是父名称空间/ /move_base。yaml文件的前几行:

local_costmap:
  #Independent settings for the local costmap
  publish_voxel_map: true
  global_frame: odom_combined
  robot_base_frame: base_link

因此,我们看到这些参数毕竟在 /move_base/local_costmap名称空间中。
Tips:Yaml文件允许使用复杂类型的参数、参数的嵌套名称空间以及在多个位置重用相同的参数值。

复用roslaunch文件 Reusing launch files

通过上面的示例,复用lauch文件是比较容易的。我们已经看到了一个示例,其中使用env substitution arg可以在不更改任何启动文件的情况下修改命令。然而,在某些情况下,这是不方便或不可能的。让我们来看看PR2J2DavaGaseBo包。这包含2d navigation app的一个版本,用于Gazebo模拟器。对于导航,在不同的静态地图环境下是我们使用不同的Gazebo,因此必须使用不同的参数加载map_server节点。我们本可以在这里使用另一种env替代品。但这需要用户设置一组环境变量,以便能够启动。相反,2dnav gazebo包含自己的launch文件,名为“2dnav stack amcl”。

<launch>
  <include file="$(find pr2_alpha)/sim.machine" />
  <include file="$(find 2dnav_pr2)/config/new_amcl_node.xml" />
  <include file="$(find 2dnav_pr2)/config/base_odom_teleop.xml" />
  <include file="$(find 2dnav_pr2)/config/lasers_and_filters.xml" />
  <node name="map_server" pkg="map_server" type="map_server" args="$(find gazebo_worlds)/Media/materials/textures/map3.png 0.1" respawn="true" machine="c1" />
  <include file="$(find 2dnav_pr2)/config/ground_plane.xml" />
  <!-- The naviagtion stack and associated parameters -->
  <include file="$(find 2dnav_pr2)/move_base/move_base.xml" />
</launch>

第一个区别是,因为我们知道我们在模拟仿真,所以我们只使用 sim.machine.文件,而不是使用替换参数。

第二,这一行

<include file="$(find 2dnav_pr2)/config/map_server.xml" />

被下面这行所替代

<node name="map_server" pkg="map_server" type="map_server" args="$(find gazebo_worlds)/Media/materials/textures/map3.png 0.1" respawn="true" machine="c1" />

与第二种情况一样,第一种情况中包含的文件只包含一个节点声明,但使用了不同的映射文件。

Tip:要修改应用程序的“lauch”温控按摩内容,请复制lauch文件并更改所需的部分。

参数覆盖Parameter overrides

全局变量的参数设置有时会变得不方便。假设我们想要使用2dnav_pr2节点,但需要将局部costmap的分辨率参数更改为0.5。我们可以在局部更改local_costmap_params.yaml文件。这是临时修改的最简单方法,但这意味着我们无法将修改后的文件签回。我们可以读取local_costmap_params.yaml文件并生成副本来修改它。然后我们就必须改变基地。xml以包含修改后的yaml文件。然后我们必须改变2dnav_pr2.launch 来include已修改的move_base.xml文件。这可能很耗时,如果使用版本控制,我们将不再看到对原始文件的更改。另一种方法是重新构造启动文件,以便在顶级文件2dnav_pr2中定义move_base/local_costmap/resolution参数。启动,并仅对该文件进行修改。如果我们事先知道哪些参数可能会改变,这是一个很好的选择。
另一个选项是使用roslaunch的覆盖行为:参数按顺序设置(在处理包含之后)。因此,我们可以制作一个覆盖原始分辨率的更高级文件:

<launch>
<include file="$(find 2dnav_pr2)/move_base/2dnav_pr2.launch" />
<param name="move_base/local_costmap/resolution" value="0.5"/>
</launch>

这样做的缺点是,这种方法会使代码理解起来变得复杂:要知道roslaunch为参数设置的实际值,需要通过包含roslaunch文件的文件进行跟踪。但它确实避免了必须复制多个文件。
Tips:要修改无法更改的启动文件树中的深度嵌套参数,请使用roslaunch的参数覆盖语义。

关于roslauch参数的一些争议 Roslaunch arguments

从CTurtle开始,roslaunch就有了一个参数替换功能,以及允许根据参数值调整启动文件部分的标记。与上面的参数覆盖机制或启动文件重用技术相比,这是一种更通用、更清晰的结构方式,代价是必须修改原始启动文件以指定可变参数。请参阅 roslaunch XML documentation.。

Tip:如果可以修改原始lauch文件,通常最好使用roslaunch参数,而不是参数重写或复制roslaunch文件。