Introduction
If you’ve checked out my Rover project – an autonomous obstacle avoidance robot – you’ll know that I am a robot junkie. But my interest isn’t limited to wheeled vehicles. I have had a biped on the workbench for over a year but inevitably, whenever I turn my attention back to it, a brighter, shinier object always seems to distract me. This time the distraction was in the form of a hexapod. This project is the first phase of a larger project to create an autonomous, interactive pet for my daughter - Hexapet.
I started
with an off-the-shelf frame kit but instead of using the manufacturer’s Arduino compatible microcontroller and servo controller, I decided
to build Hexapet using Windows 10 IoT Core running on a Raspberry Pi 2. My
platform choice delivers much more computing power than what’s needed for this phase. But, in future phases of the project, as Hexapet becomes much
more sophisticated, the reason for selecting Windows 10 IoT Core will become
evident. I used Adafruit’s Servo HATs to drive the servos and an
Xbox controller to direct Hexapet’s movements.
The goal of phase 1 is to understand Hexapet’s basic mechanics – movements, speed, strength, and power consumption. I find the 3 degrees of freedom on each leg fascinating; with 6 legs and 18 servos, there is a lot of movement going on with each motion. Admittedly, Hexapet’s movements aren’t the most graceful at this point but there is a lot of room for refinement through software; the hardware platform provides the necessary precision and control. Now that everything is operational, I'll start tracking battery life as well as trying to optimize speed.
I would rate this as an intermediate project. While the physical construction of Hexapet wasn’t complex, it was a little more involved than my past projects considering the number of servos and the need to do some mechanical trimming of the servos’ center points. On the software side, relatively speaking, the program isn’t all that sophisticated but since I am still learning software development and C#, this project introduced me to a lot of new concepts and programming constructs. (My goal for the next phase of this project is to implement some of the new object oriented concepts I am currently learning.)
Here are some of the resources I found very useful throughout the course of this project:
- Microsoft Virtual Academy’s C# Fundamentals for Absolute Beginners course. It was well worth the time and I feel much more confident now with the Microsoft platform.
- Adafruit’s tutorial on using their Servo HATs.
- Lynxmotion’s forums provided good support when I ran into issues building their hexpod kit.
Prerequisites
- Get Windows 10 IoT Core running on your Raspberry Pi 2 (instructions here).
-
Get Windows 10 and Visual Studio 2015 running on your PC (instructions here).
- Deploy a simple Windows app to the Raspberry Pi to ensure everything is working (instructions here).
What You'll Need
Parts:
-
Raspberry Pi 2 and standard accessories: 8GB micro SD card, power adapter, network cable or WiFi dongle.
- Adafruit 16-Channel PWM / Servo HAT for Raspberry Pi.
- Lynxmotion Phoenix 3DOF Hexapod kit.
- Xbox controller.
- 3S 3200mAh LiPo battery.
- 5V/6V switched-mode universal battery elimination circuit (UBEC).
- 2S 1000mAh LiPo battery.
- Voltage converter with 5V USB charger.
Tools:
- Soldering iron
- Optional: servo tester
Project Instructions
Step 1: Assemble the hexapod kit
Time: 2 hours
Tools: Screwdriver
Parts: Hexapod frame and servos
Follow the instructions that come with your hexapod kit to assemble the frame and install the servos. The instructions that came with my Phoenix kit were relatively clear and well written. Yet, it still took about two hours to assemble all the legs and the body given the number of servos involved. If you have a servo tester, go ahead and center your servos before assembly – it’s easier than having to remove the servo horns and realigning them later. (I centered all the servos before assemble and only had to do some minor realignment on 3 servos after powering up the servo control boards.)
Step 2: Mount the Raspberry Pi 2
Time: 15 minutes
Tools: Screwdriver
Parts: Raspberry Pi 2, stand-offs and screws and nuts
The mounting location and method will vary based on your frame. The Raspberry Pi was too long to fit between the stand-offs connecting the top and bottom plate of the frame so I mounted it on top of the top plate; plus, the space in between the frames is ideal for battery placement. This top mounted position of the Raspberry Pi also made it easy to plug in peripherals when needed including the Xbox controller (as well as the HDMI cable, wall wart, and network cable during development).
I was able to attach the Raspberry Pi to the two front stand-offs using the Pi's pre-drilled mounting holes. The two rear stand-offs didn't align with the Pi's mounting holes so I just rested the Pi on top of them.
Step 3: Mount the Servo HATs
Time: 30 minutes
Tools: soldering iron
Parts: Two Servo HATs and header pins
Each servo HAT supports up to 16 servos so I had to purchase a second HAT to control the remaining two servos. Luckily, the Adafruit Servo HATs are made to be stackable (just be sure to order the stacking header and the right angle headers separately). Solder the stackable header and the right angle headers to the bottom HAT. And, solder the standard headers to the top HAT. Make sure to set the address of the top HAT - each HAT must have a unique address - by using a drop of solder to bridge the rightmost address jumper (refer to the Adafruit tutorial for more info). It's not complicated but just took about 10 minutes per HAT to solder all the headers and set the address.
Finally, mount the bottom HAT onto the Pi's 2x20 pins and then mount the top HAT onto the bottom's stackable headers. Pay attention to the side of each HAT where the servos plug in to ensure that the headers aren't contacting the other HAT or the Pi. I put some skinny foam pieces to insulate the Pi from the bottom HAT and the bottom HAT from the top HAT just to be safe.
Step 4: Connect the servos to the servo hat
Time: 30 minutes
Tools: N/A
Parts: N/A
Now that the servo HATs are mounted to the Raspberry Pi, it's time to wire up the servos. I connected 15 servos to the top HAT and 3 to the bottom HAT; it made sense to keep all servos for one leg together on a single servo HAT even though I had room to put one more servo on the top HAT. Also, the plastic clips that hold the 3 wires for each servo together fit much better on the straight headers (top HAT) than on the right angle headers (bottom HAT) which is why 15 servos are connected to the top HAT. In fact, the plastic clip felt so loose on the right angle headers, I took the wires out of the clip and attached each onto a right angle header directly.
(In hindsight, I may have soldered the right angle headers in backwards. I soldered so that the black plastic bar on the header sat on top of the servo HAT (like I normally would). However, if I flipped the headers and solder them such that the black plastic was almost vertical and mated to the plastic clips on the end of the servo wires when plugged in, then the servo wires would have more of the header pin to slide on to.)
I numbered the legs counter-clockwise starting with leg 0 being the rear right leg which made the rear left leg 5. I connected the servos for each leg to the servo HAT sequentially starting with the horizontal hip servo, the vertical hip servo, and lastly the knee. This consistency makes it very easy to calculate which channel on the servo HAT each servo is connected given the leg and joint.
Step 5: Power the servos
Time: 15 minutes
Tools: Soldering iron
Parts: Switch, battery connector, universal battery elimination circuit, barrel jacks
The universal battery elimination circuit (UBEC) steps down the input from your 2S (7.4V) or 3S (11.1V) LiPo battery and allows you to set the output to 5V or 6V; I chose 6V since the servos will have a little higher torque at that voltage. The servo HAT supports 5V input at the terminals and 5-6V input at the barrel jack so I spliced two barrel jacks onto the output side of the UBEC. (The output side has three wires but we only need two - positive (red) and ground (brown or black) - so simply snip off the third wire which is signal (white, yellow, or orange).) If you decide to use 5V, you can wire straight in to the terminals and not have to worry about the barrel jacks. (I have a pile of 9 volt to barrel jack adapters to I just cut the 9 volt clip off those.)
I added an on/off switch inline with the positive wire of the battery connector and the UBEC to make it much easier to power on / off the servos. And, a nice little mounting hole for the switch was pre-drilled into the hexapod's top plate.
Step 6: Power the Raspberry Pi 2
Time: 15 minutes
Tools: Soldering iron
Parts: Voltage converter with 5V USB charger, battery connector
The Raspberry Pi doesn't support a wide voltage range for power so you really need to be right at 5 volts. The easiest power option is a portable rechargeable battery used for cellphones. They output a steady 5V and have a USB connector which makes connecting to the Pi super easy. I have several in different shapes and sizes that I use for Raspberry Pi and Arduino projects.
However, I recently came across this voltage converter and wanted to give it a try. It too outputs 5V and has a USB connector. But, it also displays voltage and it gives me the flexibility to hook up a variety of batteries (or just swap out a fresh battery so I don't have to wait for it to recharge) So, I connected a LiPo battery connector to the input terminals (just make sure you get the appropriate connector based on the connector type that comes wired to your battery (i.e. JST or Deans or XT60)) and plugged USB to micro USB cable into the output. Voila, portable power for the Pi.
It got a little tight in between the top and bottom plate with the battery for the Pi, the battery for the servos, the UBEC, and the voltage converter; so much so that it got difficult to plug and unplug the Pi's battery. So, I added a switch for this power supply as well and mounted it on the top plate next to the switch for the servo power supply.
Step 7: Download and Deploy the App
Time: 20 minutes
Tools: Visual Studio 2015
Parts: Completed hexapet
Download the hexapet source code from the github repository and load the project into Visual Studio. The application consists of three primary files: Movements.cs, Controllers.cs, and XboxHidController.cs.
The XboxHidController code comes straight from the Robot Kit project published by the Windows IoT team. The code listens for movement from the Xbox controller's DPad or the left joystick. The DPad has priority but it only supports movement in four directions - up, down, left, and right. The left joystick supports the same basic four directions but it also allows input for four additional directions - UpRight, DownRight, UpLeft, and DownLeft. Once a controller event is detected, the directional input from the controller is passed to the Controllers code.
The Controllers code initializes the Xbox controller. It too is taken from the Robot Kit project but I removed support for several other controller options (i.e. Windows 10 desktop UWA). Once the Xbox controller has been initialized, the Controllers code will translate the direction input received from the Xbox controller into the appropriate movement.
The Movement code first establishes communication with the two servo hats over I2C. Then, it defines all the primitive actions - abduct, center, adduct - for the joints (i.e. servos) as well as composes primitives into major movements (walking and turning).
I am still experimenting with the movements. You will see in the code that one of the joint primitives has an additional argument which is the number of degrees to adduct. I think that when I start to optimize for speed, I will reduce the range of motion of some joints so that the composite movement can be completed more quickly. I also need to experiment with the delays as less time is really required for the servos to complete their turns. (If you have no delays, then a center command, for example, may overwrite an earlier abduction command as servos don't wait for one command to complete before executing the next - they'll act on the latest command as soon as they get it.)
Step 8: Final alignment
Time: 15 minutes
Tools: Screwdriver
Parts: N/A
Once you have everything built and have deployed the code, you may need to tweak some of the servo positions. Centering the servos before assembly (step 1) greatly reduces the need to realign them once built but minor changes to a couple of servos will likely be needed. I only had to realign one vertical hip and one knee.
First, program all the servos to move to their center position (i.e. the Stand movement). Then look at each joint to see if it is angled properly. You can unscrew the servo horn from the motor (a single screw on top of the servo horn) and then pull the servo horn off the motor's spline. Rotate the servo horn (and the attach leg component) until it gets to the desired angle and then push the servo horn back onto the spline. If that horn location provides the desired angle for the joint, then replace the screw and tighten it. Repeat this procedure for any joints that are misaligned.
Comments