In the last example we learned about proportional closed loop control where we helped the robot drive straight by increasing/decreasing power to the left/right motors in proportion to the error between the distance traveled by the left/right wheels.
While proportional control works in many cases, it can take time to achieve the proper power balances, can be slow to react to changes, and in some cases can even oscillate or never reach the proper power levels. PID control is a more sophisticated solution that takes more factors into consideration:
- P = Proportion - the current error
- I = Integral - the error accumulated over time
- D = Derivative - the rate error is increasing/decreasing
Remember that research is a crucial part of robotics, so try to find a few sources about PID loops on your own first. Here are a few starters: https://frc-pdr.readthedocs.io/en/latest/control/pid_control.html https://www.youtube.com/watch?v=pTuPhJ0DJB8
PID control gives a more concrete control over speed, and leaves less up to chance in terms of speed control. Possible examples of usage include
- Arm control
- Driving or turning precise distsances (in the case of auto)
- Flywheel speeds, to ensure that the flywheels are maintaining a constant speed
- And much more. If you have an idea for a usage of PID loops, come see a mentor or software student leader!!
CODE EXAMPLES YAYYYYYYY
public class PID { private double error, errorSum, actualPrev; private double setpoint, output; private double kP, kI, kD; private Double tolerance; public PID(double kP, double kI, double kD, Double tolerance){ this.kP = kP; this.kI = kI; this.kD = kD; this.tolerance = tolerance == null ? null : Math.abs(tolerance); } public PID(double kP, double kI, double kD){ this(kP, kI, kD, null); } public void setSetpoint(double setpoint){ if(this.setpoint != setpoint){ this.setpoint = setpoint; errorSum = 0; } } public void update(double actual){ error = setpoint - actual; final double actualChange = actual - actualPrev; actualPrev = actual; if(tolerance == null || !withinTolerance()){ errorSum += error; output = kP*error + kI*errorSum - kD*actualChange; } else { errorSum = 0; output = 0; } } public void update(double actual, double feedForward){ update(actual); output += feedForward; } public double getOutput(){ return output; } public boolean withinTolerance(){ return Math.abs(error) < tolerance; } }
Note that WPILib includes a PIDController class; you can read about how to use it on screenstepslive and here. Some Java examples are here
EXCERSISE
Code a robot that will set a single wheel to 2000 RPM
- You will need knowledge of encoders, to analyze speed
- You can use this PID , and probably should not change the PID class unless you know what you're doing
- Just figure out how to implement it. Also, you should be able to tell what every method in this does