Close

ROS Integration take 2.

A project log for Micro Robots for Education

We aim to make multi-robot systems a viable way to introduce students to the delight that is robotics.

joshua-elsdonJoshua Elsdon 10/04/2017 at 11:382 Comments

Hello again.

ROS: Did I do this before?

ROS: Robotic Operating System is a key part of modern robotic research. The glue that lets academics and industrial system designers package their work in a way that is easy to share and stick to other modules. If you are interested in modern robotics and don't know about ROS then get to work on the tutorials! There are alternatives to ROS, though ROS has 'won', for now. 

I am keen to have these robots fully linked up with ROS, such that I can be lazy when wanting them to do fancy things. When a robot is connected to ROS and has the relevant sensors and actuators, it can leverage pre-made cutting edge research code with just a little XML jiggery-pokery and perhaps a few simple c++/python nodes to do conversions. Pretty awesome. 

I made a post quite a while ago that claimed ROS integration was working on the robots, and I wasn't lying. The problem however was that the implementation was for version 3.0 of the robots, AKA arduino on wheels. Now we are in version 5.0 (and 6.0 is ready to send to manufacture) which uses a different micro controller. In redesigning the code to run on the new hardware we decided to make the communication layer far more versatile. The old version was just spoofing NEC commands over IR, and each robot would have their own set of commands to allow them to move around. This is OK, though there is lots of redundancy in the NEC protocol, and the commands are sent at a very low rate. This meant that if you had more than a couple of robots you would be starved for data to each. Also there was no provision for up link to the master system. 

The new implementation makes use of UART as the base for the communication scheme, and this is one of the key differences between V4 and V5, the IR receiver is connected to the UART Rx pin. All you need to do is modulate your UART at 38kHz and you are good to go. In both the robots and the master this is achieved by letting the LED straddle the Tx pin and a PWM pin, when the PWM is strutting it's stuff a high voltage on the Tx pin will light the LED only when the PWM pin is low. Now we can just use the UART hardware as usual and the LED will be modulated for free. 

Where art thou packets?

Now that we have bidirectional UART (half duplex) we can start doing some more sophisticated communication. Because the IR channel can be very unreliable, a sensible packet needs to be proposed. luckily I happen to be writing a blog post about just that issue!  The packet follows, each [] is one byte:

[header][header][robots][255-robots][type][robot0 ins][robot1 ins][.....][checksum] 

Above is the current packet implementation, which is likely to change to include better validation for many-to-one communication packets (like asking all robots for their battery voltage). 

[header] is just a special byte to find the start of the packet, in my case 0xAC, as it has a fun alternation of bits. We do this twice, to lower the chance of collision with data, though that would not be a big deal if it did happen. 

[robots] is just the number of robots in the system, and [255-robots] is just some redundancy to double check this number, the sum of these should always be 255, getting this wrong could put the robot into a long loop waiting for the wrong number of robot commands. 

[type] is the command type, for example 'move', 'report battery voltage' or 'enter line following behaviour'. 

[robot0 ins][robot1 ins][.....] is then the array of instruction bytes to each of the robots. Each robot is likely going to ignore all of these apart from it's own instruction. Though you could imagine that the information given to other robots could help the robot plan locally in some cases. All robots know how long the array will be due to receiving the robots value previously. 

[checksum] is a checksum, such that we can perform a sum then check the sum matches the checksum. How many sums could a checksum check if a checksum could check sums? I think I am getting carried away, so I will move on. 

Finding a Unique Identity.

Well defined packet complete! It is not perfect, later I will move the checksum earlier, such that it can be evaluated early on frames that require the robots to respond in their 'slot', though for down link purposes this is fine for now.  The problem is all of the robots think they are the same. We need them to find their own way in the world. Well what I mean really is: they need to know which of the bytes in the instruction array they should listen to. We could hard program this into each, #define MYID 666, though this is a messy solution if you need unique source code for 100s of robots. I would like them each to be programmed with identical code, then at run time negotiate who is who. 

To achieve this we need two things, a source of entropy, and a game to play. The first is easy, STM32 parts all (I think all) come with a unique ID number burned into the hardware. This is super useful, it is actually better than a random number, it is guaranteed to never be the same between robots. We can use this to seed a pseudo-random number generator. 

Next we need a game that they can play using random numbers that will let the robots compete for dominance, who will win the right to be the blessed "robot 0"? The game that they will be playing is kind of like a version of "Snap". Each robot can pick a time between 0ms and 250ms. Then they wait till that time arrives they will then modulate their IR led iff there has been no other robot modulating their IR LED to this point. They win the round and claim the next ID number. Basically the first to 'raise their hand' wins. It is likely that at some point two robots will pick a time so similar that they both think that they won, hence we actually repeat the round 3 times with different random times (though you only play if you think you won the last round), this makes misunderstandings rare enough we can ignore them. 

Eventually there will be a round where nobody claims a win by flashing the LED, as all robots have their ID number an no longer need to play. When a round goes un-played then we know the task is complete, then king Robot0 will announce the result in a serial message over IR using the UART, this is then received by the ROS-IR interface, and the ROS system is informed of the number of robots. 

As a demo I have the robots being controlled by a joypad over the ROS system. When turned on all robots think they are 'Robot 0'. After fighting it out with flashing LEDs they have unique IDs which can be controlled by the different parts of the joypad. Video below. (ignore the fact one robot behaves strangely, his motor is broken : (  ) 

sources: robot firmware ROS packages, ROS-IR bridge (to be gitted) 

Discussions

Oskar Weigl wrote 10/05/2017 at 07:51 point

PWM pin straddling for multiplication (modulation) with UART: Awesome!

  Are you sure? yes | no

Joshua Elsdon wrote 10/05/2017 at 14:25 point

All in a days work ;) 

  Are you sure? yes | no