我们在使用ros的过程中,经常会遇到发布的话题和想要订阅的topic不匹配的问题,但是我们写的明明是相同的名称,这一般是因为topic的命名空间不匹配导致的问题,本文将介绍自己一些关于topic命名空间的学习心得
1.首先是关于/符号的问题,我们经常看到有些发布的topic中有/,有些发布的topic没有/。符号/是指定当前发布的topic作用于全局
ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);
此时不管句柄是否私有化(句柄私有化后面会提),发布的话题都是/person_info
2.句柄私有化:
ros::NodeHandle n("~"); ros::NodeHandle n("~/bar");
上面两种写法都是句柄私有化的写法,区别是第一种写法没有声明句柄名,第二种写法声明了当前的句柄名是bar 。私有化的意思就是给当前的话题加上命名空间。
ros::init(argc, argv, "person_publisher");
上面代码声明的是节点名
对于私有化的句柄 发布的topic命名空间将会发生改变 /节点名/句柄名/话题名
3.如果launch文件中存在group群组的话,没有声明为全局的topic前面都会自动加上群组名
<group ns="aaa">
<node pkg="learning_topic" type="person_publisher" name="person_publisher">
<remap from="person_publisher/person_info" to="person_info"/>
</node>
</group>
/群组名( /节点名/句柄名 )/话题名
上面的例子 使用了remap进行话题映射 要注意如果句柄私有化了 原话题要完整的话题名才可以 映射后的话题因为在aaa的群组内 所以映射后的topic是/aaa/person_info
在一个群组内的订阅者订阅相应的topic不用加上群组名 不在一个群组内的订阅者订阅相应的topic要加上群组名
如果advertise的时候是全局话题,remap的原话题也要是全局话题,也就是要加上/
4.如果没有私有化句柄
ros::NodeHandle n;
ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("person_info", 10);
那么发布的默认是全局下的topic /person_info
5.python里面可以私有化topic,但是我目前在c++中私有化topic的时候会报错 形式如
("~/person_info", 10)