[ros-users] Writing generic subscription callbacks

Daniele Calisi daniele.calisi at gmail.com
Thu May 5 08:31:16 UTC 2011

On Wed, May 4, 2011 at 7:59 PM, Troy Straszheim <straszheim at willowgarage.com
> wrote:

> On Wed, May 4, 2011 at 10:07 AM, Daniele Calisi <daniele.calisi at gmail.com>wrote:
>> The problem comes when I try to write a generic subscriber: I tried with
>> this:
>>                 sub = new
>> ros::Subscriber(rosNodeHandle->subscribe(url.getPath(), 1000,
>> &RosAphModule::subscriptionCallback, this));
>> but this cannot be done, since the callback should be something like:
>> void RosAphModule::subscriptionCallback(const ros::Message::ConstPtr& msg)
>> that is not allowed, because ros::Message is an abstract type and the
>> compiler says what I paste at the end of this email... moreover, I would
>> like to know how to get the topic the message was coming from (given the
>> ros::Message& msg in the callback, I mean).
> Hey Daniele,
> Looks tricky indeed...   the compiler can only know which serialization
> method to instantiate if it knows what message type to expect via the type
> argument to subscribe<>.  For instance, there is no procedure by which a ros
> node, given an incoming message of unknown type, can look up a serialization
> method in a table, since this table does not exist.  If it did exist, there
> would be no  guarantee that it is complete, as the incoming message might
> have been generated by code that this node does not have access to.   Also,
> to do anything with this message one would then need to type-switch or
> something, which is quickly going to break down... there are just a lot of
> problems here that might be better addressed with an alternate design.
> So...  can I ask you to elaborate on how this will all fit together?
> Troy
Hi Troy, thanks very much for the answer.

You are saying that the DEserialization method (I can do what I want with
the publisher, the problem exists only with the subscriber) is instantiated
during the building process and not dynamically at run-time (i.e., ROS uses
C++ templating facilities). This could be good for efficiency reasons (how
much?), but I do not see the point of not having the
serializers/deserializers table. Of course you can build a node with a
publisher that uses serialization method A and a node with a subscriber, for
the same object, with a serialization method B (e.g., a different version of
the same object) and things are going to fail. Unmarshalling are usually
done (by Data Distribution Services and some other middleware software) by
checking object name, version, etc. and then decide how to deserialize. Here
it seems that ROS can check this meta information, but only to decide if it
is going to use the right deserializer or not. Moreover, how subclassing is
working here? If I send an object of class A to a subscriber of class B :
public A, what happens?

I think that, since you are just receiving a stream of bytes from the
network, it's up to the subscriber to convert that stream to what is right.
Finally, you are always "type-converting" a stream of bytes to an object, I
do not see the point of fearing this conversion, being that done statically
at building time, or dynamically with an smart unmarshalling system.

What am I missing here?

Thanks again for the discussion, I am new to ROS and I want to go in deep
detail :-).
Daniele "MadMage" Calisi
"Your limit is always a bit beyond"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ros.org/pipermail/ros-users/attachments/20110505/483c8567/attachment-0002.html>

More information about the ros-users mailing list