PID with iterative template

This is my team’s first year using PID control. I got it to the point where it works extremely well, but I had to make some weird code to get it to work, and I want it to work the right way.

The PID controller controls the lift. The issue that I have is by using the PID code I’m supposed to use, the lift runs in reverse. For example: if the encoder setpoint is 200, and the current encoder value is 100, it powers it down instead of up. If the setpoint is 200 and the current encoder value is 300, it goes up. Basically the problem is it goes away from the setpoint instead of towards it.

My work-around was to use an unused talon (“pidStore” in the code) as the PIDOutput. To activate the lift, I then did

cubeLift.set(-liftPID.get());

It works, but I’d like to get it to work the proper way. All of the documentation is for command-based, and we use iterative. I originally tried setting the P value to a negative number, but it did something weird (I can’t remember what) and I just left it alone after that.

Here is a snippit of the important parts:

WPI_TalonSRX cubeLift = new WPI_TalonSRX(3); //Cube lift speed controller
MyEncoder liftEnc = new MyEncoder(cubeLift, false, 1.0); //Encoder for the cube lift
WPI_TalonSRX pidStore = new WPI_TalonSRX(1); //Speed controller for setting up liftPID
PIDController liftPID = new PIDController(0.001, 0, 0, liftEnc, pidStore); //PID controller for lift
...
public void robotInit() {
    pidStore.disable();
}
...
public void teleopPeriodic() {
...
    if(Math.abs(joy2.getRawAxis(1)) >= 0.1) { //If axis 1 is off-center...
        cubeLift.set(joy2.getRawAxis(1));//Set the lift speed to the axis reading
        liftPID.setSetpoint(liftEnc.get());//Set the lift PID setpoint to the current encoder value
    } else {
        cubeLift.set(-liftPID.get());
    }
    ...
}

The whole code can be found here, please excuse the mess :). If you need any additional info/clarification, let me know.

Our method is certainly not the right way, but for your PIDController declaration, you can do this instead:

PIDController liftPID = new PIDController(0.001, 0, 0, liftEnc, output->{}); //PID controller for lift

I still don’t really know why this works, but it looks like it is storing the pid output value (that you get from liftPID.get()) into a local value output, in the PIDController class. This value is returned when you call liftPID.get().

Both encoders and speed controllers have a method to set them inverted. Figure out which one you want to change the direction on and call the appropriate method.