Odrive GUI overriding current limits

why is Odrive GUI overriding my current_soft_max?

When I am controlling motor from inspector, I can key in 45a as a soft max. And I get the associated torque from that value.

But when I save the configuration and operate the motor using the the custom controller we developed, Odrive GUI caps the current at 20a and my torque suffers.

Im assuming I have another setting in place that is causing the override but I’m at a loss on what that could be.

Please help. Thank you

Sorry, I’m having some difficulty following exactly what the issue is / you’re trying to do here? My understanding is:

  • In the inspector tab, you set current_soft_max to 45A
  • In the inspector tab, you put the ODrive into some operating mode (pos/vel/torque control - which are you using?), and when commanding setpoints, you see the ODrive outputting up to the full 45A max (via monitoring Iq_measured? Iq_setpoint?)
  • Then you command the ODrive via your “custom controller” – I’m assuming this is some sort of external microcontroller controlling the ODrive over CAN or UART?
  • Then, when commanding the ODrive externally, you’re only seeing a maximum current of about 20A (via monitoring Iq_measured? Iq_setpoint?)

Some questions:

  • Do you see the current_soft_max value actually changing or resetting to 20A?
  • What control mode and input mode are you using?
  • How is the custom controller commanding the ODrive?
  • What motor, encoder, and power supply are you using?

If you’re able to send some screenshots of your configuration in the GUI, and maybe some videos showing the issue you’re having, that would help a lot! The more information you can give, the better.

Hello Solomon. Thank you for your attention. I believe I gotten a little closer to the truth. Its actually a power cycle that causes the current limit to revert. It doesnt have anything to do with my CAN micro controller

But yes you are correct in your understanding. I set the current limit to 45 amps. Save configuration. Go to position control to visually observe the current draw which is 45a and plenty of torque.

Save once again(or not), cycle power and reconnect and in inspector I see that the soft has auto-adjusted to 20amps. I go i to position control to once again get a visual and it is indeed drawing 20amps

I am trap_traj input mode and position control control mode with CAN bus microcontroller

The motor is a 5065bldc, power supply is 24vdc 1000w, AMT212B-v-od encoder




That’s quite weird. Could you let me know your S1’s serial number, and what firmware version it’s on? You can see that in the bottom left by clicking on the ODrive device:


One other thing – when you run save configuration, the ODrive must be in idle – if it’s in closed loop control, the configuration will not be saved. Saving the configuration will actually cause the ODrive to reboot (and disconnect/reconnect), which is a good way to know that the save worked.

So…based on your response… I feel like this is either operator error or i have some specs wrong somewhere. I need to pull some measurements of just how much current my power supply is pushing(or capable of) i was reading about ‘ibus’ and Im wondering if Odrive is autocorrecting to protect my power supply

I have 4 identical units all behaving the same way. And yes I am saving the config in idle. Ill report back…may try a different power supply

Thanks you!!!

Hmm, I don’t think it’s doing any autocorrecting based on ibus – that’s all under this, which is disabled by default.

Could you let me know the S1 serial number and firmware version?

If you have ODrivetool, it would be great if you could run odrivetool backup-config config.json when connected to one of the S1s (w/ GUI closed), and then paste the resulting config.json here – that’ll let me see the full parameter tree and better figure out if there’s a configuration issue here.

“serial_number”: “395434413331”,
“fw_version”: “0.6.11”,

