在上一讲中我们是通过输入命令来启动节点的,这一讲我们通过launch文件。
在launch文件中我们可以进行启动节点,配置参数等等操作。而且调用launch文件自动启动主节点。
来看第一个例子:
<launch>
<node pkg="learning_topic" name="listener" type="person_subscriber" output="screen" />
<node pkg="learning_topic" name="talker" type="person_publisher" output="screen" />
</launch>
<launch> launch文件中的根元素用<launch>标签定义
<node>
- pkg:节点所在的功能包名称
- type:节点的可执行文件名称
- name:节点运行时的名称
上面代码的含义就是启动两个节点,一个是位于learning_topic包的person_subscriber节点,命名为listener,另一个是位于learning_topic包的person_publisher节点,命名为talker。这两个节点是之前用c++编写的程序。
catkin_ws目录下,在命令行输入以下代码
$ source devel/setup.bash
$ roslaunch learning_launch simple.launch
会自动启动主节点,并显示以下内容:
[ INFO] [1652769427.956043126]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1652769427.956932629]: Subcribe Person Info: name:Tom age:18 sex:1
终端输入:
$ rqt_graph
出现计算图:
可以看到节点talker发布话题person_info给节点listener,和我们取的节点名一致。
第二个例子:
<launch>
<param name="/turtle_number" value="2" />
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node">
<param name="turtle_name1" value="Tom" />
<param name="turtle_name2" value="Jerry" />
<rosparam file="$(find learning_launch)/config/param.yaml" command="load" />
</node>
<node pkg="turtlesim" type="turtle_teleop_key" name="turtle_teleop_key" output="screen" />
</launch>
<param>:设置ROS系统运行中的参数,存储在参数服务器中。
- name:参数名
- value:参数值
这里设置了值为2的参数/turtle_number。
<rosparam>:加载参数文件中的多个参数
这里用find查找learning_launch功能包,然后依次查找config目录,param.yaml文件,加载这个param.yaml文件。
param.yaml文件内容如下:
A: 123
B: "hello"group:
A: 456
D: "hello"
新打开终端输入,会列出与ros有关的参数
(base) jw@Z8:~/catkin_ws$ rosparam list
/rosdistro
/roslaunch/uris/host_z8__36559
/rosversion
/run_id
/turtle_number
/turtlesim_node/A
/turtlesim_node/B
/turtlesim_node/background_b
/turtlesim_node/background_g
/turtlesim_node/background_r
/turtlesim_node/group/A
/turtlesim_node/group/D
/turtlesim_node/turtle_name1
/turtlesim_node/turtle_name2
注意到虽然有两个参数A,但是他们是在不同命名空间中定义的。这样做可以避免参数名相同导致的混乱。
同样的,turtle_name和param.yaml都是在turtlesim_node这个命名空间中定义的,通过
<node>
</node>
来把turtle_name和param.yaml包含进来。
查看一些参数:
(base) jw@Z8:~/catkin_ws$ rosparam get /turtle_number
2
(base) jw@Z8:~/catkin_ws$ rosparam get /turtlesim_node/group/A
456
(base) jw@Z8:~/catkin_ws$ rosparam get /turtlesim_node/A
123
(base) jw@Z8:~/catkin_ws$ rosparam get /turtlesim_node/turtle_name1
Tom
第三个例子:
<launch>
<!-- Turtlesim Node -->
<node pkg="turtlesim" type="turtlesim_node" name="sim" />
<node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen" />
<node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" />
<node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf_broadcasrer" />
<node pkg="learning_tf" type="turtle_tf_listener" name="listener" />
</launch>
这个launch文件起到的作用和坐标变换那一讲的相同,只不过我们不用在终端一个一个启动节点。
前两行启动海龟仿真节点和键盘控制节点,中间两行启动海龟广播节点。最后一行启动监听器,监听海龟1的动作并给海龟2发布速度指令。
第四个例子:
<launch>
<include file="$(find learning_launch)/launch/simple.launch"/>
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node">
<remap from="/turtle1/cmd_vel" to="/cmd_vel"/>
</node>
</launch>
这个launch文件实现话题名的重映射。
第一行把simple.launch文件包含进来并启动其中的内容。
第二行启动仿真节点并把话题名/turtle1/cmd_vel重映射为/cmd_vel。
启动这个launch文件,出现:
[ INFO] [1654141528.764106252]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1654141528.764763836]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1654141529.764074149]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1654141529.764764776]: Subcribe Person Info: name:Tom age:18 sex:1
查看话题并发布速度指令
(base) jw@Z8:~/catkin_ws$ rostopic list
/cmd_vel
/person_info
/rosout
/rosout_agg
/turtle1/color_sensor
/turtle1/pose
(base) jw@Z8:~/catkin_ws$ rostopic pub /cmd_vel geometry_msgs/Twist "linear:
x: 2.3
y: 4.5
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0"
publishing and latching message. Press ctrl-C to terminate
可以发现/turtle1/cmd_vel不见了,而是出现了/cmd_vel,对/cmd_vel发布速度指令,海龟确实移动了,说明话题名的重映射成功了。