Balancing robot, thoughts welcome

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi freaks,

I completed the new board for my balancing robot, wrote some quick software, assembled the stuff and there's something to show. I made a little video.
Larger version (32Mb) is here:
http://www.sensi.org/~svo/rakipaki/akipaki-rev2.mpg
Smaller (5mb) but poor quality here:
http://www.sensi.org/~svo/rakipaki/akipaki-rev2.wmv

Let me explain the construction.
The chassis is based on a cover of 3.5" floppy drive. Two fully lobotomized RC servos (HS-311) are mounted on sides. The wheels are cut from remains of floor cork boards, wrapped with duct tape for better friction.

There are two boards (the gallery on site shows older construction). One is motor logic, h-bridges and voltage regulator for logic circuit. Motor logic accepts PWM stream + direction for 2 motors and drives h-bridges.

Another is the main board with ATmega32 running at 10MHz, some complementary stuff and a daughterboard with MMA6260Q dual-axis accelerometer. This a-meter gives 2 voltages proportional to g (when mounted vertically) that are measured by ATmega builtin ADC. Three pots also allow input of PID coefficients for tuning. There's also an i2c LCD display that can show some debug information, like the actual values of coefficients and important startup message saying "AKIPAKI".

So far it doesn't carry its own batteries. I'm not sure that these motors can generate enough torque to balance bigger mass between them. The first version of Akipaki actually could carry its batteries, but it could not stand very well too. First version used only half-lobotomized servos (only feedback broken, control circuitry intact) and pic16f876 as the main controller. I burned the PIC and I'm now happy.

The robot shows some juggling in the beginning of video. I tuned the D part of PID down a notch, the juggling disappeared. But in general it seems that the construction is very very sensitive to P and D terms, lesser to the I-term. A little less P, and it can't stand up. A little more P and it goes haywire, no D can stabilize it. BTW, the loop runs at 500Hz. I couldn't make it stable enough with slower frequency and I feel I could make it even better if I could make the loop run faster.

How would you fix this beast if it was yours?
Where would you put batteries? I'm going to use two 4-AA battery holders.
Or just anything you think of when seeing this, any comments are welcome.

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is an article about a poor man's home-made scooter like a segway... says it uses a little positive feedback to balance...need to drive into the falling direction faster than it is falling. Its kind of like audio... no substitue for power. Need F to get that M Accelerating. I'd go with a 16 or 20mhz AVR right off the bat. (but that's because I'm a sw guy... always cover my butt by using the fastest hw)

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think the clock speed is the problem now. Even if I run my AVR at 16mHz, the bottleneck is ADC speed, and I need to continously switch between two ADC channels.

It feels more like the motors are indeed underpowered. In itse present form, the bot is not really an inverted pendulum, more like some platform between wheels that keeps itself level. If i stack something to make it higher, I run into trouble - the bot can't chase its own fall fast enough (it's like when you run very fast, you can lean down to the ground; but if you don't get upright when you stop, you fall).

BTW, I used some Advanced Security Technologies for a new set of wheels.
http://sensi.org/~svo/rakipaki/akipaki-newwheels.jpg

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I theorize that you only need to sample faster than it can oscillate... on the video it sounds like a steam locomotive..chugachugachugachuga... 10hz or so.... you certainly ought to be able to sample the a/d channels several 1000 times a sec. At this point I suspect processor speed WILL be the determining factor, so might as well order a 16MHz mega128.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But i made it stand still.
I changed R in RC filter on analog inputs to make sure that frequencies higher than 1/2 of sampling rate are dampened, then I moved the sensor closer to the wheel axis. It may sound weird, but in fact this steam locomotive tremor is mostly caused by error in measurements. G-meter starts metering acceleration perpendicular to G, hence the error I don't account for, hence the tremor. Moving the sensor closer to axis helped a big deal.

Other people solve this problem by combining a gyro and an accelerometer. Gyro gives inclination data, accelerometer is only used during stable periods to recalibrate the gyro (or so I thought) but I felt that this would be an overkill for a project this simple.

I sample 2 ADC channels 500 times a sec. Do you think 1000 times a sec would make a difference? With 500/sec I can kill the tremor but can't make the bot chase itself fast enough, which probably has little to do with loop frequency.

I'm going to follow your advice anyway and solder in a 16MHz quarz (my atmega is 16mhz, I just had 10mHz quarz handy and that's why I used it). It never hurts to try.

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know how to make a tilt sensor with 2 acceleromoters... atan2(yGs,xGs)... the trick is to know when its moving fwd and back..... thats when the sqrt(xGs*xGs+yGs*yGs) is within a few % of 1G. In other words, read the tilt when it isnt scooting fwd and back. Any of this make sense or am I off in the ozone?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, if you explain what is arctangent of 2 arguments, maybe it will :)

