PID on button press?

My team has gotten PID to work based on encoder inputs. We currently have it where we are getting an encoder value and making the PID stop the PID control at 10. It works perfectly fine for a setpoint of 10. We need to make it to where the setpoint value changes on button presses but we are struggling to do that. Does any have any experience with this? Thanks in advance!

Not a Java expert, but can’t you just use the setpoint function one more time if the button is pressed to change the setpoint?
If you’ll post a code snippet I might be able to help more.

2 Likes

public class Elevator extends PIDSubsystem {
private static final double kP = .52;

private static final double kI = 0;

private static final double kD = 0;

public Elevator() {
super(“Elevator”, kP, kI, kD);
setSetpoint(10); <---- I need to change this value based on a button press.
enable();
}

@Override
public void initDefaultCommand() {
// Set the default command for a subsystem here.
//setDefaultCommand(new ManualDriveCommand());
}

@Override
protected double returnPIDInput() {
// Return your input value for the PID loop
// e.g. a sensor, like a potentiometer:
// yourPot.getAverageVoltage() / kYourMaxVoltage;
return Robot.driveSubsystem.encA.get()/100;

}

protected void usePIDOutput(double output) {
// Use output to drive your system, like a motor
// e.g. yourMotor.set(output);
if(OI.pidElevator.get()) {
Robot.driveSubsystem.elevator.set(output);
}
}
}

You could have multiple commands, each one moves your lift to another height, then assign each command to a specific button.

then you are able to set your setpoint through your gampad input by setting the setpoint variable with the button.

You are setting the setpoint in the constructor of the Elevator class. The constructor should only be run once when you create your elevator instance, and should be used to initialize the hardware and PID loop. You should run the setSetpoint method in your teleop/autonomous mode when you need to set the setpoint.

1 Like

Better yet, just make one command that takes a position as an argument, then when assigning the command to multiple buttons, pass in the height you want that button to go to. That way if you need to change the logic in the command, you only need to change it in one place.

All of this is of course assuming that OP is using the Command Based framework.

1 Like

This is exactly what we’re doing this season. It works great and keeps everything clean with minimal files.

Yes, that was actually what I meant to say.

If you are just testing and tuning your PID constants and just want to try a range of setpoints, using the SmartDashboard is an easy way to get your setpoint and have it change without having to rebuild and re-deploy code all the time.

If you are trying to write competition style code where your drivers can just hit a button to have the elevator use a PID loop to set the position to different pre-computed locations then the best path forward is to have each button represent a position, and use multiple buttons. (Typically) . That’s certainly the most simple way for sure.