I've read numerous posts (1 , 2, 3 ) about using PID to control motors. All examples I've seen deal with the control signal being in the same units as the measurement signal. For example, use PID to set PWM values and measure PWM values as feedback or read stepper motor values in encoder clicks and then set new motor values also in clicks.
What I'm not understanding is how does one use PWM as the control when the measurements are in Encoder Clicks as would be common on a DC brush motor with encoder. How does the output of the PID taking Clicks as input, outputs and setpoint get translated to an appropriate 0 to 255 PWM signal (Assuming 8-bit PWM)?
It seems like there's a fundamental disconnect between the encoder clicks which can be though of as velocity (change of distance over time) vs PWM control signal which is an amount of power provided to the motor.
My naive guess would be to:
- Determine the MAX encoder clicks per second at a given PWM value of 255 emperically.
- Determine the MIN encoder value for the PWM value right before the motor stops moving under load. (For example my Pololu motors need at least 60 PWM on my motor controller to actually turn, below that value they just 'whine'.)
- Linearly map the encoder readings from the MIN and MAX to an appropriate MIN and MAX PWM reading?
// Using the Arduino PID library
encoderLow = 60; // determined empirically
encoderHigh = 8400;// determined empirically
PWMLow = 60; // determined empirically
PWMHigh = 255; // PWM as which we reach encoderHigh
Input = reading_from_encoder(); // clicks per second
Setpoint = 1000; // also in clicks
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
translated_pwm = map(Output, encoderLow, encoderHigh, PWMLow, PWMHigh)
drive_motor(translated_pwm); // control signal to motor as PWM value.
Where Input (the feedback from the encoders), Setpoint, and Output are in clicks. Output is the control signal from the Arduino PID library
Questions:
- Is this the normal approach?
- My map() function assumes a linear relationship between encoder values and PWM values. I doubt that's true. Is the PID going to compensate for the nonlinearities?
- What is the correct way to do this?