[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

pseudo code

if actTemp < SetPoint Power = ON

else Power = OFF

Code for a basic (static) balancing robot

Set point = 0

error = actAngle

pseudo code

If actAngle = 0 Motors stop

else 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.

`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

variationWith a fixed time loop, time may be omited:

`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: `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

`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.

Further readings:

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]