Power supply in security mode when forcing on the motor

Hello,
I am using an Odrive board for an internship project, this is my setup:

  • Odrive is v3.6 (56V)
  • Motor is TSDZ2 Tong Sheng (Hall encoder included)
  • Brake resistor is 3.3 Ohm
    It will be used for arm rehabilitation purposes. The motor is connected to pedals and the user may force in the opposite direction of rotation or in the same. For now I am working in velocity control mode.
    When someone forces against it (even until stopping it), there is no problem.
    However, when forcing to make it turn faster, when the Ibus drops to 0A, the power source shuts down. There is not any overvoltage (nor undervoltage) on the DC bus before the power source shuts down (or at least nothing can be seen on the liveplotter). The brake resistor is enabled. It is a 500W 3.3 Ohm resistor. Is there any way to prevent that from happening ?
    Thank you for your time.

Hi! May be power supply shutdown because of overcurrent protection?

Thanks for your answer @Kamerrer !
Indeed, when I set I_bus_hard_min to -0.3 it protects the power supply if I force gently. However it does not work if I force more fiercely or during more time.
I would like to be able to protect the power supply no matter how much force I am putting on the pedals (well the force is not infinite since it is arms produced).
Do you have an idea how I could do ? Could modifying the gains work ?

1 Like

Could you post your list of parameters and value that you configure in odrivetool? I guess that you miss something or use wrong parameters) As I understand your correct working logic should be like this: you power up your ODrive with psu and all regen current that occurs when motor will brake should go to brake resistor to prevent powersuply from damaging. Am I right?

1 Like

Thank you for your help, here are my parameters and values. Tell me if you need something else.

acim_estimator:
  config: ...
  phase_offset: 0.0 (float)
  rotor_flux: 0.0 (float)
  slip_vel: 0.0 (float)
  stator_phase: 1.619760513305664 (float)
  stator_phase_vel: 426.7330017089844 (float)
config:
  calibration_lockin: ...
  can: ...
  dir_gpio_pin: 2 (uint16)
  enable_sensorless_mode: False (bool)
  enable_step_dir: False (bool)
  enable_watchdog: False (bool)
  general_lockin: ...
  sensorless_ramp: ...
  startup_closed_loop_control: False (bool)
  startup_encoder_index_search: False (bool)
  startup_encoder_offset_calibration: False (bool)
  startup_homing: False (bool)
  startup_motor_calibration: False (bool)
  step_dir_always_on: False (bool)
  step_gpio_pin: 1 (uint16)
  watchdog_timeout: 0.0 (float)
controller:
  anticogging_valid: False (bool)
  autotuning: ...
  autotuning_phase: 0.0 (float)
  config: ...
  electrical_power: 2.456660032272339 (float)
  error: 0 (uint8)
  input_pos: 0.04114590212702751 (float)
  input_torque: 0.0 (float)
  input_vel: -8.5 (float)
  last_error_time: 0.0 (float)
  mechanical_power: 5.851099014282227 (float)
  move_incremental(obj: object_ref, displacement: float, from_input_pos: bool)
  pos_setpoint: 0.04114590212702751 (float)
  start_anticogging_calibration(obj: object_ref)
  torque_setpoint: 0.0 (float)
  trajectory_done: True (bool)
  vel_integrator_torque: -0.11262267827987671 (float)
  vel_setpoint: -8.5 (float)
current_state: 8 (uint8)
encoder:
  calib_scan_response: 0.0 (float)
  config: ...
  count_in_cpr: 29 (int32)
  delta_pos_cpr_counts: -0.06321437656879425 (float)
  error: 0 (uint16)
  hall_state: 4 (uint8)
  index_found: False (bool)
  interpolation: 0.28031229972839355 (float)
  is_ready: True (bool)
  phase: 1.3610687255859375 (float)
  pos_abs: 0 (int32)
  pos_circular: 0.533474326133728 (float)
  pos_cpr_counts: 25.198163986206055 (float)
  pos_estimate: -552.4834594726562 (float)
  pos_estimate_counts: -26519.61328125 (float)
  set_linear_count(obj: object_ref, count: int32)
  shadow_count: -26521 (int32)
  spi_error_rate: 0.0 (float)
  vel_estimate: -8.541666984558105 (float)
  vel_estimate_counts: -410.0 (float)
error: 0 (uint32)
is_homed: False (bool)
last_drv_fault: 0 (uint32)
max_endstop:
  config: ...
  endstop_state: False (bool)
mechanical_brake:
  config: ...
  engage(obj: object_ref)
  release(obj: object_ref)
min_endstop:
  config: ...
  endstop_state: False (bool)
