Recent Posts

Thursday, December 24, 2009

Merry Christmas

Have a safe and happy holiday everyone!

Monday, December 21, 2009

Phase 1: Collect underpants.

In the absence of a robot capable of supporting it's own weight, I've started planning my next move.

The purpose of writing my own firmware for this robot is purely academic. I don't have a specific goal in mind for this project, even though I'm sure we would all enjoy a robot which could clean our house, bring you drinks, or make us coffee.

As I develop more and more features, I can share them as code snippets which will help other people with their projects. Of course, when I decide I want to revolutionize the coffee robot industry, I will be adequately prepared.

Now that I have figured out how to use the servos as sensors to get feedback about the robot's position, I plan to implement an inverse kinodynamics engine to enable balance without an accelerometer.

For those who aren't down with the lingo, kinodynamics is a contraction of kinematics and dynamics.

Kinematics is concerned with modelling the behaviour of a system given a physical and geometric configuration. In the case of the humanoid robot, this means calculating the relative location of the arms, legs, feet, etc, simply given the angular position of each of the 16 servos. This can be calculated (relatively) simply using basic (again, not something you'd find next to the funny pages) vector mathematics and trigonometry.

Now, dynamics. Kinematics merely describes the geometry and structure of an object. It's velocity, mass, angular momentum and behaviour when subjected to a force are all in the domain of dynamics. When your robot falls down the stairs in a hilarious but tragic accident, his dynamic behaviour determines how long you will watch in abject horror.

So, a kinodynamic model of a humanoid robot can be used to generate a fairly reliable prediction of the state of a robot at a future instant, given the current state and control space.

Put more simply, this model can be used to calculate "safe" actions, which will result in the robot performing a motion while keeping it's centre of mass over it's feet - in other words, balancing.

These are all quite lofty goals, and right now it looks complex, but I'll outline more details in future posts.

Stay tuned for Phase 2: "???"

Friday, December 18, 2009

Two steps forward...

I did a lot of work today, improving the robobuilder motion system and writing some custom functions to take advantage of the special features that the wCKs have to offer.

Unfortunately, my efforts were met with a minor setback when I managed to strip another gear - this time in the poor robot's knee. Unlike the first time, or the time after that, the gear which needed replacing was the first gear in the set - the one which is driven directly by the motor.

This leads me to believe that it broke simply due to regular wear and tear - not because of any specific negligence on my behalf.

Gears tend to be under more stress the further away from the motor they are, because they rotate slower, but with more torque. This is why (I assume), I didn't receive any replacement #1 gears with my kit.

Therefore my plans have been put on hold until I can get my hands on a replacement. This should serve as another important selection criteria for servos - metal gears are worth the extra money.

So today's post will not, as I had intended, consist of more awesome videos of my robot doing awesome stuff.

Instead, please enjoy a variety of other people's robot's doing other people's stuffs.

Above is an earlier version of HINA, doing demonstrations for the robo-one competition. I'm fairly sure that the bottle of water is full, which means that there is quite a lot of power in that little robot. As usual, mujaki has put a lot of effort into the custom body parts and it looks absolutely stunning.

In the not too distant future, I'd like to have a go at customising my servos - particularly given the problems I'm having with these plastic gears.

From cute to creepy.

This is phoenix, a hexapod with an amazingly lifelike gait and behaviour. It looks like a real insect, especially when it goes into attack mode!

Phoenix is able to move so fluidly due to an inverse kinematics engine (another interest of mine). This enables fine control over the body and individual limbs of the hexapod, without compromising the balance or posture of the rest of the robot.

When I can get this servo fixed, I'll upload some more videos of my own - please bear with me. If anyone knows where I can get replacement wCK gears (preferably metal) in Australia - let me know.

Thursday, December 17, 2009

Mirror Mirror

When I first got it into my head that I wanted to build a humanoid robot, I spent quite a lot of time researching various types of servos I could use. They needed to be high-torque, not too big and above all cheap - other features were just gravy.

This led me to consider a number of things, such as using unbranded RC hobby servos, buying unbelievably cheap micro servos and upgrading the motors, and even building my own.

These are not bad options, per se, but what I failed to consider were just how useful those extra features that high quality servos include can be.

Fortunately, I was saved from myself by the timely arrival of my birthday (which I have written about previously).

Though the wCK servos have many additional features, the one that I am finding particularly useful right now is the ability to query a specific servo for it's current position. Although it doesn't seem like much on it's own, it has enabled me to do cool little tricks like this:

The video simply shows me moving the robot's left arm, and having the program mirror the actions on the right arm.

Non-robologists don't seem to find this very impressive, but hopefully the implications of this are apparent if you are in the robot game. Effectively (although crudely), the robot now has a sense of touch.

Don't have a distance sensor? No problem - just set your robot into zombie posture and wait until one of his arms is bumped by a wall.

Worried that you'll damage a servo? Just check to see if it's stuck and turn it off to avoid stripping a gear.

Oh, and before you ask - yes, that is Donatello in the background holding the power and serial plugs.

Here's another video of him with his arms attached (the robot, not the turtle).

The servos are placed in passive mode, which is another special feature of the wCKs, which powers them up but turns off the PID control. Because the servos use an RS485 type bus, they can then be queried by the RBC and then take control of the bus to report their current position.

Although it is a minor achievement, this is another important step on the road to my grand plan. What plan, you ask? You'll just have to wait and find out.

The code is a bit sketchy at the moment, so give me a chance to clean it up before I upload it. Watch this space.

Tuesday, December 15, 2009

Saftey First

After what happened last time, I've become significantly more paranoid about damaging my robot.

Recently, while doing some more hacking of the wCK motion timing system, I decided to simply remove the element of risk altogether.

So far, separating the arms and legs from the body has been a good move (tm), and I encourage you to do the same if you start changing low level parts of the code.

You see, I am rapidly running out of those spanner shaped connectors.

I mentioned in a previous post how careless control over pointers can cause your robot to flip out like a hyperactive kid tripping over a beehive. The wCK servos have just over 11 kgFcm of torque, which is more than adequate to cause your robot to tear itself to pieces when a rogue pointer starts issuing random commands. I speak from experience.

Serial transmission of commands to the servos can be performed in two ways. The most common method is to use the "Transmission Buffer Empty" interrupt, to send a new character whenever there is nothing waiting to be sent. A transmission is initiated simply by unmasking the interrupt, and the interrupt is set to disable itself when there is nothing left to send. This is the preferred way of sending RS232 communications, as the interrupt will continually fire as long as as something remains to be sent.

The second method of transmitting the message is to use the "Transmission Complete" interrupt. If enabled, this interrupt fires whenever a character has finished being sent. This requires a single character to be manually loaded to "prime the pump", but transmission simply stops when no more characters are available. Since the next character is sent immediately, tighter control over transmission states can be achieved, such as when using an RS485 protocol.

The wCK servos use an RS485 protocol.

The reason that the robobuilder has a tendency to spaz out is due to two things. Firstly, the transmission buffer is circular. This means that messages can be added to the buffer at the same time as they are being sent. When the pointer gets to the end of the buffer, it simply returns to the beginning and keeps sending until it reaches the end marker.

Secondly, memory is never truly empty. A byte in memory simply contains the last thing that was stored in it. On reset, unallocated space usually contains junk data. Even if you set up your program to zero out your memory before you use it, it will still contain a zero. Therefore, even a small mistake which results in one of the transmission interrupts not being disabled correctly will cause a vast number of arbitrary commands being issued to the servos, causing the aforementioned spastic behavior.

Aaaaanyway, now that you know why it happens, you know how to avoid it. I still recommend detaching your arms and legs while you're testing though.

Monday, December 14, 2009

All work and no play

I was just reading over some of my previous posts, when I suddenly realised:

They are really boring.

Useful - I hope - to those of you who are interested in building humanoid robots, but probably not that exciting to read.

There were two reasons I decided to create this blog. Firstly, I wanted to have what I have just now decided should be called a "blogbook". This is a collection of my notes on the project of writing software for my humanoid robot, so that I can refer back to it when I forget something, or at least a space where I can get my thoughts to sit down and stay in one place. Making it avaliable online adds the important contribution of allowing other people to read about my mistakes, and how not to make them.

The second reason for starting this blog is that I find humanoid robots completely fascinating. I find that enthusiasm is contagious - everyone has a favourite science/music/drama teacher who was so passionate and dedicated to their subject that they made learning something you wanted to do. I hope that reading about my endeavours will encourage more people to learn about robots and the field of mechatronics. Perhaps you will start your own robotics project.

Up until now, most of the posts have fallen very much into the former category, so the remainder of this post is dedicated to the latter. Lets look at some cool robots!

First up, we have HINA by mujaki. I personally love this video - when I first saw it, it set my imagination on fire. All of the servos and parts are completley custom made, and it reminds me of Plum and Kotoko from Chobits. Not only does it bridge the uncanny valley most successfully, but the video demonstrates exactly why we all should want a tiny robotic servant within the next 10 years.

The red robot is an early version of Omni Zero - before he put on all that weight. I find it interesting the way that he jogs in place, which I assume is a method of getting feedback for him to have dynamic balance. The best thing about Robo-one is that it tackle's the problem of bipdeal robots so casually - for decades, the problem of humanoid robotics seemed unsolvable, but now it's progressed to the level that robots can not only walk - they can wrestle.

Thursday, December 10, 2009

Son of Voltron

Enabling the robot to recharge it's own batteries was something I wanted to get done sooner rather than later. One of the primary reasons for this is that it meant I needed to periodically switch back to the default firmware if I wanted to charge up the batteries. The second reason though, was that it was a very appropriate stepping-stone on the way to getting several other features working.

You see, the atmel 128 Analog to Digital Converter has a built in multiplexer which allows the single peripheral to measure up to eight different voltage nodes relative to ground potential or other nodes, at various levels of gain. Even better, these sources and configurations are software selectable by the use of a 5-bit multiplexer.

If all that sounded like technobabble to you, the long and the short of it is that the same basic code which measures the power left in the batteries can be used to get distance readings from the IR sensor, and sound input from the microphone!

But back to the power level sensor. This version of the code uses the debug info LED configuration to report the current level of the battery. If your robot is not plugged in, you can actually see the voltage drop when PF1/2 are pressed and the servos are moving. This is achieved by setting the multiplexer ADMUX to channel ADC1, and enabling the AD conversion complete interrupt in ADCSRA, which saves the voltage to the global location gA2D. It is only occasionally necessary to know the voltage, so conversion requests are triggered manually (as opposed to continuously) by setting the ADSC bit.

Recharging is enabled by setting bit 4 on PORTB, which digitally connects the battery to the external power source. Pressing and holding PF1 and PF2 for 2.5 seconds enters recharge mode, which trickle charges the NiMH batteries. Because I'm paranoid after the previous incident, the default setting is to only charge the robot for 10 seconds at a time. If you want to fully charge the batteries, pressing PF1 while the robot is charging will keep the batteries charging indefinitely.

"But Alex!" hear you cry. "If you can measure the voltage, why not simply disable charging when it's maxed out?"

Unfortunately, it's not that simple. When the external power source is present, the RBC automatically changes over the V++ supply to the power pack and becomes the voltage source. This means that whenever the plug is in, the value of gA2D will be that of the power source - even when the battery is low. I haven't figured out a way around this - you might also have noticed that there is no automatic recharge cut-off for the default firmware either.

The code is here. I'm looking for a better hosting service, but in the meantime, remember the click the "free" tab.

Thursday, December 3, 2009

If I only had a brain

As promised, I have made some changes to the robobuilder source files so that movement commands execute properly.

The problem seemed to be that the wCK transmit interrupt was being disabled prematurely, before all of the instructions could be sent. General defensive programming practice on behalf of the designers meant that any function which placed commands into the transmit buffer intentionally waited patiently until the buffer was empty. This avoided accidentally fragmenting the instructions due to the limited size of the buffer, but meant that the program would just freeze up if (for whatever reason) the transmissions were not being sent.

With a little debugging, I identified the MakeFrame() function as the culprit, which was causing the program to get stuck waiting for the transmit queue to clear, but since the interrupt was disabled it stayed in an infinite loop. Simply placing a few lines inside the while loop making sure that the interrupts were enabled fixed the problem.

I also made a few other aesthetic changes - mostly making things more readable by replacing "magic numbers" with the names of registers. For the uninitiated, A |= (1<<X) means 'set' bit X in register A, while A &= ~(1<<X) will 'clear' the bit. The header file iom128.h in avr-libc contains the names of all the registers.

Overall, the code here is a very good starting point if you want to start messing around with your robobuilder's brain. However, the functions do a LOT of polling, which should be replaced with interrupt based timing control if you plan to implement more complicated functions.

The files can be found here. I apologise for the horrible free hosting service. Be sure you click on the "Free" tab before you hit download.

My next goal is to figure out how the recharging procedure works, and give the robot some sort of power management routine. Perhaps eventually he will be able to detect when his batteries are dying and go recharge himself.

Monday, November 30, 2009

It was only a matter of time...

It was inevitable, really.

While chasing a guinea pig under a table, I managed to cause enough vibrations for the robot to topple off and land face-first on the ground. Although this may sound both comical and adorable, I was not amused.

At first, everything seemed OK, but closer inspection revealed that one of the spanner shaped connectors had snapped, and more thorough testing revealed that one of the servos was making a grinding noise.

Disappointed, but not discouraged, I voided my warranty and opened it up to see what the problem was.

As it turns out, I had stripped some teeth of a plastic gear, which meant that the motor was spinning uselessly as the feedback loop was broken. Fortunatley - in one of the more pleasant customer experiences I have had - it turns out that the robosavvy people had included a bag of spare servo gears.

So fixing it was just a matter of unscrewing the case and feasting on the delicious goo inside. If a screwdriver was included in your kit, don't use it to open the servo cases! It's just a shade too big, and I ruined the tip by trying to get the screws out. Just one size smaller should do it, but be sure to push down hard against the screw so that you don't strip the head off.

Included in my kit was an instruction sheet (the backdrop of these photos), which explained how the wCK modules can be re-assembled. I don't know if this is because the expect them to need servicing at some time, or just because they had the CAD models lying around. Either way, there isn't much to the gear assembly, so don't be afraid to open one up if you are curious. After replacing the damaged gear, I simply slid the bearing back on to the drive shaft and put the case back on.
At this stage, I was worried that I might have not oriented the output shaft correctly, resulting in the servo position being slightly out of phase with the desired angle. However, the wCKs must use optical encoding or something to establish their position, so after putting the case back on it just worked straight away. [UPDATE - The servos actually use a potentiometer, but the shaft is designed to only fit correctly].

So there you go - a potentially disastrous situation was averted thanks to the inclusion of some spare parts. Since nothing lasts forever, I would recommend you order from robosavvy - their service so far has been exemplary.

[UPDATE - the official servo repair instructions are available]

Debugging robots for fun and profit

More astute readers who followed the procedure in my last post may have noticed that it didn't actually work.

That's not to say that the instructions were wrong - those are still the steps to build the robobuilder C source files and upload them to the RBC. The problem was that the code which I linked doesn't actually do what it says on the side of the box, so to speak.

The execution of the code posted on the robosavvy forum (which is primarily an english adaptation of the official code) should result in the robot performing the RIGHTPUNCH action when the PF1 button is pressed. However, when the files are built and installed on the robot, no amount of button pressing will elicit a response from the robot.

I'm working on producing an updated version of the code which is nice and flexible, which I will upload here when I'm satisfied with it. In the meantime, for those of you playing along at home, I thought I would share a quick debugging procedure known only to a secluded group of embedded systems programmers.

There are on-chip debuggers available for the AVR family of microcontrollers, however I don't have one. There are also situations when the debugger causes more problems than it solves - ie, by hogging certain pins on the board, or restricting the flow of real-time interrupts. The poor mans solution to this is to set up a quick method of stepping through your program and seeing where it gets to and where it gets stuck. The easiest way of allowing your program to communicate back to you is using the onboard LEDs.

#include "macro.h"
#include "main.h"

WORD gDebugMode = 1;

void Debug(BYTE code)
CHK_BIT7(code)? RUN_LED2_ON : RUN_LED2_OFF; //Green
CHK_BIT6(code)? PF1_LED2_ON : PF1_LED2_OFF; //Red
CHK_BIT5(code)? PWR_LED2_ON : PWR_LED2_OFF; //Green
CHK_BIT4(code)? PWR_LED1_ON : PWR_LED1_OFF; //Red
CHK_BIT3(code)? PF1_LED1_ON : PF1_LED1_OFF; //Blue
CHK_BIT2(code)? RUN_LED1_ON : RUN_LED1_OFF; //Blue
CHK_BIT1(code)? PF2_LED_ON : PF2_LED_OFF; //Yellow

The input to this function is just a number you can assign to a particular error/state code: ie, Debug(3) would have the error and PF1 LEDs lit, while DEBUG(0) turns all the LEDs off. Combined with the use of the _delay_ms(1000) command, you can sprinkle these throughout problem areas and observe how your code branches or if it gets stuck anywhere.

The ordering of the LEDs may seem arbitrary, and it can be a little hard because the ordering zig-zags upwards from LSB (error) to MSB (power), and then zigs back down again. The reasoning behind this is because I wanted to make the lower numbers easier to read, since three of the LEDs have two possible colours. Hence, it's just normal binary for error values up to 2^5 = 32, and only mildly more complicated for bigger numbers.

Wednesday, November 25, 2009

C is for cookie

The robobuilder kit comes with a suite of tools which can be used to easily create poses and moves. Unfortunately, the overall impression they gave me was that they were useful for little more than making the robot dance. There were some useful features, such as being able to record the current pose of the robot and save it to a file, so I will probably play around with them later.

One of the most attractive features of the robobuilder system is that the firmware can be reprogrammed in C. If that doesn't send shivers down your spine, the rest of this post will probably be over your head. Go watch tv until the grown-ups are finished talking.

The tools to customise the robobuilder firmware are available for download. It comes with a 70 page PDF tutorial which walks you through the process of using the CodeVisionAVR IDE to customise the example builds included. The CodeVision IDE is not free, but I would recommend following the official procedure if: a) You are new to the C language or microprocessor programming and b) you use Windows.

