Unexpected Overcurrent Error on Drive S1 with D5312s 330KV Motor

Hi everyone,

I’m building a robot that travels along a fixed cable — kind of like a gondola, but the cable doesn’t move. Instead, the robot has a motor that spins a rubber-covered wheel. The wheel presses against the cable and makes the robot move forward.

My goal is to have the robot accelerate at 5 m/s^2. Based on my calculations, this would require roughly 9 A to accelerate the robot, plus an additional component for friction and cable deformation, but I expect that to be somewhat small.

However, during testing, I get an overcurrent error: CURRENT_LIMIT_VIOLATION = 4096 (0x1000). This suggests that current_hard_max (set to 70 A) was exceeded. Even if my estimates are off, I’m struggling to see how the system could hit 70 A under these conditions.

  • Does the error mean what I think it means?
  • Could this be due to current spikes? If so, is there a good way to avoid or mitigate them? Could that also be linked to a bad controller tuning?

Here’s my configuration:

odrv.config.dc_bus_undervoltage_trip_level = 19.8				# min voltage for 6S battery
odrv.config.dc_bus_overvoltage_trip_level = 25.2				# max voltage for 6S battery
odrv.axis0.requested_state = 8 							# closed-loop control
odrv.axis0.controller.config.control_mode = 3					# position control
odrv.axis0.controller.config.input_mode = 5 					# trapezoidal trajectory
odrv.axis0.controller.config.vel_limit = np.inf
odrv.axis0.trap_traj.config.vel_limit = linear_to_angular(12)			# 12 m/s
odrv.axis0.trap_traj.config.accel_limit = linear_to_angular(5)			# 5 m/s^2
odrv.axis0.trap_traj.config.decel_limit = linear_to_angular(5)			# 5 m/s^2
odrv.axis0.config.motor.current_soft_max = 70
odrv.axis0.config.motor.current_hard_max = 70
odrv.axis0.controller.config.pos_gain = 20.0
odrv.axis0.controller.config.vel_gain = 0.10
odrv.axis0.controller.config.vel_integrator_gain = 0.10

Thanks in advance for any insights!

Cyril

Set current_soft_max to your expected maximum current. ~9 A (probably want to give a little overhead).
current_soft_max set to 70 allows the current set-point to move to 70 A, and then current_hard_max causes the error at 70 A, it’s a strict safety cutoff.

Hi! It’s possible some static friction or motor getting stuck is causing a larger occasional spike. We definitely recommend some headroom between current_soft_max and current_hard_max – maybe you could try 50A and 70A respectively?

This could also be an encoder mounting/slipping issue. What encoder are you using, and can you send some pictures of how it’s mounted to the motor?

If you can run odrivetool backup-config config.json and paste the config.json here, that would help a lot!

Hi, thanks a lot for your answers!

I’ll definitely try lowering current_soft_max relative to current_hard_max to see if that helps. What I’m not entirely sure about is how the controller behaves in the presence of current spikes. Does lowering the soft limit actually change how the controller reacts compared to just hitting the hard limit?

Regarding the encoder: we’re using the ODrive Encoder OA1, mounted with a 3D-printed part. So far it has seemed very reliable, with no noticeable jumps in position or speed. Here are some pictures:



And here is the content of the config.json file:

