Thursday, December 15, 2011

Robot 02

Last month, I built my second robot, which I cleverly nicknamed Robot 02. Its name stands for... well the name says it all, really.


Pictured above, Robot 02 is my second attempt at building an autonomous robot capable of navigating around a room. I wanted it to go around obstacles and detect when it gets stuck so that it can act accordingly.


The hardware


Hardware wise, the robot is quite simple. Its base chassis is a Dagu Rover 5 robot plafrorm. I've discovered that marvelous piece of hardware while searching on the net for robot platforms. This one can use both tracks and wheels, and since it has four independent motors, it can be fitted with Mecanum wheels for ultimate traction control.

Each of the four motors has a dual channel optical encoder built-in. These allow the robot to detect the speed and direction of rotation of each wheel.

Each motor takes approximately 4 amps when stalling, so the Arduino board cannot possibly drive these 4 babies. To drive them, I'm using a Dagu 4 channel DC motor controller.

This board takes care of driving the motors. It has two separate power inputs at the top left and right corners, one driving the logical components, the other driving the motors themselves. On the top side of the board are pictured the connections to the encoders. We have to provide a 5V power supply to each, and we get back two signal wires per encoder (one per optical lens, if you remembered these are dual encoders).

On the sides are the power wires running to the motors.

At the bottom, a ribbon cable sends a mix of digital and analog signals to the Arduino board. It consists of four pins per motor channel. One ground, one digital input that we set to high to reverse the direction, one analog output which varies between 0 and 4.5 volts according to the number of amps the motor uses, and finally one Pulse Width Modulated (PWM) input to control the speed.



Right beside the DC board a HMC6352 compass. From my experience a compass works much better when it isn't surrounded by a whole bunch of other electronic components and wires. Those interfere easily with the compass readings, and since the robot needs to update frequently its heading, we need fast and accurate results. I've mounted the compass on cable headers which I've hotglued to a plastic board spacer. This setup allows me to update the heading more than 5 times a second with reliable readings. Although, I resorted to doing multiple readings and averaging the results. This gives somewhat more reliable readings since it reduces the noise from possible flukes.



At the top of the robot are a pair of opposed ultrasonic sensors fixed to a servo motor. These are required to figure out how close the robot is to obstacles in its environment. I used two LV-MaxSonar-EZ0 ultrasonic sensors. These have a range between 6 and 150 inches and a beam width of about 5 inches, so they are perfectly suited for the size of my robot. These little babies can operate in digital and analog mode. The digital mode gives slower but more accurate readings. In digital mode, the component will send a digital pulse each time the echo comes back. After you do the math and factor in the speed of sound, you get the reading you need. In analog mode, the sensor is much faster but less accurate. The analog pin sends a variable voltage which represents the distance of the echo, but an analog output suffers from the noise of the other components of the robot (especially the servo). These range finders also support serial communication, but I haven't experimented with that yet.

From my experience, I get better results by using the digital mode and I programmed my robot to do multiple readings, which it then averages, to reduce the noise even further. Accuracy and speed are key here.

The SG-5010 servo can rotate 180 degrees in both direction, but we only really need to spin it in an arc of 135 degrees total, thanks to the twin-mount. Since it scans two directions at a time, scanning all around is done pretty quickly. Again, speed is key when dealing with a single threaded micro-controller.


While building my previous robot, I've learned that creating a connection hub with a prototyping board that sits between your components and your micro controller makes your life that much easier. Micro controllers have a limited number of 5V, 3V and ground pins, and this robot requires about a dozen of each. The robot is already clogged with wires; without that board, the robot would looks like a spaghetti ball.

Good prototyping boards are hard to find in Montreal. If like me you don't know where to get good and cheap ones, you can buy them off the old Chinese chap I've met while I was staying in Toronto last year. He runs a little electronics store and specializes mostly in Arduino and other small PMCs. He also makes these neat prototyping boards that you can order directly form his web site. Sadly, as I write this post, I realize that his website is offline for maintenance until December 30th. You can always call him directly to pass your order. He has two models, a 2"x1" and a 2"x4", selling for about 3 and 5 dollars respectively. Trust me, they are really worth their price.

The board will also allow you to mount all your digital and analog inputs on neat wire headers for your micro controller. One thing you don't want is a bunch of loose wires. They get easily disconnected by the moving parts tugging at them every now and then.



The brain is an Arduino Mega 2560. It is pictured above as the blue board with a USB connection and a 9V input. This micro controller is an impressive one. 53 digital (about 10 are PWM compatible) and 15 analog inputs, with 5 serial RX/TX pairs. It also supports SDA/SCL, SPDI and some other mostly shady communication protocols. At 16Mhz, it can run up to 256kb of code with 32kb of memory. This is plenty enough for a robot of that size since it currently use about a third of the inputs and barely a quarter of the processing power.

