PIDController usage?

My team has been trying to get our encoders and motors to work together in autonomous using WPILib’s PIDController. We are not sure on what P, I, or D values to use but at the moment are just trying to get it to give output to the motors.

We are using CAN Talon SRX motors as our motors and 256 pulse encoders.

We’ve tried using setpoints between .5 and 4 but no matter what we do, calling pidController.enable() never moves the motors.

Any help would really be appreciated :).

Our code goes something like this:

Encoder _rightEncoder = new Encoder(RobotMap.RIGHT_ENCODER[0], RobotMap.RIGHT_ENCODER[1], true, EncodingType.k4X);

Encoder _leftEncoder = new ...

WPI_TalonSRX _rightMotor = new ...
WPI_TalonSRX _leftMotor = new ...

PIDController _rightController = new PIDController(1, 1, 0, _rightEncoder, _rightMotor);

PIDController _leftController = new ...

...

// Configure encoders
_rightEncoder.setPIDSourceType(PIDSourceType.kRate);
_leftEncoder.setPIDSourceType(PIDSourceType.kRate);

double distancePerPulse; // in feet
distancePerPulse = (WHEEL_DIAMETER/* in */ * Math.PI) / (ENCODER_PULSES_PER_REVOLUTION * 12.0/* in/ft */);

_rightEncoder.setDistancePerPulse(distancePerPulse);
_leftEncoder.setDistancePerPulse(distancePerPulse);

_leftController.enable();
_rightController.enable();
_leftController.setSetpoint(4);
_rightController.setSetpoint(4);

Your setting the encoders source type to rate, but it sounds like you want distance.

We tried changing the mode to distance, and set it with a setpoint of 3, but it also did nothing in that case. In that case would 3 have been the correct value to use if our encoders are configured to convert pulses to feet? Or should we use a setpoint based on the encoders’ raw value?

The reason we have it set to rate is so we can regulate speed the robot moves at, and then disable the PIDController when the robot reaches a certain distance.

Hi

I would recommend reading this article: http://frc-pdr.readthedocs.io/en/latest/control/pid_control.html to understand how PID works.
Also, this article: http://frc-pdr.readthedocs.io/en/latest/control/using_WPILIB’s_pid_controller.html describes how to use WPILib’s PIDController, which could be useful although it seems like you’ve gotten most of the way.

Here are my thoughts on what it could be:

  1. You call setSetpoint after enabling the PIDController. It could, without a setpoint, end immediately (or refuse to start). Try setting the setpoint before enabling it
  2. Your setpoint is 4. While I’m not super familiar with the encoder class, and it would make sense that it would use the value you put in setDistancePerPulse, I would still try setting the setpoint to the encoder value, and seeing if that works
  3. You don’t call setTolerance, which might make it a bit upset as it doesn’t know when to stop
  4. Your encoders are configured to kRate. While you commented that you have plans to use the PID loop to manipulate your robots speed, I would say that you should at least get a basic PID loop working on distance first, and then expand to more complicated goals. Also, I’d imagine you might have difficulty if you just disable the PID controller once you reach a certain distance, as you will likely overshoot your setpoint. You would need to know ahead of time to start slowing down before you reach the setpoint. It might be worthwhile to take a look at motion profiling, as it sounds like what you want. This video is a good start - https://www.youtube.com/watch?v=8319J1BEHwM (But again, get a simple PID loop working for driving forward, and then expand.)

Thanks for the help! We’ll try some of those options when we meet again this Friday :).

We tried setting the setpoint before enabling the encoders, and set it to go for distance, but now our motors move wayy too fast. Is there a way to lower the power it gives the motors?

We’ve tried lowering our P,I,D values to .05,.1,0 but the loop still keeps overcorrecting and far overshooting the target, causing a loop of going forward then backward then forward and so on.

Hint, the PID values change the output to the motors. How did you determine those values? Did you follow the tuning procedure in the CTRE documentation?