Well, its been a boring year with no droid outings, tho thanks to doing some live youtube events under the Droid Builders UK banner, we’ve managed to raise over £14k for CALM.
I know droid 2 isn’t finished yet (tho some slight progress has been made which I will blog about later) but I have decided to push my knowledge and skillset by building an autonomous droid. Nothing as big or heavy as an astromech, but a much smaller and lighter HO15 droid. These are a new one that was built by Oliver Steeples for The Force Awakens.
The droid is designed to be driven using omni or mecanum wheels which allow it to not only drive forward and turn, but also to strafe to the sides and generally move in any direction it wants. The type of drive system is called a holonomic drive.
Originally I was just going to build it with standard RC controls, but after seeing a few articles and presentations about ROS it got my ambitions up! ROS is Robot Operating System, and whilst it isn’t technically an operating system, it is a very mature platform for developing robots on. As well as driving the droid it can also do navigation, obstacle avoidance, and even 2d/3d mapping of its environment.
So, the idea is:
Styrene HO15 droid, as accurate as possible.
4 omniwheels as the drive.
Multiple (8?) ultrasonic range sensors to detect obstacles.
Xbox Kinect camera/sensor to detect 3d space infront of the droid.
RPi cam for remote operation.
Autonomous random movement – I can leave it to wander and it will just meander about the place, avoiding objects.
Directed movement – Take control of it directly to drive it, but still avoid objects as a safety measure
And even full mapping and navigation, tho this is definitely a stretch goal!
Central control will of course be a Raspberry Pi running Ubuntu and the latest version of ROS2. The original ROS is being rewritten and will be retired in the next year or so, so I decided to push forward with version 2 from the start. Unfortunately, this causes complications as most tutorials and packages are still designed for version 1. But then, I like making life difficult for myself!
Well, the connectors didn’t turn up on Saturday, but they did turn up today! So after a bit of crimping, and a bit of soldering (and a few mistakes, but we won’t go into that) I had a couple of cables made up to allow me to connect the Q85 motors to the ODrive.
Here is one of the sets of cables. They consist of the red wires in the back that go to an MT60 connector that carries the main signal to the motors, and then another bunch of wires that come from the hall effect sensor that is embedded in the motor. This tells the controller where the motor is in its cycle, so that it knows which coils to energise.
With all that in place, I gingerly powered it all up and set about calibrating everything. I followed a guide on the main astromech forum, along with the odrive guide for hoverboards (same principal as driving an astromech it seems). It took a bit of trial and error, that I’m hoping to iron out into a proper tutorial at some point, but the motors were eventually running!
The mixing that I’d done in software all looks like its working as intended. I can also bump the speed up incrementally, as I can with R2, but with a lot more control and accuracy.
I do need to change the ramping settings on this, which I may even make changeable on the fly from the controller. Also the multiplier may need some tuning to set top speed, but that will require some testing in situ. I need to push my changes back into github, and make sure that R2 still works with the new code.
I think this brings the electronics to a good resting place for now. Just going to tidy up some of the cabling and add a volt/current meter. Its time to concentrate on making the actual droid. So this weekend it will be time to don the breathing mask and start glueing everything together.
Currently, my PS3 controller code uses the channel mixing built into the Sabertooth speed controller. This means that I send it speed and turn commands, and the speed controller mixes these to drive R2 in a tank style, where you vary the speed in the feet to go forward/back or turn.
The problem with this is that not many speed controllers do this, so I am very much tied into using the Sabertooth with my code and the Sabertooth doesn’t support brushless motors. Droid 2 is going to use an ODrive, which has no mixing built in.
Well, until now!
I’ve abstracted out the speed controller portion of the code and added a function that takes the two axis from the drive stick and then outputs the required motor speeds. In this video you can see when I push the stick forward, the top number changes to show the position of the axis, and motor 1 is set a signal of 1, or full speed forward and motor 2 gets -1, or full reverse. (Remember, the motors are flipped)
Minimal wiring is done now, enough to get everything powered up and r2_control installed.
A quick flash of an SD card, some tweaks to the install instructions, a few small tweaks to the code to make first boot a little smoother, and shes alive!
Only got audio working for now, but it meant I could test the base code and web interface. I need to get a remote working next I think, and then I can start working on interfacing with the Odrive and Q85 motors. Theres already a python module for that, so that saves a lot of work. Unlike the Sabertooth, which required me to write a python module to interface using serial.
Also, the documentation is now up to date for the latest version of Raspbian, and the code now auto creates basic configs correctly so it will work on first start without having to pre write any configuration files. It should also be easy enough to write a setup script to install required packages and python modules.
And of course, seeing as the Pi is powered up I can now remotely access it to do coding from the comfort of my office.
Most people start by building their droid, then doing the electronics. I’m pretty much doing it all in reverse.
Here you can see all the electronics for R2. The left hand board has all the main power, and the right hand board is the actual electronics. Both boards have edging around them, and will happily sit back to back, making the whole system easily removable. It also means that once removed, it can be opened up as shown to be worked on.
Wiring is nearly complete for the core parts (Pi, Odrive, and Amp), I just need to get an XT60 soldered on to accept a battery. Now, I know I’ve a load of XT60 connectors somewhere in my office, but so far they have eluded me. They must be somewhere *really* safe!
Also, at the top of the pictures you can see the stripped down Q85 motors, getting modified to freeze the clutch system.
Next step it to get power to the Pi at least so that I can start installing the brain. It will also be an opportunity to get the documentation improved, and initial config sorted, incase anyone else wants to use my code.
Oh, and I think I’ve decided on a name for my droid.
One of the things I’m quite interested in keeping an eye on (and wish I’d started making notes a lot earlier) is how much battery power I consume at an event.
R2 is quite a heavy droid, with lots of gadgets, and is generally very active at events. I like to drive round and entertain rather than staying in one place. I also may have gone overkill on the battery, tho that being said by never fully depleting the cells I’ll probably get a lot more life out of the packs.
So, I have started a spreadsheet to keep track of how much actual power I use in a given event, to hopefully get some meaningful stats for my droid(s).
Besides standard stuff like the event name and date, I’ll be logging the amount of power put back into the droid after the event, as measured by the charger I’m using. I’ll also log approximate hours the droid was powered up, along with how much of that time he was actually active and moving around.
The spreadsheet will be public, as it may help other builders:
A few people have expressed an interest in my r2_control system, so I thought I’d do a post about how it works, and what it needs.
At the core is a Raspberry Pi 3B+. This runs the main code, and also any programs to interface controls (PS3, Web, Instant Messenger). It also acts as a wifi hotspot.
From this Pi you can add a Sabertooth 2×32 and Syren 10 via USBSerial to allow control of those using packet serial communications. A python library for which I have written to make things easier.
Recently, a GPIO option has been added to the core code so that you can trigger relays and other switched items directly from pins on the Pi. I use this to trigger the relays that break the connections to the foot motors and dome motor.
Lastly, an i2c connection is available for communicating with various other boards such as the Adafruit 16 Channel PWM controllers, RSeries lights, ReelTwo system, etc.
A basic system to have simple control over a droid with no opening panels and no triggering of dome light sequences can be had with just:
1 x Raspberry Pi 3B+
1 x Sabertooth 2×32
1 x Syren 10
1 x USB FTDI (For USB interface to Syren 10)
1 x PS3 controller (Or PSMove)
Whatever dome lights you wish, eg TeeCees.
Power distribution (Fuses, power switch, etc.)
2 x Drive motors (eg. 100W Scooter)
1 x Dome motor (eg. pittman)
You can run the Pi from the BEC built into the Sabertooth if you wish, but I do recommend at least a 2A buck converter on its own fuse.
If you want to run any servos, you can add the Adafruit PWM controllers onto the i2c bus, up to 6 can be added by configuring the address jumpers. One in the body and one in the dome is usually enough.
This system can of course be added to. Relay control over the motors, light sequence triggers, and other gadgets such as smoke machines.
The current state of PSI displays from the club are either simple TeeCees ones, or the VADER boards. I’ve had a couple of the VADER boards in R2 for a while, but recently I’ve had issues with some of the LEDs failing. Unfortunately, as these are WS2812 addressable LEDs which means when one fails then you can’t communicate with any further down the line. They are also all surface mounted, so not exactly easy to replace, especially as they are so closely spaced. On top of this, they are not open source so I have been unable to do any fun stuff with i2c triggers.
I wanted to build some PSIs from off the shelf parts and allow it to do some more interesting effects. After a lot of hunting, I finally found some i2c addressable 8×8 RGB Matrix displays from Seeed Studios. Couple one of these with an Arduino Pro Mini, and you have a relatively cheap PSI using standard components.
Arduino Pro Mini (https://coolcomponents.co.uk/products/arduino-pro-mini-328-5v-16mhz)
Header pins for the arduino (not necessary)
Not really much to the circuit, just using the pro mini i2c pins to talk to the rest of R2’s i2c bus, and then software i2c on another couple of pins to talk to the display. This has to be done as the displays have a fixed i2c address of 0x65, so only one can be on the bus at once. This also allows the rendering of the display to be offloaded onto the arduino.
The display comes with a short cable which you can cut the end off and solder directly to the pro mini if you wish.
Currently, when powered on the display will just do the standard left/right swipe of two colours (all configured in the arduino code). Also, two functions have been added to either pulse a heart or do a random pattern to simulate a malfunction. Others may be added at a later date, feel free to suggest ideas!
The heart doesn’t really show up too well through the diffuser, but it still looks like a pulsing pattern, so I’m happy with that.
The random malfunction will take an integer number of cycles and randomly turn pixels on to a random colour on each cycle. The number of pixels that are on will slowly reduce to zero. Ten cycles is about 1 second
To trigger these effects, you send an i2c command to the address defined in the arduino code (typically 0x06 or 0x07) with either H or M as the first character, and then a number of cycles (1-255).
I have implemented this into my r2_control software, which allows me to script actions together. The plan is to do something like trigger the malfunction sound, set the PSIs to malfunction mode for enough cycles to cover the sound, and also flap all the panels in a pseudo random way.
I have a set of Ultimate PSI Housings from IA-Parts, which hold both the standard teecees boards, and the vader ones. To fit the square peg (rgb matrix) into a round hole, I knocked up a very simple 3d print.
This clips in nicely to the PSI housings, however you may have to do your own system.
I’m actually quite pleased with these. Its really hard to find a densely packed RGB matrix as an off the shelf product. After much searching this was only one I could find. Its by no means as nice as the custom VADER boards (and I know others in the community are working on their own), but it does work and looks a lot better than the TeeCees ones (IMHO).
Not only that, its cheap too at about £25 per PSI (not including any costs for making the mount, but in my case that was a few pence for a 3d print)
Next step is to figure out some more fancy things I can do with it, and maybe add a selector jumper so that you don’t need to change the code between the front and rear PSIs. I may also do a custom board to connect it all together in a neater form factor.
For a long time I’ve wanted to make a much more stealthy method of control. When I first started R2, I’d considered using a Wii remote and nunchuck, but I realised that as I’d already done the PS3 controller code, it wasn’t that much different to use a PS Move navigation controller. They show up as a standard joystick in Linux, so easy to interface with.
As the code for this wasn’t going to be changing much from the ps3 code, I pretty much just copied it over to give me a foundation. Currently it only supports a single navigation controller, but the plan is to allow two controllers to give me more options and things I can trigger.
The main drawback at the moment is the lack of dome control, but that just gives me more reasons to finally get round to doing some automatic dome functionality.
Battery life is an unknown at the moment, and as with the ps3 controller it doesn’t seem to charge unless plugged into a computer.
Along with doing this code, I also worked on getting it easy to switch between the different control systems. There is now an API call to list and select a different joystick, with options to call it via both web and telegram at the moment.
The last few days have been spent doing some fairly major refactoring and other code improvements. I wanted to add functionality for the FlthyMcNasty HP control systems and realised as I add extra API calls, then the main.py code would start to get a bit unwieldy.
To this end, I started learning about Blueprints in the Flask web framework I use. Blueprints allow API calls to be added functionally in a modular fashion. This meant all the API definitions and functions could be brought out of main.py and into the actual script for the device in question.
Along with this I learnt how to dynamically import code into main.py, which coupled with using blueprints has given me a much more modular approach to adding various devices.
Now, plugins can be loaded by just adding them to a line in the config file. They will then be dynamically added on startup. This is going to make it a lot easier to add the various modules such as the PSI, logics, Charge Bay, etc. to the API.