Avoiding calibration at startup


As mentioned on the Discord support channel, we at the Greppy team are making a 5 DoF robot arm integrated with ROS using 3 ODrives. Because of all the joint constraints & interactions, we can’t run calibration at every bootup. So we’re looking at doing the “Encoder Calibration” with “Encoder with Index signal” (following https://github.com/madcowswe/ODrive/tree/master/Firmware#encoder-with-index-signal )

I’d like to understand a bit more how this works. @madcowswe mentioned in the channel:

So there are two uncertainties that need to be calibrated out. One is what angle the encoder had when you mounted it to the motor shaft. There is no good way to do this repeatable enough, so it’s random, but stays the same once mounted: so we need to calibrate this once.

The other uncertainty is where is the encoder when the ODrive boots. […] The encoders are incremental so the ODrive doesn’t know where “0” is, the encoder only sends the equivalent of “+1, +1, +1, -1, +1”, etc, indicating that we moved one count up/down. We don’t make any assumptions about where the encoder is on startup, so we need to find out where it was. This is done with the index pulse. When the index pulse fires, that is “0”. So when we see it, we can start counting from there, and be correct.
finding where “0” is needs to be done at every startup, since we stop counting when shut down.

On boot the encoder count is just something, we don’t care. Then we find the index, at that time we reset the count and start from there. […] if we do this index search before we calibrate the 1st time, and then always do the index search on every bootup, then we can restore the calibration offset, because we know we are locked into the correct start-position, so the calibration is still valid

A couple follow up questions. The documentation says that “check that the motor scans for the index pulse but skips the encoder calibration”.

I’m guessing this means that there is still motion from the odrive on bootup?

Is there any way to call this manually, so our code could start it on odrive 1, then 2, then 3? Because all the odrive motors are connected to each other mechanically, having everything spinning at once on bootup can get a bit out of hand.


When manually calibrated, motors will spin in one direction until the index pulse is found. You can choose which direction it turns. Maybe have it so that each axis always calibrates to a safe direction. Afaik a way to avoid this index pulse search altogether would be to use absolute sensors.

Another way to get rid of calibration would be a battery backup that keeps the position monitoring enabled when main supply is off. This way you’d maintain both calibration and even the position of the arm between each bootup.

btw is it possible to have ODrive powered from battery connected to AUX? It would be so sweet to have a small but powerful NiMH or LTO battery pack work as a dump load, power reserve and a backup battery at the same time :open_mouth:


This will be available on firmware v0.4.0.


Nice @madcowswe – is there a branch it’s currently in?


If you want to take a look, the latest stuff on that is sam_oskar_testing. Note that this is not released and we can’t spend time on helping you if you have issues with it.


Just posting here for the next person.
You can now set this up (after you’ve gone through the full calibration once) by:

<odrv>.<axis>.motor.pre_calibrated = True
<odrv>.<axis>.encoder.pre_calibrated = True
<odrv>.<axis>.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

You still need to have it do a couple of revolutions in the offset calibration, but heaps better than before.

Perhaps there’s also a way around this now too? It seems the <odrv>.<axis>.encoder.pre_calibrated = True isn’t working properly perhaps?


Is there any good way around this or being able to jog the motor without having this parameter set (to ensure the motor doesn’t hit end stops)?


To avoid the calibration, should be searching for index on the subsequent boots. There is more information in the documentation.

We don’t yet have the ability to jog the motor (in an inefficient mode) before index has been found, but it’s a planned feature.


Thanks. Good to know. I guess I’ll just have to come up with some way to avoid it hitting end stops in the mean time