I'm building a 2 wheel balancing robot and am having some trouble with the motor control.
I have a PID controller for each gearmotor and encoders that are generating an RPM signal feeding back into the PID which is evaluated at 100hz.
The motor pids are driven by a PID tied to an IMU. When the robot is balancing the speed request being sent to the motors looks pretty much like a slow sine wave.
The problem I'm running into is low speed control. When things are well balanced and the robot is sitting still, it wants to slowly run the motors forward and back to keep it's balance. This could be as slow as 10-30 RPM, rocking back and forth maybe once every one or two seconds. At that speed the PIDs have a hard time keeping the motors moving without pulsing, oscillating or jumping. It particularly has trouble when the speed goes from slow forwards to slow reverse.
I think one of the causes may be lack of precision in the encoders creating a slightly noisy speed signal that can get amplified by the D term in the PID, making it hard use.
I think the other issue is that the PID is having trouble dealing with the point where the motors stop and then reverse. Sometimes the output of the PID oscillates from positive to negative or just has problems getting the motors restarted after they stop and reverse.
Honestly I think I'm having multiple problems here so I'm looking for some suggestions in a couple of areas.
-
My encoders are not so good, the square waves they put out are not symmetrical (ie: the ON part of the square wave is shorter than the OFF) and from reading to reading the if you measure the period of the square wave it varies. I have tried using a basic moving average which helps but introduces too much lag in motor response time, any suggestions on a better way to filter the encoder output?
-
At slow speeds I can get less than 1 count per 1/100 second loop, so the low speed signal from the encoders doesn't have much resolution.
-
Maybe PID isn't the best algorithm to use for motors with speeds that vary like this? PIDs seem to work great for keeping a reasonably steady speed but with motors where the PID setpoint oscillates slowly back and forth they don't seem so great. Are there other motor control algorithms that might work better?
Any suggestions on other motor control algorithms that might work better than PID for this application, or better ways of dealing with noisy RPM signals would be helpful.
P.S. Part of the solution is probably buy better motors/encoders, which I'm doing, but I'd like to see if there is also a way to solve the above problem.