PID turning help - balance robot

Thread Starter

bug13

Joined Feb 13, 2012
2,002
NOTE: I got a typo in my title, it should be PID turning help. (I don't seem to find a way to fix it)
Opps, it's fixed now

Hi guys

My new dc motors arrived last week, and I replaced my old noise motors with the new ones, more info here.

Now I need to turn the PD loop to control my little robot so it can stand up. I have no experience on turning any PID/PD loop, all I know is what they are from reading some material.

So I have a few tried myself, no luck, I got to a point where it oscillate for a couple seconds and fall over.

Any advice/suggestion on how should I solve this problem?

Thanks guys
 
Last edited:

GopherT

Joined Nov 23, 2012
8,009
We will need some info about how many readings you are taking per second (or duration between reads). Also, how much change do you expect between reads?

What kind of sensors (time constant or how long will it take from the time an error first starts until the motors can respond to start correcting the change).

Also, here is a general from Wikipedia...

Pseudocode

Here is a simple software loop that implements a PID algorithm:[18]
previous_error = 0
integral = 0
start:
error = setpoint - measured_value
integral = integral + error*dt
derivative = (error - previous_error)/dt
output = Kp*error + Ki*integral + Kd*derivative
previous_error = error
wait(dt)
goto start
In this example, two variables that will be maintained within the loop are initialized to zero, then the loop begins. The current error is calculated by subtracting the measured_value (the process variable or PV) from the current setpoint (SP). Then, integral and derivative values are calculated and these and the error are combined with three preset gain terms – the proportional gain, the integral gain and the derivative gain – to derive an output value. In the real world, this is D to A converted and passed into the process under control as the manipulated variable (or MV). The current error is stored elsewhere for re-use in the next differentiation, the program then waits until dt seconds have passed since start, and the loop begins again, reading in new values for the PV and the setpoint and calculating a new value for the error.


Note: if your updates happen at a regular interval, then you can ignore the dt factor since you can just assume it is 1 (no need for multiplication).
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
We will need some info about how many readings you are taking per second (or duration between reads).
I am currently doing 100 reading per second

Also, how much change do you expect between reads?
I have no idea, how do I find out?

What kind of sensors (time constant or how long will it take from the time an error first starts until the motors can respond to start correcting the change).
I am using MPU6050 breakout board

Sorry, I don't know about the time constant, I will read the datasheet and add some code to measure the time, will report back if I find something.

Note: if your updates happen at a regular interval, then you can ignore the dt factor since you can just assume it is 1 (no need for multiplication).
Thanks, good to know.

here is my code:

Rich (BB code):
float updatePID(float angle, float gyro_angle, float setPoint)
{
	float pTerm;
	float error;
	float dTerm;

	error = angle - setPoint;

	pTerm = P_GAIN * error;
	dTerm = D_GAIN * gyro_angle;


	return pTerm + dTerm;
}
the setPoint is 0 at the moment, instead of calculate the dTerm from:

dTerm = old_error - new_error
I use the data from gyro.

The float angle is the fusion angle from accelerometer and gyroscope with a complementary filter.
 

GopherT

Joined Nov 23, 2012
8,009
I would start with just PGain = 1 and Dgain = 0

Increase PGain until you see it make too much correction. Then you can add the Dgain until it stops over correcting.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
I would start with just PGain = 1 and Dgain = 0

Increase PGain until you see it make too much correction. Then you can add the Dgain until it stops over correcting.
What do you mean by too much correction? Do you mean it can stand up (not falling on the floor) but oscillating?
 

GetDeviceInfo

Joined Jun 7, 2009
2,271
There are many excellent documents on PID tuning. A picture paints a thousand words. Look at dynamic loop response charts. You might try initial tuning by stepping your drive mechanism unloaded to obtain a classic response, then adding gain as load is introduced.
 

GopherT

Joined Nov 23, 2012
8,009
What do you mean by too much correction? Do you mean it can stand up (not falling on the floor) but oscillating?
Yes, oscillating. A self-balancing robot will usually just fall over if pGain is not high enough and you will look like it is just falling over. As you turn up gain, then you see it falling slightly slower. Finally, you turn it up so much that it starts oscillating or falling the opposite direction (always use a common starting point (e.g. 5-degrees off balance forward)).

Once you have that defined, you can start adding D and I gain.

If you start adding bumps and other obstacles, you may have to add additional PGain for faster correction.
 

GopherT

Joined Nov 23, 2012
8,009
Bug13 plans to use only P and D terms for a start. Integral terms can get tricky.

I like to use I-term from only the last X number of readings.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Now I can turn the PD control loop to make my robot stand up reasonably well, but I got a new problem.

At some conditions, the robot will go faster and faster, and to a point where the motors is not fast enough to keep the robot balance.

So I need to somehow limit the top speed, make the motors go faster to push back before it fall over.

here have discussed how it was done, but I don't understand it, can someone please explain it to me, thanks.

you will find the codes about half way down the page.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
That's how he discussed it his words:

There is another complication. What happens if you keep leaning forward until the scooter is going so fast that the wheels can't keep up? It has to change the tilt of the scooter so instead of keeping the bar vertical, it tilts back. The bar is at waist level, so it pushes you back until the center of gravity is no longer in front of the wheels and it stops accelerating. If you lean farther forward it keeps tilting back in order to keep the speed down. In order to be able to tilt the scooter back it needs to speed up the wheels and get them out in front, so the speed limiter needs to kick in before the motors are maxed out. I currently have the limit set to 50% of maximum speed.
I mentioned above that when it's going too fast it needs to tilt the stick back. This is tricky to do, because in order to tilt back it needs to accelerate the wheels forward to get them a few inches out in front. It then seems like it's going even faster, and it tries to tilt even farther back. This is called "positive feedback" and it's a recipe for uncontrollable oscillation. Making this stable was the trickiest part of the whole project, and the fact that it can only be tested at high speed resulted in several moments of terror and a few bruises before I got it right.
That's his example codes: ( I have added some formatting, hope it's readable)