“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”: 2.598930835723877,
“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.init_pos”: NaN,
“axis0.config.init_torque”: 0.0,
“axis0.config.init_vel”: 0.0,
“axis0.config.load_encoder”: 10,
“axis0.config.off_axis_k_commutation”: 1.0,
“axis0.config.off_axis_k”: 1.0,
“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”: 0,
“axis0.config.can.error_msg_rate_ms”: 0,
“axis0.config.can.heartbeat_msg_rate_ms”: 0,
“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”: 24,
“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.harmonic_compensation.calib_settling_delay”: 2.0,
“axis0.config.harmonic_compensation.calib_turns”: 8,
“axis0.config.harmonic_compensation.calib_vel”: 8.0,
“axis0.config.harmonic_compensation.cos2x_coef”: 0.0,
“axis0.config.harmonic_compensation.cosx_coef”: 0.0,
“axis0.config.harmonic_compensation.sin2x_coef”: 0.0,
“axis0.config.harmonic_compensation.sinx_coef”: 0.0,
“axis0.config.harmonic_compensation_commutation.calib_settling_delay”: 2.0,
“axis0.config.harmonic_compensation_commutation.calib_turns”: 8,
“axis0.config.harmonic_compensation_commutation.calib_vel”: 8.0,
“axis0.config.harmonic_compensation_commutation.cos2x_coef”: 0.0,
“axis0.config.harmonic_compensation_commutation.cosx_coef”: 0.0,
“axis0.config.harmonic_compensation_commutation.sin2x_coef”: 0.0,
“axis0.config.harmonic_compensation_commutation.sinx_coef”: 0.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”: 85.0,
“axis0.config.motor.current_slew_rate_limit”: 10000.0,
“axis0.config.motor.current_soft_max”: 20.0,
“axis0.config.motor.dI_dt_FF_enable”: false,
“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”: 1.4162485058477614e-05,
“axis0.config.motor.phase_inductance_valid”: true,
“axis0.config.motor.phase_resistance”: 0.0313139334321022,
“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.030629629269242287,
“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”: true,
“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”: 3,
“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”: 5,
“axis0.controller.config.pos_gain”: 175.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.2800000011920929,
“axis0.controller.config.vel_integrator_gain”: 0.5040000081062317,
“axis0.controller.config.vel_integrator_limit”: Infinity,
“axis0.controller.config.vel_limit”: 15.0,
“axis0.controller.config.vel_limit_tolerance”: 0.31111112236976624,
“axis0.controller.config.vel_ramp_rate”: 10.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.a”: 3.9082999229431152,
“axis0.motor.motor_thermistor.config.b”: -0.0005774999735876918,
“axis0.motor.motor_thermistor.config.beta”: 0.0,
“axis0.motor.motor_thermistor.config.enabled”: false,
“axis0.motor.motor_thermistor.config.gpio_pin”: 4,
“axis0.motor.motor_thermistor.config.mode”: 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”: 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”: 2.0,
“axis0.trap_traj.config.decel_limit”: 2.0,
“axis0.trap_traj.config.vel_limit”: 1.0,
“can.config.baud_rate”: 500000,
“can.config.data_baud_rate”: 10000000,
“can.config.protocol”: 1,
“can.config.tx_brs”: 0,
“config.dc_bus_overvoltage_trip_level”: 30.0,
“config.dc_bus_undervoltage_trip_level”: 10.5,
“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”: true,
“config.brake_resistor0.resistance”: 2.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,
“inc_encoder0.config.filter”: 0,
“rs485_encoder_group0.config.mode”: 2,
“rs485_encoder_group1.config.mode”: 0,
“spi_encoder0.config.baudrate”: 1687500,
“spi_encoder0.config.biss_c_bits”: 18,
“spi_encoder0.config.biss_c_multiturn_bits”: 0,
“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.biss_c_multiturn_bits”: 0,
“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

Interesting, can’t see anything that explicitly points to the issue you’re having. Could you try seeing if you can replicate the issue after a firmware update and re-running the configuration steps?

Something you can try first, very simply, is just:

  • Start with the ODrive only connected over USB, not over power
  • Open ODrivetool
  • Query odrv0.axis0.config.motor.current_soft_max (should be 20)
  • Set odrv0.axis0.config.motor.current_soft_max = 45
  • Query odrv0.axis0.config.motor.current_soft_max (should be 45 now)
  • Run odrv0.save_configuration() (ODrive should disconnect/reconnect, you’ll see the LED on the ODrive turn to orange and then back to blue)
  • Query odrv0.axis0.config.motor.current_soft_max again, and we can see if it’s 20 or 45.

Shoo wee looks like that worked!! It saved and held across a reconnect. And then I disconnected, cycled power, and operated with the micro controller. Then powered down, reconnected to odrivetool and checked and it stayed at the keyed in current limits.

Thank you so much!

Oh great to hear! If you think you know what the issue was originally, would be super good to know that for the future, but no worries if this is a mystery issue as long as it doesn’t come up again :slight_smile:

Well I am def not the guy who could work that out… But it is consistent whatever it is.

Thanks again Im very grateful