PID control does not work properly

I’m trying to write a program that uses PID control to move a drive to a specific location.
But the motor keeps spinning forever.
The Encoder value was successfully retrieved.
Why?
DriveMortor is TalonSRX.

pid = new PIDController(0.1,0.1,0.1);
/*
~~~~
*/
driveMotor.set(ControlMode.PercentOutput,pid.calculate(encoder.getDistance();,2.0));

Could you please share more of the code, and not only these two lines? Where do you call driveMotor.set? Also, this semicolon after encoder.getDistance seems weird.
My guess is that you don’t call driveMotor.set(ControlMode.PercentOutput, 0) and that might make the Talon SRX go forever at the last speed received from pid.calculate.

1 Like

I think the problem lies in the semicolon after getDistance(). You only need a semicolon at the end of the whole line.

I’d also recommend starting with only a P value and then add I and D values if needed

1 Like

To add to this - those constants look wrong. I’ve never seen a tuned PID where they are all the same. Start with just a P - don’t use the other two until you’re happy with the proportional response. In addition, have you verified that the encoder counts in the positive direction when you command your motor to move in the positive direction? This is called having a sensor ’ in phase ’ with the motor direction, and is required for PiD control to function.

2 Likes

While I commend you on trying to use a software PIDController to drive your TalonSRX I would highly encourage you to read CTRE docs on Talons and use the speed controller’s built in PID and if you’re just trying to drive a straight line a certain distance I highly recommend Motion Magic.

Start here…
https://phoenix-documentation.readthedocs.io/en/latest/ch14_MCSensor.html#bring-up-talon-srx-sensors
Pay special attention to the “Sensor Phase” section

Then move to their Closed Loop documentation…
https://phoenix-documentation.readthedocs.io/en/latest/ch16_ClosedLoop.html#motor-controller-closed-loop
Your “drive to a specific location”, assuming straight line movement, could be accomplished using “Position Closed-Loop Control Mode” but you should really look at Motion Magic
https://phoenix-documentation.readthedocs.io/en/latest/ch16_ClosedLoop.html#motion-magic-control-mode

White paper for motion magic control mode and PID tuning FRC 6377 The howdy bots just released our first whitepaper! "Dont break your bot a guide for testing large and delicate mechanisms

This is all the code.

    SimpleMotorFeedforward feedforward = new SimpleMotorFeedforward(0.1, 0.2, 0.2);
// constructor
drive(TalonSRX driveMotor, Encoder encoder){
    this.encoder = encoder;
    this.driveMotor = driveMotor;
    this.pid = new PIDController(0.1,0.1,0.1);
}

/**
 * ToDo
 */
public void applyState(State state) {
    // checkPIDenable
    if(state.is_drivePIDOn){
        this.setSetpoint(state.driveSetpoint);
        this.enablePID();
    }else{
        this.disablePID();
        this.setSpeed(state.driveSpeed);
        System.out.println("PIDOFF");
    }
}

// モーター
public void setSpeed(double speed) {
    driveMotor.set(ControlMode.PercentOutput,speed);
}

// encoder
public double getHeight() {
    double height = encoder.getDistance();
    return height;
}
public double getSpeed() {
    double speed = encoder.getRate();
    return speed;
}

// PID
public void enablePID(){
}

public void disablePID(){
}

public void setSetpoint(double height){
    double speed = pid.calculate(this.getHeight(),height)+feedforward.calculate(height);
    setSpeed(speed);
}

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.