Implements a PID (Proportional, Integral, Derivative) control loop.
A PID control loop allows you to optimise how 'something' changes from A to B. The 'something' in question can be anything which has a 'measurable goal' and a 'measurable progress'.
As an example: you may want your motors to turn at a given RPM (measurable goal) and so long as you have some encoders then you can measure how quickly they are currently turning (measurable progress). A PID allows you to reach the required RPM as quickly as possible. And if your robot starts going up a hill then the RPM will drop and so the robot will apply more power to the motors to try to keep the speed constant.
But this could apply to many other 'measurable' things where the robot can directly effect the output. Servo locations, speed, acceleration, bearing and position to name but a few. However: it is not suitable for goal seeking where the robot cannot directly effect the result such as maze solving. Although this has a measurable goal (the destination) and a measurable progress (the distance from the goal) there is no magical action the robot can make in order to get closer as it depends on lots of other things it cannot control (like where there are walls!).
A 'practical' example of a control loop: consider a tank moving over rough ground. It spots a target and can work out the gun barrel angle to fire a shell to hit the target. But the tank barrel is heavy, so moves slowly, and the rough ground makes the problem worse. How do we keep the barrel at the correct location?
The theoretical programming use of PID is very easy: tell it your goal once, and then keep updating it with your current progress. ie tell the PID the angle you want for the barrel and then keep updating it with the current true position (taking into account the rough ground). The PID will output the amount of force to use to lift/lower the barrel.
However: the 'tuning' of your PID system is partly manual trial-and-error or can be based on certain calculations like Ziegler–Nichols. These tunings are critical to get to the goal in the optimum time but they depend on all sorts of things - ie the weight of the tank barrel, the maximum torque of the motors that move it etc etc. So sorry .... no quick fix. You have to tune the PID to your set up.
Don't despair: there is lots of web info about PID on the net. Such as:-
There is also lots of info about the best way to tune your PID.
WebbotLib provides a PID that can be used in two situations. Standard and circular.
What's a circular system. Well think of a tank turret. It can move clockwise or anti-clockwise and both movements will end up getting to the correct place - a circular PID will choose the best way to go.
We provide two constructors. For a standard PID use:-
PID myPID = MAKE_PID(kP,kI,kD, il, outMin, outMax);
or for a circular PID:-
PID myPID = MAKE_CIRCULAR_PID(kP,kI,kD, il, outMin, outMax, inMin, inMax);
The kp, kI, kD values are the standard constants used by the PID theory.
il - is the maximum value of the integral component and is used to stop the integral from swamping the system.
outMin/outMax - are the range of values you want to be returned by the PID. If you are using it to drive a motor, for example, then the returned speed would be need to be between DRIVE_SPEED_MIN and DRIVE_SPEED_MAX.
For a circular PID the additional inMin/inMax values are the range of input values that represent a full circle. If the input value was from an encoder then these values would be the encoder values that represent a position of 0° and 360°.
- pidSetTarget - Specify the goal, or 'set point' for the PID.
- pidSetActual - Updates the PID with the current measurement and returns the output value.
void pidSetTarget(PID* pid,float setPoint)
Specify the goal, or 'set point' for the PID.
This is the value you want to achieve.
float pidSetActual(PID* pid,float actual)
Updates the PID with the current measurement and returns the output value.
The output value is the value that is used to 'drive' the 'thing' you are measuring.