0
$\begingroup$

Rosanswers logo

Hello all.

As indicated by the quick response of catagay and Lorenz to my previous question here

http://answers.ros.org/question/38088/how-do-i-create-a-ros-topic-publishersubscriber/

I started reading up on how to create publishing and subscribing agents, on the ros tutorials page.

http://www.ros.org/wiki/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

Here is what I understood from the tutorial:

  1. The publisher in the example keeps on publishing forever.

  2. advertise<std_msgs::String>() is the harbinger of the topic to be published. So this step seems necessary.

  3. chatter_pub.publish(msg) is the guy who does the talking. Since he is in a while(ros::ok()), this will publish forever.

  4. The subscriber also keeps on subscribing forever.

  5. ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); tells the master to subscribe to the topic and call chatterCallback whenever there is a new message. Because of ros::spin(), however, this subscriber will continue listening to the topic and printing to the screen forever (till node dies, of course).

Based on these points, here are my related questions:

  1. Is my understanding enumerated in the points above right? Or am I missing something?

  2. What do you mean by "..call chatterCallback whenever there is a new message."? What does new message mean here? Does it mean that the function is called whenever the message on the topic is updated?

  3. Suppose the publisher wants to keep on publishing the topic forever, but the subscriber wants to get messages from the topic only at select locations in my code. Say I want the subscriber to listen to a topic, extract a string from the message, convert it to an integer using atoi() and then print to screen. But I want it to do this in a for loop, while a particular condition in it holds. Is this possible?

  4. Can I pass more arguments to the chatterCallback function? say instead of

void chatterCallback(const std_msgs::String::ConstPtr& msg);

I want it to be

void chatterCallback(const std_msgs::String::ConstPtr& msg, int &i, char c);

Is this possible? If yes, what changes do I need to reflect in the argument for the callback function for subscribe()?

5)I ask the above question (4) because I want some way, in which I can bring the result of all that I do in my callback function, into my main() function. Is there a way in which I can do this?

6)In the ROS tutorial I described above, there are the following few lines which escape my understanding. Any idea as to what they mean?

The message is passed in a boost shared_ptr, which means you can store it off if you want, without worrying about it getting deleted underneath you, and without copying the underlying data.

I somehow feel the above lines are related to my questions (4) and (5) above.

  1. What happens if I don't use ros::spin() at all, in my subscriber code? Does that mean that the callback is called only once then?

Thanks to Lorenz, I was able to view this question posted about 2 days ago and related to the same subject

http://answers.ros.org/question/37869/subscribing-and-publishing/

From joq's answer on this question, it seems that I need to manipulate the data in the callback function. But somehow, I don't understand how I can bring that effect back into main(). Any light shed on this matter would be greatly helpful.

Thanks for the patience to go through this long post! All views greatly appreciated.


Originally posted by Nishant on ROS Answers with karma: 143 on 2012-07-06

Post score: 5


Original comments

Comment by Nishant on 2012-07-06:
Thanks dornhege. In your response to (3), do you mean that being in the callback is like being in main() itself? Which means variables created and assigned values in the callback continue to exist in main()..?

Comment by dornhege on 2012-07-06:
No, the callback is just a function where you react on a new message and do whatever you want - including ignoring it by doing nothing.

Comment by dornhege on 2012-07-06:
It might help to split up multiple questions in different "question threads", otherwise there will be multiple mixed answers.

Comment by Nishant on 2012-07-06:
Your response to (5) is what I was really looking for. Also, I shall keep in mind to post multiple questions on different threads. I posted all in one, because I thought they were closely related. Thanks! :)

Comment by Nishant on 2012-07-06:
Thanks joq! Is that what Thomas D's comment means in the question I referred to above?

Comment by dornhege on 2012-07-07:
Yes, that is related.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

  1. In general, yes. Regarding 4) technically it is subscribed once and the callback is called as often as new messages arrive.

  2. for each message someone else publishes on the same topic, the callback is called.

  3. Once you are in the callback function, you are running your code. If you want to skip certain messages, or react to your own code, you can just return from the callback. There is also the possibility to unsubscribe() the subscriber and then the callback will not be called anymore.

  4. The answer to this is: use boost::bind. For your example this probably looks like this (unchecked):

    boost::bind(&chatterCallback, _1, boost::ref(i), c);

  5. Usually the callback would be preferred for structure. If you want to handle something in your main loop, you could either set some global variable currentMessage in you handler and use that or pass a reference to the (local) current message using boost::bind that is updated by the handler.

  6. You should read up on shared pointers to understand that meaning. In short: You can pass the pointer around as you like without this taking time, but you don't need to care about memory management.


Originally posted by dornhege with karma: 31395 on 2012-07-06

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by joq on 2012-07-06:
The usual solution to sharing information between a callback and other parts of your program is to define the callback as a class method. Then, it has access to all the class data.

Comment by mateo_7_7 on 2013-06-12:
as regard the point 3: how can i unsubscribe from a topic for, for instance, subscribe from another one using the same callback?

Comment by dornhege on 2013-06-12:
For unsubscribing the Subscriber class provides a shutdown() method. Subscribing from another one is just the same as normally, no need to do anything special.

Comment by mateo_7_7 on 2013-06-12:
the problem is that, to subscribe from another topic (chosen runtime) my subscriber should be defined in a scope that "lives" sufficiently for the process of reading from the topic (it is the reason, i think, the subscribers are define in the main, before the while) but, in the same time,

Comment by mateo_7_7 on 2013-06-12:
in a scope that gives me the possibility to update the topic (so a sort of loop)...i really don't know how to do that

$\endgroup$

Your Answer

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