ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

publisher/subscriber of the same topic on the same node

asked 2016-07-22 06:39:46 -0500

randaz gravatar image

Hi, it's not clear to me what is the default ROS behavior if I a have node which publishes and subscribes to the same topic. Are the published messages automatically received by the subscriber?

If the answer is yes, how I can prevent my node to re-read the messages that the node itself is publishing?

If the answer is no, how can I allow my node to read the messages that the node itself is publishing?

Thank you!

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2016-07-22 15:31:19 -0500

Chrissi gravatar image

I am not entirely sure what you are trying to achieve but I'll give it a try. From your question I see two possible ways you would like to use that:

You create a message in part of your node and want to process it in a different function:

publisher = rospy.Publisher("/mytopic", ...)
rospy.Subscriber("/mytopic", eggs, ...)

def spam():
    message.a = 1
    message.b = 2
    publisher.publish(message)

def eggs(msg):
    print msg.a + msg.b

If this is he case, I wouldn't know why you would transfer the message via a tcp connection instead of just calling the function directly if both spam and eggs are in the same node.

If you are trying to modify data on a topic and then republish it on the same topic:

publisher = rospy.Publisher("/mytopic", ...)
rospy.Subscriber("/mytopic", spam, ...)

def spam(msg):
    msg.a += 1
    publisher.publish(msg)

then this is completely ambiguous and you will create an endless-loop because spam will trigger itself by publishing. It might sound like a solid idea to take data on a topic, modify it and then send it off to a different compent which is supposed to work on the modified data:

msg.a = 1 ---> spam(msg) ---> msg.a = 2 ---> foo

The problem here is that spam does not consume the message. What you would actually get is that foo receives msg.a=1 and msg.a=2 while spam receives msg.a=2 and turns it into msg.a=3 which is then received by foo and spam and so forth.

I think the issue here is more conceptual. Messages on a topic are not consumed by the receiver and, therefore, you cannot receive and publish on the same topic without creating an endless-loop. Every other behaviour would be completely counter intuitive. Also, you cannot choose which messages to receive and which to ignore.

Solution: create a different topic for one of them via remapping either the incoming or the outgoing topic.

Hope that answers your question.

edit flag offensive delete link more

Comments

1

Also, you cannot choose which messages to receive and which to ignore.

that's not entirely true. You could check the name of the publishing node by using a ros::MessageEvent, and ignore your own.

Brittle though.

gvdhoorn gravatar image gvdhoorn  ( 2016-07-23 00:52:35 -0500 )edit

I think the issue here is more conceptual.

That could certainly be true. Perhaps this is an xy-problem. But we'd need more information to determine that.

gvdhoorn gravatar image gvdhoorn  ( 2016-07-23 00:53:14 -0500 )edit

I agree that you could find out who sent the message but then every node on that topic would have to know which nodes are publishing and which to ignore. That is indeed quite brittle as well as soon as you adopt this paradigm and keep adding publishers to the same topic.

Chrissi gravatar image Chrissi  ( 2016-07-23 03:54:15 -0500 )edit
1

No -- every node would (trivially) have to be able to identify itself and ignore only those messages.

kramer gravatar image kramer  ( 2016-07-23 08:42:50 -0500 )edit

Sure, but that only works if every node is supposed to work with all the messages from the other nodes. Say node 3 would have to use the messages of node 1 and node 2. So you cannot just modify and expect the receiving nodes only to get the modified message.

Chrissi gravatar image Chrissi  ( 2016-07-23 15:45:46 -0500 )edit
1

answered 2016-07-23 10:41:04 -0500

kramer gravatar image

It seems to me that the heart of your question is: what happens when a message is published (on a specific topic)?

The behind-the-scenes ROS machinery communicates that data to all subscribers for that topic. Whether a subscriber is in the same node (i.e., computational process), in a different node on the same machine, or in a different node on a totally different machine, the message will be put in a subscriber node's callback queue for processing. Message reception is independent of the message's source and/or location.

To ignore a message that originated within the same node requires a means of identifying the source of the message. One way to do this, as noted by @gvdhoorn in the comments of another answer, is to query the MessageEvent for the node name. Another would be to add that information to the message data.

One scenario where this might be useful is in a robotic swarm application where data needs to propagate to all agents, but individual agents have incomplete global information. Agents re-broadcast events from other agents to their neighbors upon first receiving them. But to avoid network storms, an agent needs to not re-broadcast messages it's already seen and not re-broadcast messages for which it is the originator.

Note that it's not clear to me that one would use ROS for this, rather than custom, highly optimized and specialized software. Furthermore, I'm not familiar with the literature for network data propagation -- I'm sure this has been covered in sensor network and smart dust research.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-07-22 06:39:46 -0500

Seen: 3,400 times

Last updated: Jul 23 '16