Motor Control Instability

I have a 900kv motor (Scorpion HK-3014-900KV) tracking a velocity setpoint in sensorless mode using v3.5 of the ODrive hardware. I have release v0.4.1 of the firmware that I have added to ability to set the pm_flux_linkage Post. The motor spins up and regulates velocity great until I get to a high enough requested velocity (around 3000 rad/s electrical). The motor then begins to shutter as if it is bouncing off a limit or going unstable. When the motor shutters both the resistor and motor start to get warm/hot. If I keep increasing velocity the driver eventual shuts down with an error code 0x31:

ERROR_INVALID_STATE
ERROR_BRAKE_RESISTOR_DISARMED
ERROR_MOTOR_DISARMED

I have tried replacing my 24V 10 A power supply with a LiPo battery, setting the brake resistance to zero so that the battery is the sink for braking, increasing the current_lim, and tuning the velocity controller. I think the instability may be coming from the current controller and I was going to decrease the gains to see if there is any improvement. I wanted to get a second pair of eyes on my setup to make sure I have not missed anything obvious, or if there are any additional suggestions.

Below is a print out of the axis state after a failure resulting in an error code of 0x31.

motor:
  gate_driver: ...
  armed_state = 0 (int)
  current_meas_phB = -0.038694679737091064 (float)
  DC_calib_phC = -1.7575383186340332 (float)
  current_control:
    v_current_control_integral_q = 0.0 (float)
    i_gain = 43.920989990234375 (float)
    p_gain = 0.010267496109008789 (float)
    Iq_measured = -71.01968383789062 (float)
    v_current_control_integral_d = 0.0 (float)
    Iq_setpoint = 1.8226861953735352 (float)
    final_v_alpha = -6.225567817687988 (float)
    max_allowed_current = 71.99999237060547 (float)
    final_v_beta = -5.765687942504883 (float)
    Ibus = -53.85747146606445 (float)
  DC_calib_phB = -0.8072223663330078 (float)
  current_meas_phC = -0.0551450252532959 (float)
  phase_current_rev_gain = 0.02500000037252903 (float)
  config: 
    current_lim = 10.0 (float)
     resistance_calib_max_voltage = 1.0 (float)
    direction = 1 (int)
    phase_resistance = 0.04392099007964134 (float)
    pre_calibrated = True (bool)
    phase_inductance = 1.0267495781590696e-05 (float)
    requested_current_range = 70.0 (float)
    motor_type = 0 (int)
    pole_pairs = 5 (int)
    calibration_current = 10.0 (float)
  timing_log: ...
  is_calibrated = True (bool)
  error = 0x0000 (int)
current_state = 1 (int)
controller:
  set_current_setpoint(current_setpoint: float)
  current_setpoint = 0.0 (float)
  pos_setpoint = 0.0 (float)
  vel_integrator_current = 0.0 (float)
  vel_setpoint = 0.0 (float)
  config:
    vel_limit = 7500.0 (float)
    pos_gain = 20.0 (float)
    control_mode = 2 (int)
    vel_integrator_gain = 0.0010000000474974513 (float)
    vel_gain = 0.0024999999441206455 (float)
  set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
  set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
  start_anticogging_calibration()
encoder: …
requested_state = 0 (int)
loop_counter = 360370 (int)
sensorless_estimator:
  phase = 2.0527780055999756 (float)
  pm_flux_linkage = 0.0012251753360033035 (float)
  pll_pos = 1.9686251878738403 (float)
  pll_vel = 4027.0927734375 (float)
  pll_ki = 1000000.0 (float)
  error = 0x0000 (int)
  pll_kp = 2000.0 (float)
enable_step_dir = False (bool)
error = 0x0031 (int)
config:
  ramp_up_distance = 12.566370964050293 (float)
  counts_per_step = 2.0 (float)
  spin_up_target_vel = 1500.0 (float)
  spin_up_acceleration = 800.0 (float)
  startup_encoder_offset_calibration = False (bool)
  startup_encoder_index_search = False (bool)
  spin_up_current = 10.0 (float)
  ramp_up_time = 0.4000000059604645 (float)
  startup_closed_loop_control = False (bool)
  startup_sensorless_control = False (bool)
  enable_step_dir = False (bool)
  startup_motor_calibration = False (bool)

Hm interesting. The sensorless should be able to go faster than that, but to be honest I haven’t tested it myself in quite a while.

FYI We added that in v0.4.2

When you tried this, did the error still include ERROR_BRAKE_RESISTOR_DISARMED?

I think this is your problem, it seems the current controller went unstable. There could be a few different reasons for that, but I probably have to test here to really dig into it. Here are some things you can try:

  1. Your pm_flux_linkage could be wrong. I checked your value from the dump, and it’s computed correctly given 5 pole pairs and 900kv. You could use the drill test (see “measurement” heading of this post) to verify. It would be interesting to see the shape of the back-emf also, so take a picture if you do this test.

  2. Try reducing the current controller bandwidth.

  3. Try increasing or decreasing the sensorless observer gain.