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.
And also, how often will different bots be communicating with each other?

How about a 16bit unique address for each bot? We could use the LMR node numbers of the bot pages as the addresses or open an LMR page where you can register your robots address. 


Liking the node number idea. Not every bot will have its own node number here though. For example, my pair of mapping bots are a single project, so they'll share a node number.

How about a two part address (not entirely unlike an IP number I guess). The first part of the number could be LMR user number, followed by that user's defined number of the individual bot. For example, sendPacket("812:1", $command, $data) would address my bot named "1". What I don't like, though it's not a bad thing, is we already have too many users to make the first part a single byte ;)

We could define broadcast numbers here, so 0xFFFF:0xFFFF would address all LMR bots using the protocol, 0x12A:0xFFFF would address all of BOA's bots, etc...That wouldn't blow up until we had well over 65000 users, or someone built 65000 bots. We'd still want a bot number registration setup, in addition to BOA's mention of registering function names.

I'm getting the feeling that this is gonna be a large project ;) 

if two robots share their robot page, just add a blog entry or one of the bots and use that node number. 

We can either use LMR user/node numbers or setup an ID registry for the all-new-LMR-inter-bot-protocol 

I like "($address_of_receiver, $command, $data)" because it's a meta protocol. Bots can legitimately have subsets of it defined.

I could go the the 16 bit command byte. The rationale being that there isn't really likely to be that much overlap between the hooks used by various bots. A ground based robot, for example, might not really care what height a flying robot is at.

I'd also like to see this protocol implemented on other platforms: my pipe dream is that my bot would roam looking for open WiFi links. That might be quite easy in some parts of the US, but here in the UK, very few WiFi nets are wide open. Consequently, if the protocol were available via a WiFi router, then the router wouldn't have to be "open for all": just for the bots.

The command format is unimportant, and there's no reason why there should be consistency. HOWEVER, there MUST be a central repository of commands which a programmer can choose to implement.

I propose:

1) Reserve the first 256 commands for the top level designers (ie, us) alone to define.

2) The Next 256 commands (256 to 512) should be reserved as free for all, undefined, undocumented and unpublished. That is to say that anyone can use them for whatever they want and they needn't define the command or protocol. That means that folk don't have to register with us what they're doing. HOWEVER, coders using this range of command IDs must recognise that if per chance their bots come into range with another bot also using this range for a different purpose, there is potential for much confusion. This allows coders to design and test their command before registering it.

3) All the rest (513 upwards) should be for user registered commands only. That is, if a coder is using them, they MUST have registered the command, or be using a command format registered by someone else. These commands would be held on a publically readable database.Once registered, a command can only be changed if it is demonstrably backwards-compatible with older variants. Otherwise, it must be re-registered with a different command ID number.

On authentication, this might be command-dependant. For example command 0 ("Hello, I'm BOA-bot number 69.") doesn't need authentication. Command 255 ("All bots in range, please shut down immediately.") would require authentication. Command 1 ("Your mother was a starfish.") might be an authentication key or might be used to identify a bot as part of a particular swarm. Command 2 ("Who are you?") might be responded to ONLY after command 0 has been sent, or perhaps only after command 0 AND command 1 have been sent, and even then, only after the recipient likes the authentication or group identifier.

On the wifi note, so should we just build it around standard serial? Then it's just whatever device the builder decides to attach to the micro. That way it'd work with everything, wifi, xbee, IR, wire, whatever. It wouldn't guarantee that the bot that's met up with would have a matching comm device, but it would (with a little thought) allow bots to communicate over the 'net.

In the long run maybe we could end up with a simple hardware device for LMRians that implements a common IR thingie. Open source, easy to build, cheap to buy a PCB if desired, etc... Will think more on that some other time.

Ack, I'm replying to myself. I feel horrible about it. Truly.

After further thought, it doesn't matter if it's UART, i2c, blinky lights, smoke signals, thumps on the noggin, whatever. It's all serial anyway, right? Is that what was meant by "The command format is unimportant..."?

If I rigged up an Arduino YDM to tap out morse, anything with a microphone could theoretically translate it. As long as I registered and shared my packet construction for others to see WTF I was up to. Whoever writes (and shares) an Arduino function to speak morse should provide a matching listening function as well, wrapping it up in a library if they want to. Someone who then wanted to listen and understand and talk back to the AMDM (Arduino Morse Drum Machine) with a Picaxe would need to write their own Picaxe routines, based off my already shared packet, and we'd greatly appreciate it if they'd share it as well (on the central repository thingy).

It would be up to the individual bot builder to choose their method of communication. The repo could then contain a "phone book" of registered bots, their address, and what comm method they use. If I thought I wanted to use I2C, I could search the phone book and see what other bots use an I2C comm devices, then I'd know who I could talk to. The phone book could even just be part of the bot's Project page info here on LMR. No reason to duplicate functionality elsewhere. I'm thinking too far ahead again though.

For now all we really need is an address specification, some of the 0-255 predefined command set, and the understanding that the implementation of some predefined commands will require additional basic commands (e.g. receiving "shut off" command means send back "love to, but what's the password"). I guess the format of the first 256 commands is important then. Anyway, with that we can all get on with our projects (using our own custom commands in the 256-511 range).

Edit: On re-reading this, Calculon realizes that Rudolph was already suggesting this ...

Calclulon recently worked for airline systems that had to send and recieve messages to other systems constantly. They have an 8-character protocol that works pretty well. The code determines how the message is intended by the sender, but lets the recieving system use the info however it wants.

We could do something like this:


2-message recieved

3-received pending

4-ping, please reply

5-ping, please DON'T reply


101-danger danger, all bots shut down now

102-you are a competant person

66 - kill all the jedi. :)

You get the idea. But this way a the first byte (s?) can let the recieving bot decide whether or not it can ignore the rest of the message. Can XMOS communicate with the Picaxe Sony IR protocol?

I lol-ed at 66.

The Sony IR protocol can be bit-banged if nothing else. See this for an example of how it's done on Arduino.

Something I forgot to mention, overall packet structure could be like "two start bytes, address (0xFF for broadcast?), specify end byte to watch for, command byte, data, previously specified end byte". This would prevent the transmitted data from having to be any specific length, though a dropped byte could spell disaster. Somewhere in there should probably be a checksum.