!!!  (PID) Controller

It's surprisingly difficult to drive a wheeled robot in a straight line. No two motors are exactly the same, and the floor surface may differ as well. If we want a robot to follow a more complicated trajectory, or to have some indication of where it has traveled, we need to be able to measure how many times the left and right wheels have turned. This is called __odometry__.

But we also want to be able to control those motors in such as way that the robot's movements are both accurate and smoothly executed. We can measure the speed of the motors themselves using the motor encoders, then use that to determine the difference between the intended and actual motor speeds. 

!! What is a PID Controller?

A __Proportional–Integral–Derivative__ or __PID Controller__ is a general-purpose mechanism for regulating the output of any kind of system through the use of a ''feedback loop''. The feedback signal provides an indication of the current output of the system and is used to alter the system so that its output matches the desired value. PID Controllers are used in temperature controllers and automobile cruise controls. One of its first industrial uses was as an automated steering system for ships.

A PID Controller uses two numbers, the __Set Point__ (SP), the target value of the system, and the __Process Variable__ (PV), the current measured output value of the system. If the SP and the PV are equal the output from the algorithm is zero and no change is necessary. If there is a difference that is considered the controller's ''error''.

What sets a PID controller apart from simpler controllers is that it combines three types of __control terms__ to quickly reach the desired system output, minimising overcorrection and maximising stability. These three control terms are what forms its acronym: ''Proportional'', ''Integral'', and ''Derivative''. 

A __Proportional term __ multiplies the error value by a fixed proportional gain value to determine the corrective value influencing the system output. Because a controller using only a proportional term is using the value of the error to generate its corrective value, it will overshoot its target, then undershoot, with smaller and smaller oscillations until the error approaches zero. Unfortunately, as the oscillation of the system gets closer and closer to its target the amount of correction also approaches zero, so the controller never gets there.

The __ Integral Term__ integrates the error value into the correction over time so that it minimises this overshoot and pushes the output towards the target value. This requires that the amount of integral applied to the formula be carefully tuned, otherwise this can create its own form of oscillation. Given this tuning is quite tricky to get right, there is generally some overshoot and therefore oscillation in a PI controller.

A __Derivative Term__ projects the rate of change of the corrective value, and reduces its amount as the system nears the target. This allows the controller to move towards its Set Point as fast as possible, with as little oscillation as possible.

The more I read about PID controllers the more I found that tuning the Integral and Derivative control terms is considered something of a black art. There are a couple of constants in the formula, and tweaking them is done by trial and error, in other words: guessing.

To add another twist to a robot motor controller, we don't want to tell the motors to go from zero to a projected speed immediately, as that would both overly stress the motors and drive system, and cause the robot's movements to be very jerky. I want to ''slew'' the value so that it changes at a maximum speed, called a __slew rate__.

All in all, I've now got requirements for a robot motor control that include a proportional term, integral term, derivative term, and a slew rate.





See: [PID Controller|https://en.wikipedia.org/wiki/PID_controller] on Wikipedia
    
!! Links

* [pimotors|https://github.com/pootle/pimotors] on github, by the author of Pootle's Place blog
* [RobotPID|https://projects.raspberrypi.org/en/projects/robotPID] (Complete PID in Python with integral etc.)
* [Robert O'Hanlan's Robot PID |https://github.com/martinohanlon/RobotPID]
* [Programming PID Control|https://www.societyofrobots.com/programming_PID.shtml] (Society of Robots)
* [Reading encoder Tue Apr 10, 2018 12:04 am|https://www.raspberrypi.org/forums/viewtopic.php?t=210559]
* pigpio example: [Python Rotary Encoder|http://abyz.me.uk/rpi/pigpio/examples.html#Python_rotary_encoder_py]

The rest needs a lot of cleanup, titles, etc.

* [https://www.microchip.com/forums/m337816.aspx]
* [https://github.com/MrYsLab/razmq/blob/master/razmq/encoders/encoders_pigpio.py]
* [https://onion.io/2bt-pid-control-python/]
* [https://pypi.org/project/simple-pid/] (too simple)
* [http://code.activestate.com/recipes/577231-discrete-pid-controller/] (also too simple)
* [https://www.oreilly.com/library/view/intelligent-iot-projects/9781787286429/26242fa7-713e-4e5d-b1dc-b5566a39d5b7.xhtml]
* [https://www.element14.com/community/community/raspberry-pi/blog/2019/02/12/pid-based-dc-motor-controller-project]
* [https://www.phidgets.com/docs21/DC_Motor_-_PID_Control]
* [http://robotsforroboticists.com/pid-control/]
* [https://www.stuffaboutcode.com/2014/10/raspberry-pi-initio-robot-driving.html]
* [https://github.com/martinohanlon/initio]

----

[{Tag Software}]