motor:
  DC_calib_phA: 1.2644273042678833 (float)
  DC_calib_phB: -0.48575085401535034 (float)
  DC_calib_phC: -0.7785403728485107 (float)
  I_bus: 0.05784515663981438 (float)
  config: ...
  current_control: ...
  current_meas_phA: -0.23939263820648193 (float)
  current_meas_phB: -0.3178805410861969 (float)
  current_meas_phC: 0.4565104842185974 (float)
  effective_current_lim: 7.0 (float)
  error: 0 (uint64)
  fet_thermistor: ...
  is_armed: True (bool)
  is_calibrated: True (bool)
  last_error_time: 0.0 (float)
  max_allowed_current: 30.375 (float)
  max_dc_calib: 3.0375001430511475 (float)
  motor_thermistor: ...
  n_evt_current_measurement: 2002129 (uint32)
  n_evt_pwm_update: 2002137 (uint32)
  phase_current_rev_gain: 0.012500000186264515 (float)
requested_state: 0 (uint8)
sensorless_estimator:
  config: ...
  error: 0 (uint8)
  phase: -1.9241141080856323 (float)
  phase_vel: 424.8955383300781 (float)
  pll_pos: -1.0634453296661377 (float)
  vel_estimate: 8.501914024353027 (float)
step_dir_active: False (bool)
steps: 42 (int64)
task_times:
  acim_estimator_update: ...
  can_heartbeat: ...
  controller_update: ...
  current_controller_update: ...
  current_sense: ...
  dc_calib: ...
  encoder_update: ...
  endstop_update: ...
  motor_update: ...
  open_loop_controller_update: ...
  pwm_update: ...
  sensorless_estimator_update: ...
  thermistor_update: ...
trap_traj:
  config: ...
watchdog_feed(obj: object_ref)

What I want to do is forcing in the same direction (brake) as the velocity or in the opposite direction. I am in velocity control mode. I have no problem when forcing in the opposite direction (brake), my problem is when forcing in the same direction. If I am forcing too much or too long, the power supply shuts down. Is it a little clearer ?

Try to set this properties:

max_regen_current = 0
dc_max_negative_current = -INFINITY
I_bus_hard_min = -INFINITY
1 Like

Hi !
I’ve just tested it and it didn’t work. Moreover, I don’t understand why putting dc_max_negative_current = -INFINITY would help me since my problem is that there is negative current going to the power supply…

Hi !
I am still stuck on the same issue, would someone have an idea to help me ?
To summarize, how can I protect my power supply from negative currents when accelerating the motor by physically forcing on it, in velocity control ?

Thank you very much

You are correct, dc_max_negative_current should not be -INFINITY for what you’re trying to achieve. Can you confirm the psu is shutting down with the default value (or lower) of dc_max_negative_current = -0.01?
While in closed loop control can you verify that <odrv>.brake_resistor_armed is True?
Also, could you please share your config from the <odrv> object, specifically the parts that pertain to the brake resistor?

Thank you for your interest in my issue.
I’ve just checked dc_max_negative_current is -0.01 and brake_resistor_armed is True during the entire closed loop control and the psu is shutting down.
I’ve noticed that from as soon as i run my script brake_resistor_saturated is True, is that normal ?
Also, here are the brake_resistor_current just before the psu is shutting down:

0.0
0.06863147020339966
0.07906229048967361
0.14503176510334015
0.1937473565340042
0.23900607228279114
0.26492369174957275
0.24485796689987183
0.3198602795600891
0.25840944051742554
0.2562006115913391
0.23144547641277313
0.1891786903142929
0.1548852175474167
0.15860699117183685
0.17121414840221405
0.11528303474187851
0.033284857869148254
0.0

And here is the config of my <odrv> object, tell me if you need something else !

brake_resistance: 3.299999952316284 (float)
dc_bus_overvoltage_ramp_end: 48.349998474121094 (float)
dc_bus_overvoltage_ramp_start: 48.20000076293945 (float)
dc_bus_overvoltage_trip_level: 59.92000198364258 (float)
dc_bus_undervoltage_trip_level: 8.0 (float)
dc_max_negative_current: -0.009999999776482582 (float)
dc_max_positive_current: inf (float)
enable_brake_resistor: True (bool)
enable_can_a: True (bool)
enable_dc_bus_overvoltage_ramp: True (bool)
enable_i2c_a: False (bool)
enable_uart_a: True (bool)
enable_uart_b: False (bool)
enable_uart_c: False (bool)
error_gpio_pin: 0 (uint32)
gpio10_mode: 0 (uint8)
gpio11_mode: 0 (uint8)
gpio12_mode: 12 (uint8)
gpio13_mode: 12 (uint8)
gpio14_mode: 2 (uint8)
gpio15_mode: 7 (uint8)
gpio16_mode: 7 (uint8)
gpio1_mode: 4 (uint8)
gpio1_pwm_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio2_mode: 4 (uint8)
gpio2_pwm_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio3_analog_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio3_mode: 3 (uint8)
gpio3_pwm_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio4_analog_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio4_mode: 3 (uint8)
gpio4_pwm_mapping:
  endpoint: None (object_ref)
  max: 0.0 (float)
  min: 0.0 (float)
