ROS launch启动文件

若如初见. 提交于 2019-12-28 02:01:53

启动文件(launch)

下面的命令可以启动单个节点(首先需要roscore运行节点管理器)

rosrun package_name executable_file_name 

但是如果是比较大型的项目需要启动许多节点,使用rosrun命令显然效率太低,幸好ros提供了同时启动节点管理器(master)和多个节点的途径。

创建测试实例

创建工作空间

mkdir -p ~/test/src    //工作区目录
cd ~/test/src
catkin_init_workspace	//初始化工作区
cd ../
catkin_make

创建功能包( 在~/test/src文件夹下)

source ~/test/devel/setup.bash
catkin_create_pkg launch_test roscpp
cd launch_test
mkdir src

创建节点(存放在launch_test/src下)
launch_test_adv_node.cpp

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <string>
int main(int argc, char** argv){
	ros::init(argc,argv,"launch_test_adv_node");
	ros::NodeHandle nh;
	ros::Publisher launch_test_pub = nh.advertise<std_msgs::String>("launch_test",1000);
	std_msgs::String test;
	std::string o = "ros_launch_test: hello world, recieve count: ";
	int count = 1;
	ros::Rate rate(1);
	while(ros::ok){
		test.data = o + std::to_string(count++);
		launch_test_pub.publish(test);
		
		rate.sleep();
	}
	return 0;
}

launch_test_sub_node.cpp

#include <ros/ros.h>
#include <std_msgs/String.h>

void launch_sub_testCall(const std_msgs::String msg){
	ROS_INFO_STREAM(msg.data);
}
int main(int argc, char** argv){

	ros::init(argc,argv,"launch_test_sub_node");
	ros::NodeHandle nh;
	ros::Subscriber launch_test_sub = nh.subscribe<std_msgs::String>("launch_test",1000,launch_sub_testCall);	
	ros::spin();
	
	return 0;
}

创建启动文件(.launch文件)

ros的launch文件是xml格式,里面罗列了需要同时启动的一组节点。其基本格式为

<launch>
	<node pkg="" name="" type="">
	</node>
	...
</launch>

这是最基本启动文件的格式,至少包含一个节点,并且节点至少有pkg,name,type三个属性,关于launch文件中node标签的具体属性和子标签,我们下面会介绍。
我们在launch_test功能包的根目录下创建launch文件夹存放启动文件,并在launch文件夹中创建名为launce_test.launch的启动文件,内容为:

<launch>
	<node pkg="lanunch_test" type="launch_test_adv_node" name="launch_test_adv_node" />
	<node pkg="lanunch_test" type="launch_test_sub_node" name="launch_test_sub_node" />
</launch>

这样我们通过运行,至于pkgtypetype内容为什么这么写,接下来介绍。

roslaunch launch_test launch_test.launch

便可以一次启动两个节点,其中中间的launch_test代表功能包名称 launch_test.launch代表功能包下面的启动文件的名称。

node标签的属性

node标签英文文档介绍

pkg=“package_name”

节点所在的功能包名称

type=“node_type”

节点所在的cpp文件对应的可执行文件名字。即在对应CMakeLists.txt中生成的对应可执行文件的名字:

add_executable(abc ABC.cpp)

如果节点所在的cpp文件生成的可执行文件名为abc,则有type="abc".

name=“node_name”

name 属性给节点指派了名称, 它将覆盖任何通过调用 ros::int来赋予节点的名称,注意节点名称不能有命名空间。可通过ns属性赋值命名空间。

ns=“namespace” (可选)

设置命名空间可以避免节点使用默认命名空间。

output=“log|screen”(可选)

如果output="screen",则节点里的stdout和stderr会被发送到屏幕;
如果output="log",则stdout和stderr会被保存到$ROS_HOME/log/run_id/node_name-number-stout.log下的日志文件,stderr同时会从屏幕输出,默认为"log"1.

respawn=“true”(可选, 默认: False)

如果节点退出自动重启节点。

respawn_delay=“30” (可选, 默认0)

如果respawn是true,如果尝试重启节点失败,等待respawn_delay秒之后重试

required=“true”(可选)

如果节点退出,结束整个roslaunch。

Launch-prefix=“command-prefix”

