| I agree 100% with you. Rigidity is something you don't want, but this is something entirely different. ROS serialisation format is basically a C++ struct that gets send over the wire. You specify your .msg definition, tell the (horrible) build system that you want to use it, and the build system will compile it to deserialisation code in your language. During deserialisation of C/C++ this code will just try to recast the message from a void* buffer to a valid .msg struct. So O(1) message parsing, nice in theory, but also what causes the rigidity that makes it harder for dynamic languages that would easily be capable to deal with a self-encoding message format. But because you end up with this unsafe recasting "parser", you _really_ want to feed it what it expects, and this is why during tcpros handshake between two clients they will exchange hashes of the msg format that they speak. Note that this is fundamentally different from JSON where you are adding fields. JSON _will still work_, as long as the new message is a superset of the old one. But with ros msgs a command might end up putting your nice robotic arm into the table/human because you changed the LED from a green one to a multicoloured that has a field `color[3]` instead of `color`. The field will use up more space, and the field that came after it, say `arm-height`, will now have the color value in it. But we got the hash of messages to protect us from this right? NO! Because the build system does a half assed normalisation step on each .msg format in which it removes comments, reformats and reorders fields and tries to find the canonical _textual_ representation of messages.
Sadly somebody forgot to keep the arity (variable/tuple/list) in there. So it gets thrown out and is not part of the hash. Source: I build a ros-msg deserializer from scratch for clojure that can import message definitions at runtime, compiling them into ad-hock deserialisers. |