Motor Speed Control Algorthims

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.

  1. 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?

  2. 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.

  3. 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.

Why are you controlling speed? Particularly when your desired speed is zero.

I thought most balancing bots controlled torque, with some very simple limits on speed. The PWM output to the motor driver is a pretty good estimate of torque (near zero speed) so there's no PID feedback required.

milo_mindbender:
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.

You might have answered your own question right there. At the moment, it just appears that the good quality encoders with relatively high resolution are relatively large. But..... if you have a large enough robot, with enough battery power and energy to support everything, it should be possible to use those sorts of encoders.... with the higher resolution.

I have seen those small hall effect encoders that they attach to small motors...... around 12 ppr. They do have their own uses for velocity measurements. But maybe not good enough for super stable balancing robots.

Maybe they do have miniature rotary encoders with relatively high precision these days.... but probably cost an arm and/or leg.

I haven't tried to build a balancing robot but my instinct is with @MorganS. AFAIK the balancing robot in this link (the link is to Reply #2) does not use wheel encoders to balance.

I can see that encoders may be useful if you want to control the speed of the robot when it is moving.

...R

Yes the D term will get all the noise, but it also gives more stability so you have a trade off.

The 100Hz update rate is very slow, aim for higher update rate if possible - any latency in response
directly reduces stability, so reducing this allows a PID loop to perform better.

As for the transition from slow forwards to slow backwards, you are probably not using the best
decay mode in the motor driver.

You want synchonous rectification for best performance, ie the motor drive voltage oscillates between
full forwards and full backwards voltage at the PWM rate, with 50% PWM corresponding to stationary.

This means full torque is available throughout the direction change, and crucially the loop-gain of the PID
is constant across the transition.

If you drive a motor in synchronous rectification mode at zero drive (ie 50%), you'll feel the rotor
is more firmly held than any other mode which is what you need for a servo.