0
$\begingroup$

Rosanswers logo

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 listener was started before.

These observations mean that the presence of a standard listener changes the behavior of rostopic echo.

In my opinion, this is unintuitive and most importantly not "repeatable". It means that my scripts using rostopic echo would yield different results if my colleagues started some listeners on the ROS network, for example.


Originally posted by Benoit Larochelle on ROS Answers with karma: 867 on 2012-11-12

Post score: 1


Original comments

Comment by Lorenz on 2012-11-12:
What's the output of rosnode info on the two subscriber nodes?

Comment by dornhege on 2012-11-12:
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.

Comment by Benoit Larochelle on 2012-11-13:
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.

Comment by dornhege on 2012-11-13:
Can you reproduce the exact steps (after a roscore restart) using standard messages? This looks like a weird bug to me.

Comment by Benoit Larochelle on 2012-11-13:
Ok, I'll come up with a minimal example that shows this behavior

Comment by dornhege on 2012-11-14:
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.

Comment by dornhege on 2012-11-14:
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.

Comment by Lorenz on 2012-11-14:
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...

Comment by Benoit Larochelle on 2012-11-15:
I filed this issue: https://github.com/ros/ros_comm/issues/24

Comment by Benoit Larochelle on 2012-12-11:
I would suggest that rostopic echo take a -f option to list the fields to be displayed within a topic. Not providing this option would display all fields (standard current behavior)

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

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:

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()```



---

Originally posted by [Dirk Thomas](https://answers.ros.org/users/2575/dirk-thomas/) with karma: 16276 on 2012-11-21


This answer was **ACCEPTED** on the original site

Post score: 0

---

### Original comments

**Comment by [Benoit Larochelle](https://answers.ros.org/users/216/benoit-larochelle/) on 2012-12-11**:\
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.

**Comment by [felix k](https://answers.ros.org/users/606/felix-k/) on 2012-12-12**:\
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.
$\endgroup$
0
$\begingroup$

Rosanswers logo

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.

See the last example in the documentation.

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.


Originally posted by felix k with karma: 1650 on 2012-11-15

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by Benoit Larochelle on 2012-11-15:
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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.