ROS中的重名问题

一、节点重名

  1. 问题介绍
    概念:在ROS系统中节点是最为基本的概念,在创建节点时,例如使用C++语言进行初始化,需要通过指定API定义节点名称,而如果存在重名节点,那么在调用时就会出现问题;
    实际情况:在ROS中重名节点启动时,会直接关闭之前已经存在的节点,提示如下:
[ WARN] [1578812836.351049332]: Shutdown request received.
[ WARN] [1578812836.351207362]: Reason given for shutdown: [new node registered with same name]

解决策略:
使用命名空间:添加前缀
名称重映射:重新起名
对于上述两种策略,实现途径有三种方法:rosrun命令、launch文件与编程实现,本文将一一进行分析介绍

  1. 解决方法
    1)rosrun
    设置命名空间: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

2)launch
在先前的launch文件解析教程中,我们提到了node标签的两个属性,name和ns,通过设置这两个属性就可以轻松实现上述两种策略;

<launch>

    <node pkg="turtlesim" type="turtlesim_node" name="t1" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1" ns="xxx"/>

launch>

3)c++
设置命名空间:

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);

二、话题重名

  1. 问题介绍
    相比于节点,ROS中的话题当然也存在重名问题,但是会更加复杂一些,因为在实际的应用中 ,话题名的设置相对灵活,需要灵活修改。
    解决策略:与节点重名相同,基本的策略仍旧是重映射和前缀两种方法,区别在于这里的前缀种类很多,可以分为以下三种:
    全局前缀:参考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
2. 解决方法
1)rosrun
主要使用名称重映射方法,通过如下指令实现便捷修改话题名
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

2)launch
同样,通过launch文件中node中的remap可以实现话题重映射

<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>

3)c++
对于C++的解决办法,主要采用添加前缀的办法,而不同的名称,添加的前缀不同:
前提:设置节点名称为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

三、参数重名

  1. 问题介绍
    概念:与先前不同,参数名称也会出现重名覆盖问题,但是解决办法大多只有添加前缀的办法;
    解决办法:在参数生成时,本质上都会带有一定的前缀,前缀种类同话题的三种,本文将会一一介绍;
  2. 解决方法
    1)rosrun
    采用rosrun启动节点,可以通过如下指令设置:

rosrun 功能包名 节点名 _参数名:=参数值

实例:自动添加节点前缀(私有模式):

rosrun turtlesim turtlesim_node _A:=100
// 查看对应参数信息
/turtlesim/A

2)launch
两种方法:
node标签外设置参数:全局性质

<launch>

    <param name="p1" value="100" />
    <-- 结果:/p1 -->

</launch>

node标签内设置参数:私有性质

<launch>

    <node pkg="turtlesim" type="turtlesim_node" name="t1">
        <param name="p2" value="100" />
    </node>
     <-- 结果:/t1/p2 -->

</launch>

3)c++
对于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

NodeHandle:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值