Hub wheel motors are not in sync for the same vel_setpoint

Both motors are out of sync in velocity, please help, please let me know what am I missing

I am using the odrive for building a robot with hub wheels as a differential drive robot.
I need both wheels to be running exactly at the same velocity for it to go in a straight line
The config.cpr is set at 90 for a 15 pole pair hub motors, this wheels are from a hoverboard
I am able to drive both the wheels using the 48v odrive controller
axis0.controller.vel_setpoint = 270
axis1.controller.vel_setpoint = 270

but the wheels are turning at different velocities and it is making my robot turn or twist instead of going in a straight line

I issue a drive command and here is the output
Driving at velocities, left 270, right 270

OdriveBus voltage: 25.3953
left error0: 0
right error1: 0
left state0: 8
right state1: 8
left cpr pos0: 29.1738
right cpr pos1: 27.9142
left velocity0: 101.25
right velocity1: 81
left config cpr: 90
right config cpr: 90
left curr0b: -0.030012
left curr0c: -0.0639999
right curr1b: -0.204814
right curr1c: -0.10667
left temp0: 34.2053
right temp1: 31.6064

How to make both the wheels turn at the same velocity, it is very important for me to make the robot go in straight line, but it is drastically out of sync

left velocity0: 101.25
right velocity1: 81

I checked the inductance and resistance of the both the wheels it seems to be slightly different, does it matter?
In [1]: odrv0.axis0.motor.config

Out[1]:
pre_calibrated = True (bool)
pole_pairs = 15 (int)
calibration_current = 10.0 (float)
resistance_calib_max_voltage = 4.0 (float)
phase_inductance = 0.0004774605040438473 (float)
phase_resistance = 0.1966893970966339 (float)
direction = -1 (int)
motor_type = 0 (int)
current_lim = 20.0 (float)
current_lim_tolerance = 1.25 (float)
inverter_temp_limit_lower = 100.0 (float)
inverter_temp_limit_upper = 120.0 (float)
requested_current_range = 25.0 (float)
current_control_bandwidth = 1000.0 (float)

In [2]: odrv0.axis1.motor.config
Out[2]:
pre_calibrated = True (bool)
pole_pairs = 15 (int)
calibration_current = 10.0 (float)
resistance_calib_max_voltage = 4.0 (float)
phase_inductance = 0.0004224381991662085 (float)
phase_resistance = 0.1820838749408722 (float)
direction = -1 (int)
motor_type = 0 (int)
current_lim = 20.0 (float)
current_lim_tolerance = 1.25 (float)
inverter_temp_limit_lower = 100.0 (float)
inverter_temp_limit_upper = 120.0 (float)
requested_current_range = 25.0 (float)
current_control_bandwidth = 1000.0 (float)

How to put both motors run at the same velocity, I am giving both motors same vel_setpoint values
Thanks a lot for your help

Hi Fermi,

There are a few different things that could cause this.

With the wheels unloaded, will they reach your velocity setpoint of 270?

If your wheels can reach a velocity setpoint of 270 unloaded, the next step is making sure that you are allowing the motors to produce enough torque to get to that speed under load. Your current limit is 20A - can the motors handle more? Torque scales linearly with current. If the load of moving your robot is greater than the torque that the motors produce, you will never hit your target speed.

If your torque is adequate and the motors can achieve a speed of 270 counts/s, the next step is to tune the velocity gains. There is a guide here: https://docs.odriverobotics.com/control. Follow that but skip the position gain part if you are only using the motors in velocity control mode.

1 Like

Also, try increasing vel_integrator_gain a bit - it will correct for uneven load & friction in the wheels.

Thanks tOwen and PJohnson
Increasing the vel_integrator_gain seems to help, now I get it to work for vel_setpoint of 270 but for other vel_setpoint values it is still off some times the velocity overshoots and sometimes it is of lower values then the requested velocities.

It seems like I need a PID control
I was hoping that there was a PID Controller already embedded in the ODrive Controller and we can invoke it, wow that would be awesome isn’t it?

Since we don’t have it I guess, it seems to be a very common request to have a PID Controller for Odrive for Velocity commands, which means we need I and D feedback loops implemented, is there any open source code for ODrive implementing a PID controller?

I am sure a lot of people might have written one, if so please kindly point me to any starting point for this PID Controller open source, I would greatly appreciate it.

Thanks a lot for your help

Hi Fermi,

You already have most of a PID controller - the Velocity controller in ODrive is a PI controller! If you know how to tune a PID, you should be able to tune ODrive. In the control link I posted before, there’s a diagram of how the ODrive control works.

If you really need the D term, you could add it to the firmware in controller.cpp. In most cases, the anti-windup on the velocity integrator is good enough.

The velocity P gain is vel_gain and the I gain is vel_integrator_gain.

Also - did you go through the tuning procedure from the Control documentation page? Good tuning is crucial for ODrive performance.

Fermi,

You will never be able to “exactly” make it “go straight” by just “making the motors move the same”. Even if you get the software to keep the wheels locked in phase, you can rarely, if ever, guarantee that the wheels never slip or have a perfectly constant diameter. What if you go over a piece of dirt on one wheel?

You need some other system to measure if you’re drifting off axis and correct your “straight line” to keep it that way.

Don’t get me wrong. I bet you can calibrate things well enough that, with a good phase lock between the two wheel positions, you can probably get good enough for what you’re doing. But it will never be “perfect”.

1 Like

I’d also point out that most industrial motion controllers also use PI for velocity - there’s little point in having a derivative for velocity, because you’d be amplifying so much noise (since you’d have a double differentiator on a position encoder)

as @cinderblock said, it’s impssible to get perfect tracking with wheel odometry alone - you need an external sensor e.g. IMU and/or GPS and/or computer vision to keep a robot on the straight-and-narrow :slight_smile:

That said, if you increase vel_gain and vel_integrator_gain a little more, they should be able to spin more or less in lockstep.
If you have tuned the velocity controller to the point where it’s almost unstable, and you still find that the odometry drifts, then perhaps you should be running in position mode instead.

PJohnson and Cinderblock Thanks a lot.
Odrive Community is the best.

I understand IMU and Lidar will help to keep everything straight when needed according to the path planning.
For now I just wanted to have accurate wheel odometery
and for that I need to tune vel_gain, and vel_intergrator_gain
at this point if I request 1 meters/sec, I would like to have 1 meters/sec velocity on both wheels.
I understand wheel slippage, uneven tire wear and tear, not having the same volume of air in each tire and other physical differences. All these physical parameters are not a constant and it will keep changing slightly over time, I don’t have any control over that.

The only control I have is set_velocity. For that I need to tune to set/read the same velocity on both wheels. I have to keep the feedback errors to the minimum.
I got my answers on this forum, and as suggested I am working on I and D values.
IMU adjustment will be secondary and it will obliviously make it more accurate, previously without tuning I was noticing 30% off the requested velocities, now after increasing the vel_integrator_gain it is better.

Thanks a lot

1 Like