Inverted pendulum robot

Introduction

It was my second year of engineering at UC and I had chosen to specialise in Mechatronics. Athough I was busy with my RC aeroplanes and did not really need another hobby, I liked the idea of building a robot. Afterall, this is what Mechatronic folk are known for! I started generating concepts for a small robot late in 2007. Once I had finally settled on what I was going to build, work started on my robot in the summer of 2007. This page is devoted to the robot I ended up creating. Since then, it has undergone several revisions, reflecting my increasing knowledge and skills from my coursework. So far it has been a challenging journey that was anything but 'smooth sailing'. A gallery of images of my robot:

Overview

This robot I have built from scatch balances by itself. Like a Segway, it needs an inertial measurement unit (IMU) and complicated filtering to move its two co-axled wheels appropriately to prevent it from falling over. Why go to all this hassle? Well, for the Segway, it is beneficial as the centre of gravity of it plus its occupant is always over the top of the wheels. This makes it more stable over inclined surfaces as there is no static torque trying to make it fall over. My robot is way too small to carry anyone on it, but it was made this way as inverted pendulum robots are cool!

This project has consumed a lot of my spare time. I've created the design of the robot, machined all the parts, designed the schematics, made the circuit boards (excluding the webcamera and its embedded computer), and written a lot of code! The block diagram of the robot with its current hardware:

The robot does not have a purpose other than to apply what I've learnt and for me to have a bit of fun. It is a so called telerobot, in that it is controlled remotely. It streams its webcamera and sensor data back to a computer, offloading the computationally intensive tasks. The computer program then sends commands back to control the motors and other actuators. Communication is via TCP or UDP sockets using a Wifi network. In my masters project, this robot was used to test a navigation system consisting of: mapping the environment, obstacle avoidance, and path planning. It can be driven around manually but I'm more interested in developing algorithms to get it to driving and doing stuff by itself.

Sensors

The robot has the following sensors on it:

  • A custom IMU with a three axis accelerometer and two dual axis gyros. It uses the Sparkfun IMU Razor along with a PCB with a STM32 running the Kalman filters to estimate the orientation of the robot. I ported and hacked at software from the CHR-6d IMU to run on my IMU board. Communication to the master controller is achieved via an I2C bus.
  • A USB wecamera provides the onboard video feed. This data is streamed to a host computer that uses computer vision algorithms to extract information from the video.
  • Two DIY ultrasonic rangefinders mounted on the head of the robot. These sensors are used for sensing the distance to obstacles.
  • Two 300 counts per revolution quadrature optical encoders mounted on the robot's motor shafts. The encoders provide feedback for velocity control, and also input for dead reckoning.
  • It used to have a laser rangefinder that was pulled out of a robotics vacuum cleaner. This sensor was evaluated during my masters. The laser rangefinder provided distance to obstacles and in reating a map of the environment (using SLAM).
  • Voltage monitoring of all each of its 6 cell A123 battery pack.

Mechanical

In many respects, the inspiration for its general shape came from David Anderson's nBot, which is also a balancing robot. The first mockup consisted of a cardboard model. A picture of the mockup model and the bare machined frame:

Once I was happy with the proportions of the mockup model, I created a detailed model of the robot in SolidWorks. It was neccessary to model the robot components in detail to ensure that they all fit together nicely. I also used SolidWorks to create mechanical drawings.

After completing the model I started to source the materials. I found that a lot of industrial outlets are more than happy to give you some offcuts for free. Show them a nice picture of your design and tell them why you are making it! This is how I got the aluminium, plastics and gears (taken from broken industrial laser jet printer) for my robot.

I now could start making the frame of my robot. The perspex disks were cut on a bandsaw and then sanded to shape. This was quite time consuming, and I would suggest to get such parts laser cut. I did for the robot's head disk, at Ponoko. Each of the wheel axles are supported by two bearings. The housing for this was machined out of a solid aluminium rectangle section, using a four jaw chuck on a metal lathe. Sections in the middle were removed using a mill. To get a very good fit for the bearing cases, the hole was precisely cut using a long boring bar.

The robot's tyres are from 5.0" RC aeroplane wheels. They came with a plastic hub, which would have looked ugly on the robot. Instead, I made some aluminium hubs. The aluminium pillars that separate the disks and layers of the robot were also machined. To achieve a high quality finish, a final pass over the piece was done using the lathe's automatic feeder. Cutting oil and appropriately setting the rotation speed also helps to give a good finish. A gallery of the mechanical parts of the robot: 


