在上一篇博客中,我们对于ROS的文件管理系统进行了层次分析,并研究了工作空间覆盖以及不同主机之间的通信问题,本节内容主要转换方向,来考虑ROS系统中的存在的诸多重名问题,例如节点重名、话题重名、参数重名等。
[ WARN] [1578812836.351049332]: Shutdown request received.
[ WARN] [1578812836.351207362]: Reason given for shutdown: [new node registered with same name]
- 使用命名空间:添加前缀
- 名称重映射:重新起名
对于上述两种策略,实现途径有三种方法:rosrun命令、launch文件与编程实现,本文将一一进行分析介绍
rosrun 功能包名 节点名 __ns:=/新节点名
rosrun turtlesim turtlesim_node __ns:=/xxx
rosrun turtlesim turtlesim_node __ns:=/yyy
rosrun 功能包名 节点名 __name:=新节点名
rosrun turtlesim turtlesim_node __name:=t1 | rosrun turtlesim turtlesim_node /turtlesim:=t1
rosrun turtlesim turtlesim_node __name:=t2 | rosrun turtlesim turtlesim_node /turtlesim:=t2
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1" />
<node pkg="turtlesim" type="turtlesim_node" name="t1" ns="xxx"/>
launch>
std::map<std::string, std::string> map;
map["__ns"] = "xxxx";
ros::init(map,"test_node");
ros::init(argc,argv,"test_node",ros::init_options::AnonymousName);
- 全局前缀:参考ROS系统,与命名空间平级
- 相对前缀:参考命名空间,与节点名称平级
- 私有前缀:参考节点名称,位于节点名称之下
sudo apt install ros-noetic-teleop-twist-keyboard
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rosrun turtlesim turtlesim_node
cmd_vel
,后者(显示节点)是/turtle1/cmd_vel
rosrun 功能包名 节点名 话题名:=新话题名
示例如下:
rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel
rosrun turtlesim turtlesim_node
// 或者相反
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1" />
<node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key">
<remap from="/cmd_vel" to="/turtle1/cmd_vel" />
</node>
<-- 注释:相反的解决办法 -->
<node pkg="turtlesim" type="turtlesim_node" name="t1">
<remap from="/turtle1/cmd_vel" to="/cmd_vel" />
</node>
<node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key" />
</launch>
- 前提:设置节点名称为tsnode,启动节点时添加空间前缀:xxx
- 全局名称:
//以/开头的名称,与节点名称无关 ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000); //结果:/chatter
- 相对名称:
//非/开头的名称,参考工作空间确定话题名 ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000); //结果:xxx/chatter
- 私有名称:
//以~开头的名称,添加工作空间和节点名前缀 ros::NodeHandle nh("~"); ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000); //结果:/xxx/tsnode/chatter
rosrun 功能包名 节点名 _参数名:=参数值
rosrun turtlesim turtlesim_node _A:=100
// 查看对应参数信息
/turtlesim/A
<launch>
<param name="p1" value="100" />
<-- 结果:/p1 -->
</launch>
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1">
<param name="p2" value="100" />
</node>
<-- 结果:/t1/p2 -->
</launch>
对于C++编程来说,通过API:param::set或者NodeHandle实现:
paramset:
ros::param::set("/set_A",100); //全局,和命名空间以及节点名称无关
ros::param::set("set_B",100); //相对,参考命名空间
ros::param::set("~set_C",100); //私有,参考命名空间与节点名称
//结果
/set_A
/xxx/set_B
/xxx/yyy/set_C
ros::NodeHandle nh;
nh.setParam("/nh_A",100); //全局,和命名空间以及节点名称无关
nh.setParam("nh_B",100); //相对,参考命名空间
ros::NodeHandle nh_private("~");
nh_private.setParam("nh_C",100);//私有,参考命名空间与节点名称
//结果
/nh_A
/xxx/nh_B
/xxx/yyy/nh_C