Problem with subscribing to a topic that contains slash
I noticed something weird that seems like a bug. When a subscriber listens to a topic that contains a slash and that a publisher advertises the "parent" topic (the part before the slash), then the subscriber changes the topic to what it listens to match the publisher.
Here is an example. I open three terminals that will exchange on topic /parent/child
.
Step 1: In Terminal 1, I start rostopic echo /parent/child
Step 2: In Terminal 2, I start rostopic echo /parent
Step 3: In Terminal 3, I start a node with publishers for /parent
and parent/child
Step 4: In Terminal 3, the node publishes on both topics
The result is that only the subscriber in Terminal 2 gets the message. In addition, rxgraph shows that Terminal 1 is then subscribing to /parent instead of /parent/child. In Terminal 1, I get this instead of the message: no field named [/child]
What's happening here?
Here is the code:
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "MyPublisher");
ros::NodeHandle nh("~");
ros::Rate oneSecond(1);
// Creates a publisher to see if it replicates the bug
ros::Publisher pubParent = nh.advertise<std_msgs::String>("/parent", 10);
// Waits for the subscribers to connect
oneSecond.sleep();
ros::Publisher pubChild = nh.advertise<std_msgs::String>("/parent/child", 10);
// Waits for the subscribers to connect
oneSecond.sleep();
std_msgs::String msgChild;
msgChild.data = "Hello World! (on /parent/child)";
pubChild.publish(msgChild);
ROS_INFO("Message published (on /parent/child)");
std_msgs::String msgParent;
msgParent.data = "Hello World! (on /parent)";
pubParent.publish(msgParent);
ROS_INFO("Message published (on /parent)");
// Waits for the user to manually stop the node (to give time to see the update in rxgraph)
ros::spin();
return 0;
}
Here is the info about the nodes:
Terminal 1:
Node [/rostopic_27422_1352897219007]
Publications:
* /rosout [rosgraph_msgs/Log]
Subscriptions:
* /parent [std_msgs/String]
Services: None
Pid: 27422
Connections:
* topic: /rosout
* to: /rosout
* direction: outbound
* transport: TCPROS
* topic: /parent
* to: /MyPublisher (http://dfki-benoit:33822/)
* direction: inbound
* transport: TCPROS
Terminal 2:
Node [/rostopic_27405_1352897218194]
Publications:
* /rosout [rosgraph_msgs/Log]
Subscriptions:
* /parent [std_msgs/String]
Services: None
Pid: 27405
Connections:
* topic: /rosout
* to: /rosout
* direction: outbound
* transport: TCPROS
* topic: /parent
* to: /MyPublisher (http://dfki-benoit:33822/)
* direction: inbound
* transport: TCPROS
Terminal 3:
Node [/MyPublisher]
Publications:
* /parent [std_msgs/String]
* /parent/child [std_msgs/String]
* /rosout [rosgraph_msgs/Log]
Subscriptions: None
Services:
* /MyPublisher/get_loggers
* /MyPublisher/set_logger_level
Pid: 27455
Connections:
* topic: /rosout
* to: /rosout
* direction: outbound
* transport: TCPROS
* topic: /parent
* to: /rostopic_27405_1352897218194
* direction: outbound
* transport: TCPROS
* topic: /parent
* to: /rostopic_27422_1352897219007
* direction: outbound
* transport: TCPROS
EDIT (12/12/12): Following the answer from @Dirk Thomas, I tried his Python script. The behavior that I observe is the following. If I start the standard Python listener and rostopic echo
, they both receive the messages on /parent/child
. However, if I start only rostopic echo
, then it "switches" to /parent
and tries to read the field /child
. In addition, rostopic echo
does not print the WARNING: topic [/parent/child] does not appear to be published yet
if the standard ...
What's the output of
rosnode info
on the two subscriber nodes?Does the subscription for 1 change in between the other steps? I cannot reproduce this with rostopic echo/pub. For me in step 4 both rostopic echo get the message.
No, the
rosnode info
for Terminal 1 does not change between steps, other than adding the publisher when I start it in Step 2. The subscriber in Terminal 1 thus starts on/eoi
.Can you reproduce the exact steps (after a roscore restart) using standard messages? This looks like a weird bug to me.
Ok, I'll come up with a minimal example that shows this behavior
I can confirm this by following step 1 and 2 and then
rostopic pub -r 5 /parent/ std_msgs/String -- "{data: Hello}"
. It only works after a roscore restart. When a publisher for /parent and /parent/child are present before the subscribers are started everything works fine.Either you are not allowed to have a topic at /parent while there is one at /parent/child (thus parent becoming a namespace) or this is a bug that should be filed. In any case something is wrong as I can get both subscriptions to run depending on the order. It should be always or never.
I think that's definitely a bug and should be filed. Even if that's desired behavior, it is not intuitive and at least a warning or error should be thrown. Nice catch...