Low speed robot control at high mechanical load

Does anyone have experience with driving BLDC motors at low speed with high mechanical load? I’m attempting to diff-drive a robot with hoverboard-style wheels (modified to have high resolution AS5304 encoders, at 6880cpr). The robot configuration is actually similar to this powered cart made by @madcowswe.

I need responsive velocity control in order to interface with the robotics controllers that I’m using. Under no load, the motors do indeed respond well to velocity commands, both in terms of accuracy and response time. Under load however, the motors lag behind the target velocity (especially when turning).

Increasing the vel_integrator_gain parameter improves response time but introduces too much unwanted overshoot. I’ve increased vel_gain to about as high as it can go before it becomes unstable. It still seems that at low speeds (e.g. 0.2rev/s), the error terms between the estimated velocity from the encoder and the velocity setpoints are too small so the controller isn’t driving the motor with enough current to overcome the inertia of the robot.

I am not an expert in PID control but regarding the ODrive control diagram below, it seems to me that it would be beneficial to have acceleration error feedback by differentiating the encoder output twice. However, I have read that this is susceptible to noise and is therefore generally avoided.

Is the diff-drive + castor wheel design simply unfit for this application? Would a stepper motor with high holding torque be preferable in this case? Or a BLDC as part of a geared system that can spin at higher speeds while the wheels move more slowly with high torque?

Any input appreciated. Thanks!

You simply need higher vel_gain, and higher current_limit.

Yes, this isn’t a great idea. Instead, rely on the motor current feedback. Acceleration and motor torque are proportional (F = ma) and motor torque is proportional to motor current (Motor torque = torque_constant * Current), so you could add a torque feed-forward OR increase your motor.config.current_limit or controller.config.torque_limit

That’s pretty much all you can do.

Yeah, gearing can help. I think you just need more torque.

1 Like

Increasing the motor current limits was a good suggestion but wasn’t applicable in my case since the limits were already much higher than the current produced in the motors.

Initially I thought this was not possible, because increasing vel_gain any further would make my motors unstable, causing huge vibrations. However, I found that decreasing the encoder bandwidth effectively smooths out the velocity estimate, which allows me to set more a more aggressive vel_gain and rely less on the vel_integrator_gain to produce the needed torque. This makes the motors much more responsive. I’ve got further testing to do but this helps. Thanks

1 Like

It might be a better idea to reduce the current controller bandwidth instead of the encoder bandwidth, otherwise you are running a fast controller on an incorrect (filtered) position reading.

1 Like

If it’s running at low speed or low resolution (or worse… both), then reducing the encoder bandwidth can be a good idea