How can I access all msg fields recursively in a message_generator?

Hallo,

I am trying to create a message_generator. For this purpose I need to access all message fields recursively until I reach the level of pure primitive types (for which I have basic templates). What I would like to do is to process all fields in a msggen.MsgSpec.parsed_fields() and for each of them that is not "is_builtin" I would like to get the corresponding msggen.MsgSpec class and go on in a recursive way. Does this make sense? How can I do this? Another possibility that I explored would be to use rosmsg.get_msg_text on the non-primitive types but this seems more complicated since I have to parse the message description myself. Thanks for your help.

Riccardo

edit retag close merge delete

Sort by » oldest newest most voted

I'm not exactly sure what you're trying to accomplish but I'd like to propose to take a look at the built-in "dir()" function in python. For example:

>>> from sensor_msgs.msg import LaserScan
>>> dir(LaserScan)
['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__getattribute__', '__getstate__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_check_types', '_connection_header', '_full_text', '_get_types', '_has_header', '_md5sum', '_slot_types', '_type', 'angle_increment', 'angle_max', 'angle_min', 'deserialize', 'deserialize_numpy', 'header', 'intensities', 'range_max', 'range_min', 'ranges', 'scan_time', 'serialize', 'serialize_numpy', 'time_increment']


This would give you the ability to "access all message fields recursively".

more

You might not need to iterate the msg fields recursively in the first place. It should be sufficient to iterate only the fields of the current message and for non-builtin field type invoke the serialization / deserialization function of the sub message (rather then implement it again within this message). At least that is the way gencpp, genpy and genlisp deal with it.

Update:

Pointing you to code might not be the best help since the message generator code / templates are everything but easy to read. You could look at the gencpp and genpy packages though.

What I am referring to is the following idea: for each built-in type you will have e.g. a serialize function:

serialize(bool)
serialize(int)


When you now want to serialize a Message Foo you will serialize all of its members like this:

serialize(Foo) {
serialize(my_bool_member)
serialize(my_int_member)
}


For a nested message you also only care about its member and not about their recursive fields because you will delegate the serialization of sub messages to there existing serialize implementation:

serialize(Bar) {
serialize(my_foo_member)
serialize(my_other_foo_member)
}

more

Hi Dirk. Thanks for the reply. Sorry but I am not quite sure that I understand how your solution should work. Can you please give me more details or point me to some documentation? I would really appreciate that. Thanks.

( 2014-04-25 05:18:11 -0500 )edit

after struggling for 2 days I found a solution (maybe) defining this method

def get_children_spec(base_type, search_path):
(package, name) = genmsg.names.package_resource_name(base_type)
return spec_temp


I would be curious to know if there is a better solution but for the moment I am happy with this.

more