Skip to content

PIDF Tips and Bits

12sliu edited this page Dec 21, 2023 · 3 revisions

What is PID and Feedforward?

The simplest explanation without any technical terminology is that a PID controller takes a setpoint (where it should be) and a position (where it is now) and then gives you what speed you need to go to the setpoint perfectly.

The video is very highly recommended, as it provides a intuitive explanation of what PID is.

Tuning PIDF

NOTE: If you are from the 2023-2024 season, FTC dashboard has already been installed. If you are reading this, the ftc-dashboard branch should have been merged into main - check if these changes have appeared in your build.dependencies.gradle file, if not contact your senior and ask them to merge main into your branch.

1. Install FTC Dashboard by adding the lines with a plus in front of them to your build.dependencies.gradle file.

 repositories {
     mavenCentral()
     google() // Needed for androidx
+    maven{url = "https://maven.brott.dev/"}
 }

 dependencies {
     implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.3'
     runtimeOnly 'org.tensorflow:tensorflow-lite:2.12.0'
     implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation "com.acmerobotics.dashboard:dashboard:0.4.9"
 }

Remember to sync your Gradle, or the changes won't go through.

2. Create an OpMode for tuning the PID using FTC Dashboard.

@Config
@TeleOp( name = "Linear Slide PIDF", group = "linear-slide-test")
public class LinearSlidePIDF extends OpMode {
    public static int POSITION_ERROR = 5;

    private PIDController controller;

    public static double p = 0;
    public static double i = 0;
    public static double d = 0;
    public static double f = 0;

    public static int target = 0;

    private final double ticks_in_degrees = 700.0 / 360.0;

    private DcMotorEx slide_motor;

    public static boolean atsetpoint = false;


    @Override
    public void init() {
        controller = new PIDController(p, i, d);
        telemetry = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());

        slide_motor = hardwareMap.get(DcMotorEx.class, "linear_slide_motor");
    }

    @Override
    public void loop() {
        int slidePos = slide_motor.getCurrentPosition();

        controller.setPID(p, i, d);
        double pid = controller.calculate(slidePos, target);
        double ff = Math.cos(Math.toRadians(target / ticks_in_degrees)) * f;

        double power = pid + ff;

        slide_motor.setPower(power);

        telemetry.addData("at setpoint?: ", atsetpoint);
        telemetry.addData("pos ", slidePos);
        telemetry.addData("target ", target);
        telemetry.update();
    }
}

This example uses a linear slide, but can be modified easily for any other mechanism (i.e. arm).

  • The most important parts of this OpMode include the @Config decorator, which allows for static variables to be edited from FTC Dashboard on your computer.

3. Open FTC Dashboard

a. Connect to your Control Hub's WiFi.

b. Go to http://192.168.43.1:8080/dash in any browser of your choice.

4. Use FTC Dashboard and Your OpMode to Tune

a. Use your Driver Hub to initialize and run the PID Tuner OpMode you have made. (Do not run the OpMode from the Dashboard, as previous attempts have not worked with it)

b. Check all the telemetry boxes so they appear on your graph.

c. Make edits to the static variables by changing the values in the boxes and pressing the Save (flash drive) button.

Video Source

Tuning PIDF

Each Coefficient

  • kP is for the main push force, and corrects for error in position.
  • kI is for when it settles down, but doesn't quite reach where it's supposed to be. (when the system stops because the current position is really close to where it needs to be, and kP and kD give such a small output that it can't overcome friction - kI means "give the motor a bit larger shove if we aren't at the desired position yet")
  • kD is to stop it going way too fast, and corrects for error in velocity (reaching the setpoint, but going too fast).
  • kF is supposed to counteract gravity, so once kF is applied, you have a symmetric situation for PID to work with (PID by itself can't handle non-symmetric situations well).

Instructions

  1. Start with kF first - set kI and kD to 0 and kP to something sensible, and increase kF until just about holds itself due to gravity when you aren't telling it to go somewhere (so if you move the motor manually, it will do so without resistance, and it takes the same amount of force both ways.)

  2. Start with kP, kI and kD as all 0.

  3. Increase kP until it overshoots slightly, and there are oscillations around the target that dampen with time. (Make sure it doesn't jitter too much, but still has enough power to drive it to the setpoint at good speed)

  4. Increase kD until it slows down on time and no overshoot occurs.

  5. If there is steady state error (the line does not move, but not at the target), increase kI until it is corrected. (It is easy to increase kI too much, so increase it very slowly.)

  6. Start balancing kI and kD if needed.

Notes about kI:

Only increase kI when you are happy with the amount of jitter and how quickly the arm reaches rest, but it doesn't quite get to where it's supposed to be.

Clone this wiki locally