gpio5_mode: 3 (uint8)
gpio6_mode: 0 (uint8)
gpio7_mode: 0 (uint8)
gpio8_mode: 0 (uint8)
gpio9_mode: 0 (uint8)
max_regen_current: 0.0 (float)
uart0_protocol: 3 (uint8)
uart1_protocol: 3 (uint8)
uart2_protocol: 3 (uint8)
uart_a_baudrate: 115200 (uint32)
uart_b_baudrate: 115200 (uint32)
uart_c_baudrate: 115200 (uint32)
usb_cdc_protocol: 3 (uint8)

Hi @Nicholas_Schneider,
I still need help on this issue, do you have an idea ?

Thank you !

Hi @student, so sorry for the delay!

No, it is not normal for brake_resistor_saturated to immediately be True. Could you briefly outline what this script is doing, and at which point does brake_resistor_saturated become True?
Also, I see you have enabled the overvoltage ramp feature, with a relatively tight margin of 48.35 and 48.2 for the start and end points. What is the psu voltage and/or vbus_voltage reading?
Does this issue persist of you try setting enable_dc_bus_overvoltage_ramp to False?

Thanks for your help,

It is worse if I set enable_dc_bus_overvoltage_ramp to False… It seems normal to me since the power is not dissipated in the brake resistor anymore.

The motor is in velocity control and the instruction sent are in magenta on the graphs (the velocity is the one of the pedals, not the motor r=42).
Here is the vbus and ibus during an experiment (in velocity control) where the psu didn’t crash (with enable_dc_bus_overvoltage_ramp to True), someone was forcing on the pedals from 20s:


And the same experience (someone forced on the pedals from 11s) but the psu crashed:


Zoom on the vbus before the crash

Hmm okay. It sounds like this PSU has a very narrow margin that it can operate in. I would suggest using a diode to separate the power supply from the DC bus, I’ve found this one to be pretty good.
With the diode in place the bus voltage can move away from the PSU voltage without it failing. From there you will not need such a tight margin for the overvoltage ramp, for a 48V supply I would suggest setting dc_bus_overvoltage_ramp_start to 49 and dc_bus_overvoltage_ramp_end to 51 (start at +1 from nominal, end at +3 from nominal)

1 Like

Thanks for the suggestion @Nicholas_Schneider !

I have some question about the use of a diode in this circuit:

  • Theoretically I would say it is the same to put the diode between the psu + and the ODrive + or between the psu - and the ODrive - but is there a better way to do it in practice?
  • As the forward current increases, the voltage at the diode terminals also increases. Won’t the vbus drop (if proportional, it could drop 728 AM)? I’m not sure whether that would have an impact on the proper functioning of the board.
  • How does the voltage at the diode terminals behave when the current is reversed, does the diode behave as a switch? If yes, the ODrive will not receive power for a moment.
  • How can I be sure that the reverse recovery time and the reverse leakage will be below the power supply protection threshold?

Hello!
Thank you so much for your advice this works really well with diode!
However the vbus is now 47.6, should I set dc_bus_overvoltage_ramp_start to 48 and dc_bus_overvoltage_ramp_end to 50, is it an issue for the correct functioning of the ODrive?
If anybody has any answers to my questions, it would be an excellent bonus.
Thank you for your help and support,
Have a nice weekend!

I just noticed my power supply output voltage adj. range is 48-56 V (security at 60V). As I think the range is the same for the ODrive, can I set dc_bus_overvoltage_ramp_end to 56 V ? If yes, should I change the securities on the current ?

Thank you again for your kind help,
Have a nice day !

If the psu is outputting 48V I would suggest keeping the limits at 49 and 51, as long as its below 56V it won’t be an issue for the ODrive.

1 Like

Yeah, you can set the end to 56V. You’ll still want a range of at least 2V for the ramp (start at 54V) and if you’re using the diode you’ll want a margin of about 1V between the psu output and the start of the ramp (psu set to 53V).

This shouldn’t require any changes to your current limits.

1 Like