If, like me, you fall into neither of the above categories, I suggest you save your money and have a go at using the avr-gcc compiler and/or WinAVR (which is just a Windows implementation of avr-gcc).

But first, a short rant.

When did motherboard manufacturers stop including serial ports?! I know that they are an aging technology, but they are damn useful. And you, robobuilder - you knew this all along but you didn't ship with a USB adapter or anything. I'm very disappointed. So here I am, forced to write code on the only computer in the house with a serial port - an old Dell Latitude D600. It runs Ubuntu 9.04 and was being used as a media centre PC, but I've since commandeered it in the name of the robot uprising. FYI, all of the robobuilder tools and software will run under WINE.

If you are compiling your code in linux, you will need to install avr-gcc and avr-libc. For reasons unknown, avr-gcc will not detect that avr-libc is installed and include it's headers when you compile. If you get an error message like:

error: avr/io.h: No such file or directory

You may need to copy the contents of /usr/lib/avr/include to /usr/lib/gcc/avr/4.3.2/include.

This robosavvy thread contains a port of the official robobuilder example source files which use the standard avr-gcc headers (also, comments in english!). Details about converting headers to gcc can be found at the avr-libc page. This is the skeleton code you need to edit. Use the command:

avr-gcc -mmcu=atmega128 -I. -g -Wall -Os -c main.c