Rich (BB code):
//Inputs
//angle, angle_rate: the tilt angle of the scooter in radians and its derivative in radians/sec 
//steer_knob: the reading from the steering knob, between -1 and +1.

/*   Balance   */                                          
balance_torque = 5.0 * (angle - rest_angle) + 0.4 * angle_rate

// Limit top speed by tilting back
overspeed = max(0, cur_speed - 0.5) 
if (overspeed > 0) 
{ 
       overspeed_integral = min(0.4, overspeed_integral + min(0.2, overspeed+0.05) * dt) 
} 
else 
{ 
       overspeed_integral = max(0, overspeed_integral - 0.04*dt) 
} 

rest_angle = 0.4*overspeed + 0.7*overspeed_integral

//Steer. Decrease steering rate at high speed
steer_cmd = 0.07/(0.3+abs(cur_speed)) * steer_knob

//Track current speed

cur_speed += 1.2 * balance_torque * dt

//Differential steering
left_motor_pwm = balance_torque + cur_speed + steer_cmd 
right_motor_pwm = balance_torque + cur_speed - steer_cmd

//Outputs
//left_motor_pwm and right_motor_pwm directly 
//set the duty cycle of the pulse width modulator for the wheel controller,
//and range from -1 to +1 (+1 is 100% forward, -1 is 100% reverse.)
 

GopherT

Joined Nov 23, 2012
8,009
The way I understand his program is, his PGain is set to 50% of max gain, then he has some "headspace" to make corrections with the D and I terms.

========================================
Balance
balance_torque = 5.0 * (angle - rest_angle) + 0.4 * angle_rate
========================================

I read (angle - rest_angle) to be the ERROR. where "angle" is the current position and "rest_angle" being the target or reference set point.

I read angle_rate as the derivative term. (Current error - previous error).

The 5 and 0.4 are the gain (importance) of each factor.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Is your project an autonomous bot, a radio controlled bot or a rideable Segway-type device?
Hi GopherT

My project goal is building a rideable Segway-type device, this is only a small prototype, I want to learn as much as I can with is small prototype first, before spending money on a big one.
 

GopherT

Joined Nov 23, 2012
8,009
Ok, then you really have no way to pull forward/back on the handle. Do you just want to go some speed forward while maintaining balance? For the prototype?
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Ok, then you really have no way to pull forward/back on the handle. Do you just want to go some speed forward while maintaining balance? For the prototype?
Say my robot will fall over if the angle is greater than +/-5 degree, no matter how fast my motors go.

I want to say limit the tilt angle no more than +/-4 degree, by over correcting it before it's too late, so the angle is within +/-5 degree.

Does it make sense? Or there is something else I don't know here?
 
Last edited:

GopherT

Joined Nov 23, 2012
8,009
I think you will need to make a slight correction constantly, no matter how much or how little.
Your mind is very good at doing his. A weak office worker with no athletic activity tries to stand on one foot and they wobble all over and fall quicky. An athletic person with no experience stands on one foot and wobbles a bit but soon over corrects and has to put the other foot down. A ballet dancer stands on one foot and can stay for a very long time with no problem. But, if you look closely, you see small muscle movements all over her leg and foot. She is correcting constantly while keeping her head completely still - hundreds of small, imperceptible corrections each minute.

You might want to set full correction (full power) if you are already at 4-degrees. What is really important is the Derivative factor, or, how fast is it falling when it passes 4-degrees?

Do you have full forward and reverse PWM control of your motors?
 
Top