Let's Make Robots!

LMR Bot Communication Protocol*

My xmos project proposal included (rather, was refined to include) a communications library to make it easier for the robots to share map data. Then BOA mentioned a communication protocol to allow different peoples' robots to communicate as well. That is a pretty damn good idea, so here's a forum topic to discuss and finalize said protocol. While I really should be thinking about is SLAM, this thought is occupying my thoughts today instead...I figure if I start a post and my current thoughts maybe I can get back to other things.

Those interested in working on or using this protocol, please chime in, and feel free to trash talk my ideas. Keep in mind I'm neither an engineer nor a technical writer, so this'll be ugly ;)

I'm thinking that there doesn't really need to be a defined set of functions to act upon. Instead I'd like to see something where the talking micro spits out ($address_of_receiver, $command, $data) or something. A receiving micro looks at the packet(s), says "hey, I have a hook implemented for $command" and runs it with passed data. That way a whole command set does not have to be implemented in the library, and each user/programmer can implement whatever functions they want. Ya, it'd require extra communciation between bot builders as to who may or may not have implemented what and how, but that's not a bad thing.

That said, some commands do need to be explicitly defined. For example, "command 0" could be "Hi, my name is $name. Anybody there?". 1 could be "Hi, $sender_name, I'm $name". etc... so they're the same across all receivers.

We need to define how a command is defined and called. Maybe just a simple hex byte would be enough? 0xFF would give 256 possible commands. With however many required/predefined commands, we're looking at 200+ available for user definition. If 200+ isn't enough we could even go with a two-byte system, sending High and Low bytes and have over 65000 commands available.

An example conversation as described above could be:

  • BOA's bot sendPacket(0x00, "BOABot");
  • My bot sendPacket(0x01, "RudBot");
  • Voodoo's bot sendPacket(0x01, "VooBot");
  • // BOABot knows two bots are listening. RudBot knows of BOABot, VooBot knows of BOABot, but RudBot and VooBot don't know about each other. Yet
  • BOABot sendPacket(0x32, "wifi");  // BOA has defined 0x32 as "Anybody seen a wifi spot?", with a code key of "wifi"
  • RudBot sendPacket(0x02); //  library defined "Sorry, I don't have a function named 0x32 with a key of "wifi"
  • VooBot sendPacket(0x32, _0x32_callback);  // Voodoo does have 0x32 keyed with wifi, and sends the result of his own defined callback function for that command
  • or something like that 

Naturally BOA and Voodoo would have had to conspire ahead of time to agree upon the type/format of data sent back and forth when both parties implement a function. BOA and Voodoo wouldn't have to have the exact same implementation of the function, they'd just have to return data formatted the same way.

With a setup like this it would also be reasonably trivial to port this library to various platforms. In other words, in the long run we'd end up with libs for Xmos, Arduino, Picaxe, and anything else that someone cares to write up. After that any LMR-er could use the lib and know that they can easily chat with other LMR bots if/when they meet up in person. As such, citing previous example, BOA and Voodoo wouldn't even have to be running the same microcontroller to share data.

