JAVA PID with Encoders

Hello all,
We were able to get the PIDController to work great with the gyro but are having problems with the encoders.

Here is the part of the code we are using: the problem is when I run autoN it does nothing. The Output class doesn’t print nor does the robot move.

package TestRobot;
import edu.wpi.first.wpilibj.*;

public class RobotMain extends IterativeRobot {

public static LinearVictor VictorLeft  = new LinearVictor(1);
public static LinearVictor VictorRight = new LinearVictor(3);

Encoder LeftEncoder = new Encoder(4,6,4,7,false,CounterBase.EncodingType.k2X);
PIDEncoderClass PidWriteEncoder = new PIDEncoderClass();
PIDController PidEncoder1 = new PIDController(0.1,0,0,LeftEncoder,PidWriteEncoder);

public void robotInit() {
    System.out.println("ROBOT IS ON.");
    LeftEncoder.start();
}
public void autonomousPeriodic() {
    System.out.println("AutoN");
    PidEncoder1.enable();
    PidEncoder1.setSetpoint(10000);
}
public void teleopPeriodic() {
    System.out.println("TeloP");
    System.out.println(LeftEncoder.getRaw());
}

}

package TestRobot;
import edu.wpi.first.wpilibj.PIDOutput;

public class PIDEncoderClass implements PIDOutput{

public void pidWrite(double output) {

  System.out.println("Output " + output);
  
  RobotMain.VictorLeft.set(output);
  RobotMain.VictorRight.set(output);

}

}

Mark,

Encoder LeftEncoder = new Encoder(4,6,4,7,false,CounterBase.EncodingType.k2X );

are you using the KOP Encoders? They are quadrature encoders, if I remember correctly.

This constructor should work:


Encoder(DigitalSource aSource, DigitalSource bSource, boolean reverseDirection) 

the constructor seems to be the only issue that jumps out at me. Also, there is always the usual “double check your connections and wiring”.

Yes they are the usDigital KOP encoders.
You can set them to be 1x 2x or 4x, I have tried all four without success. I have also used that constructor without the “CounterBase.EncodingType.k2X” and it still refused to work.

Running encoder.get() the values print fine.

If you want a working solution now, I suggest writing your own PID controller.

You are using P only, so this should be easy.


output = P * (encoder.get() - setpoint);

The issue is with the encoder. Because you can use encoders to measure either speed or distance (or both), you need to tell the encoder which measurement to use when the PIDController calls pidGet().

You can do this by adding the line (assuming you want to use distance as your measurement):


LeftEncoder.setPIDSourceParameter(Encoder.PIDSourceParameter.kDistance);

…after you instantiate the encoder but before you instantiate the PIDController.

The kDistance what kind of value does it return with pidGet()?

It returns the result of GetDistance().