to compile the source. I do recommend the -Os flag, since there is only 128kB of flash memory on the chip. You may still get some error messages at this stage - I did.

The names of header files are case sensitive in gcc, so check that the names of the #includes match the filenames:

#include "macro.h"
#include "main.h"
#include "comm.h"
#include "dio.h"
#include "math.h"

This should get rid of the remaining compile errors. Next you must link the files together using:

avr-gcc -o main.elf -mmcu=atmega128 main.o comm.o dio.o

If you get linker errors at this stage, check that you used the same -mmcu values for both compiling and linking (otherwise, gcc will try to link to code intended for different platforms).The final step is to convert the instructions to hex using the command:

avr-objcopy -j .text -O ihex main.elf main.hex

The .hex file created from this step is the actual firmware which will be written to the atmega128 chip. To upload it to the robot, simply run the "RBC Firmware update tool", and connect the robot using the (shudder) serial cable. Select the appropriate .hex file, and click the "Click Here" button. Now, press the reset button on the robot, and let the download finish.

To start the custom program, press the PF1 button. BEWARE! If you've made a mistake in your code, your robot will spaz out like an epileptic kid during a fire drill! To prevent damage itself and nearby life forms, either hold it by the head or make sure it is on the floor before testing it. Also note that unless you've specifically prevented such actions, the robot has no idea of it's own kinematics - meaning that it is quite likley to try and put it's arms through it's body when trying to scratch it's back. Be ready to kill the power if you want to prevent damage to the servos.