{
  "axis0.commutation_mapper.config.approx_init_pos": 0.0,
  "axis0.commutation_mapper.config.approx_init_pos_valid": false,
  "axis0.commutation_mapper.config.circular_output_range": 1.0,
  "axis0.commutation_mapper.config.circular": true,
  "axis0.commutation_mapper.config.index_gpio": 10,
  "axis0.commutation_mapper.config.index_offset": 0.0,
  "axis0.commutation_mapper.config.index_offset_valid": false,
  "axis0.commutation_mapper.config.offset": -1.8704965114593506,
  "axis0.commutation_mapper.config.offset_valid": true,
  "axis0.commutation_mapper.config.passive_index_search": false,
  "axis0.commutation_mapper.config.scale": 7.0,
  "axis0.commutation_mapper.config.use_endstop": false,
  "axis0.commutation_mapper.config.use_index_gpio": false,
  "axis0.config.I_bus_hard_max": Infinity,
  "axis0.config.I_bus_hard_min": -Infinity,
  "axis0.config.I_bus_soft_max": Infinity,
  "axis0.config.I_bus_soft_min": -Infinity,
  "axis0.config.P_bus_soft_max": Infinity,
  "axis0.config.P_bus_soft_min": -Infinity,
  "axis0.config.calib_range": 0.019999999552965164,
  "axis0.config.calib_scan_distance": 8.0,
  "axis0.config.calib_scan_vel": 2.0,
  "axis0.config.commutation_encoder_bandwidth": NaN,
  "axis0.config.commutation_encoder": 10,
  "axis0.config.dir_gpio_pin": 5,
  "axis0.config.enable_error_gpio": false,
  "axis0.config.enable_step_dir": false,
  "axis0.config.enable_watchdog": false,
  "axis0.config.encoder_bandwidth": 1000.0,
  "axis0.config.error_gpio_pin": 6,
  "axis0.config.index_search_at_target_vel_only": false,
  "axis0.config.load_encoder": 10,
  "axis0.config.startup_closed_loop_control": false,
  "axis0.config.startup_encoder_index_search": false,
  "axis0.config.startup_encoder_offset_calibration": false,
  "axis0.config.startup_homing": false,
  "axis0.config.startup_max_wait_for_ready": 3.0,
  "axis0.config.startup_motor_calibration": false,
  "axis0.config.step_dir_always_on": false,
  "axis0.config.step_gpio_pin": 8,
  "axis0.config.torque_soft_max": Infinity,
  "axis0.config.torque_soft_min": -Infinity,
  "axis0.config.watchdog_timeout": 0.0,
  "axis0.config.anticogging.calib_bidirectional": true,
  "axis0.config.anticogging.calib_coarse_integrator_gain": 10.0,
  "axis0.config.anticogging.calib_coarse_tuning_duration": 60.0,
  "axis0.config.anticogging.calib_end_vel": 0.15000000596046448,
  "axis0.config.anticogging.calib_fine_dist_scale": 1.0,
  "axis0.config.anticogging.calib_fine_tuning_duration": 120.0,
  "axis0.config.anticogging.calib_start_vel": 1.0,
  "axis0.config.anticogging.enabled": false,
  "axis0.config.anticogging.max_torque": 0.15000000596046448,
  "axis0.config.calibration_lockin.accel": 3.183098793029785,
  "axis0.config.calibration_lockin.current": 10.0,
  "axis0.config.calibration_lockin.ramp_distance": 0.5,
  "axis0.config.calibration_lockin.ramp_time": 0.4000000059604645,
  "axis0.config.calibration_lockin.vel": 6.36619758605957,
  "axis0.config.can.bus_voltage_msg_rate_ms": 0,
  "axis0.config.can.encoder_msg_rate_ms": 10,
  "axis0.config.can.error_msg_rate_ms": 0,
  "axis0.config.can.heartbeat_msg_rate_ms": 100,
  "axis0.config.can.iq_msg_rate_ms": 0,
  "axis0.config.can.node_id": 63,
  "axis0.config.can.powers_msg_rate_ms": 0,
  "axis0.config.can.temperature_msg_rate_ms": 0,
  "axis0.config.can.torques_msg_rate_ms": 0,
  "axis0.config.can.version_msg_rate_ms": 0,
  "axis0.config.general_lockin.accel": 20.0,
  "axis0.config.general_lockin.current": 10.0,
  "axis0.config.general_lockin.finish_distance": 100.0,
  "axis0.config.general_lockin.finish_on_distance": false,
  "axis0.config.general_lockin.finish_on_vel": false,
  "axis0.config.general_lockin.initial_pos": 0.0,
  "axis0.config.general_lockin.ramp_distance": 3.1415927410125732,
  "axis0.config.general_lockin.ramp_time": 0.4000000059604645,
  "axis0.config.general_lockin.vel": 40.0,
  "axis0.config.motor.acim_autoflux_attack_gain": 10.0,
  "axis0.config.motor.acim_autoflux_decay_gain": 1.0,
  "axis0.config.motor.acim_autoflux_enable": false,
  "axis0.config.motor.acim_autoflux_min_Id": 10.0,
  "axis0.config.motor.acim_gain_min_flux": 10.0,
  "axis0.config.motor.acim_nominal_slip_vel": 2.3399999141693115,
  "axis0.config.motor.bEMF_FF_enable": false,
  "axis0.config.motor.calibration_current": 10.0,
  "axis0.config.motor.current_control_bandwidth": 1000.0,
  "axis0.config.motor.current_hard_max": 60.0,
  "axis0.config.motor.current_slew_rate_limit": 10000.0,
  "axis0.config.motor.current_soft_max": 40.0,
  "axis0.config.motor.direction": 1.0,
  "axis0.config.motor.ff_pm_flux_linkage": 0.0,
  "axis0.config.motor.ff_pm_flux_linkage_valid": false,
  "axis0.config.motor.fw_enable": false,
  "axis0.config.motor.fw_fb_bandwidth": 500.0,
  "axis0.config.motor.fw_mod_setpoint": 0.6103333234786987,
  "axis0.config.motor.motor_model_l_d": 0.0,
  "axis0.config.motor.motor_model_l_dq_valid": false,
  "axis0.config.motor.motor_model_l_q": 0.0,
  "axis0.config.motor.motor_type": 0,
  "axis0.config.motor.phase_inductance": 2.5791126972762868e-05,
  "axis0.config.motor.phase_inductance_valid": true,
  "axis0.config.motor.phase_resistance": 0.030721694231033325,
  "axis0.config.motor.phase_resistance_valid": true,
  "axis0.config.motor.pole_pairs": 7,
  "axis0.config.motor.power_torque_report_filter_bandwidth": 8000.0,
  "axis0.config.motor.resistance_calib_max_voltage": 2.0,
  "axis0.config.motor.sensorless_observer_gain": 1000.0,
  "axis0.config.motor.sensorless_pll_bandwidth": 1000.0,
  "axis0.config.motor.sensorless_pm_flux_linkage": 0.0,
  "axis0.config.motor.sensorless_pm_flux_linkage_valid": false,
  "axis0.config.motor.torque_constant": 0.025060605257749557,
  "axis0.config.motor.wL_FF_enable": false,
  "axis0.config.sensorless_ramp.accel": 31.83098793029785,
  "axis0.config.sensorless_ramp.current": 10.0,
  "axis0.config.sensorless_ramp.finish_distance": 15.915493965148926,
  "axis0.config.sensorless_ramp.finish_on_distance": false,
  "axis0.config.sensorless_ramp.finish_on_vel": true,
  "axis0.config.sensorless_ramp.initial_pos": 0.0,
  "axis0.config.sensorless_ramp.ramp_distance": 0.5,
  "axis0.config.sensorless_ramp.ramp_time": 0.4000000059604645,
  "axis0.config.sensorless_ramp.vel": 63.6619758605957,
  "axis0.controller.config.absolute_setpoints": false,
  "axis0.controller.config.circular_setpoint_range": 1.0,
  "axis0.controller.config.circular_setpoints": false,
  "axis0.controller.config.commutation_vel_scale": 1.0,
  "axis0.controller.config.control_mode": 2,
  "axis0.controller.config.enable_gain_scheduling": false,
  "axis0.controller.config.enable_overspeed_error": true,
  "axis0.controller.config.enable_torque_mode_vel_limit": true,
  "axis0.controller.config.enable_vel_limit": true,
  "axis0.controller.config.gain_scheduling_width": 0.0010000000474974513,
  "axis0.controller.config.homing_speed": 0.25,
  "axis0.controller.config.inertia": 0.0,
  "axis0.controller.config.input_filter_bandwidth": 20.0,
  "axis0.controller.config.input_mode": 2,
  "axis0.controller.config.pos_gain": 20.0,
  "axis0.controller.config.spinout_electrical_power_bandwidth": 20.0,
  "axis0.controller.config.spinout_electrical_power_threshold": 10.0,
  "axis0.controller.config.spinout_mechanical_power_bandwidth": 20.0,
  "axis0.controller.config.spinout_mechanical_power_threshold": -10.0,
  "axis0.controller.config.steps_per_circular_range": 1024,
  "axis0.controller.config.torque_ramp_rate": 0.009999999776482582,
  "axis0.controller.config.use_commutation_vel": false,
  "axis0.controller.config.use_load_encoder_for_commutation_vel": false,
  "axis0.controller.config.vel_gain": 0.1666666716337204,
  "axis0.controller.config.vel_integrator_gain": 0.3333333432674408,
  "axis0.controller.config.vel_integrator_limit": Infinity,
  "axis0.controller.config.vel_limit": 50.0,
  "axis0.controller.config.vel_limit_tolerance": 1.0,
  "axis0.controller.config.vel_ramp_rate": 30.0,
  "axis0.enable_pin.config.debounce_ms": 50,
  "axis0.enable_pin.config.enabled": false,
  "axis0.enable_pin.config.gpio_num": 7,
  "axis0.enable_pin.config.is_active_high": false,
  "axis0.enable_pin.config.offset": 0.0,
  "axis0.interpolator.config.dynamic": true,
  "axis0.max_endstop.config.debounce_ms": 50,
  "axis0.max_endstop.config.enabled": false,
  "axis0.max_endstop.config.gpio_num": 0,
  "axis0.max_endstop.config.is_active_high": false,
  "axis0.max_endstop.config.offset": 0.0,
  "axis0.mechanical_brake.config.gpio_num": 0,
  "axis0.mechanical_brake.config.is_active_low": true,
  "axis0.min_endstop.config.debounce_ms": 50,
  "axis0.min_endstop.config.enabled": false,
  "axis0.min_endstop.config.gpio_num": 0,
  "axis0.min_endstop.config.is_active_high": false,
  "axis0.min_endstop.config.offset": 0.0,
  "axis0.motor.motor_thermistor.config.beta": 3435.0,
  "axis0.motor.motor_thermistor.config.enabled": true,
  "axis0.motor.motor_thermistor.config.gpio_pin": 4,
  "axis0.motor.motor_thermistor.config.r_ref": 10000.0,
  "axis0.motor.motor_thermistor.config.t_ref": 25.0,
  "axis0.motor.motor_thermistor.config.temp_limit_lower": 110.0,
  "axis0.motor.motor_thermistor.config.temp_limit_upper": 130.0,
  "axis0.pos_vel_mapper.config.approx_init_pos": 0.0,
  "axis0.pos_vel_mapper.config.approx_init_pos_valid": false,
  "axis0.pos_vel_mapper.config.circular_output_range": 1.0,
  "axis0.pos_vel_mapper.config.circular": false,
  "axis0.pos_vel_mapper.config.index_gpio": 10,
  "axis0.pos_vel_mapper.config.index_offset": 0.0,
  "axis0.pos_vel_mapper.config.index_offset_valid": false,
  "axis0.pos_vel_mapper.config.offset": 0.0,
  "axis0.pos_vel_mapper.config.offset_valid": false,
  "axis0.pos_vel_mapper.config.passive_index_search": false,
  "axis0.pos_vel_mapper.config.scale": 1.0,
  "axis0.pos_vel_mapper.config.use_endstop": false,
  "axis0.pos_vel_mapper.config.use_index_gpio": false,
  "axis0.trap_traj.config.accel_limit": 30.0,
  "axis0.trap_traj.config.decel_limit": 0.5,
  "axis0.trap_traj.config.vel_limit": 2.0,
  "can.config.baud_rate": 250000,
  "can.config.protocol": 0,
  "config.dc_bus_overvoltage_trip_level": 16.799999237060547,
  "config.dc_bus_undervoltage_trip_level": 12.800000190734863,
  "config.dc_max_negative_current": -Infinity,
  "config.dc_max_positive_current": Infinity,
  "config.enable_uart_a": false,
  "config.gpio0_mode": 17,
  "config.gpio10_mode": 17,
  "config.gpio11_mode": 17,
  "config.gpio12_mode": 17,
  "config.gpio1_mode": 17,
  "config.gpio2_mode": 17,
  "config.gpio3_mode": 17,
  "config.gpio4_mode": 17,
  "config.gpio5_mode": 17,
  "config.gpio6_mode": 17,
  "config.gpio7_mode": 17,
  "config.gpio8_mode": 17,
  "config.gpio9_mode": 17,
  "config.max_regen_current": 0.0,
  "config.uart0_protocol": 3,
  "config.uart_a_baudrate": 115200,
  "config.usb_cdc_protocol": 3,
  "config.user_config_0": 0,
  "config.user_config_1": 0,
  "config.user_config_2": 0,
  "config.user_config_3": 0,
  "config.user_config_4": 0,
  "config.user_config_5": 0,
  "config.user_config_6": 0,
  "config.user_config_7": 0,
  "config.brake_resistor0.dc_bus_voltage_feedback_ramp_end": 53.0,
  "config.brake_resistor0.dc_bus_voltage_feedback_ramp_start": 51.0,
  "config.brake_resistor0.enable_dc_bus_voltage_feedback": false,
  "config.brake_resistor0.enable": false,
  "config.brake_resistor0.resistance": 0.0,
  "config.gpio11_analog_mapping.endpoint": null,
  "config.gpio11_analog_mapping.max": 0.0,
  "config.gpio11_analog_mapping.min": 0.0,
  "config.gpio1_analog_mapping.endpoint": null,
  "config.gpio1_analog_mapping.max": 0.0,
  "config.gpio1_analog_mapping.min": 0.0,
  "config.gpio8_pwm_mapping.endpoint": null,
  "config.gpio8_pwm_mapping.max": 0.0,
  "config.gpio8_pwm_mapping.min": 0.0,
  "config.inverter0.current_hard_max": 96.0,
  "config.inverter0.current_soft_max": 80.0,
  "config.inverter0.drv_config": 9029553697166464,
  "config.inverter0.mod_magn_max": 0.6781481504440308,
  "config.inverter0.shunt_conductance": 1999.9998779296875,
  "config.inverter0.temp_limit_lower": 83.95999908447266,
  "config.inverter0.temp_limit_upper": 103.11000061035156,
  "hall_encoder0.config.edge0": NaN,
  "hall_encoder0.config.edge1": NaN,
  "hall_encoder0.config.edge2": NaN,
  "hall_encoder0.config.edge3": NaN,
  "hall_encoder0.config.edge4": NaN,
  "hall_encoder0.config.edge5": NaN,
  "hall_encoder0.config.edges_calibrated": false,
  "hall_encoder0.config.enabled": false,
  "hall_encoder0.config.hall_polarity_calibrated": false,
  "hall_encoder0.config.hall_polarity": 0,
  "hall_encoder0.config.ignore_illegal_hall_state": false,
  "inc_encoder0.config.cpr": 8192,
  "inc_encoder0.config.enabled": false,
  "rs485_encoder_group0.config.mode": 4,
  "spi_encoder0.config.baudrate": 1687500,
  "spi_encoder0.config.biss_c_bits": 18,
  "spi_encoder0.config.delay": 0.0,
  "spi_encoder0.config.max_error_rate": 0.004999999888241291,
  "spi_encoder0.config.mode": 0,
  "spi_encoder0.config.ncs_gpio": 12,
  "spi_encoder1.config.baudrate": 1687500,
  "spi_encoder1.config.biss_c_bits": 18,
  "spi_encoder1.config.delay": 0.0,
  "spi_encoder1.config.max_error_rate": 0.004999999888241291,
  "spi_encoder1.config.mode": 0,
  "spi_encoder1.config.ncs_gpio": 12
}