We'd also need to agree on a method of communicating this data, hardware wise. My only request is "as cheap as possible". It'd be nice to do all this over XBee or something, but those are quite out of my budget for the time being. While it would be rather slow, IR is likely the cheapest way to keep it wireless. Unless anybody involved is happy with requiring the bots to have a physical connection anyway. Having them meet up and connect an I2C connector could work too. While that would still require something like an IR beacon to line up, it sure would make for faster data transfer (after all, I'm looking at transferring full maps).

 

Anything obvious I missed? Any ideas, suggestions, threats, accusations? The asterisk in the title means we need to come up with a better name for it too. LMRBCP or even LBCP doesn't quite roll off the tongue.

Thanks for reading

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Instead of a few replies, and breaking thoughts up across posts, here's one post that asks "lemme see if I've got this straight".

Using Rik's layers, the Hardware layer would be up to the builder (I2C, smoke signals, SPI, UART). If RobotFreak wants to send the data via Skype, or if BOA really felt the need to send stuff via Twitter (lol), this is where they would need to implement their own functions to do that (or around this layer anyway). This is where the Arduino I2C library would be needed if using I2C.

The Logical layer is where the information is assembled into the thing that's handed off to the Hardware layer to transmitted, the Packet(s). This is not programming that needs to be explicitly defined either, as it would be different depending on which micro is being used. All we have to do is define the structure of the packet, so that any bot that receives a packet knows which byte means what. Is this the layer in which the addressing format is specified as well?

The Meaningful layer is the actual command part. This would include "0 - 0x00 -is unused", "#1 - 0x01 - ACK", "#2 - 0x02 - NACK", "#42 - 0x2A - Don't Panic", etc... While these would be predefined, it could still be up to the individual bot builder which ones to implement. For example, BOA doesn't _have_ to impelement "#30 - 0x1E - Turn Right" if he doesn't want to (meaning BOABot is not required to accept a turn command from anybody). 

I think iit should also be up to the bot builder whether to accept commands without authentication. For example, RikBot says "0x00F" (kick yourself), RudBot says "0x01" and does it (cause it's been in the rum again), BOABot says "0x191" (Unauthorized) and does not. (I know, 401 is outside the range of 0-255 for predefined codes)

The Meaningful layer for predefined commands doesn't really need to consist of anything more than a wiki page of definitions. Right? If users choose to share how they implemented a certain command on a specific platform that'd be swell, but not required, and wouldn't go on that page anyway. (that is if we go with BOA's idea of commands 0-255 are fixed, 256-511 are "private", 512-* are undefined as of yet)(which sounds like a good idea to me).

Addressing should not consist of a Skype number, as that would require every bot to have the hardware needed to use Skype. Anything that requires a specific hardware can't be part of the protocol. So that basically goes back to mintvelt's  idea of a unique 16 bit identifier (either node number or from a registry), or my idea of user_number:builder_defined_number. Unless I'm forgetting other options, in which case slap me. 

What'd I miss (or misunderstand)?

Translating one protocol to another, so that info can travel different kinds of links/networks, is done by "gateways". The main problem with that setup is the addressing info. It would need to be encapsulated into the meaningful layer (in a command package), rather than in the obvious transport layer.

Additional questions that popped in my head after hitting Post...

Are there protocols that already do this?

ROBIN seems to require specific hardware.

S.N.A.P. doesn't require specific hardware, but also doesn't seem like it would allow me to easily send 512B of map data in a shot.

Firmata seems to be really Arduino-specific, though adding hardware support doesn't seem to hard.

None of them seem to make it easy for individual users to create/define their own custom commands and make them available for anybody who wants to use them (without rewriting almost everything, in which case we might as well create our own).

Is this reinventing a wheel? Is this idea overkill? Is it a solution looking for a problem?

 

edit = typo

edit2 = hhmmm, reading more about SNAP, it does do more than I thought. Still reading.

edit3 = Okay, Robin and SNAP are specs for packet structure. Not hardware specific. So one or the other of them would be (part of) the Logic layer?

Robin appears to only allow for 59 bytes of data payload. 

SNAP seems to allow for up to 512 bytes of data. It also handles 16.7 million possible addresses. We'd still have to have a registry of some sort though so nobody's addresses clash (in case they ever do actually meet up someday, or for 'net talking). Things like "command10 means turn right" is something we'd still have to setup ourselves too, going back to defining a set of commands, and having new custom commands registered.

SNAP would be handy, as the design work is already done. It is just a specification, there's no code libraries to build packets in arduino, xmos, etc... There are some examples (in Basic it appears). It's not free though (as in freedom) for us OSS geeks...

Why not give each robot a Skype account.  Each Robot gets is unique id like 'lmr<lmr-username><robotname>'. So all robots can communicate with each other using Skypes via chat. They can talk about their users, their home and country, make meetings, conspiracy about takeover the world,... Ouch, ok forget about my idea, or the 'rise of the machines' will come true.

BTW, my robot ask me if someone know the phone number and address of Mrs. Sarah Connor, living in LA, USA.

OK, to be more  serious. I know two protocols that maybe useful:

ROBIN  ROBot Independent Network. A simple network protocol using an RS485 bus, but can also be used with RS232.

The command packets are series  of byte max 64 bytes long following the format:

<preamble> <dst> <src> <flags> <len> <data> ... <data> <cksum>

S.N.A.P  Scalable Node Address Protocol. Originally used for power line modem, this protocol can also be used media independent.

Different message formats can be used. One simple example  looks like:

<SYNC><HDB2><HDB1><DAB1><SAB1><DB1><CRC2><CRC1>

 

How about Twitter? Damn it all, the framework already exists, the code to intereact with Twitter is well documented. The bots could all simply be "Twats." (Or whatever you kids are calling yourselves these days.)

I just threw up a little bit...

 Yes. Some coffee came out my nose when I thought of it. Nasty.

A word about lessons people learned before. About computer communication protocols.

They tend to split up in "layers". I propose to do the same with this discussion. International Standards would have us describe seven layers, but I think we can get away with one or two. Leave all the other layers to the outside world.

Hardware layers: already exist. Suggestions have been made. Radio, wire, IR.
Logical layer: The previous posts are suggesting some sort of packet format.
Meaningful layer: This is where commands are coming in. I suggest to call this the "command protocol".

Defining layers alone won't do us much good. It is important to define how they interact and how they depend on each other. Most importantly, we would describe which functionality we leave up to out hardware suppliers and which ones we (re)invent. For example; the Arduino library for I2C may already exist, so our own library would only need to understand how to call its functions. Our library would know how to wrap the logical stuff into I2C packets. Guarding I2C specific limits.

The "command protocol" would not be required to understand anything about the underlying layers. As long as it adheres to the design specifications. One of the things this layer would not realise is the kind of medium it is working. If it is secure or not, broadcast or unicast.

The command protocol would just order the next layer to "tell BoAbot to turn right, broadcast if you have to". The logical layer would look up the required method of talking to the receiver (it would hold Rudolph's phone book) and than send the message via the correct hardware driver. And maybe report back to the command layer about failure or success.

I agree - my bot currently has a few different layers of active communication.

Local comms within the bot are serial (talking directly to hardware, with USB thrown in), UDP (for comms where never is better than late), the glue between serial and UDP is python, using pickle to easily create a message consisting of multiple parts to be sent to/from the "control app". I am looking at throwing firmata in there as a more standard low-level control protocol.

The next step would be a flexible, overall command/status/query system. i have a few wxwidgets and pygame utilities to display and control assorted things on the 'bot from a remote system, again using python and pickle to pass messages. (pygame for sonar display and motor control, wxwidgets to control servos) but ainter-bot level of communication thatdeals with messages at a higher level, independant of local hardware specifics would be nice. Internally, my main control app already has a lot of "common" functions so i can give it a series of simple commands to do semi-complex functions (do a quick object scan, slow object scan, turn while scanning, etc etc)as well as all of the basic motion functions

Protocols like these have been proposed for decades. Even before eligible computers actually existed.

That would suggest that all we are trying to achieve here, already exists. Somewhere, sometime. Question is:
"Do we like to use existing inventions?"
or would we rather Build It Ourselves? My vote is somewhere in between. I like this exploration. It's fun and very educational and it introduces a new level of cooperation on LMR.

But I would vote against reinventing the most basic of features. That would feel like investigating the roundness of our new wheel.