Motor PIDF Tuning Guide
Updated 3 September 2019
Table of Contents
Maximum Velocity Measurement in Blocks 2
Maximum Velocity Measurement in Java 3
Calculating PIDF Values from Maximum Velocity 4
Setting PIDF Values in Op Modes 4
Velocity versus Position PIDF Values 5
Tuning the Velocity PIDF Value 6
The Control Hub has preset PIDF values for the motors in the FIRST Global Kit of Parts, but they are based on a freely spinning motor. When that motor is a part of a mechanism which adds load, the PIDF values should be re-tuned, or else the motor will not perform optimally in RUN_USING_ENCODER mode or RUN_TO_POSITION mode. This guide will teach you how to set the PIDF values for your specific mechanism in your Op Mode.
Read the Motor Encoder Guide before reading this guide. In addition, make sure that your Control Hub and Expansion Hub have been updated with the latest firmware using the Control Hub and Expansion Hub Firmware Update Guide.
You can establish basic PIDF values for your mechanism by plugging a simple measurement into a formula. This will be sufficient for most use cases. The measurement you need is the maximum motor velocity of your mechanism. To get this, run a maximum velocity measurement Op Mode with a full battery. In this Op Mode, it is important that you set your motor’s mode to RUN_WITHOUT_ENCODER, and the power to 1. Example velocity measurement Op Modes are listed below.
An Op Mode like this will display the maximum telemetry for a motor to telemetry. You will need to create variables named maxVelocity and currentVelocity in the Variables section of the left toolbar. Note that you can find the velocity block under Actuators -> DcMotor -> Extended.
Here is the same Op Mode written in Java:
package org.firstinspires.ftc.teamcode;
@TeleOp
public class MaxVelocityTest extends LinearOpMode {
DcMotorEx motor;
double currentVelocity;
double maxVelocity = 0.0;
@Override
public void runOpMode() {
motor = hardwareMap.get(DcMotorEx.class, "CoreHex");
waitForStart();
while (opModeIsActive()) {
currentVelocity = motor.getVelocity();
if (currentVelocity > maxVelocity) {
maxVelocity = currentVelocity;
}
telemetry.addData("current velocity", currentVelocity);
telemetry.addData("maximum velocity", maxVelocity);
telemetry.update();
}
}
}
Once you have your maximum velocity (maxV), you can calculate the velocity PIDF values. Your F value is calculated like this: . So if your max velocity is 2600 ticks per second (reasonable for a mechanism that uses the HD Hex Motor), then your F value should be about 12.6.
Then your P value is calculated from your F value:
Then your I value is calculated from your P value:
Your D value should be zero.
So for a maximum velocity of 2600 ticks per second, your velocity PIDF values are:
Regardless of your maximum velocity, you can set the position PIDF values to:
Position-mode PIDF only requires a single value because it also uses the velocity PIDF values.
PIDF values are only remembered for the duration of the Op Mode that they are set in, so you must apply them at the beginning of all Op Modes that you want them to apply to. In Blocks, you apply velocity and position PIDF values using these blocks (found under Actuators -> DcMotor -> Extended).
When you run your Op Mode, you may see an error that says Fatal error occurred while executing the block labeled “call motor.setVelocityPIDFCoefficients”. This indicates that you have not updated your Control Hub or Expansion Hub firmware.
In Java, you can do the same thing with the following lines of code (your motor variable must be defined as a DcMotorEx instance).
motor.setVelocityPIDFCoefficients(1.26, 0.126, 0, 12.6);
motor.setPositionPIDFCoefficients(5.0)
When you run your Op Mode, you may see an error that says User code threw an uncaught exception: UnsupportedOperationException - setting of pidf coefficients not supported. This indicates that you have not updated your Control Hub or Expansion Hub firmware.
You should test your PIDF values by switching to RUN_USING_ENCODER mode, setting the velocity to around half of the measured maximum velocity of your mechanism, and continuously printing the current velocity to telemetry. If the motor does not quickly get close to the specified velocity, you should ensure that you did the math correctly.
For each motor, you are able to set PIDF values for velocity and position. The velocity PIDF values are used to help the motor target a particular speed in RUN_USING_ENCODER mode. In RUN_TO_POSITION mode, the position P value is used to find a target velocity for the motor, and the velocity PIDF values are used to target that velocity. Therefore, it is important to correctly tune your velocity PIDF values before tuning the position P value.
The simplest customization to make to your PIDF values is to tune the position P value. The higher the value is, the faster the motor will move towards the target. However, if the value is too high, then the motor will overshoot the target and begin to oscillate.
The F value is used to make a guess for what the motor power should be in a perfect system, based on the maximum velocity of your mechanism. Therefore, you should leave it at the value calculated in the section titled Calculating PIDF Values from Maximum Velocity. The remaining values (P, I, and D) work like they do in any other PID closed-loop system. There are many ways to tune these, which you can research yourself. Remember that the target value is a velocity, not a position. This YouTube video made by Worcester Polytechnic Institute serves as a starting point: https://www.youtube.com/watch?v=2Yif6PdXPWg.
FIRST Global: Motor PIDF Tuning Guide