Electrical

Motherboard

Over the duration of the project, the robot's motherboard has went through four revisions, each with fairly large changes. The current (fourth) revision has the following features:

  • PIC32 32-bit microcontroller at 80MHz with 512KB of flash and 32KB of RAM.
  • Dual MC33886 5.0A H-bridge motor drivers.
  • A 5V 3A SMPS. This is used to power the onboard computer (in this case, a Beagleboard).
  • A SMPS to efficiently reduce the 19.8V battery down to power a linear regulator that delivers power to the digital electronics.
  • Four interrupt driven interfaces to quadrature encoders. Two can be configured to decimate the frequency of the encoder pulses.
  • A USB port. One endpoint emulates a serial communication device that is reserved for debug messages. Another USB endpoint is later to be used for upgrading firmware.
  • Three UARTS (two are provided by the SC16IS762 SPI UART bridge).
  • Two I2C interfaces and one SPI interface.
  • LEDs, I2C EEPROM and a buzzer.
  • Onboard fuse protection.

The schematic of the current revision:

The first robot motherboard was based off an 8-bit ATmega running at 20MHz. The design philosophy for this was to interface to external components through a PPM interface, i.e., the interface used by standard RC servos. The motor drivers were external to the motherboard and made from this design (with slightly modified firmware) which used a servo interface. Athough a PPM interface is acceptable for some projects, I would advise against it for projects requiring precise and high speed control of the motors. Another benefit of having a direct interface to an H-bridge is you can easily adjust the PWM frequency (by changing a line or two of code). The optimum frequency will depend on the particular application. My robot's motors are happy with ~5kHz.

My second iteration of the motherboard used a PIC32. It was much larger and had onboard H-bridge motor drivers. These motor drivers were made from discrete MOSFETs and had logic driving the gates such that it was 'impossible' to blow it up. I'm not entirely sure why this revision did not last for very long. If I recall correctly, I had issues with the PIC32 doing basic things such as bit-bashing pins, yet using its hardware peripherals was a breeze. I also made the mistake of re-using some difficult to get part I pinched from a PC motherboard. It was a Maxim SEPIC power converter. Despite building my design to the reference circuit, it did not work. Perhaps the chip I pulled from an old computer was already toast? Anyway, I've always had trouble sourcing exotic Maxim chips.

The third generation motherboard retained the footprint of its predecessor. However, it took a slighly different approach. I took a slightly more modular approach that used a two layer stackable design. There were three separate boards. The top level had two boards: one with the PIC32 master controller and the power regulation board. The bottom layer had an ATmega, along with two H-bridges and other hardware. For the motor drivers, I opted to use the MC33886 integrated chip, over building a bridge from discrete parts. The MC33886 solution used less board space and saved a lot of hassle. It also has more features such as over-temperature protection. I recommend this route.

Unfornuately this setup required a bit more work to get up and running - it required maintaining two different code bases. The PIC32 would receive commands via its UART port, and told the ATmega what to do via an I2C bus. The information would flow the other way when a request about the status of a sensor connected to the ATmega. The project also surpassed the limits of the ATmega. The encoder signals, which were ~78kHz when the motor maxed out, was too much for the interrupt driven decoder running on the micro, despite being efficiently implemented (each transition was only either incrementing or decrementing a 32-bit variable). An interim solution was to decimate the signals by feeding them into a ripple counter.

I then created the fourth and current revision of the motherboard. This design reverted back to the single board, one CPU (PIC32) design. This is working fine for me at the moment and I have no reason to change it. It is also the first revision where I got the PCB made professionally (at PCBCART) as became too time consuming to make the PCBs myself. Professionally etched boards are also a lot more reliable, look way better, and are easier to solder! An album of my robot's motherboards, with the most recent revisions first:

Battery management system

The robot is powered from six A123 cells. This gives a nominal pack voltage of 19.8V, which makes the robot motors (19.1V Pittman GM8712 with 30.9:1 gearhead and HEDS-5500 encoder) run well. As I did not want to go through the hassle of integrating a battery charger into the robot (but I wanted to monitor the voltages of the cells and make it easy to recharge the pack), I designed and built a battery management system (BMS). Essentially, I'm measuring the voltage of each of the cells. Since I've also measuring the current (of the entire load), the circuit can compute the power being drawn. When the battery charger plugs are detected, the monitor circuit turns off power to the robot so it does not interfer with the charging process. A record of the energy consumed since the last recharged is also maintained. The circuit also provides a soft switch to power on/off the robot. The management microcontroller (ATmega) is always powered, and when the robot is hibernating (i.e., off) the entire system draws a measly 161 microamps. The management controller also shuts down when there is a large imbalance between the cell voltages, or when the battery pack is low. It also acts as a slave I2C device. The schematic of the robot's BMS:

