对照运行的mav_path_plan.launch文件进行一个学习
(一)什么是roslaunch?
roslaunch是ROS提供的一个启动工具,它能够使得启动多个ROS节点的过程变得简单,同时也简化了ROS参数服务器进行参数设置的过程。roslaunch配置文件使用XML语言编写,文件以.launch为扩展名,放在package的launch文件夹下,最简单的launch文件可以仅包含几个节点。
(简单来说:launch文件就是可以同时启动多个节点,在一个XML格式的文件内将需要同时启动的节点一一罗列出来)
1.1 与rosrun的区别
rosrun只能运行一个节点, roslaunch可以同时运行多个节点。
1.2 使用launch文件
roslaunch的句法结构
roslaunch <package_name> <launch_file_name>
也可以同如下方法一样(即我运行mav_path_plan.launch文件)
roslaunch+launch文件的绝对路径。因为launch文件可以不被包含于package中,执行launch文件的绝对路径即可。
roslaunch '/home/lab/catkin_ws/src/rotors_simulator/rotors_gazebo/launch/mav_path_plan.launch'
(二)创建launch文件之 单独的节点元素
2.1 launch文件是XML文件,每个XML文件必须有一个根元素。而launch文件的根元素由一对launch 标签定义。
<launch>
...
</launch>
launch文件中的其他元素必须都在这一对标签之间。
开始为<launch>,结束为</launch>,注意有一个斜杠!!表示结束,这是配对的,有头必有尾。
2.2 launch文件的核心是一系列节点元素node elements,每个节点元素node element启动一个节点node。
一个node element包含三个必须的属性:pkg, type, name。
pkg和type属性指出ROS应该运行哪个pkg中的哪个node,注意:此处的type是可执行文件的名称,而name则是可以任意给出的,它覆盖了原有文件中ros::init指定的node name。
<node
pkg="package_name" type="executable_name" name="node_name"
/>
最后的“/”是必不可少的,表示一个节点的结束。
也可以写成<node pkg=”..” type=”...” name=”...”></node>,如果该节点中有其他标签,则必须使用这种形式。
(三)创建launch文件之 include
include element为包含其他launch文件,包括这些launch文件的所有节点nodes和参数parameters。
常用
<include file=”$(find package_name)/launch_file_name”/>
注意,执行该launch文件时,roslaunch会搜索该package下的所有子目录;因此,必须给出package_name。
**mav_path_plan.launch文件对应include部分
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find rotors_gazebo)/worlds/$(arg world_name).world" />
<!-- <arg name="debug" value="true"/> -->
<arg name="paused" value="true"/>
<!-- <arg name="gui" value="false"/> -->
<!-- <arg name="verbose" value="true"/> -->
</include>
注:开始为<include>,结束为</include>,注意有一个斜杠!!表示结束,这是配对的,有头必有尾。(与launch一样)
其中:<!-- <arg name="gui" value="false"/> -->表示注释,即<!-- < xxx xxx/> -->为注释。
(四)创建launch文件之 launch arguments
为便于launch文件重构,roslaunch支持launch arguments,即arguments或者args,类似于局部变量。
注意:尽管argument和parameter有时可互换,但他们在ROS中的意义完全不同。Parameters是ROS系统使用的数值,存在parameter server上,nodes可通过ros::param::get函数编程得到,用户可通过rosparam获取。与之不同,arguments仅在launch文件内部有意义,nodes不能直接获取它们的值。
(1)声明argument
<arg name="arg_name">
(2)指定argument的值
launch文件中的每个argument都必须有指定值。赋值方法有好几种。
第一种,在命令行赋值
$roslaunch package_name launch_file_name arg-name:=arg_value
第二种,在声明argument时赋值
<arg name="arg_name" default="arg_name"/>
<arg name="arg_name" value="arg_name"/>
上面两行的区别在于,命令行参数可以覆盖default,但是不能重写value的值。
**mav_path_plan.launch文件对应声明argument及赋值部分
<arg name="mav_name" default="firefly"/>
<arg name="world_name" default="basic"/>
<arg name="enable_logging" default="false" />
<arg name="enable_ground_truth" default="true" />
<env name="GAZEBO_MODEL_PATH" value="${GAZEBO_MODEL_PATH}:$(find rotors_gazebo)/models"/>
<env name="GAZEBO_RESOURCE_PATH" value="${GAZEBO_RESOURCE_PATH}:$(find rotors_gazebo)/models"/>
arg:参数 name:名字 default:赋值
如第一个:参数mav_name,赋值为firefly
env:环境 如环境为:GAZEBO_MODEL_PATH,可以在路径为rotors_gazebo/models中找到对应的GAZEBO_MODEL_PATH。(第二个环境也一样)
(3)获取变量值
一旦声明某个argument并赋值后,我们可以通过arg使用该argument.
$(arg arg-name)
如果该行出现,roslaunch将会用给定arg-name的值替换其左边的值(即赋值给左边)。
**mav_path_plan.launch文件对应获取变量值部分
<arg name="mav_name" value="$(arg mav_name)" />
(4)将argument值传给included launch文件
<include file="path-to-file">
<arg name="arg_name" value="arg_value"/>
......
</include>
若在launch文件中,launch文件及其包含的launch文件出现相同的arguments(参数),则需在launch文件及included launch文件中同时写:
<arg name="arg_name" value="$(arg arg_name)"/>
第一个arg_name表示include launch文件中的argument
第二个arg_name表示当前launch文件中的argument
其结果是指定的argument在当前launch文件及include launch文件中都有相同的值。
**mav_path_plan.launch文件对应argument值传给included launch文件部分
<include file="$(find rotors_gazebo)/launch/spawn_mav.launch">
<arg name="mav_name" value="$(arg mav_name)" />
<arg name="model" value="$(find rotors_description)/urdf/mav_with_vi_sensor.gazebo"/>
<arg name="enable_logging" value="$(arg enable_logging)" />
<arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
<arg name="log_file" value="$(arg log_file)"/>
</include>
(五)创建launch文件之 创建groups
group element可以再大型的launch文件中将指定的节点nodes组织起来。
它有两个用处:
其一,group可以将几个nodes放进同一个namespace
<group ns="namespace">
<node pkg=".." .../>
<node pkg=".." .../>
......
</group>
注意,如果group node已经有它自己的namespace,并且是relative name,那么该node的namespace是其relative name,并以group namespace为后缀。
**mav_path_plan.launch文件对应创建groups
<group ns="$(arg mav_name)">
....
</group>
其二,group可以同时启动或者终止一组nodes
<group if="0 or 1">
......
</group>
如果该属性的值是1,一切正常;如果该属性的值为0,那么group内所有的nodes都不会运行。
同理,除了if,还有unless。
<group unless="0 or 1">
......
</group>
注意,这些属性的合法值只有0和1。另外,group element中只能使用ns,if,unless这三个属性。
(六)创建launch文件之 remap重命名(重映射)
remap用于修改节点nodes当前使用的名称。
重映射相当于重命名,每次需提供一个原始的名字original name和一个新的名字new name。每次node节点使用它的original name, ROS client library都会将其替换为remap name重命名了的名字。
创建remap name两种方法:
1. 对于单个node,在命令行进行remap(remap对象可以是node,topic等)。
original-name:=new-name
如: $ rosrun turtlesim turtlesim_node turtle1/pose:=tim
2. 在launch文件内remap names,使用remap element
<remap from="original_name" to "new_name">
如果remap出现在launch文件开头,作为launch文件的子元素,则该remap将被用于后续所有的nodes;
如果remap作为某个node的子元素,则只用于该节点。
**mav_path_plan.launch文件对应remap重命名
<remap from="odometry" to="odometry_sensor1/odometry" />
</node>
其中<remap from ***/>与</node>配对。
注意:在ROS进行remap之前,remap的所有name,包括original和new names,都将被解析为global names。所以,remap之后所有的名字通常都是relative names。
上述部分有参考:ROS launch整理_turtlebot的博客-CSDN博客_roslaunchhttps://blog.csdn.net/fengmengdan/article/details/42984429
(七)创建launch文件之 group中的param
group标签中的param标签的作用等同于rosparam set命令
node标签中的param标签设置为该节点的子元素
在launch文件中也支持等同与rosparam load 功能的rosparam标签
用于一次性加载大量的参数到参数服务器中
<rosparam command="load" file="path-to-param-file" />
这里的file是.yaml类型,所需要设置的参数放到该文件中。
**mav_path_plan.launch文件对应 group中的param
<rosparam command="load" file="$(find rotors_gazebo)/resource/$(arg mav_name).yaml" />