Sitting right on top of the micro controller is a WiFly shield. Its RN-131G chip uses very little power and has a plethora of features, from wifi network scan to hardware HTTP server. I haven't had time to use it as part of the robot yet, but my plan is to have it serve an HTML page with status information and a manual override of the robot controls.

Power-wise, I use 12 Ni-Mh 2700mAh AA batteries. Its quite a lot of batteries, but then again, that robot is power hungry. The Hong Kong reseller DealExtreme sells these for really cheap (about 14$, shipping included).

The software

Software wise, the robot uses a classical "robot loop". It consists of the three following phases.
  1. Scan the environment.
  2. Analyze and decide what to do next.
  3. Act.
  4. Goto 1.
This loop has to be non-blocking, meaning that if the robot has decided to go forward, the loop must still be executed so that the robot can run the scan phase, thus detecting any problems it should act upon.

I'm programming it in C++ on Eclipse and the AVR plugin. If you are interested the source code of the robot is available on Google code. Arduino boards come with a simple IDE, but I find it to be a bit childish and doesn't offer the productivity tools that you would normally expect from a contemporary IDE. It doesn't have code completion, doesn't let you checkin your files in a SCM, on top of which is a very bad pseudo-file management kinda scheme. I know the ins and outs of Eclipse, so to me this was a no brainer. The effort required to setup Eclipse for AVR development is a bit painful, but nowadays there are some pretty decent tutorials that can help you get there. It's definitely worth the effort though.

As I'm usually working on software only (I'm a software engineer by day...) having to interface with hardware was a brand new experience for me. For one thing, hardware is far from being as precise as simple arithmetics. Most of the components I'm using for this robot have quite a big margin of error when performing measurements. The range finders can give wrong results at random. The compass is easily affected by its surroundings. The servo has to physically turn and you have to account for the time it needs. All these little things add up pretty quickly.

If you fail to factor in all these little things, your robot will quickly behave erratically. From my experience, it feels like each mistake the robot makes is exponentially affecting the final behavior, as each individual error amplifies the others. Make sure that your code can detect these errors and perform the necessary corrections as it goes along.

For this iteration (because I do plan to build many more robots) I haven't really used any fancy path finding algorithm. It uses a heuristic algorithm which goes like this.
  1. Scan the surroundings and map the distance available per polar heading, in increments of 45 degrees.
  2. Pick a direction towards which there is a minimum cleared distance and that is closest to the front of the robot (try to turn as little as possible).
  3. Turn the robot either left or right, whichever is the quickest to the desired heading.
  4. Go forward.
  5. While going forward, scan by alternating between the front and either front-left or front-right (at random, in a proportion of 66% to the side where the distance available is the smallest)
  6. Check the polar heading of the robot. If the robot is not headed properly, goto 3.
  7. If it failed to correct the heading for more than X seconds, the robot is most likely stuck. Back up a little and goto 1.
  8. If a collision is imminent, back up a little, and goto 1.
  9. Goto 4.



I'm planning on implementing something more fancy eventually, but for now it does the job.

In a near future, I'll spend time finishing the HTTP server. It turns out that because the robot's brain has to run in a non blocking loop, HTTP connections are working only scarcely, if at all. This is a problem I still have to resolve. I have a spare ATMega328 micro controller so it will become dedicated to HTTP and will communicate with the brain through SPDI. I've always wanted to learn SPDI anyways.

My girlfriend wants us to build a cute robot body for it, so I'll have to spend some time redesigning the wiring in order to make it much more compact. Right now it is in a bulky prototype form, allowing me to change this and that as I tweak it, but soon enough, I won't need to make any changes to the hardware anymore.

I'll also be spending time perfecting the software, so if you want to collaborate on it, I've made it freely available on Google Code.

If you want more information or need any help with your own design, ask away and maybe we can all benefit from our experiments.

8 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. @fatmi: The gear is worth about 400 US$ total.

    ReplyDelete
    Replies
    1. You have done completly superb work. It's Perfect! I am looking to build something smilar to this robot. Would like to ask you couple of questions.

      Delete
  3. awesome work! I am in Toronto and will definitely pop up at the store that u said! ! do u have any material that explain better the connections between rover 5 and the Dagu motor controller! i got both! and I am not using arduino, so i am kind of lost!

    ReplyDelete
  4. source code is not availale on google
    can u please post it...

    ReplyDelete
    Replies
    1. It is only available within the SVN repository. I don't plan to release it as a single archive. To obtain it, you will need to perform a checkout. It can also be browsed from:

      http://code.google.com/p/devdonkey-arduino/source/browse/#svn%2Ftrunk

      Delete
  5. I am also looking to build something similar, would you be willing to post your code?

    ReplyDelete
  6. For those of you asking for the code, I apologize. Google code was closed, so I moved it on GitHub.

    Cheers

    https://github.com/lucboudreau/devdonkey-arduino/blob/master/robot_02/robot.cpp

    ReplyDelete