4.5 ROS话题名称设置

4.5 ROS话题名称设置

在ROS中节点名称可能出现重名的情况,同理话题名称也可能重名。

在 ROS 中节点终端,不同的节点之间通信都依赖于话题,话题名称也可能出现重复的情况,这种情况下,系统虽然不会抛出异常,但是可能导致订阅的消息非预期的,从而导致节点运行异常。这种情况下需要将两个节点的话题名称由相同修改为不同。

又或者,两个节点是可以通信的,两个节点之间使用了相同的消息类型,但是由于,话题名称不同,导致通信失败。这种情况下需要将两个节点的话题名称由不同修改为相同。

在实际应用中,按照逻辑,有些时候可能需要将相同的话题名称设置为不同,也有可能将不同的话题名设置为相同。在ROS中给出的解决策略与节点名称重命类似,也是使用名称重映射或为名称添加前缀。根据前缀不同,有全局、相对、和私有三种类型之分。

  • 全局(参数名称直接参考ROS系统,与节点命名空间平级)
  • 相对(参数名称参考的是节点的命名空间,与节点名称平级)
  • 私有(参数名称参考节点名称,是节点名称的子级)

名称重映射是为名称起别名,为名称添加前缀,该实现比节点重名更复杂些,不单是使用命名空间作为前缀、还可以使用节点名称最为前缀。两种策略的实现途径有多种:

  • rosrun 命令
  • launch 文件
  • 编码实现

本节将对三者的使用逐一演示,三者要实现的需求类似。

案例

在ROS中提供了一个比较好用的键盘控制功能包: ros-noetic-teleop-twist-keyboard,该功能包,可以控制机器人的运动,作用类似于乌龟的键盘控制节点,可以使用 sudo apt install ros-noetic-teleop-twist-keyboard 来安装该功能包,然后执行: rosrun teleop_twist_keyboard teleop_twist_keyboard.py,在启动乌龟显示节点,不过此时前者不能控制乌龟运动,因为,二者使用的话题名称不同,前者使用的是 cmd_vel话题,后者使用的是 /turtle1/cmd_vel话题。需要将话题名称修改为一致,才能使用,如何实现?


 

 

4.5.1 rosrun设置话题重映射

 

rosrun名称重映射语法: rorun 包名 节点名 话题名:=新话题名称

 

实现teleop_twist_keyboard与乌龟显示节点通信方案由两种:

 

1.方案1

 

将 teleop_twist_keyboard 节点的话题设置为

/turtle1/cmd_vel

 

启动键盘控制节点:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel

 

启动乌龟显示节点: 

rosrun turtlesim turtlesim_node

 

二者可以实现正常通信

 

2.方案2

 

将乌龟显示节点的话题设置为 

/cmd_vel

 

启动键盘控制节点:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

 

启动乌龟显示节点: 

rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel

 

二者可以实现正常通信

4.5 ROS话题名称设置 

 

4.5 ROS话题名称设置


 

 

4.5.2 launch文件设置话题重映射

 

launch 文件设置话题重映射语法:

<node pkg="xxx" type="xxx" name="xxx">
    <remap from="原话题" to="新话题" />
</node>

 

 

实现teleop_twist_keyboard与乌龟显示节点通信方案由两种:

 

1.方案1

 

将 teleop_twist_keyboard 节点的话题设置为/turtle1/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>

</launch>

 

 

二者可以实现正常通信

 

2.方案2

 

将乌龟显示节点的话题设置为 /cmd_vel

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

 

 

二者可以实现正常通信

 

4.5 ROS话题名称设置

4.5 ROS话题名称设置


 

4.5.3 编码设置话题名称

话题的名称与节点的命名空间、节点的名称是有一定关系的,话题名称大致可以分为三种类型:

  • 全局(话题参考ROS系统,与节点命名空间平级)
  • 相对(话题参考的是节点的命名空间,与节点名称平级)
  • 私有(话题参考节点名称,是节点名称的子级)

结合编码演示具体关系。

4.5 ROS话题名称设置

1.C++ 实现

演示准备:

1.初始化节点设置一个节点名称

ros::init(argc,argv,"hello")

2.设置不同类型的话题

3.启动节点时,传递一个 __ns:= xxx

4.节点启动后,使用 rostopic 查看话题信息

1.1全局名称(全局话题名称)

格式:以/开头的名称,和节点名称无关

比如:/xxx/yyy/zzz

示例1:ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000);

结果1:/chatter

示例2:ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money",1000);

结果2:/chatter/money

4.5 ROS话题名称设置

 

 

 

 

 

 

 

1.2相对名称(相对话题名称)

格式:非/开头的名称,参考命名空间(与节点名称平级)来确定话题名称

示例1:ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);

结果1:xxx/chatter

示例2:ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money",1000);

结果2:xxx/chatter/money

1.3私有名称(私有话题名称)

格式:以~开头的名称

示例1:

ros::NodeHandle nh("~");

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);

结果1:/xxx/hello/chatter

示例2:

ros::NodeHandle nh("~");

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money",1000);

结果2:/xxx/hello/chatter/money

PS:当使用~,而话题名称有时/开头时,那么话题名称是绝对的

示例3:

ros::NodeHandle nh("~");

ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money",1000);

结果3:/chatter/money

 

 

 

 

 

 

4.5 ROS话题名称设置

上一篇:[composer] composer dump-autoload 的加载优化


下一篇:21、Electron调用CSharpDll