# Week 11 - PID Tuning

Proportional-Integral-Derivative (PID) control is a tried and true method used in robotics (and many other fields) to achieve a desired system response by adjusting control inputs. PID control takes a desired target (setpoint) and the current state of a system (process variable) and calculates the necessary output to make the process variable match the setpoint.

## The Basics

1. Proportional (P): The difference between the setpoint and the process variable is called the error. The proportional term adjusts the output in proportion to this error. If the error is large, the proportional term produces a large output.
2. Integral (I): This is concerned with the accumulation of errors over time. If the error has been present for an extended period, it will accumulate, and the integral term will seek to eliminate it.
3. Derivative (D): This anticipates future behavior of the error by understanding its rate of change. If the error is rapidly increasing, the derivative term works to counteract this.

## Implementing PID on the SparkMax Motor Controllers:

Here's how you can implement position control with the SparkMax motor controllers:

``````import com.revrobotics.CANSparkMax;
import com.revrobotics.ControlType;
import edu.wpi.first.wpilibj.TimedRobot;

public class Robot extends TimedRobot {

private final CANSparkMax sparkMax = new CANSparkMax(1, CANSparkMax.MotorType.kBrushless);

@Override
public void robotInit() {
// Reset encoder count to ensure we're starting from 0
sparkMax.getEncoder().setPosition(0);

// Set PID constants. You'll tune these values!
sparkMax.getPIDController().setP(0.1);
sparkMax.getPIDController().setI(0.0);
sparkMax.getPIDController().setD(0.0);

// Set the desired position setpoint (e.g., 1000 encoder counts)
sparkMax.getPIDController().setReference(1000, ControlType.kPosition);
}

@Override
public void teleopPeriodic() {
}
}
``````

## Tuning Position PID

2. Tune P: Slowly increase P until your system starts to oscillate around the desired position. Once you observe oscillations, reduce P a bit until they stop.
3. Tune I: Introduce a bit of I. If your mechanism consistently stops a bit short or a bit past the target (known as steady-state error), I can help correct this. However, be wary: too much I can cause overshoot or oscillations.
4. Tune D: Introduce D to counteract the overshoot or oscillations introduced by P and I. Remember, a small amount of D can go a long way, and too much can make the system unstable.
5. Iterate: Go back and adjust each term as necessary, bearing in mind that changes to one term might necessitate changes to the others.

Remember that the actual values you'll need for P, I, and D will vary based on the specifics of your robot, such as the weight of moving parts, friction, and the characteristics of the motor and gearing.

In practice, position control PID tuning often requires more patience than velocity control because you're trying to get the system to settle at a precise value, rather than maintain a steady state. As always, it's crucial to make changes incrementally and observe how each change affects system behavior.

1. Implement the provided PID control structure for SparkMax on your robot's drivetrain or any mechanism. Try achieving a specific speed or position.
2. Tune the PID parameters, start with P, then introduce I and D as necessary. Remember, often you'll adjust one, then have to go back and readjust the others.
3. Incorporate a sensor, like an encoder, to get feedback from the mechanism and give the PID controller a process variable to work with.
4. Challenge: Introduce external disturbances (e.g., manually slowing down a wheel) and see how well your PID-controlled system can handle and correct for it.