Thanks again for your help!

Thanks!

Rapid accelerations/decelerations can cause small current spikes – if you’re hitting unexpected load, it could definitely cause a very very brief transient.

That being said, it can also be caused by encoder misalignment errors. Magnetic encoders are very very sensitive to misalignment, even +/- 0.5mm can be enough to add some periodic error. I’d be worried about flex in the 3D printed part holding the OA1, especially if there’s no strain relief on the RS485 cable, and the fact you have a very small contact area due to the shim washers:

I would definitely redesign the OA1 holder to be thicker and have more points of contact on the baseplate.

In the newest firmware (v0.6.11) we also have support for a feature to compensate for small misalignments, called harmonic compensation. I would strongly recommend giving that a shot, and seeing if it helps your issues (I generally would expect it to).

Lastly, I would make sure you’re 100% confident that your magnet isn’t slipping in any way, and I’d maybe try redoing calibration with a higher axis0.config.calibration_lockin.current value, maybe around 20-25A. This will reduce any encoder calibration errors that may be present. As a bonus, if you run this after harmonic compensation, the encoder calibration is further improved :slight_smile:

So I would:

  1. Fix your OA1 mounting, see if you can get that 3D printed part more rigid and strain relief the RS485 cable so it doesn’t flex the part
  2. Upgrade to 0.6.11, set axis0.config.calibration_lockin.current to 20
  3. Run harmonic compensation
  4. Run encoder offset calibration

Then see if that helps the problem.

Thanks for your answer!

I’ve improved the OA1 mount, and I’ll also look into harmonic compensation and rerun the encoder offset calibration.

In the meantime, we ran new tests with the same mechanical setup. This time, the 70 A current spikes disappeared. Instead, we only observed more reasonable spikes of around 20 A when accelerating at 5 m/s².

The only change we made was in the power supply:
• Previously: ODrive + onboard Raspberry Pi both powered in parallel from a single 6S battery.
• Now: ODrive powered by a 6S battery, Raspberry Pi powered separately from a 4S battery.
(the Raspberry Pi was always powered through a UBEC)

We still need to run more tests to confirm whether this is a coincidence, whether something else in the setup changed, or if the separate power supplies are indeed what eliminated the large current spikes. In your opinion, could powering the ODrive in parallel with another device (in this case, a Raspberry Pi 5 rated up to 5 A) cause such high current spikes? For example, due to coupling effects or amplified noise?

Thanks again for your help!

I generally don’t expect a wiring change like that to have a significant difference. What was the communications interface between the ODrive and the Raspberry Pi? If you were using USB, was it with a USB isolator?