Here's how it's set up in my robot:
Accelerometer is placed so that its axes point down like a wedge: \ /
So

yAcc = f1(tilt), xAcc = f2(tilt)

I calculate tilt (error) in no-units, as in your terms that would be

    error = yAcc - xAcc

so that when the wedge is pointing downwards, error == 0. This is convenient because
I don't have to calibrate the sensor and when power or something else plays funny, I would still get 0 at vertical position. I'm pretty sure that it's safe to assume that f1 and f2 are linear at relatively small angles and with overall low precision.

Then I have something like

  output = PID(error);
  PWMReloadValue = abs(output);
  PWMDirection = sgn(output);

About the hypot - that I have yet to understand. This is a dynamic system and the only way to be sure that it isn't scooting is to check that difference between current and last error is within certain range, e.g. == 0. This of course never happens when it's scooting :)

I have a suspiction that you assumed that I have 2 sensors, while I have only one and it is a dual axis accelerometer. The only option is to never let the system enter the state when it's unstable, or detect instability and forcingly reset the loop to dump of accumulated error and momentum.

Maybe this is unacceptable solution in industry, but pretty much ok for a hobby robot that's too weak to wield an axe.

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, if you explain what is arctangent of 2 arguments, maybe it will
==========================================
atan2(y,x) computs atan in all 4 quadrants.

you assumed that I have 2 sensors, while I have only one and it is a dual axis accelerometer.
==========================================================
I said I knew how to build a tilt sensor with 2 acceleromoters. That is exactly the hw you have

Show me your formula to get tilt. Mine is accurate to less than a degree, but I convert the volts to Gs, and it helps me to visualize if one axis is fwd and one down. I call this 0 degree tilt. I'd call your arrangement 45 deg tilt. Guess it doesnt matter.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

/Rant

Quote:
main board with ATmega32 running at 10MHz

Quote:
and pic16f876 as the main controller

I'd go with Bob's 1st suggestion:

Quote:
I'd go with a 16 or 20mhz AVR right off the bat.

Or choose a pic (P_tur) forum.
/endRant

Sorry Guys, i'm in a bad mood tonight :)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rberger: you obviously didn't read the discussion at all and just snapped some words that resonate with your bad mood in the most efficient way, isn't it so?

bobgartner: I already posted the formula for tilt calculation. I do not use physical values of any kind, I just calculate the error (proportional to tilt) and try to minimize the error with the only actuator I have (wheels). I see no use for calculating tilt angle in degrees because what I have is actually a kind of a blackbox: I can modify its state by and the only input variable and I can check its state by reading its only output variable. Well, it also works!

I'm not sure this discussion is really going in the right direction because calculating tilt is not my problem. I can make the platform stand still and I can make it tilt in any direction at will. Or are you making a point I recklessly miss again and again?

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or are you making a point I recklessly miss again and again?
================================
The tilt sensor gets confused under 'dynamic' conditions... fwd and back accelerations are indistinguisable from tilt.... so what if there was a way to tell when you were reading tilt or manuvering? If I'm sitting still and level, the accel pointing fwd will read 0Gs, and the one pointing down will read 1G. If I am tilted 45 down, I will read .7G fwd and .7G down, but sqrt(X*X+Y*Y) will still be 1G. This test fails when manuvering.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:

The tilt sensor gets confused under 'dynamic' conditions... fwd and back accelerations are indistinguisable from tilt.... so what if there was a way to tell when you were reading tilt or manuvering? If I'm sitting still and level, the accel pointing fwd will read 0Gs, and the one pointing down will read 1G. If I am tilted 45 down, I will read .7G fwd and .7G down, but sqrt(X*X+Y*Y) will still be 1G. This test fails when manuvering.

Bob! This is genious. I'm ashamed that I haven't thought of that myself. Thank you!

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is AVRfreaks a great board or what? I just love this place. Too bad we cant use it to leverage some programming jobs somehow.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It helped. I don't know what would be the most practical to do when measurement is disqualified, but after some experiments I just keep the error value as measured but substitute proportional coefficient with 1/2 of its normal value thus relying more on integral term. I could increase proportional term a little while shaking became much less persistent. This is good.

Now I have another problem. I gave up on the idea of making this bot balance a big pole because the speed my motors give just doesn't cut it. Instead I tried to put batteries on both sides of the platform, near the bottom. Works fine, except that now any little static offset from equilibrium (and it always has place) makes Akipaki go into the direction where the balance is shifted. Apparently this happens because the tilt is not large enough to speed up significantly, it compensates a little and it only causes more movement in the same direction. So it travels slowly in one direction instead of standing in place.

I think I could solve this by usin shaft encoders and adding measured speed into the equation. So that if robot is supposed to stay still but it keeps moving, it should compensate more. Any suggestions?

The Dark Boxes are coming.