Drifting in Position Mode
Describe the bug The motor doesn't keep its position as it should.
To Reproduce
- Make motors free to spin.
- Make sure it uses ODrive v3.6, 24V, the 330 kv motors and the amt 102 encoders.
- Build ODrivefirmware at commit daa089c3 and flash it.
- Run odrivetool from the repo:
$ ~/repos/ODrive/tools/odrivetool -
In [1]: odrv0.erase_configuration() -
In [2]: exit -
$ ~/repos/ODrive/tools/odrivetool restore-config odrive-config-AB.json, where odrive-config-AB.json is linked here -
$ ~/repos/ODrive/tools/odrivetool -
In [1]: odrv0.config.brake_resistance = your_measured_value -
odrv0.axis0.requested_state = AXIS_STATE_IDLE odrv0.axis1.requested_state = AXIS_STATE_IDLE odrv0.save_configuration() odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE odrv0.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE odrv0.axis0.motor.config.pre_calibrated = True odrv0.axis1.motor.config.pre_calibrated = True odrv0.axis0.encoder.config.pre_calibrated = True odrv0.axis1.encoder.config.pre_calibrated = True odrv0.axis0.requested_state = AXIS_STATE_IDLE odrv0.axis1.requested_state = AXIS_STATE_IDLE odrv0.save_configuration()``` - Attach a constant load mechanism to motor0.
- Put a slight constant load on motor0. 1-2 Ncm or something. This is not strictly neccesary, the bug appears without it as well, but the load makes the drift much larger.
- Observe and note down motor0's
pos_estimate. For me it was 0.0057. - While under slight load, move motor0 backwards ca 1 revolution with step/dir signals. For me this moved
pos_setpointfrom 0.899 to 99.83. - Still under slight load, step motor0 forwards again by the exact same amount. For me this mover
pos_setpointfrom 99.83 to 0.899 as expected. - Observe your
pos_estimateagain. For me it was 0.03457.
Expected behavior
I expected the pos_estimate to be the same as before (0.0057) after I stepped pos_setpoint back to its original value.
Instead, the motor has drifted away from it's initial position by ca 1.65 degrees, according to the new pos_estimate (0.03457).
The drift in pos_estimate is also observed in physical reality. During a real 3d-print with Hangprinter, similar drift happens several times per second, and the print quickly go haywire. When using 0.5.1 this doesn't happen.
I think the drift happens as the moment when we're crossing down through pos_setpoint = 0
Desktop (please complete the following information):
- OS: Ubuntu 20.04
- odrivetool Version v0.5.4.dev (commit daa089c3)
Additional context
I was asked on Discord if this happens even if I disconnect the step signal and hard-wire it to GND or 3.3V.
I failed at testing this, since I don't know any other way to move the motor than with the step/dir signals.
The ODrive in the current (linked) configuration doesn't respond properly to input_pos changes.
I tried
In [56]: odrv0.axis1.controller.input_pos = 0.1
... but motor remained still, and odrv0.axis1.controller.input_pos kept its old value.
Signal noise on the step/dir signals is not the problem since the machine has been running long prints with 0.5.1 showing no drift. With v0.5.5 (devel) substantial drift is visible within a few seconds of starting a print.
Did #680 fix this issue?
TLDR; No. The config combination step/dir + circular range is still broken. It won't get fixed. Instead, the config combination step/dir + linear range was fixed and used as a workaround.
Long answer
No, #680 was not related to this issue.
Pardon me for digging deep in my memories about this issue, haven't thought about it since May 5.
@madcowswe and I had a separate debugging session about this issue. I don't have my notes at hand but can look at my odrivetool history.
We found a discrepancy between counters two counters: axis0.encoder.shadow_count and axis0.encoder.count_in_cpr.
This issue was never fixed as far as I remember. Looking at my config history, it looks like I worked around this bug by disabling circular range.
I also found this commit on ODrive's main branch: https://github.com/odriverobotics/ODrive/commit/c5017f4baf2f50b78cdcb2c28339a779bec62b30, which says:
"Making circular_setpoints optional in step/dir mode because circular_setpoints was broken beyond repair." I think that's how this issue was worked around.
Under the Additional Context I also mention an issue where the motor remained still although I told it to move via a input_pos change. That issue was resolved in these commits: https://github.com/odriverobotics/ODrive/commit/fa144cff291f8d80f6a7a8c7626e92b7bbe1b71c, https://github.com/odriverobotics/ODrive/commit/6444197251fafde5c4ff957aee6149b93bf22970, and https://github.com/odriverobotics/ODrive/commit/4ca99a62c88278a332fa83b23256c05dcea5ebdd.
We found a discrepancy between counters two counters: axis0.encoder.shadow_count and axis0.encoder.count_in_cpr.
Doesn't sound right. Only way that happens is if you're using an absolute encoder.