Hardware: ODrive Pro, firmware tested on both 0.6.6 and 0.6.11 (same issue on both)
Motor: T-Motor Velox 3.0 2306, 1950KV, 7 pole pairs (12N14P), no encoder — sensorless only
Power: 24V DC supply, regen clamp on the bus
Calibrated values: phase_resistance ≈ 0.084Ω, phase_inductance ≈ 31.4µH (calibration_current=40A, resistance_calib_max_voltage=7V)
I can get the open-loop sensorless ramp to run cleanly at any speed from ~10 turns/s up to 50+ turns/s. The problem is specifically at (or shortly after) the open-loop→closed-loop handoff: the axis either disarms immediately (CURRENT_LIMIT_VIOLATION or DC_BUS_OVER_REGEN_CURRENT) or, with very low vel_gain, survives indefinitely in CLOSED_LOOP_CONTROL state with disarm_reason staying 0 — but the motor is not actually spinning. I confirmed this by hand: with the drive reporting a smooth ~600 RPM tracked speed (driven and estimated columns agreeing within a few percent), the rotor is physically stalled.
This means the telemetry (motor.foc.phase_vel and motor.sensorless_estimator.phase_vel) was self-consistent but decoupled from reality — likely because at near-zero vel_gain the controller just follows the estimator’s output, and the estimator was extrapolating from the controller’s commanded frequency, with no actual back-EMF correction happening. I want to flag this because it means any automated check based on these fields alone (e.g. “does estimated velocity match target”) could give a false positive while the motor is actually stalled and heating.
What I’ve tried (all fail the same way, or produce the false-lock behavior above)
- torque_constant: swept from 8.27/1950 (rated-KV) up to 2.5x that value. Higher values measurably reduced estimator noise/oscillation during the ramp, consistent with the Kt-sensitivity discussed in this thread, but never resulted in genuine sustained rotation past handoff.
- sensorless_observer_gain: 500 (default), 200, 50
- sensorless_pll_bandwidth: 1000 (default), 500, 300, 150
- current_control_bandwidth: 1000 (default), 300 (closer to the motor’s own L/R electrical bandwidth of ~427Hz)
- sensorless_ramp target speed: 10 to 50+ turns/s (well above the ~1-2V back-EMF floor for this KV)
- vel_gain / vel_integrator_gain: swept from defaults down to vel_gain=0.0001, vel_integrator_gain=0 (per the fix in this thread) — this is what produced the “false lock” (stalled motor, clean-looking telemetry) described above
- Reverted sensorless_pm_flux_linkage to automatic (left at 0.0/not manually overridden) per your advice in the thread linked above
- bEMF_FF_enable / wL_FF_enable: tried both on and off
- Confirmed calibration is accurate: current soft/hard max raised well above anything we hit (80/100A), dc_max_positive/negative_current given generous headroom
Questions
-
Is this motor (31µH inductance, 84mΩ resistance) simply outside the range the sensorless estimator can reliably handle on ODrive Pro? I found several independent sources describing motors in this inductance range as a known-hard case for general FOC sensorless control due to current ripple at achievable PWM frequencies — wondering if that’s the actual ceiling here rather than a tuning issue.
-
Is there a way to directly verify, from the API, whether the sensorless estimator has a genuine lock vs. is just echoing the commanded ramp value?
-
Any other sensorless-specific parameters worth trying that I haven’t found via the Python API surface?
Happy to share full config dumps / data logs for any specific test if useful.