使用 roslaunch 的一个缺点是所有的节点共享一个终端,有时候我们需要单独一个节点使用一个终端,这时候Launch-prefix属性就发挥作用了。roslaunch 在启动节点时的内部工作原理是调用相应的命令行工具,即 rosrun。启动前缀的主要思想是在其命令行前面添加给出的命令行前缀。对节点元素使用启动前缀,比如launch-prefix=”xterm -e”,在这个属性的作用下,节点元素和在命令行中输入下面的命令基本上是等价的:

xterm –e rosrun turtlesim turtle_teleop_key

xterm 命令将打开一个简单终端窗口。参数-e告诉 xterm 在新打开的终端中执行该命令行的剩余部分。
启动前缀属性并不只局限于xtrem。该属性也可以用来调试(通过gdbvalgrind)或降低一个进程的优先级(通过nice) 。

node标签的元素

remap

每个重映射包含一个原始名称和一个新名称。每当节点使用重映射中的原始名称时,ROS客户端库就会将它默默地替换成其对应的新名称。
在启动文件内使用重映射(remap):

<remap from=”original-name”to ”new-name”/>

如果该属性在顶层,即作为 launch 元素的子元素出现,重映射将会应用到所有的后续节点。这些重映射元素也可以作为一个节点元素的子元素,如:

<launch>
	<arg name="namespace" default="a4zhangfei" />
	<node pkg="lanunch_test" type="launch_test_adv_node" name="launch_test_adv_node" ns="sim1" output="screen">
		<remap from="launch_test" to="$(arg namespace)/launch_test" />
	</node>
	<node pkg="lanunch_test" type="launch_test_sub_node" name="launch_test_sub_node" ns="sim1" output="screen" />
</launch>

launch_test_adv_node节点内会将launch_test映射为/sim1/a4zhangfei/launch_test

param

见下,参数服务器

启动参数(argument)

启动参数有两种形式:

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

两者的唯一区别在于命令行参数可以覆盖默认值 default,但是不能覆盖参数值 value。
命令行参数

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

获取启动参数:

$(arg arg-name)

每个该替换出现的地方,roslaunch 都将它替换成参数值。

参数服务器(parameter)

参数服务器( parameter server )维护一个变量集的值,包括整数、浮点数、字符串以及其他数据类型,每一个变量用一个较短的字符串标识 。由于允许节点主动查询其感兴趣的参数的值,它们适用于配置那些不会随时间频繁变更的信息。需要铭记的是,所有的参数都属于参数服务器而不是任何特定的节点。这意味着参数——即使是由节点创建的——在节点终止时仍将继续存在。
查看参数列表

rosparm list

查询参数

rosparam get parameter_name

查询某个命名空间下的参数

rosparam get namespace

命令行设置参数

rosparam set parameter_name parameter_value

创建和加载参数文件
为了以 YAML 文件的形式存储命名空间中的所有参数,可以使用 rosparam dump 命令:

rosparam dump filename namespace

与 dump 相反的命令是 load,它从一个文件中读取参数,并将它们添加到参数服务器:

rosparam load filename namespace

在启动文件中设置参数

<param name="param-name" type="" value="param-value" />

其中type可填内容为

"str|int|double|bool|yaml"(可选)

设置私有参数
另一个可选方法是在节点元素中包含 param 元素:

<node ...>
	<param name="param-name" type="param-type" value="param-value" />
		...
</node>

在该结构下,参数名将被当做该节点的私有名称。
在文件中读取参数
启动文件也支持 与rosparam load等价的命令,可以一次性从文件中加载多个参数:

<rosparam command="load" file="path-to-param-file" />

这里列出的参数文件通常是通过 rosparam dump 命令创建的。使用查找替换来指定功能包的相对路径是常见做法:

<rosparam command="load" file="$(find package-name)/param-file" />

尽 管 在 计 算 机 领 域 术 语 中 很 多 情 况 下 prarmeter 和argument 都是可以互换的,但是在 ROS 中,二者的含义是非常不同的。parameter 是运行中的 ROS 系统使用的数值,存储在参数服务器(parameter server)中,每个活跃的节点都可以通过 ros::param::get 函数来获取 parameter 的值,用户也可以通过 rosparam 来获得 parameter 的值。而 argument 只在启动文件内才有意义;他们的值是不能被节点直接获取的。


  1. 在当前版本的 roslaunch 中 ,标准错误(包括控制台中的 ERROR 和 FATAL 级别的日志消息)的输出是显示在控制台上的,而不是在记录文件中。然而, roslaunch 源代码的注释中标明将在今后对这一点做出改变。 ↩︎

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!