# 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

// Waits for the subscribers to connect
oneSecond.sleep();

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

edit retag close merge delete

What's the output of rosnode info on the two subscriber nodes?

( 2012-11-12 05:09:39 -0600 )edit

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.

( 2012-11-12 05:17:56 -0600 )edit

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.

( 2012-11-13 02:41:58 -0600 )edit
1

Can you reproduce the exact steps (after a roscore restart) using standard messages? This looks like a weird bug to me.

( 2012-11-13 04:16:55 -0600 )edit

Ok, I'll come up with a minimal example that shows this behavior

( 2012-11-13 19:48:44 -0600 )edit

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.

( 2012-11-14 01:14:11 -0600 )edit
1

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.

( 2012-11-14 01:16:49 -0600 )edit
1

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

( 2012-11-14 01:18:17 -0600 )edit

Sort by » oldest newest most voted

As guessed by felix k before this is intended behavior of rostopic echo. It subscribes to parent topics and attempts to extract field names with that name from the messages.

When the subscription is performed in a node it will not auto magically subscribe to the parent topic. You can try the following Python script sub.py with the argument /parent or /parent/child instead of invoking rostopic: #!/usr/bin/env python import sys import rospy from std_msgs.msg import String def callback(data): rospy.loginfo(rospy.get_caller_id() + 'Incoming message: %s',data.data) rospy.init_node('listener', anonymous=True) rospy.Subscriber(sys.argv[1], String, callback) rospy.spin()

more

I added the results of an experiment with this script to the question. I'd be interested to know if you expected this behavior, or if something weird is going on.

( 2012-12-11 21:29:56 -0600 )edit

My guess: With the python subscriber the /full/topic is announced to the system, despite missing any publisher. The rostopic echo sees this (when started afterwards) and accepts it as the topic, therefore no warning.

( 2012-12-12 01:54:28 -0600 )edit

I think this happens because you can do a rostopic echo directly on a field (or a field of a field...) of a message topic, instead of echoing the full message.

I havn't looked into rostopic code but it might check that /parent/child isn't an existing topic, then strips it down to /parent beeing the topic and /child the message field. Though that topic also does not yet exist it might hang on that guess, therefore expecting named field in that topic's message.

Addendum: the conclusion would be not to start such an rostopic echo without registering the topic itself previously.

more

Your guess is also my guess. :-) However, it's probably not related to rostopic. This is a minimal example, but the real integrated system uses real nodes, no rostopic. The subscriber will also always be running (i.e. before the publisher). Temporary workaround: use topic /eoi_confirmation.

( 2012-11-15 01:56:18 -0600 )edit

## Stats

Seen: 1,518 times

Last updated: Dec 11 '12