Now that I have some skeleton code to play with, over the next few days I'll experiment with various useful functions of the chip, like loading pre-built motions and getting data from the IR remote.

Monday, November 23, 2009

It's Alive!!

The Robobuilder kit is actually really easy to put together. Inspired by similar robots, I chose to assemble the HUNO configuration.

The instructions are very easy to follow, but here are a few things that I learned which might make it easier if you are having trouble.

Firstly, whenever I build something, I assume I will make at least one mistake. This might mean undoing and re-doing several steps, so I never tighten anything down completely. This has the added advantage of making it easier to line up parts which are already attached to the assembly. Most of the wCK servos are attached to the frame using four screws, but only two are necessary to fully constrain the unit. Once I had fully tested the robot, I went back and put the other two screws in each of the servos.

I was glad I took my own advice when I realised about 4 steps in that the numbers on the servos actually matter. I should have realised this earlier, since the servos are daisy chained together, so they must need to be addressed in some fashion. It is possible to reassign the ID numbers on the servo, but all of the examples and tools assume you have assembled the model as shown in the instructions.

The little spanner shaped connectors have a tiny bronze threaded nut in one side of them. If the bolt you are using isn't exactly lined up with the hole, it has a tendency to push the bronze nut out of the plastic. Once out, it's really hard to get back in, so make sure that you can see right through the hole before you put the bolt in.

Finally, I strongly recommend attaching the arms (steps 15 and 16) before attaching the legs (step 14). The legs are very heavy and tend to flop around while you're trying to orient the arms to put the bolt in. The arms are much lighter and won't move under their own weight.

Anyway, without further ado, here he is!

Isn't he cute?

Sunday, November 22, 2009

Some assembly required

Having a birthday close to Christmas can be challenging when you are young. Cool toys are released all year round, so it is important to put a lot of forethought into your letters to Santa if you are to weather the 11-month-drought until next year.

As an adult however, has it's perks. Despite the discovery of impulse purchases, knowing how hard you work for each dollar you can spare for indulgences usually sucks out all the fun. Hence, I restrict myself to cruising the interslice, imagining all the cool stuff I could buy and stopping just short of entering my credit card information.

Often, more than half of my open tabs fall into the "would love to have, but would never buy for myself" category. Sometimes, the right mix of unattended computer, exceptionally bright girlfriend and a wonderful family allows the Christmas-birthday combo to really pay off... when your entire extended family pitches in to get you your very own robotic minion.

Now, as everyone has surely figured out, robots are cool. However, I find them particularly fascinating, and have spent 5 years of my life studying them. So I did what any self respecting member of the internet would do, and started a blog.