Go Down

Topic: Balancing robot for dummies (Read 283295 times)previous topic - next topic

kas

#30
Oct 10, 2010, 08:28 amLast Edit: Oct 10, 2010, 08:36 am by kas Reason: 1

http://www.pololu.com/catalog/product/1443

Pros:
- powerfull (110 oz.in)
- solid design (metal gears)
- fast (350RPM, don't settle for less than 200RPM)
- integrated, efficient encoders (464 counts per wheel rotation)
- acceptable price (40 bucks, including encoder)

Cons:
- noticiable backlash (as with all spur gearmotors)

Planetary gearboxes are supposed to have no backlash
I have still to identify a planetary geared equivalent motor (speed, power, encoder)

kas

#31
Oct 16, 2010, 11:49 am
I am currently integrating encoders data in order to reduce forward/backward drift

Wandering around for new ideas, I came across this one:
I have yet to see a more stable bot
Lets hope this guy will open a blog soon for documenting his project
Congratulation beautifulsmall

kas

#32
Oct 22, 2010, 03:03 pm
[size=14] ** Balancing robot for dummies **[/size]

[size=14]Part four: PID control[/size]

Forewords: Control strategy is a whole univers, let's keep it simple

[size=14]8 - Possible control strategies[/size]

error = Actual value - Set point

[size=12] - ON/OFF control[/size]
This strategy in used for electric heaters with mechanical thermostat

Code: [Select]
`pseudo codeif actTemp < SetPoint      Power = ONelse                  Power = OFF`

Code for a basic (static) balancing robot
Set point = 0
error = actAngle

Code: [Select]
`pseudo codeIf actAngle = 0       Motors stopelse if actAngle <0      Motor full forward (PWM 256)else if actAngle >0      Motor full backward (PWM 256)`
Don't try it, it just doesn't work; let's be more sophisticated.

[size=12]- PID control (Proportional Integral Derivative)[/size]
This control is the sum of 3 actions

Proportional action:
The proportional term makes a change to the output that is proportional to the current error value.

Code: [Select]
`pTerm = Kp * error`
A high value will cause a hard counter reaction to a change in attitude.
Above a certain value the system will start to oscillate, the ideal spot is just below this point.
You cannot ballance a robot with a proportional value of 0.
Proportional control only is much better than pure ON/OFF, but the Bot will keep oscillating and finally fall on the floor

Derivative action:
This action is proportional to the error variation
With a fixed time loop, time may be omited:

Code: [Select]
`dTerm = Kd * (error - last_error);                              last_error = error;`
The Derivative portion calculates how fast a change in angle occurs.
With ballancing bot, these values are usually used as a damping factor, meaning negative signs in the formula.
Without the derivative action, there is no damping to dissipate the energy of the system.
With only proportional control, any input to the system will cause an undamped oscillation that will continue for ever.
If you are an electrical engineer, think of how an RLC circuit differs from an LC circuit
The derivative term works the fastest, because it detects change in rate before even a significant error appears.

Integral action:

Code: [Select]
`integrated_error += error;                                        iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN);`GUARD_GAIN sets up a limit for iTerm.

The integral term allows a precise landing at setpoint, it is known as "steady state error".
It is the only term that keeps changing no matter how small the error remains.
You're basically telling the controller, "if you aren't quite getting to angle, keep increasing PWM over a period of time until you get there".

PID control is the sum of those 3 actions

Code: [Select]
`int updatePid(int targetPosition, int currentPosition)   {  int error = targetPosition - currentPosition;  pTerm = Kp * error;  integrated_error += error;                                        iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN);  dTerm = Kd * (error - last_error);                              last_error = error;  return -constrain(K*(pTerm + iTerm + dTerm), -255, 255);}`

The best PID analogy I found is the spring car suspension:

kp is the strength of the spring.
kd is the amount of damping needed to stop oscillations due to kp.

Proportional reacts to a measure of the present error.
Derivative reacts as a prediction of the future error,
Integral adjustment is based on past errors

PID tuning:
For manual tuning, set all three constants to zero, then turn up Kp until oscillation occurs.
Then turn up Kd until oscillation disappears.  Adjust Kd until the system is critically damped, i.e. there's no overshoot.
Then increase Ki until the steady-state error goes to zero in a reasonable time.

http://en.wikipedia.org/wiki/PID_controller
http://www.jashaw.com/pid/tutorial/

[size=14]Next part: DC motor control and final complete code (Version 1)[/size]

beautifulsmall

#33
Oct 23, 2010, 09:13 pm
first post in Arduino,may well be teaching granny to suck eggs,  been making a 2-wheel balancing robot for 12months now. earwig robot on youtube, The BMA180, arctan2, combined with the ADXR150 gyro(10-bit) gives a 1/16 of a degree resolution. Nice.complementary filter. After Hours spent tuning pid values the best solution I found was to have a timer giving a step change to the motor PID, the step level was interactive as were the pid values, this way you can see whare the Buzz and unstable parameters are. The balance equation,
vert_error+base_vel+body_vel+position_error.
if vert error is initially off, the robot drifts until the pos error cancels out and the bot oscillates around a + or -pos offset , this can be used to calibrate the true vertical.
trying to map now and getting lost.
i wouldn't be this far on without the help of others

kas

#34
Oct 24, 2010, 10:28 amLast Edit: Oct 24, 2010, 05:43 pm by kas Reason: 1
Hi beautifulsmall, welcome to this forum

As already mentioned, you built the more stable Bot I have ever seen (I saw a lot those last 2 years  )

I am really impressed by the lean back motion when pushed

My Version 1.0 KasBot doesn't yet take advantage of the encoder wheels;
It is stable and can balance forever, however it may drift forward/backward.
This is perfectly normal as the bot is not yet position aware
The idea is to inject encoder data in the PID loop:

Code: [Select]
`KasBot V2 alphaint updatePid(int targetPosition, int currentPosition)  {    int error = targetPosition - currentPosition;    pTerm = Kp * error;                             // error: angle    integrated_error += error;                                          iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN);    dTerm = Kd * (error - last_error);                                last_error = error;    xpTerm = K2p * count;                               // count: encoder tics    xdTerm = K2d * (count - last_count);                              last_count = count;    return -constrain(K*(pTerm + iTerm + dTerm + xpTerm + xdTerm), -255, 255);  }`
For encoders, I use speed proportional (K2p) and derivative (K2d), no integral
It does help somehow, forward/backward drift is reduced, but I am still far from what you achieved.

Code: [Select]
`vert_error+base_vel+body_vel+position_error`Not sure to understand  :-?
vert_error = angle
base_vel = angle (derivative)
body_vel = encoder (derivative)
position_error = encoder

- forward/backward drift suppession
- lean back

finally, please post relevant code or speudo code

Patrik

#35
Oct 26, 2010, 07:54 pm
Now I have gotten the parts and will start building a jig to be able to test the parts.

I have started thinking about how to build the robot and especialy where to place the accelerometer and the gyro,

What I understand I need to have the gyro X-axis in the rotation centre of the wheels but how is it with the accelerometer. when its reading acceleration couldn't I place it where ever I want on the robot?

http://www.x-firm.com/?cat=6
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

T.J.L.

#36
Oct 26, 2010, 10:10 pm
Quote
I have started thinking about how to build the robot and especialy where to place the accelerometer and the gyro,

What I understand I need to have the gyro X-axis in the rotation centre of the wheels but how is it with the accelerometer. when its reading acceleration couldn't I place it where ever I want on the robot?

Could someone please explain me why the gyro should be in the centre of rotation. As far is I understand gyro measures angular velocity, which is exactly the same in every point of a rigid body.

I think the average acceleration would be the same in every point of the robot. When the robot starts leaning to some direction the upper part of the robot accelerates slowly and when it corrects the position the lower part accelerates rapidly.

kas

#37
Oct 27, 2010, 08:58 amLast Edit: Oct 28, 2010, 07:48 am by kas Reason: 1
Quote
Quote
I have started thinking about how to build the robot and especialy where to place the accelerometer and the gyro,

What I understand I need to have the gyro X-axis in the rotation centre of the wheels but how is it with the accelerometer. when its reading acceleration couldn't I place it where ever I want on the robot?

Could someone please explain me why the gyro should be in the centre of rotation. As far is I understand gyro measures angular velocity, which is exactly the same in every point of a rigid body.

I think the average acceleration would be the same in every point of the robot. When the robot starts leaning to some direction the upper part of the robot accelerates slowly and when it corrects the position the lower part accelerates rapidly.

Interesting question

I tend to agree with TJL for Gyros
Gyros sense rotation only, not acceleration.
Rotation is a "system wide" variable for a rigid system
They can be placed anywhere you want, even at the very top of the bot

I have a different analysis for accelerometers
Accelerometers measure both static acceleration (gravity) and dynamic acceleration (movement). They are also very noisy.
Static acceleration is system wide, dynamic acceleration (as speed) is not
As we are interested only in gravity measurement, we want dynamic  acceleration as low as possible.
The best place for reducing rotational acceleration is near the the motor axis.

Others may jump in and correct me if I am wrong
For those who build or already built a bot, where did you decide to place the sensors ??

@Patrik:   I went on your blog, nice start!
Keep feeding it and report here your baby's first steps

gibby623

#38
Oct 28, 2010, 01:29 pm

This is my understanding of the sensor's placement for a balancing system, the ideas are off the top of my head and should not be considered right unless you feel they are correct or can be proven. Feel free to correct me, I am writing my Thesis at the moment and any input would be encouraged. Without further ado, my answer.

Quote
I tend to agree with TJL for Gyros
Gyros sense rotation only, not acceleration.
Rotation is a "system wide" variable for a rigid system
They can be placed anywhere you want, even at the very top of the bot

I agree Kas. The basic calculation to vary between translational and rotational movement is v = wr, where the translational velocity (v) can be found by multiplying the angular velocity (w) by the radius it is rotating (r).

As the gyroscope a.k.a angular rate sensor is able to read only rotational velocities, it may be placed anywhere on the robot, assuming that the sensing axis is parallel to the axis of rotation of the mechanical system.

Quote
Accelerometers measure both static acceleration (gravity) and dynamic acceleration (movement). They are also very noisy.
Static acceleration is system wide, dynamic acceleration (as speed) is not
As we are interested only in gravity measurement, we want dynamic  acceleration as low as possible.
The best place for reducing rotational acceleration is near the the motor axis.

I partly agree with this. Accelerometers sense, as the name suggests, the acceleration along the corresponding sensing axis. However, I stray slightly from your definition Kas.

Your definition of dynamic acceleration seems more like the rate of change of acceleration, which, if anyone is interested it is known as a Jerk. I understand what you were trying to say though!

However, back to the point. In terms of a static system, the only acceleration the accelerometers will sense will the the earth's gravitational pull referenced to each sensing axis. This, for a balancing robot, is what you require from the sensor. However, the situation is complicated when the mechanical system also has translational acceleration. The Accelerometer sense translational accelerations, not angular acceleration. Returning back the to previous equation. As the rate of the angular velocity changes (i.e. angular acceleration) so does the translational acceleration of a particular point of the mechanical system, proportional to the radius of rotation.

So, what does this all mean? placing a gyroscope (theoretically) should be ok to place anywhere, paying close attention to the sensing axes.

Placing the accelerometer as close to the rotating axis is best. This can be proved considering if you placed the accelerometer precisely on the axis ie r = 0. Therefore the translational acceleration of the system will contribute wr = wx0 = 0m/s/s.

Does everyone agree? Too complicated? INCORRECT?

Regards!

P.S. Mentioned previously, I am writing my Thesis and also sitting exams therefore have had no time to program, however my more recent attempts of balancing can be seen here
-> http://www.youtube.com/watch?v=lRK9mlc0iD0 (moving forward for a given time stopping while balanced)
and

Regards, AGAIN!

beautifulsmall

#39
Oct 28, 2010, 10:37 pmLast Edit: Oct 29, 2010, 12:55 am by meatmydesk Reason: 1
Hi,  for months i just used the vertical angle , or its error from vertical to drive the PID data for the wheels. despite my best efforts the robot would drift and when pushed would catch up with vertical then stop the wheels but the upper body momentum would carry on giving a jerky start stop motion. so i tried adding in (or subtract ) the body velocity, calculated from the change in angle /dt , wheel velocity must be added to body velocity for a true body velocity. I had it all in different places but it was the same as N-bot's equation which I finally used in N-bots form.
Im not a SW engineer, code is messy.
I average the pwm, just by 2 but its jerky without. Code is for aDsPic.

setting Kpos=0, I tuned Kbody and Kbase which gives the lean back when pushed, also when moving between two locations the wheels move away ,changing the body angle towards the target, the wheels then change direction and the whole robot moves towards the target. when it reaches the target position the wheels speed up and overshoot to slow the body. Ill try and film this. The position error stops drift by offsetting the target vertical (which is incorrect if the robot drifts, and changes every time you breath), the robot will drift until the position offset gives a -ve motor drive when the robot will move back toward the zero position (not to the zero), but will oscillate around some offset.
As for gyro positioning, the gyro is a mems device, A lump in a void on springs, accel will affect it although it is compensated out ??. yes both my sensors are in completely the wrong place

as you can see the Kalman filter is on commented out, I just don't have a spare lifetime to understand it (or tune it) and the comp filter works.

going to try cheap motors next with ball mouse encoders.

Code: [Select]
`// ***************** gyro read and average *************a_angle=BMA180_accel_read();gyro_delta=gyro_read(gyro_null);ga=ga+(gyro_delta*dt);comp_angle = (0.997 * (comp_angle +(gyro_delta * dt)))+(0.003 * (a_angle));   // complimentary filterangle[0]=(16*comp_angle)-vertical;  //  adjust for 1/16 degree , and vertical offset//ars_predict(&filter_roll, gyro_delta, dt);    // Kalman predict//K_angle = ars_update(&filter_roll, a_angle);        // Kalman update + result (angle)     //************ GET WHEEL VELOCITY************velocity_read(dt,&M1_vel,&M2_vel,&map_x,&map_y,&heading,&delta_pos);  // returns velocity, updated x,y and current headingbase_vel=(M1_vel/2)+(M2_vel/2);//************ GET BODY VELOCITY**********body_vel=body_velocity(comp_angle,M1_vel,M2_vel,dt,height);// **********GET POSITION *************// use a local x which is referenced to the wheels only and not any map.use this to correct for drift// and to calibrate the balance vertical this local X can be negative where distance to goal cannot//get_heading(map_x,map_y,req_x,req_y,&req_heading,&distance);//if (mode==0)req_heading=0;heading_error=heading-req_heading;local_x=local_x+delta_pos; //use x,heading should already be correctpid_pos_error=position_PID(local_x,Pp,Pi,Pd,dt);//if ((heading_error>5)||(heading_error<-5)) distance=0;   //  get correct heading before//pid_pos_error=-position_PID(distance,Pp,Pi,Pd,dt);  // for mode2 use distance//******************* Heading PID ************************//PID_heading=heading_PID(heading_error,Hp,Hi,Hd,dt);// *** DO BALANCE PID **********************c_angle=(angle[0]+angle[1]+angle[2]+angle[3])/4;angle[3]=angle[2];angle[2]=angle[1];angle[1]=angle[0];//error= sum of angle, body_velocity, wheel rate, positionerror=((c_angle))+((Kbody*body_vel)/32)+((Kbase*base_vel)/32)+((Kpos*pid_pos_error)/16); // use 1/16 of a degree as standard    COMPLEMENTARY FILTERbalance_error=balance_PID(error,Kp,Ki,Kd,dt);   // get actual balance PID errormotor_PID(balance_error,PID_heading,Mp,Mi,Md,M1_vel,M2_vel,&M1_pwm,&M2_pwm,dt);av3_pwm1=av2_pwm1;av2_pwm1=av1_pwm1;av1_pwm1=av0_pwm1;av0_pwm1=M1_pwm;M1_pwm=(av0_pwm1+av1_pwm1)/2;   //+av2_pwm1+av3_pwm1)/4;av3_pwm2=av2_pwm2;av2_pwm2=av1_pwm2;av1_pwm2=av0_pwm2;av0_pwm2=M2_pwm;M2_pwm=(av0_pwm2+av1_pwm2)/2;  //+av2_pwm2+av3_pwm2)/4;M1_dir=0;if (M1_pwm >1) M1_dir=2;     // forward ?if (M1_pwm <-1) M1_dir=1;     // forward ?M2_dir=0;if (M2_pwm >1) M2_dir=2;     // forward ?if (M2_pwm <-1) M2_dir=1;     // forward ?M1_pwm=abs(M1_pwm); // +deadzone;M2_pwm=abs(M2_pwm); // +deadzone;if (M1_pwm>200) M1_pwm=200;if (M2_pwm>200) M2_pwm=200;if (abs(error)>720) // stop motors if fallen over > 45 degrees{      M1_pwm=0;     M2_pwm=0;}//if (int_seconds<5)if (motor_en & 1){M1_dir=2;M2_dir=2;M1_pwm=0;  // test step resopnseM2_pwm=0;  // test step resopnse}pwm_set(M1_dir,M1_pwm,M2_dir,M2_pwm); `

beautifulsmall

#40
Oct 29, 2010, 12:53 am

as mentioned above , showing the effect of the full balance equation
angle+Vbody+Vbase+position,  when stepping a 256mm change in requested  (x) position every 8 seconds, 0, 0x100,repeated step.

has anyone tried graphing live data in excel, I have a one channel prototype , it lags a bit but its better than cut and paste.

Patrik

#41
Oct 29, 2010, 06:16 am
Thanks for all the info about the placement of the sensors on the robot. I think a have a idea now on how to build the robot..

I want to ask you guys also what you think should be the best settings for my accelerometer and may gyro.

LPR510AL Dual-Axis (Pitch and Roll or XY) Gyro with ±100°/s and 400°/s Ranges

MMA7341L 3-Axis Accelerometer ±3/11g with Voltage Regulator

3g or 11g
100 degrees/s or 400 degrees/s

My jig is now complete so I can start testing some things:

The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

kas

#42
Oct 29, 2010, 09:17 am
@Gibby623

Quote
The Accelerometer sense translational accelerations, not angular acceleration.
Hoops   I fully agree, the angular acceleration is obtained from two orthogonal accelererometers, using Arctg function.
Thanks for those very precise comments
What is the precise subject of your thesis

You won't get much better without motor encoders

I will post the end of my tutorial and KasBot V1 code probably this week end

Patrik

#43
Oct 29, 2010, 01:42 pm
Ok I have one more question just to clarify something for me. The X-axis of the accelerometer should be in the rotational axis of the wheels. But should the axis from the gyro be a perpendicular axis to the X-axis of the accelerometer like an Y-axis?

Should i use the Gyro Y-axis on the IMU? I'm cute sure I should use the Y-axis...

I see to different things below, just to clarify this

Code: [Select]
`// Main module   K_bot angle    angles in Quids, 10 bit ADC -----------------------------// 5 - angle and rate calculation       display ACC_Angle and GYRO_rate#include <math.h>#define   GYR_Y                 0                              // Gyro Y (IMU pin #4)#define   ACC_Z                 1                              // Acc  Z (IMU pin #7)#define   ACC_X                 2                              // Acc  X (IMU pin #9)`

Quote

The sensors values vs position should read as follow:
Horizontal  ( 0° =  0 Quid )        ACC_X: 0         ACC_Z: XX      GYR_X: 0
Left side   (-90° = -256 Quid)    ACC_X: XX       ACC_Z: 0        GYR_X: 0
Right side (+90° = +256 Quid)  ACC_X:-XX       ACC_Z: 0        GYR_X: 0
Reversed  (180° = +512 Quid)  ACC_X: 0         ACC_Z:-XX      GYR_X: 0
The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

kas

#44
Oct 29, 2010, 02:16 pm
Quote
I want to ask you guys also what you think should be the best settings for my accelerometer and may gyro.
LPR510AL Dual-Axis (Pitch and Roll or XY) Gyro with ±100°/s and 400°/s Ranges
MMA7341L 3-Axis Accelerometer ±3/11g with Voltage Regulator
3g or 11g
100 degrees/s or 400 degrees/s

I would definitly go for the shortest range (3g and 100°/s)
Mines are 3g 500°/s and I would appreciate more resolution for the gyro

Quote
Ok I have one more question just to clarify something for me. The X-axis of the accelerometer should be in the rotational axis of the wheels. But should the axis from the gyro be a perpendicular axis to the X-axis of the accelerometer like an Y-axis?
Should i use the Gyro Y-axis on the IMU? I'm cute sure I should use the Y-axis...
:-? :-?   Lets make it clear, you need:
- one gyro
- two accelerometers (could work with one)
The gyro should parallel to the rotational axis of the wheels
one Acc axis according to horizontal
one Acc axis according to vertical

Quote
I see to different things below, just to clarify this