Hacker News new | ask | show | jobs
by ticking 4106 days ago
The current serialisation code needs to die, and be replaced with something usable and already existing, e.g. zeromq + msgpack.

There are currently horrible bugs in the very foundation of ROS, the spec of the serialisation format and its hashing, that are in `wontfix` status because the maintainers are idiots.

The arity of a field (value, array [and its arity], list) is not part of the hash of a message definition. Thus it is possible to change a message definition breaking existing protocols without the clients noticing. This is a hard to detect bug, that I've seen several times in the wild. But it won't be fixed because it would break old precompiled packages (yes one would have to recompile things gasp). So instead everything is left broken.

But hey I heard they want to change the messaging protocol to CORBA for 2.0, what could go wrong with that...

1 comments

Well, my company uses ROS for two different robotic systems currently in production.

We use ros serialization quite intensively and I would have to say it "works fine". I previously came from a more enterprise-centered environment working with a rabitMQ/Protobuff&Json stack, so I probably wouldn't have created ROS serialization the way the maintainers did, but it hasn't gotten in our way at all.

I don't think it's that great of an idea to place too much validation in a serialization framework, as your are just asking for rigidity, which is why Json went the way they did and is much better for it.

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.