LeJOS PIDController not working, output is zero

June 5th, 2013 | by Sean |

This problem had me baffled for more than a few minutes: I wrote a leJOS PIDController loop for a LEGO NXT project that used one motor’s rotation encoder as the input to control another motor’s set point. It didn’t work: the output from the PIDController’s doPID(int) was reliably zero. My loop seemed quite reasonable: read encoder from motor A, apply it to setpoint of motorB’s PIDController, read motorB’s encoder, apply it to motorB’s PIDController as the ‘process variable’, get controller output, apply it with motorB’s setPower() method. It didn’t work!

I found the answer in lejos.util.PIDController’s source, in setPIDParam(int paramID, float value):

case PIDController.PID_SETPOINT:
  this.setpoint = (int)value;
  this.cycleTime = 0;
  break;

and in doPID(int processVariable):

if (this.cycleTime==0) {
  this.cycleTime = System.currentTimeMillis();
  return 0;
}

Setting the setpoint resets the cycle time and the next invocation of doPID returns zero! I don’t understand why it’s necessary to reset cycleTime on change of setpoint, but that’s what the leJOS code does. I kludged around it in my code by only invoking setPIDParam if the setpoint has changed and doPID works as expected.

Post a Comment