十八、ROS话题名称设置

文章目录

  • 1. ROS话题名称重映射
    • 1.1 简介
    • 1.2 实现方法
      • 1.2.1 rosrun设置话题重映射
        • 1.2.1.1 方案一
        • 1.2.1.2 方案二
      • 1.2.2 launch文件设置话题重映射
        • 1.2.2.1 方案一
        • 1.2.2.2 方案二
      • 1.2.3 编码设置话题名称
        • 1.2.3.1 C++实现
        • 1.2.3.2 Python实现

1. ROS话题名称重映射

1.1 简介

在ROS中,有时会出现话题名称重名现象,导致信息发布,接收不匹配;有时也需要话题名称不同的节点相互通信。这时,就需要使用话题名称重映射的方法来解决问题

1.2 实现方法

在ROS操作系统中,提供了ros-noetic-teleop-twist-keyboard键盘控制包,话题名为cmd_vel,在turtlesim功能包中,其键盘控制话题为/turtle1/cmd_vel,通过话题重映射,来实现二者的通信

1.2.1 rosrun设置话题重映射

  • 格式: rosrun 功能包 节点名 话题名:=新节点名

1.2.1.1 方案一

  • 目标: /cmd_vel 映射到 /turtle1/cmd_vel
  • 代码实现:
    bash1:启动乌龟节点
    rosrun turtlesim turtlesim_node 
    
    bash2:启动键盘控制节点,并进行映射
    rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel
    

1.2.1.2 方案二

  • 目标:/turtle1/cmd_vel 映射到/cmd_vel
  • 代码实现:
    bash1:启动键盘控制节点
    rosrun teleop_twist_keyboard teleop_twist_keyboard.py 
    
    bash2:启动乌龟节点,并进行话题映射
    rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel
    

1.2.2 launch文件设置话题重映射

  • 格式:
    <node pkg="" type="" name="">
        <remap from="原话题" to="新话题"/>
    node>
    

1.2.2.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="t2">
            <remap from="/cmd_vel" to="/turtle1/cmd_vel" />
        node>
    launch>
    

1.2.2.2 方案二

  • 目标:将turtlesim节点的话题名设置为/cmd_vel
  • 代码实现
    <launch>
        <node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="t1" />
        <node pkg="turtlesim" type="turtlesim_node" name="t2">
            <remap from="/turtle1/cmd_vel" to="/cmd_vel" />
        node>
    launch>
    

1.2.3 编码设置话题名称

  • 话题的名称与命名空间,节点的名称有关,按照所属关系不同,话题名称大致可分为三类(可以理解为在话题前加的前缀不同):
    • 全局:参考整个ROS系统,与命名空间平级
    • 相对:参考命名空间,与节点名平级
    • 私有:参考节点名,是节点的子级

1.2.3.1 C++实现

  1. 全局话题
  • 格式:已 / 开头
  • 代码实现:
    #include"ros/ros.h"
    #include"std_msgs/String.h"
    
    int main(int argc,char *argv[]){ 
        ros::init(argc,argv,"topic_name");
        ros::NodeHandle nh;
        //全局话题:在话题前加 / 
        ros::Publisher pub = nh.advertise<std_msgs::String>("/chtter",1000);
        //设置自己的命名空间
        ros::Publisher pub1 = nh.advertise<std_msgs::String>("/xxx/chtter",1000);
    
        while (ros::ok())
        {
        
        }
        return 0;
    }
    
  • 运行结果:
    bash1: 启动节点
    rosrun rename_01 topic_name
    
    bash2:查看话题列表
    rostopic list
    /chtter    //全局话题
    /rosout
    /rosout_agg
    /xxx/chtter     //加入了自己的命名空间
    
  1. 相对话题
  • 格式:非 / 开头的话题
  • 代码实现:
    #include"ros/ros.h"
    #include"std_msgs/String.h"
    
    int main(int argc,char *argv[]){ 
        ros::init(argc,argv,"topic_name");
        ros::NodeHandle nh;
        //全局话题:在话题前加 / 
        ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
        //设置自己的命名空间
        ros::Publisher pub1 = nh.advertise<std_msgs::String>("yyy/chatter",1000);
    
        while (ros::ok())
        {
        
        }
        return 0;
    }
    
  • 运行结果:
    bash1:启动节点,并加入命名空间
    rosrun rename_01 topic_name __ns:=xxx
    
    bash2:查看话题
    rostopic list
    /rosout
    /rosout_agg
    /xxx/chatter
    /xxx/yyy/chatter
    
  1. 私有话题
  • 格式: ros::NodeHandle nh(“~”);
  • 代码实现:
    #include"ros/ros.h"
    #include"std_msgs/String.h"
    
    int main(int argc,char *argv[]){ 
        ros::init(argc,argv,"topic_name");
        //私有话题,与NH结合使用,在其后加入~
        ros::NodeHandle nh("~"); 
        ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
        //若以 / 开头,则为全局话题
        ros::Publisher pub1 = nh.advertise<std_msgs::String>("/chatter",1000);
    
        while (ros::ok())
        {
        
        }
        return 0;
    }
    
  • 运行结果:
    bash1: 启动节点
    rosrun rename_01 topic_name __ns:=xxx
    
    bash2:查看节点列表
    rostopic list
    /chatter
    /rosout
    /rosout_agg
    /xxx/topic_name/chatter
    

1.2.3.2 Python实现

  • 代码实现:
    #! /usr/bin/env python
    
    from ast import Str
    import rospy
    from std_msgs.msg import String
    
    if __name__ == "__main__":
        rospy.init_node("topic_name_p")
        # 1.全局
        pub1 = rospy.Publisher("/chatter1",String,queue_size=10)
        # 设置自己的命名空间,不受 __ns:=xxx 的影响
        pub2 = rospy.Publisher("/zzz/chatter2",String,queue_size=10)
    
    
        # 2.相对
        pub3 = rospy.Publisher("chatter3",String,queue_size=10)
        # 设置自己的命名空间
        pub4 = rospy.Publisher("yyy/chatter4",String,queue_size=10)
    
    
        # 3.私有
        pub5 = rospy.Publisher("~chatter5",String,queue_size=10)
        # 设置自己的命名空间
        pub6 = rospy.Publisher("~ns/chatter6",String,queue_size=10)
        while not rospy.is_shutdown():
            pass
    
  • 运行结果:
    bash1:启动节点
    rosrun rename_01 topic_name_p.py __ns:=xxx
    
    bash2:查看节点列表
    rostopic list
    /chatter1
    /rosout
    /rosout_agg
    /xxx/chatter3
    /xxx/topic_name_p/chatter5
    /xxx/topic_name_p/ns/chatter6
    /xxx/yyy/chatter4
    /zzz/chatter2
    

你可能感兴趣的:(ROS学习笔记,ROS,c语言,c++)