PID loop help?

Our programming team is mentor-less and needs to figure out PID loops. The idea is to be able to press a button and have an arm move to a certain position. We’re using a Talon SRX and an encoder, coding in Java (Iterative).

Here’s what we have so far (with everything not-PID and all the imports cut out):


public class Robot extends IterativeRobot {
	
	//Initialize the encoders
	AnalogInput lift_measure = new AnalogInput(2);
	
        WPI_TalonSRX(kLiftMotorChannel);
	
	//Create empty storage values
	double initial_lift_value;
	double lift_value;
	
	//Define the actual joy sticks
	Joystick stick2 = new Joystick(1);
	
	//Variables for PID loop
		double PIDsource = 0;
		double PIDoutput = 0;
		double Kd = 0;
		double Ki = 0;
		double Kp = 0.3;
		PIDSource pidsource = lift_measure;
		PIDOutput pidoutput = lift_screw_motor;
		
	//Initialize PID loop for the lift screw motor
	PIDController lift_pid = new PIDController( Kp,  Ki,  Kd, pidsource, pidoutput);
	
	@Override
	public void robotInit() {

		//Retrieve initial encoder value in order to have a reference to zero the lift
		initial_lift_value = lift_measure.getAverageValue();
		
		//Enables PID controller for lift motor
		lift_pid.enable();
	}

	@Override
	public void teleopPeriodic() {
		robotDrive.setSafetyEnabled(true); 
		while (isOperatorControl() && isEnabled()) { // Ensures that robot is enabled and in Teleoperated mode
			
			lift_value = (Math.abs(lift_measure.getAverageValue() - initial_lift_value));
			
			
			if(stick1.getRawButton(9)) {
				lift_screw_motor.set(0.3);
			}else if(stick1.getRawButton(10)) {
				lift_screw_motor.set(-0.4);
			}else if(stick2.getRawButton(14)) {
				lift_pid.setSetpoint(1.2);
			}else {
				lift_screw_motor.set(0);
			}
			
			SmartDashboard.putNumber("Lift Angle", lift_value);
			
			Timer.delay(.005); //Delays Cycles in order to avoid undue CPU usage
}

This obviously isn’t right, but it’s been a few days now and we’re pretty stuck. Any help or guidance would be appreciated.
Thanks!

If you are using a quadrature encoder you need to initialize it differently.

This is how we generally add encoders as they require two digital inputs.

public static Encoder DTELeft;
DTELeft = new Encoder(0, 1);

Hope that helps

I can’t get a complete solution but I did notice you didn’t enable the PID. You have to enable the controller for it to start moving the motor. Disable it when you want to manually move it.

On a side note, I highly recommend you use CommandBased if you want to use PID. It is really useful to separate out these devices.