Followers

Recent Posts

Showing posts with label robobuilder. Show all posts
Showing posts with label robobuilder. Show all posts

Friday, May 7, 2010

Bayesian Classifier Answers the Question: "Is it art?"




The title is a joke, by the way. Although I would be interested to see what the results of such an exercise would be. "Statue of David... *beep*: ART!", "Justin Beiber's Music... *beep* NOT_ART!".

Almost as exciting as my 0-R Spam filter. Catches 100% of spam with a 97% accuracy rate! Oh mercy.

The reason that I mention Bayesian Classifiers is because I wanted to talk about machine learning. This is the other branch of artificial intelligence and what most people think of when the topic of Skynet is brought up.

Fear not though. Bayes rule, decision trees and rule based learning are actually pretty mild. They are simply statistical methods of attempting to classify data by using the results of previous observations. Mostly harmless.

However, today I'm going to talk about genetic algorithms.

A genetic algorithm is an abstract representation of a mathematical function. They can take many forms, such as a string of bits which might indicate the presence/absence of a set of inputs, or a literal mathematical function "y = cos(x) - 2*z". The range of variables which is represented by the function is called a genome.

This can get a bit hard to visualize, so I often just settle for imagining genomes as Taylor polynomials. Therefore, a single genome consists of "x = A*input1^a + B*input2^b ..." where the values of A and a can take any real number. If some of the inputs are simply a higher derivatives of other inputs, then any arbitrary function can be represented in this way. There is also a rather nice representation involving trees.

If we start off with a population of individuals with random valued variables in their genomes, then we can evaluate each function to see how well it 'fits' a set of training data. The individuals which produce the minimum mean squared error for the training data are declared the 'fittest', and are allowed to survive into the next generation.

This is where the 'genetic' part comes in. There are many ways of 'evolving', 'mutating' and 'breeding' individuals, but the easiest to understand is the asexual method. This means that all individuals except the best performer are killed off (ie, deleted) and then their places are taken by the offspring of the remaining individual. However, tiny random 'mutations' are introduced to each of the new individuals variables - such as doubling/halving the values of A or B, or incrementing/decrementing a or b.

Anyway, thats the 30 second version of genetic algorithms. They can be used to find a semi-optimal solution to many problems, provided you can throw enough generations at them. I have been working with a C++ implementation called GAlib. If you are interested, I highly recommend going through the examples.

Now, some of you may be wondering what all this has to do with robots (actually, most of you are probably already filling in the blanks and peeing your pants in terror).

I've spoken on several occasions about using Robobob as a platform to investigate dynamic balance and movement. I plan to represent the control state of the robot as a search tree, with the robot beginning at a starting node/state and attempting to plan a path of control actions to reach a goal node/state. To navigate the tree, I want to implement a greedy search heuristic which will choose which control actions are most likely to lead to the goal state.



Now here's the tricky part - I intend to implement the heuristic as an evolutionary algorithm which can then be rewarded or punished depending on the outcome of executing the control path on the real robot. ie, if the heuristic gets stuck or can't find the goal state, it will be disfavored whereas successfully reaching the goal will be favored. After a series of generations, I will be able to study the path planning method which has evolved from this process.

Cool? I hope so.

Terrifying? Definitely.




Tuesday, February 2, 2010

Robobob

Ladies and gentlemen, I give you: Robobob!



You may recall that awhile back I opened my inbox to email suggestions for a good name. I actually intended to draw the name randomly or put up a poll, but once I started calling him Robobob the name sort of just stuck.

So here he is, in all his 16DOF glory standing up to a withering barrage of socks from all directions.

Once again, he has no gyroscope or accelerometer - he is simply using kinematic feedback from his servos to keep himself stable. The algorithm is almost identical to the one I used way back in this post - but he can now withstand attacks from all directions.

You may notice that he always moves with the force that he is being subjected to. This is the same way that humans usually react - recoiling from a blow or a source of pain. I think it gives him a bit of a personality.

Friday, January 22, 2010

A puzzle

Boy do I have a good one for you today!

First off, version 0.2 pre-pre-alpha-alpha-etc is available. Please download it and try it out - report any bugs or suggestions in the comments.

The improvements in this update focus on enabling the execution of pre-generated actions, such as those from the robobuilder site. A few are included in the Hunobasic.h header for demonstration purposes. I have also written a few useful functions to transfer data from program memory to working memory (which will probably be the subject of the next update).

In keeping with the philosophy of not trying to rewrite the default firmware, I've broken the procedure for executing an action (which is a series of poses) into much smaller steps, which makes it much more intuitive.

Here is the method of making the robot walk forwards:

        getPGMWordArray((int*)HunoBasic_WalkForward_TrTime, (int*)delay, HUNOBASIC_WALKFORWARD_NUM_ACTION);
//Load transition times

        for(i = 0; i <= HUNOBASIC_WALKFORWARD_NUM_ACTION; i++)
        {
//For every pose in the action,
            getPGMByteArray((char*)HunoBasic_WalkForward_Position[i],(char*)position,16);
//Load the angle for each of the servos
            setPose(position,torque,16);
//Tell each servo to move
            if(i < (HUNOBASIC_WALKFORWARD_NUM_ACTION))
            {
//After each frame, except the last,
                j = delay[i];
                while(j > 0){_delay_ms(1);j--;}

//Pause for the required transition time.... 
//wait... 
//..WTF??
            }
        }

What's up with that last part? Why would you loop ten times and each time delay for 1ms, when you could just delay for 10ms in one go?

Well, here's why - it doesn't work!

Substituting the line with:

_delay_ms(delay[i]);

will pause for a much longer time than it should. If you have a AVR, please test this out for me and confirm it. However, passing a constant value to _delay_ms() works exactly as intended. I've tried it many ways, but this is the only method which works so far.

_delay_ms(25);
works, but
delay[i] = 25; 
_delay_ms(delay[i]);
does not.

Mysterious.

As I've mentioned before, this solution is hacky and unattractive. But I thought I might upload the code (the rest of which is working fine) and see if anyone has any suggestions as to why this might be.

Friday, January 15, 2010

One step back

That wasn't so hard.

I think that this code will be more useful to anyone who is trying to use the robobuilder for educational purposes. My goal is not to rewrite the official firmware, but to let programmers have access to the functionality of the RBC and the wCKs.

Code can be found here. It is in pre-pre-alpha mode at the moment, so use it at your own risk. You might want to read this before you test it out.

Wednesday, January 6, 2010

Form vs Function

I thought you might appreciate this video of my robot falling over.



At the end, you may notice that his legs get stuck together like an imperial walker during the battle of Hoth! Ah, memories.

The instructions in the manual indicate very clearly that the nuts should be placed on the inside of the leg - presumably for aesthetic reasons. However, the short section of bolt which sticks out of the inside has a nasty habit of getting hooked on the opposite foot.

If you can tolerate your robot looking a bit road warrior themed, I suggest reversing the direction of the bolts to avoid having your robot flail about like a memermaid, and also the internal damage to the plastic casing:





I do often complain about the robobuilder design, but I think I should make it clear that I am by no means unhappy with it. These are small complaints which (I hope) will be addressed by the robobuilder community and also allow others to avoid my mistakes.

The wCK servos are actually the best robotics servos I've used for their price. You can skip the durability issues I've been having, simply by getting the wCK 1111 version, which has 3 metal gears and a higher torque! They have a suite of extra features, such as brake mode, 10bit positioning (360/1024 = 0.35 degree accuracy!), runtime adjustable PID settings, continuous rotation mode, and the ability to write simple programs to run on the servos themselves.

I have yet to use these features, but I can already think of a thousand uses for them.