Adventures in running larger hall only motors

I thought I’d share some of my findings when running larger hall only motors.
The motors I’m using are 500W 48V motors with a built in 6:1 gearbox, designed for electric vehicles. These are pretty low inductance motors so the recommended ODrive settings are a long way from optimal. I started with the Hoverboard guide.

First of all, a note about the number of pole pairs. The guide says you have to find the correct number of poles for your motor. This isn’t easy with no-name Chinese motors. However as long as you are only running hall sensors the pole count does not matter. Pick any number. encoder.config.cpr must be 6 times this value. I tested this on my motor with 2 pole pairs and 9 pole pairs. It made no difference at all.

Another thing worth mentioning is that when calibrating the motors, depending on your wiring, the offset_float may be something like 1.5 instead of 0.5. Only the number to the right of the decimal matters.

The first issue I found after setting up the motor was that if I tried running the motor with a velocity anything above 100 it immediately tripped out with a ERROR_CURRENT_UNSTABLE fault. After much experimentation and research I worked out the problem is the current control bandwidth. As these motors have a very low inductance the current loop can’t react quickly enough with the recommended settings. Increasing motor.config.current_control_bandwidth to 4000 made a huge difference. When stationary the motors are a bit noisy but they can now be run at high speed. The faster you go the higher you need to run the bandwidth. For my application 4000 was a good balance. Increasing it to 8000 increased the noise a lot and didn’t make a huge difference to the top speed.

Here are my motor settings if anyone is interested:
direction = -1 (int)
phase_inductance = 0.000105345141492 (float)
resistance_calib_max_voltage = 10.0 (float)
current_lim = 30.0 (float)
inverter_temp_limit_lower = 100.0 (float)
current_control_bandwidth = 4000.0 (float)
inverter_temp_limit_upper = 120.0 (float)
current_lim_tolerance = 1.25 (float)
calibration_current = 30.0 (float)
requested_current_range = 80.0 (float)
motor_type = 0 (int)
pre_calibrated = True (bool)
pole_pairs = 2 (int)
phase_resistance = 0.0583755970001 (float)

The recommended velocity tuning is very soft, which is understandable for the demonstrated application. However I am controlling an autonomous differential steer rover so I want the wheel speeds to track as accurately as possible. The more accurately the drives control the wheel speeds, the easier it is to keep in a straight line. First of the recommended encoder.config.bandwidth makes it very difficult to tune the controller. Increasing this to 600 made it much easier to tune the controller. Increasing beyond this value just made the motor sound rough at low to medium speed, with no real improvement in accuracy.
After a bit of experimentation I found controller.config.vel_gain=0.8 and controller.config.integrator_gain=2 gave really good results. Increasing the velocity gain beyond that just make the motor sound rougher at medium speeds. Increasing the integrator gain caused oscillation when stationary. With these settings if I try to turn the wheel it hardly moves at all, even if I really try hard. As far as I can tell it is probably staying within 1 or 2 encoder counts.

Getting the motors running in the first place was a bit of a learning curve but now I have found some good settings I’m really plesed with the ODrive.

2 Likes