Closed loop control: Axis Error 512

I am seaching for any information on AXIS ERROR 512. Documentation provided on the website does not clearly explain the root cause of this error and how to fix it. Error only occurs when operating in closed loop control. I can provide more information as needed to better explain the failure mode.

Have you tried the dump_errors command?
i.e. dump_errors(odrv0) from the odrivetool shell

Have tried it many times for various reasons. dump.errors seems to not respond. see below

In [88]: dump_errors(odrv0)

NameError Traceback (most recent call last)
C:\ProgramData\Anaconda3\lib\site-packages\fibre\shell.py in ()
----> 1 dump_errors(odrv0)

NameError: name ‘dump_errors’ is not defined

In [89]:

But we see the error by calling axis1 errors as below:

In [62]: odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

In [63]: odrv0.axis1.error
Out[63]: 512

What version of odrivetool are you using and what is the firmware version (odrv0.fw_version_minor)?

Axis error 512 is 0x200 which is no longer a valid error in 0.5.2, so we’ll have to determine your version first.

Please see below:

ODrive control utility v0.4.7
Please connect your ODrive.
You can also type help() or quit().

Connected to ODrive 387437803437 as odrv0
In [1]:



In [4]: odrv0
Out[4]:
vbus_voltage = 14.71142578125 (float)
serial_number = 387437803437 (int)
hw_version_major = 3 (int)
hw_version_minor = 5 (int)
hw_version_variant = 24 (int)
fw_version_major = 0 (int)
fw_version_minor = 4 (int)
fw_version_revision = 7 (int)
fw_version_unreleased = 0 (int)
user_config_loaded = True (bool)
brake_resistor_armed = True (bool)
system_stats:
  uptime = 73898874 (int)
  min_heap_space = 14264 (int)
  min_stack_space_axis0 = 7860 (int)
  min_stack_space_axis1 = 7772 (int)
  min_stack_space_comms = 3136 (int)
  min_stack_space_usb = 1196 (int)
  min_stack_space_uart = 3964 (int)
  min_stack_space_usb_irq = 1828 (int)
  min_stack_space_startup = 556 (int)
  usb: ...
  i2c: ...
config:
  brake_resistance = 0.4699999988079071 (float)
  enable_uart = True (bool)
  enable_i2c_instead_of_can = False (bool)
  enable_ascii_protocol_on_usb = True (bool)
  dc_bus_undervoltage_trip_level = 8.0 (float)
  dc_bus_overvoltage_trip_level = 25.920001983642578 (float)
  gpio1_pwm_mapping: ...
  gpio2_pwm_mapping: ...
  gpio3_pwm_mapping: ...
  gpio4_pwm_mapping: ...
axis0:
  error = 0x0000 (int)
  step_dir_active = False (bool)
  current_state = 1 (int)
  requested_state = 0 (int)
  loop_counter = 591178212 (int)
  config: ...
  get_temp()
  motor: ...
  controller: ...
  encoder: ...
  sensorless_estimator: ...
  trap_traj: ...
axis1:
  error = 0x0200 (int)
  step_dir_active = False (bool)
  current_state = 1 (int)
  requested_state = 0 (int)
  loop_counter = 591178204 (int)
  config: ...
  get_temp()
  motor: ...
  controller: ...
  encoder: ...
  sensorless_estimator: ...
  trap_traj: ...
can:
  node_id = 0 (int)
  TxMailboxCompleteCallbackCnt = 0 (int)
  TxMailboxAbortCallbackCnt = 0 (int)
  received_msg_cnt = 0 (int)
  received_ack = 0 (int)
  unexpected_errors = 0 (int)
  unhandled_messages = 0 (int)
test_property = 0 (int)
test_function(delta: int)
get_oscilloscope_val(index: int)
get_adc_voltage(gpio: int)
save_configuration()
erase_configuration()
reboot()
enter_dfu_mode()

Thanks. I went ahead and fixed your formatting for you (use three “backticks” ```) before and after a pre-formatted block to get it like that)

You are on firmware version 0.4.7, which released on January 12 of 2018. It’s probably time to update :wink:

But to answer your question, axis error 0x0200 is … CONTROLLER_FAILED. Which means you need to check axis1.controller.error

In [5]: odrv0.axis1.controller.error
Out[5]: 1

It looks like you are using the generic Fibre shell? That would explain why you have no dump_errors, because that is specific to odrivetool.

Can you run odrivetool from the ODrive Git repository?
i.e.:
git clone https://github.com/odriverobotics/ODrive.git
cd ODrive
git checkout fw-v0.5.1
python tools/odrivetool

Controller error 1 is ERROR_OVERSPEED
Probably, you need to increase vel_limit.

Also, you should checkout fw-v0.5.2 and update your firmware. :wink:
There have been many improvements since 0.5.1.

I will try to run it from the GIT repository. And we can update the firmware to take advantage of the improvements. I look forward to that.
The following are the present speed settings. Does vel_limit higher than 60000 make sense? Do you have a feeling for how much tolerance is acceptable?

Appreciate your help with this.

In [6]: odrv0.axis1.controller
Out[6]:
error = 0x0001 (int)
pos_setpoint = 286.75 (float)
vel_setpoint = 0.0 (float)
vel_integrator_current = 0.00034962789504788816 (float)
current_setpoint = 0.0 (float)
vel_ramp_target = 0.0 (float)
vel_ramp_enable = False (bool)
config:
control_mode = 2 (int)
pos_gain = 2.0 (float)
vel_gain = 0.03999999910593033 (float)
vel_integrator_gain = 0.05000000074505806 (float)
vel_limit = 60000.0 (float)
vel_limit_tolerance = 1.2000000476837158 (float)
vel_ramp_rate = 10000.0 (float)
setpoints_in_cpr = False (bool)
set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
set_current_setpoint(current_setpoint: float)
move_to_pos(goal_point: float)
start_anticogging_calibration()

Are there any concerns about the new firmware on the older board?

Shouldn’t be an issue with an older board, just make sure you set the board version in tup.config when you build the firmware.

60000 sounds about reasonable for the old firmware - possibly a bit on the low side, depending on the motor.

In the old firmware, vel_limit, pos_setpoint etc were in encoder counts and counts/sec, so many settings e.g. control gains would vary with encoder resolution.
One of the many changes in the new firmware is that position and velocity are normalised to revolutions and revolutions/sec, so the default gains and limits are VERY different, but they work for a wider range of motors & encoders.

Also, in the new firmware you no longer set pos_setpoint or vel_setpoint directly, and move_to_pos is also gone. Instead you use controller.input_pos or input_vel, with one of the configurable input modes, which can be low-pass filtering, trapezoidal trajectory, etc.

Also in the new firmware, you can have it so that the velocity limit will actually limit the velocity rather than just triggering an error. (the error is still there, but only if it exceeds the limit by a configurable margin)
You can even use the velocity limit in torque mode.

1 Like