Applying Open- and Closed-loop Control in Your Code

Be sure you have read the previous page before heading here, as that is where all of the reasoning behind this code is from.

Applying PID Control

Applying PID control depends on what you're trying to do. However, once implemented it is pretty simple.

PID controllers, as well as Profiled PID Controllers (which include some feedforward constants) are both included as classes in WPILib.

A basic PID controller is an object that needs to be instantiated.

import edu.wpi.first.math.controller.PIDController;
PIDController controller = new PIDController(Kp, Ki, Kd);

The PID constants will stay the same and will need to be tuned to fit the specifications of the control system. For the system to function, a basic distance-time PID controller for an autonomous command is shown here:

    public MoveDistancePid(RomiDrivetrain drivetrain, double distance) {
        addRequirements(drivetrain);
        this.drivetrain = drivetrain;
        this.distance = distance;

        pid.setSetpoint(distance);
    }
    @Override
    public void execute() {
        double power = pid.calculate(drivetrain.getLeftDistanceInch());
        power = MathUtil.clamp(power, -1, 1);
        drivetrain.arcadeDrive(power, 0);
    }

There are a number of items to note here. Remember that in command based programming, all commands are checked every millisecond until they are finished. In this case, the PID uses the method pid.setSetpoint() in the constructor. However, this may not be the best practice in most practical application. The reason will be discussed later.

Secondly, since this is a distance-time PID controller, with the output being change over time, then we can insert the output directly in the system as power. Remember that what we insert into the motors has to always be power.

circle-info

In this case, the all motion profiling is already hard-coded into the XRP. In addition, as the arm is servo-powered, adding an advanced control system isn't necessary.

For most intents and purposes, a closed-loop system is enough. However, in professional programming like on the competition robot, the following describes concepts that will become important.

Further reading: The PIDF Controller

PIDF stands for Proportional-Integral-Derivative-Feedforward. In the previous page, we saw the power of feedforward control algorithms in the context of closed-loop systems like PID. There isn't exactly a class in WPILib dedicated to this. However, the implementation is still rather simple.

It is important to note that this type of controller is most often used in flywheelsarrow-up-right and basic drivetrains, of which the latter is the example shown. This was why it isn't necessarily ideal to put the setpoint in the constructor, it's that if the setpoint changes, you want it in a place that continuously updates it, like a method where commands are being processed. Here, the feedforward that is sent in is calculating how much feedforward is necessary here.

Further Reading: Motion Profiling

Motion profiling is important for precise control of the system. What it is, is creating a curve that dictates your exact velocity according to time.

For instance, here the system gains speed and looses speed at exact times. In its final form, the feedforward discussed earlier will bring the system to roughly the desired speed, and final corrections will be made with feedback control.

If your goal is to simply create a motion profile, then a PID can be a good option.

note that this method is built in the subsystem class

This is a basic motion profile where a PID controller will continuously update the velocity. However, the primary issue with this is that it's not what a PID is built for, therefore will have undesired effects. Here, the acceleration is painfully slow, because the velocity controllers are calculating the best path for the motors, not the motion profile.

Adding feedforward would improve the situation. Take this flywheel:

The feedforward will first set a value, which the motor will attempt to target, after which the feedback controllers will correct the rest of the error.

For a real motion profile, WPILib has a real class for this. Enter the Profiled PID Controller. This is a PID controller with a few more parameters: a maximum acceleration and a maximum velocity. With these upper limits, our motion profile will be closer to what is desired.

Last updated