Lesson 5 - PID Loop Basics
What is a PID Loop?
PID loops are a type of control loop that utilise odometry systems to correct for input error.
These loops allow for precise controll of motors and are a staple of FRC coding.
To perform this task PID loops look at the current position, expected position, and past position of the motor to create a new input value.
PID loops should be placed inside the subsystem - NOT THE COMMAND.
This is because they modify the behavior of the subsystem, and this ensures that if another command is made it will have the same PID loop
Some real use case of PID loops include:
- Swerve Drive: Allows all the motors to be in sync
- Balancing: For example, in a climber, it ensures that the robot is never tilted too far off its axis
- Shooting: In our 2024 robot, we hve a main shooting motor and a flywheel which charges up the shot. PID allow to control the flywheel to ensure that the same motor speed is reached by both.
PID Loop Setup/Declaration
PID loops are declared by creating a new PIDcontroller object and declaring the weight that each part (Proportional, Derivative, Integral) should have on the calculated output.
P (Proportional) | The term that generate motor speed to move the motor in the correct direction with the correct speed | Tuned with constant Kp |
I (Integral) | The sum of all errors over the code run time, will keep increasing until the set point of error is reached. | Tuned with constant Ki |
D (Derivative) | Rate of change of error, which is used to slow down the motor if it's spinning too fast by taking [currentErrorValue - previousErrorValue] | Tuned with constant Kd |
As a result, the only field that should be non zero is the first one where you input a value between 0 and 1
For a more gradual PID effect use lower numbers as this will mean that offsets will cause less change in the loop's output value
The actual code definition is (please note that the input values are not ones you would actually use):
PIDController m_xPositionalController = new PIDController(0.11, 0.23, 0.27);
These values are almost never final and will be tested to find ones that work so if you are just making something put in a value between 0.15 - 0.3
setTolerance()
After initializing a pid controller it is important to set a tolerance for it so that it doesn't constantly spin the motor if it off by a neglible ammount and keeps over correcting
To do this, call the .setTolerance()
method with a value between 0 and 1. Again, initial value doesn't really matter as it will all be tweaked later.
Using PID Loops
Now that the setup is all done the PID loop can now be used to get useful informaton.
To begin a control loop, set the desired position of the PID controller using the setPosition()
method.
This method will set the position of the motor that you want it to spin to
This value will be checked against the position you give the controller and put though a calculation with the weights perviously described to output a new motor speed
To actually get this value, call the calculate()
method with the current position of the motor as the parameter
Take this value and use it to modify the motor output - repeat the process. By doing so, you have created a PID loop.
PID Examples
A good example of PID loops is the AlignToTargetCommand here:
A Good PID ExampleNote that it does use a ProfiledPIDController, but the general idea is the same.