Constant CURRENT_LIMIT_VIOLATIONs

Hi, I have a new micro ODrive on a FingerTech FT1806 motor and an external SPI encoder. I keep getting CURRENT_LIMIT_VIOLATION errors even though I’ve put the current limits up really high. I’ve tried increasing the current_control_bandwidth and other items I’ve read about on the forum but no luck. I could really use some help.

I captured a triggering event using the webgui, I’ll see if I can post it here.
odrive_current_limit

I’ll also attach my current config - I have tried various settings changes but this is my latest. It doesn’t look like the current actually goes over my limits so I’m not sure why the error is triggered.

{
“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”: 4,
“axis0.commutation_mapper.config.index_offset”: 0.0,
“axis0.commutation_mapper.config.index_offset_valid”: false,
“axis0.commutation_mapper.config.offset”: -2.5144221782684326,
“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”: 5,
“axis0.config.dir_gpio_pin”: 11,
“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”: 8,
“axis0.config.index_search_at_target_vel_only”: false,
“axis0.config.init_pos”: NaN,
“axis0.config.init_torque”: 0.0,
“axis0.config.init_vel”: 0.0,
“axis0.config.load_encoder”: 5,
“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”: 10,
“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”: 5.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”: 0,
“axis0.config.can.error_msg_rate_ms”: 0,
“axis0.config.can.heartbeat_msg_rate_ms”: 100,
“axis0.config.can.input_torque_scale”: 1000,
“axis0.config.can.input_vel_scale”: 1000,
“axis0.config.can.iq_msg_rate_ms”: 0,
“axis0.config.can.node_id”: 16,
“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”: 3.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”: 3.0,
“axis0.config.motor.current_control_bandwidth”: 1500.0,
“axis0.config.motor.current_hard_max”: 100.0,
“axis0.config.motor.current_slew_rate_limit”: 10000.0,
“axis0.config.motor.current_soft_max”: 10.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.354069692955818e-05,
“axis0.config.motor.phase_inductance_valid”: true,
“axis0.config.motor.phase_resistance”: 0.08217086642980576,
“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”: 1.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.0035956520587205887,
“axis0.config.motor.wL_FF_enable”: false,
“axis0.config.sensorless_ramp.accel”: 31.83098793029785,
“axis0.config.sensorless_ramp.current”: 3.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.0010000000474974513,
“axis0.controller.config.vel_integrator_gain”: 0.0,
“axis0.controller.config.vel_integrator_limit”: Infinity,
“axis0.controller.config.vel_limit”: 50.0,
“axis0.controller.config.vel_limit_tolerance”: 10.0,
“axis0.controller.config.vel_ramp_rate”: 75.0,
“axis0.enable_pin.config.debounce_ms”: 50,
“axis0.enable_pin.config.enabled”: false,
“axis0.enable_pin.config.gpio_num”: 65535,
“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”: 0.0,
“axis0.motor.motor_thermistor.config.enabled”: false,
“axis0.motor.motor_thermistor.config.gpio_pin”: 1,
“axis0.motor.motor_thermistor.config.r_ref”: 0.0,
“axis0.motor.motor_thermistor.config.t_ref”: 25.0,
“axis0.motor.motor_thermistor.config.temp_limit_lower”: 100.0,
“axis0.motor.motor_thermistor.config.temp_limit_upper”: 120.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”: 4,
“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”: 75.0,
“axis0.trap_traj.config.decel_limit”: 0.5,
“axis0.trap_traj.config.vel_limit”: 2.0,
“can.config.baud_rate”: 250000,
“can.config.data_baud_rate”: 10000000,
“can.config.protocol”: 1,
“can.config.tx_brs”: 0,
“config.dc_bus_overvoltage_trip_level”: 15.0,
“config.dc_bus_undervoltage_trip_level”: 6.0,
“config.dc_max_negative_current”: -Infinity,
“config.dc_max_positive_current”: Infinity,
“config.enable_uart_a”: false,
“config.gpio0_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.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.gpio5_analog_mapping.endpoint”: null,
“config.gpio5_analog_mapping.max”: 0.0,
“config.gpio5_analog_mapping.min”: 0.0,
“config.gpio6_analog_mapping.endpoint”: null,
“config.gpio6_analog_mapping.max”: 0.0,
“config.gpio6_analog_mapping.min”: 0.0,
“config.inverter0.current_hard_max”: 7.900000095367432,
“config.inverter0.current_soft_max”: 7.0,
“config.inverter0.drv_config”: 5913173802956800,
“config.inverter0.mod_magn_max”: 0.6781481504440308,
“config.inverter0.shunt_conductance”: 1.0,
“config.inverter0.temp_limit_lower”: 135.0,
“config.inverter0.temp_limit_upper”: 145.0,
“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,
“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”: 5,
“spi_encoder0.config.ncs_gpio”: 0,
“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”: 0
}

I should mention I get the error both when doing velocity control and torque control.

Thanks for the comprehensive info! Looks like the current soft max is set to above the ODrive’s internal current limit – it’ll self-limit to a safe point of 7A, but there’s likely not enough margin to catch current spikes before they exceed the absolute maximum trip current limit of 7.9A. I’d recommend setting axis0.config.motor.current_soft_max to 5A or so and seeing if that helps.

Thanks for the quick reply. Turning current_soft_max down helped a lot.

There’s a bit of a balance I have to make between turning it down to avoid the current limit error and making the system under powered, maybe I’m near the limit of what the setup can handle. I think I’m close to an acceptable configuration now.

This is a great product by the way, nice work!

Totally understood - you should be able to slim down the margins with those feedforwards and the current / encoder bandwidths.

Glad to hear it’s working out for you :slight_smile: very curious what you’re using it with?

Hi again, unfortunately I’m still struggling with this and decided I should ask for some clarification.

When you mentioned “feedforwards” did you mean wL_FF_enable and bEMF_FF_enable?

Also, you mentioned the current / encoder bandwidths and the tuning webpage also mentions those but after reading as much as I can in the documents, forum and code, I’m not sure what to do with those values other than randomly try different numbers but that is getting me nowhere.

Is there a tuning procedure I can try for the bandwidths or a good explanation of what they should be somewhere?

My symptoms are sometimes the motor seems underpowered and sometimes it doesn’t. And sometimes I get CURRENT_LIMIT_VIOLATION when there isn’t a load and sometimes, I get MISSING_ESTIMATE errors. This is all during tuning different parameters so none of these are happening consistently - I’ve been kind of aimlessly trying different things.

It’s kind of like a simple arm on a rover

I also get a DRV_FAULT every now and then. I have a few other boards here; I’ll try some other ones and see if they behave the same.

It may be nothing, but one thing I’ve wondered about is this graph:

My vel_limit is 70 and current limit (I assume that is current_soft_max) is 5 and when I tune my vel_gain I get around 0.001. With these numbers the parallelogram there leans over all the way to almost flat:

image

Maybe there’s something inherit about this motor/setup that doesn’t jive well with the assumptions made in the controller?

I have tried setting the torque_constant to 1, in which case the vel_gain is around 0.65 and the parallelogram is standing up, but didn’t notice any improvement in the issues I’m having.

I tested a few other controllers - none of them threw DRV_FAULT errors but I can’t get enough power out of them for what I need before throwing the CURRENT_LIMT_VIOLATION.

I tried bumping my input voltage up from 12 to 18V to see if that would help but no luck. I noticed my power supply is only giving about 9W when I’m getting the CURRENT_LIMIT_VIOLATION.