Inconsistent phase_offset_float values with hoverboard motor and encoder

I’m using ODrive (fw-v0.5.4) with hoverboard motors and AMT103 encoders, and it all works quite well now, but it worries me that I get highly inconsistent phase_offset_float values after ENCODER_OFFSET_CALIBRATION.

Here are the commands that I’ve run in odrivetool to demonstrate the issue:

odrv0.erase_configuration()
odrv0.config.enable_brake_resistor = True
odrv0.config.brake_resistance = 2
odrv0.config.gpio12_mode = GPIO_MODE_ENC1
odrv0.config.gpio13_mode = GPIO_MODE_ENC1
odrv0.config.gpio14_mode = GPIO_MODE_DIGITAL
odrv0.axis1.motor.config.pole_pairs = 15
odrv0.axis1.motor.config.resistance_calib_max_voltage = 4
odrv0.axis1.motor.config.requested_current_range = 25
odrv0.axis1.motor.config.current_control_bandwidth = 100
odrv0.axis1.motor.config.torque_constant = 8.27 / 16
odrv0.axis1.encoder.config.mode = ENCODER_MODE_INCREMENTAL
odrv0.axis1.encoder.config.cpr = 8192
odrv0.axis1.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL
odrv0.save_configuration()

odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION
print(odrv0.axis1.motor.error, odrv0.axis1.motor.config.phase_inductance, odrv0.axis1.motor.config.phase_resistance)
0 0.0004988669534213841 0.24248993396759033
odrv0.axis1.motor.config.pre_calibrated = True

import time
for d in range(5, 201, 5):
    print("%3.0f:" % d, end="")
    odrv0.axis1.encoder.config.calib_scan_distance = d
    for repeat in [1, 2, 3]:
        odrv0.axis1.encoder.config.phase_offset_float = 0
        for state in [AXIS_STATE_ENCODER_INDEX_SEARCH, AXIS_STATE_ENCODER_OFFSET_CALIBRATION]:
            odrv0.axis1.requested_state = state
            time.sleep(0.2)
            while odrv0.axis1.current_state != AXIS_STATE_IDLE:
                time.sleep(0.1)
            time.sleep(0.2)
            print(" %6.3f" % odrv0.axis1.encoder.config.phase_offset_float, end="")
        print()

(An ENCODER_INDEX_CALIBRATION before each offset calibration may or may not be necessary;
I just wanted to make sure that all offset calibrations start at the same motor/encoder position, eliminating the possibility that these inconsistent values are caused by the random starting position.)

And the resulting phase_offset_float values for various calib_scan_distances:

  5:  1.117 -0.093 -0.341
 10:  0.418 -0.335  0.499
 15:  0.420 -0.203  0.077
 35:  0.289 -0.447  0.231
 40: -0.129 -0.267 -0.315
 45: -0.216 -0.197 -0.058
 50:  0.385  0.237  0.345
 55: -0.397 -0.449 -0.150
 60:  0.311  0.145 -0.482
 65:  0.286  0.138 -0.226
 70: -0.293 -0.342  0.312
 75:  0.038  0.090  0.161
 80:  0.373  0.256  0.017
 85:  0.443 -0.412 -0.398
 90:  0.160  0.196  0.190
 95:  0.250  0.248  0.333
100:  0.304 -0.473  0.453
105:  0.099  0.045  0.169
110:  0.207  0.321  0.245
115:  0.324  0.314  0.346
120:  0.304 -0.163  0.129
125:  0.239  0.337  0.337
130: -0.492 -0.397 -0.393
135: -0.024  0.017 -0.008
140: -0.089 -0.226 -0.210
145:  0.285  0.429 -0.291
150: -0.017 -0.038 -0.100
155: -0.278 -0.223 -0.164
160:  0.172  0.281  0.329

The first column shows calib_scan_distance while the other three show the resulting phase_offset_float. As you can see the value of phase_offset_float doesn’t seem to converge with increasing calib_scan_distance values, and, worse, repeated offset calibrations with the same distance tend to vary considerably.

Is this normal? Or at least is it something that I should not be worried about?

FWIW, when I used the same motors with Hall effect sensors, then phase_offset_float was always quite close to 0.5 % 1 as mentioned in docs/hoverboard.md.

phase_offset_float of ~ 0.5 is only a thing for hall sensors. Does the drive work otherwise?

Yeah, I understood that with the encoder I will get phase_offset_float values different from 0.5 % 1, but what puzzles me is that I don’t get a consistent value with a reasonable tolerance, but it’s all over the place. And it worries me that something might be wrong that I can’t even grasp yet, and it’s just waiting to blow up.

As far as I can tell the ODrive and the motor work well (apart from some cogging).

Thanks for taking the time to look into this.