Other electronics

The head unit of the robot has a webcamera and two ultrasonic rangefinders on it. The ultrasonic rangefinder circuits were custom built (read about them here). The head is attached to rest of the robot via the output shaft of a servo. This servo has been modified in that I have replaced its electronics with an OpenServo controller board. This was done to achieve better position response but also because I preferred interfacing to it via I2C. The attitude of the webcamera can also be controlled by another servo. 

Software

Embedded computer

The robot is configured as a telerobot. In my masters project, the high level navigation software (SLAM, obstacle avoidance, path planning, etc) ran on a host PC. It communicated to the robot's onboard computer (a Beagleboard rev. C4) through Wifi. Athough the navigation software could be made to run on the Beagleboard (BB), I think it would require a bit of effort to get it running - cross compilation of code is always a pain, and the program used libraries optimised for x86/x64 CPUs. My intention later on down the track have the entire navigation software running on the robot's computer, but for now, getting the 'heavy lifting' done by a computer works fine.

Before the robot had a Beagleboard I used a modified Wifi router to stream the data back to the computer. It had an ASUS WL-520gU running OpenWrt (a Linux distribution targeted to running on commerially available routers). To get this up and running, I downloaded an image and followed the fantastic MightyOhm Wifi radio project instructions. Last time I checked, only the 2.4 kernel was working properly on the WL 520-gU. This made it hard to get USB webcam drivers to run on it. I eventually managed to do so and described how I did it here. I also wanted to make a serial port (to interface to the robot's motherboard) wirelessly accessible. Again, I've written a page up on how this was achieved. In a nutshell, the webcamera data is made available by a spcaserv network video server, while serial ports are made accessible remotely by a ser2net daemon. The client program (runs on the PC) interfaces to these programs via sockets.

Other than the limitations with running an old kernel, the WL 520-gU router served its purpose on the robot well. When the US-NZ exchange rate was favourable, I bought a BB rev. C4 from Sparkfun. The BB performs much the same tasks as the router did - creates a Wifi access point, and makes the webcamera and serial port data available on its network. Clearly, this configuration is not really utilizing the BB's 600MHz Cortex A8 CPU and 256MB of RAM. However, it fits on the robot's chasis much better than the router. The BB is running an Angstrom image that was built from source using OpenEmbedded.

Motherboard

The robot's motherboard is responsible for interfacing to low level hardware (servos, motors, encoders, LEDs, etc). It also runs time sensitive tasks, such as dead reckoning from the robot's wheel encoders. The current revision of motherboard has a PIC32 on it. Like most microcontroller applications, it was written in C

Although the motherboard contains the core of the custom electronics to control the robot, it uses an I2C bus to interface to other custom built microcontroller controlled module boards (such as the BMS, IMU and the ultrasonic rangefinders). This approach does take longer to implement, but I recommend it for projects that require future expansion. It firstly reduces the risk of having a flaw in the entire hardware, and if there is one, just revisit that particular module. You can also re-use hardware modules that you've created in other projects. Having to communicate via a hardware interface also forces you to abstract your software. Throughout the project, I would often implement software changes that needed to be performed on multiple modules. Since I used an I2C bus, I was forced to implement a communication layer which tends to hide the implementation-specific details. This saved me refactoring code each time I updated something.

A convenient bus to exchange information between a computer and a microcontroller is through a UART port. Although the UART hardware interface has been standardised, it is up to you to define a protocol. For communication between the PC (actually PC to the BB, via sockets) and the robot's motherboard, I implemented a scheme similar to NMEA 0183. It uses ASCII characters, because unlike binary, it is much easier to debug. There are reserved characters ('$' indicates the start of a packet), variables are comma separated, and each packet has a checksum. The payload consists of a message format which I standardised over all of my UART interface modules. The first element indicates the message type, followed by a sub-message type, then the payload. It took a bit of work to get something lightweight, modular and extensible up and running, but it was well worth the effort.

Share |