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.