mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-18 09:29:03 +08:00
1304 lines
56 KiB
YAML
1304 lines
56 KiB
YAML
---
|
||
version: 0.0.1
|
||
ns: com.odriverobotics
|
||
summary: ODrive Interface Definitions
|
||
|
||
dictionary: [ODrive] # Prevent the word 'ODrive' from being detected as two words 'O' and 'Drive'
|
||
|
||
userdata:
|
||
c_preamble: |
|
||
#include <tuple>
|
||
using float2D = std::pair<float, float>;
|
||
struct Iph_ABC_t { float phA; float phB; float phC; };
|
||
|
||
interfaces:
|
||
ODrive:
|
||
c_is_class: True
|
||
brief: Toplevel interface of your ODrive.
|
||
doc: |
|
||
The odrv0, odrv1, ... objects that appear in odrivetool implement this
|
||
toplevel interface.
|
||
attributes:
|
||
error:
|
||
nullflag: 'None'
|
||
flags:
|
||
ControlIterationMissed:
|
||
brief: At least one control iteration was missed.
|
||
doc: |
|
||
The main control loop is supposed to runs at a fixed frequency.
|
||
If the device is computationally overloaded (e.g. too many active
|
||
components) it's possible that one or more control iterations
|
||
are skipped.
|
||
DcBusUnderVoltage:
|
||
brief: The DC voltage fell below the limit configured in `config.dc_bus_undervoltage_trip_level`.
|
||
doc: |
|
||
Confirm that your power leads are connected securely. For initial
|
||
testing a 12V PSU which can supply a couple of amps should be
|
||
sufficient while the use of low current ‘wall wart’ plug packs may
|
||
lead to inconsistent behaviour and is not recommended.
|
||
|
||
You can monitor your PSU voltage using liveplotter in odrivetool
|
||
by entering `start_liveplotter(lambda: [odrv0.vbus_voltage])`. If
|
||
you see your votlage drop below `config.dc_bus_undervoltage_trip_level`
|
||
(default: ~ 8V) then you will trip this error. Even a relatively
|
||
small motor can draw multiple kW momentary and so unless you have
|
||
a very large PSU or are running of a battery you may encounter
|
||
this error when executing high speed movements with a high current
|
||
limit. To limit your PSU power draw you can limit your motor
|
||
current and/or velocity limit `controller.config.vel_limit` and
|
||
`motor.config.current_lim`.
|
||
DcBusOverVoltage:
|
||
brief: The DC voltage exceeded the limit configured in `config.dc_bus_overvoltage_trip_level`.
|
||
doc: |
|
||
Confirm that you have a brake resistor of the correct value
|
||
connected securely and that `config.brake_resistance` is set to
|
||
the value of your brake resistor.
|
||
|
||
You can monitor your PSU voltage using liveplotter in odrivetool
|
||
by entering `start_liveplotter(lambda: [odrv0.vbus_voltage])`. If
|
||
during a move you see the voltage rise above your PSU’s nominal
|
||
set voltage then you have your brake resistance set too low. This
|
||
may happen if you are using long wires or small gauge wires to
|
||
connect your brake resistor to your odrive which will added extra
|
||
resistance. This extra resistance needs to be accounted for to
|
||
prevent this voltage spike. If you have checked all your
|
||
connections you can also try increasing your brake resistance by
|
||
~ 0.01 Ohm at a time to a maximum of 0.05 greater than your brake
|
||
resistor value.
|
||
DcBusOverRegenCurrent: {doc: too much current pushed into the power supply}
|
||
DcBusOverCurrent: {doc: too much current pulled out of the power supply}
|
||
BrakeDeadtimeViolation:
|
||
BrakeDutyCycleNan:
|
||
# BrakeResistorDisarmed:
|
||
# doc: The brake resistor was unexpectedly disarmed.
|
||
|
||
vbus_voltage:
|
||
type: readonly float32
|
||
unit: V
|
||
brief: Voltage on the DC bus as measured by the ODrive.
|
||
ibus:
|
||
type: readonly float32
|
||
unit: A
|
||
brief: Current on the DC bus as calculated by the ODrive.
|
||
doc: |
|
||
A positive value means that the ODrive is consuming power from the power supply,
|
||
a negative value means that the ODrive is sourcing power to the power supply.
|
||
|
||
This value is equal to the sum of the motor currents and the brake resistor currents.
|
||
The motor currents are measured, the brake resistor current is calculated based on
|
||
`config.brake_resistance`.
|
||
ibus_report_filter_k:
|
||
type: float32
|
||
doc: |
|
||
Filter gain for the reported `ibus`. Set to a value below 1.0 to get a smoother
|
||
line when plotting `ibus`. Set to 1.0 to disable. This filter is only applied to
|
||
the reported value and not for internal calculations.
|
||
serial_number: readonly uint64
|
||
hw_version_major: readonly uint8
|
||
hw_version_minor: readonly uint8
|
||
hw_version_variant: readonly uint8
|
||
fw_version_major: readonly uint8
|
||
fw_version_minor: readonly uint8
|
||
fw_version_revision: readonly uint8
|
||
fw_version_unreleased:
|
||
type: readonly uint8
|
||
doc: 0 for official releases, 1 otherwise
|
||
brake_resistor_armed: readonly bool
|
||
brake_resistor_saturated: bool
|
||
|
||
# Diagnostics & performance monitoring
|
||
n_evt_sampling: {type: readonly uint32, doc: Number of input sampling events since startup (modulo 2^32)}
|
||
n_evt_control_loop: {type: readonly uint32, doc: Number of control loop iterations since startup (modulo 2^32)}
|
||
task_timers_armed:
|
||
type: bool
|
||
doc: |
|
||
Set by a profiling application to trigger sampling of a single
|
||
control iteration. Cleared by the device as soon as the sampling
|
||
is complete.
|
||
task_times:
|
||
c_is_class: False
|
||
attributes:
|
||
sampling: TaskTimer
|
||
control_loop_misc: TaskTimer
|
||
control_loop_checks: TaskTimer
|
||
system_stats:
|
||
c_is_class: False
|
||
attributes:
|
||
uptime: readonly uint32
|
||
min_heap_space: readonly uint32
|
||
max_stack_usage_axis: readonly uint32
|
||
max_stack_usage_usb: readonly uint32
|
||
max_stack_usage_uart: readonly uint32
|
||
max_stack_usage_can: readonly uint32
|
||
max_stack_usage_startup: readonly uint32
|
||
stack_size_axis: readonly uint32
|
||
stack_size_usb: readonly uint32
|
||
stack_size_uart: readonly uint32
|
||
stack_size_startup: readonly uint32
|
||
stack_size_can: readonly uint32
|
||
prio_axis: readonly int32
|
||
prio_usb: readonly int32
|
||
prio_uart: readonly int32
|
||
prio_startup: readonly int32
|
||
prio_can: readonly int32
|
||
usb:
|
||
c_is_class: False
|
||
attributes:
|
||
rx_cnt: readonly uint32
|
||
tx_cnt: readonly uint32
|
||
tx_overrun_cnt: readonly uint32
|
||
i2c:
|
||
c_is_class: False
|
||
attributes:
|
||
addr: readonly uint8
|
||
addr_match_cnt: readonly uint32
|
||
rx_cnt: readonly uint32
|
||
error_cnt: readonly uint32
|
||
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
# TODO: add support for arrays
|
||
gpio1_mode: {type: GpioMode, doc: Mode of GPIO1 (changes take effect after reboot), c_name: 'gpio_modes[1]'}
|
||
gpio2_mode: {type: GpioMode, doc: Mode of GPIO2 (changes take effect after reboot), c_name: 'gpio_modes[2]'}
|
||
gpio3_mode: {type: GpioMode, doc: Mode of GPIO3 (changes take effect after reboot), c_name: 'gpio_modes[3]'}
|
||
gpio4_mode: {type: GpioMode, doc: Mode of GPIO4 (changes take effect after reboot), c_name: 'gpio_modes[4]'}
|
||
gpio5_mode: {type: GpioMode, doc: Mode of GPIO5 (changes take effect after reboot), c_name: 'gpio_modes[5]'}
|
||
gpio6_mode: {type: GpioMode, doc: Mode of GPIO6 (changes take effect after reboot), c_name: 'gpio_modes[6]'}
|
||
gpio7_mode: {type: GpioMode, doc: Mode of GPIO7 (changes take effect after reboot), c_name: 'gpio_modes[7]'}
|
||
gpio8_mode: {type: GpioMode, doc: Mode of GPIO8 (changes take effect after reboot), c_name: 'gpio_modes[8]'}
|
||
gpio9_mode: {type: GpioMode, doc: Mode of GPIO9 (changes take effect after reboot), c_name: 'gpio_modes[9]'}
|
||
gpio10_mode: {type: GpioMode, doc: Mode of GPIO10 (changes take effect after reboot), c_name: 'gpio_modes[10]'}
|
||
gpio11_mode: {type: GpioMode, doc: Mode of GPIO11 (changes take effect after reboot), c_name: 'gpio_modes[11]'}
|
||
gpio12_mode: {type: GpioMode, doc: Mode of GPIO12 (changes take effect after reboot), c_name: 'gpio_modes[12]'}
|
||
gpio13_mode: {type: GpioMode, doc: Mode of GPIO13 (changes take effect after reboot), c_name: 'gpio_modes[13]'}
|
||
gpio14_mode: {type: GpioMode, doc: Mode of GPIO14 (changes take effect after reboot), c_name: 'gpio_modes[14]'}
|
||
gpio15_mode: {type: GpioMode, doc: Mode of GPIO15 (changes take effect after reboot), c_name: 'gpio_modes[15]'}
|
||
gpio16_mode: {type: GpioMode, doc: Mode of GPIO16 (changes take effect after reboot), c_name: 'gpio_modes[16]'}
|
||
|
||
enable_uart_a:
|
||
type: bool
|
||
brief: Enables/disables UART_A.
|
||
doc: |
|
||
You also need to set the corresponding GPIOs to GPIO_MODE_UART_A.
|
||
Refer to [interfaces](interfaces.md) to see which pins support UART_A.
|
||
Changing this requires a reboot.
|
||
enable_uart_b:
|
||
type: bool
|
||
brief: Enables/disables UART_B.
|
||
doc: |
|
||
You also need to set the corresponding GPIOs to GPIO_MODE_UART_B.
|
||
Refer to [interfaces](interfaces.md) to see which pins support UART_B.
|
||
Changing this requires a reboot.
|
||
enable_uart_c: {type: bool, doc: Not supported on ODrive v3.x.}
|
||
uart_a_baudrate:
|
||
type: uint32
|
||
unit: baud/s
|
||
brief: Defines the baudrate used on the UART interface.
|
||
doc: |
|
||
Some baudrates will have a small timing error due to hardware limitations.
|
||
|
||
Here's an (incomplete) list of baudrates for ODrive v3.x:
|
||
|
||
Configured | Actual | Error [%]
|
||
-------------|---------------|-----------
|
||
1.2 KBps | 1.2 KBps | 0
|
||
2.4 KBps | 2.4 KBps | 0
|
||
9.6 KBps | 9.6 KBps | 0
|
||
19.2 KBps | 19.195 KBps | 0.02
|
||
38.4 KBps | 38.391 KBps | 0.02
|
||
57.6 KBps | 57.613 KBps | 0.02
|
||
115.2 KBps | 115.068 KBps | 0.11
|
||
230.4 KBps | 230.769 KBps | 0.16
|
||
460.8 KBps | 461.538 KBps | 0.16
|
||
921.6 KBps | 913.043 KBps | 0.93
|
||
1.792 MBps | 1.826 MBps | 1.9
|
||
1.8432 MBps | 1.826 MBps | 0.93
|
||
|
||
For more information refer to Section 30.3.4 and Table 142 (the column with f_PCLK = 42 MHz) in the
|
||
[STM datasheet](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf).
|
||
uart_b_baudrate:
|
||
type: uint32
|
||
unit: baud/s
|
||
brief: Defines the baudrate used on the UART interface.
|
||
doc: See `uart_a_baudrate` for details.
|
||
uart_c_baudrate: {type: uint32, doc: Not supported on ODrive v3.x.}
|
||
enable_can_a:
|
||
type: bool
|
||
doc: |
|
||
Enables CAN. Changing this setting requires a reboot.
|
||
enable_i2c_a:
|
||
type: bool
|
||
doc: |
|
||
Enables I2C. The I2C pins on ODrive v3.x are in conflict with CAN.
|
||
This setting has no effect if `enable_can_a` is also true.
|
||
This setting has no effect on ODrive v3.2 or earlier.
|
||
Changing this setting requires a reboot.
|
||
enable_ascii_protocol_on_usb: bool
|
||
max_regen_current: float32
|
||
brake_resistance:
|
||
type: float32
|
||
unit: Ohm
|
||
brief: Value of the brake resistor connected to the ODrive.
|
||
doc: Set to 0 to disable.
|
||
|
||
dc_bus_undervoltage_trip_level:
|
||
type: float32
|
||
unit: V
|
||
brief: Minimum voltage below which the motor stops operating.
|
||
dc_bus_overvoltage_trip_level:
|
||
type: float32
|
||
unit: V
|
||
brief: Maximum voltage above which the motor stops operating.
|
||
doc: |
|
||
This protects against cases in which the power supply fails to dissipate
|
||
the brake power if the brake resistor is disabled.
|
||
The default is 26V for the 24V board version and 52V for the 48V board version.
|
||
|
||
enable_dc_bus_overvoltage_ramp:
|
||
type: bool
|
||
status: experimental
|
||
brief: Enables the DC bus overvoltage ramp feature.
|
||
doc: |
|
||
If enabled, if the measured DC voltage exceeds `dc_bus_overvoltage_ramp_start`,
|
||
the ODrive will sink more power than usual into the the brake resistor
|
||
in an attempt to bring the voltage down again.
|
||
|
||
The brake duty cycle is increased by the following amount:
|
||
|
||
* `vbus_voltage` == `dc_bus_overvoltage_ramp_start` => brake_duty_cycle += 0%
|
||
* `vbus_voltage` == `dc_bus_overvoltage_ramp_end` => brake_duty_cycle += 100%
|
||
|
||
Remarks:
|
||
- This feature is active even when all motors are disarmed.
|
||
- This feature is disabled if `brake_resistance` is non-positive.
|
||
dc_bus_overvoltage_ramp_start:
|
||
type: float32
|
||
status: experimental
|
||
brief: See `enable_dc_bus_overvoltage_ramp`.
|
||
doc: Do not set this lower than your usual `vbus_voltage`,
|
||
unless you like fried brake resistors.
|
||
dc_bus_overvoltage_ramp_end:
|
||
type: float32
|
||
status: experimental
|
||
brief: See `enable_dc_bus_overvoltage_ramp`.
|
||
doc: Must be larger than `dc_bus_overvoltage_ramp_start`,
|
||
otherwise the ramp feature is disabled.
|
||
|
||
dc_max_positive_current:
|
||
type: float32
|
||
unit: A
|
||
brief: Max current the power supply can source.
|
||
dc_max_negative_current:
|
||
type: float32
|
||
unit: A
|
||
brief: Max current the power supply can sink.
|
||
doc: You most likely want a non-positive value here. Set to -INFINITY to disable.
|
||
|
||
gpio1_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[0]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
|
||
gpio2_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[1]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
|
||
gpio3_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[2]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
|
||
gpio4_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[3]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
|
||
gpio3_analog_mapping: {type: Endpoint, c_name: 'analog_mappings[3]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_ANALOG_IN`.}
|
||
gpio4_analog_mapping: {type: Endpoint, c_name: 'analog_mappings[4]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_ANALOG_IN`.}
|
||
user_config_loaded: readonly uint32
|
||
misconfigured:
|
||
# TODO: make this a system error
|
||
type: readonly bool
|
||
doc: |
|
||
If this property is true, something is bad in the configuration. The
|
||
ODrive can still be used in this state but the user should investigate
|
||
which setting is problematic. This variable does not cover all
|
||
misconfigurations.
|
||
|
||
Possible causes:
|
||
- A GPIO was set to a mode that it doesn't support
|
||
- A GPIO was set to a mode for which the corresponding feature was
|
||
not enabled. Example: `GPIO_MODE_UART_A` was used without enabling
|
||
`config.enable_uart_a`.
|
||
- A feature was enabled which is not supported on this hardware.
|
||
Example: `config.enable_uart_c` set to true on ODrive v3.x.
|
||
- A GPIO was used as an interrupt input for two internal components
|
||
or two GPIOs that are mutually exclusive in their interrupt
|
||
capability were both used as interrupt input.
|
||
Example: `step_gpio_pin` of both axes were set to the same GPIO.
|
||
|
||
axis0: {type: Axis, c_name: get_axis(0)}
|
||
axis1: {type: Axis, c_name: get_axis(1)}
|
||
oscilloscope: {type: Oscilloscope}
|
||
can: {type: Can, c_name: get_can()}
|
||
test_property: uint32
|
||
|
||
functions:
|
||
test_function: {in: {delta: int32}, out: {cnt: int32}}
|
||
get_adc_voltage: {in: {gpio: uint32}, out: {voltage: float32}, doc: Reads the ADC voltage of the specified GPIO. The GPIO should be in `GPIO_MODE_ANALOG_IN`.}
|
||
save_configuration:
|
||
erase_configuration:
|
||
reboot:
|
||
enter_dfu_mode:
|
||
get_interrupt_status:
|
||
in: {irqn: {type: int32, doc: '-12...-1: processor interrupts, 0...239: NVIC interrupts'}}
|
||
out:
|
||
status:
|
||
type: uint32
|
||
doc: |
|
||
bit 31: enabled (1) or disabled (0)
|
||
bits 30:8: number of times the interrupt fired (modulo 0x800000)
|
||
bits 7:0: priority (0 is highest priority)
|
||
0xffffffff if the specified number is not a valid interrupt number.
|
||
doc: Returns information about the specified interrupt number.
|
||
get_dma_status:
|
||
in: {stream_num: {type: uint8, doc: '0...7: DMA1 streams, 8...15: DMA2 streams'}}
|
||
out:
|
||
status:
|
||
type: uint32
|
||
doc: |
|
||
bit 31: zero if the stream's configuration is equal to the reset state
|
||
bits 4:2: channel
|
||
bits 1:0: priority (3 is highest priority)
|
||
0xffffffff if the specified number is not a valid DMA stream number.
|
||
doc: Returns information about the specified DMA stream.
|
||
clear_errors:
|
||
doc: Clear all the errors of this device including all contained submodules.
|
||
|
||
ODrive.Can:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: None
|
||
flags: {DuplicateCanIds: }
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
baud_rate: readonly uint32
|
||
protocol: Protocol
|
||
functions:
|
||
set_baud_rate: {in: {baudRate: uint32}}
|
||
|
||
ODrive.Endpoint:
|
||
c_is_class: False
|
||
attributes:
|
||
endpoint: endpoint_ref
|
||
min: float32
|
||
max: float32
|
||
|
||
ODrive.Axis:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: 'None'
|
||
flags:
|
||
InvalidState:
|
||
brief: An invalid state was requested.
|
||
doc: |
|
||
You tried to run a state before you are allowed to. Typically you
|
||
tried to run encoder calibration or closed loop control before the
|
||
motor was calibrated, or you tried to run closed loop control
|
||
before the encoder was calibrated.
|
||
WatchdogTimerExpired: {bit: 11}
|
||
MinEndstopPressed:
|
||
MaxEndstopPressed:
|
||
EstopRequested:
|
||
HomingWithoutEndstop:
|
||
bit: 17
|
||
doc: the min endstop was not enabled during homing
|
||
OverTemp:
|
||
# unused
|
||
doc: Check `motor.error` for more details.
|
||
step_dir_active: readonly bool
|
||
current_state: readonly AxisState
|
||
requested_state: AxisState
|
||
loop_counter: readonly uint32
|
||
is_homed: {type: bool, c_name: homing_.is_homed}
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
startup_motor_calibration:
|
||
type: bool
|
||
doc: run motor calibration at startup, skip otherwise
|
||
startup_encoder_index_search:
|
||
type: bool
|
||
doc: run encoder index search after startup, skip otherwise this only has an effect if encoder.config.use_index is also true
|
||
startup_encoder_offset_calibration:
|
||
type: bool
|
||
doc: run encoder offset calibration after startup, skip otherwise
|
||
startup_closed_loop_control:
|
||
type: bool
|
||
doc: enable closed loop control after calibration/startup
|
||
startup_homing:
|
||
type: bool
|
||
doc: enable homing after calibration/startup
|
||
enable_step_dir:
|
||
type: bool
|
||
doc: Enable step/dir input after calibration.
|
||
Make sure to set the corresponding GPIO's mode to `GPIO_MODE_DIGITAL`.
|
||
step_dir_always_on:
|
||
type: bool
|
||
doc: Keep step/dir enabled while the motor is disabled.
|
||
This is ignored if enable_step_dir is false.
|
||
This setting only takes effect on a state transition
|
||
into idle or out of closed loop control.
|
||
enable_sensorless_mode: bool
|
||
turns_per_step: float32
|
||
watchdog_timeout:
|
||
type: float32
|
||
unit: s
|
||
enable_watchdog: bool
|
||
step_gpio_pin: {type: uint16, c_setter: 'set_step_gpio_pin'}
|
||
dir_gpio_pin: {type: uint16, c_setter: 'set_dir_gpio_pin'}
|
||
calibration_lockin: # TODO: this is a subset of lockin state
|
||
c_is_class: False
|
||
attributes:
|
||
current: float32
|
||
ramp_time: float32
|
||
ramp_distance: float32
|
||
accel: float32
|
||
vel: float32
|
||
sensorless_ramp: LockinConfig
|
||
general_lockin: LockinConfig
|
||
can: CanConfig
|
||
gate_driver:
|
||
c_name: gate_driver_exported_
|
||
c_is_class: False
|
||
attributes:
|
||
drv_fault:
|
||
typeargs: {fibre.Property.mode: readonly}
|
||
nullflag: NoFault
|
||
flags:
|
||
FetLowCOvercurrent: {bit: 0, doc: FET Low side, Phase C Over Current fault}
|
||
FetHighCOvercurrent: {bit: 1, doc: FET High side, Phase C Over Current fault}
|
||
FetLowBOvercurrent: {bit: 2, doc: FET Low side, Phase B Over Current fault}
|
||
FetHighBOvercurrent: {bit: 3, doc: FET High side, Phase B Over Current fault}
|
||
FetLowAOvercurrent: {bit: 4, doc: FET Low side, Phase A Over Current fault}
|
||
FetHighAOvercurrent: {bit: 5, doc: FET High side, Phase A Over Current fault}
|
||
OvertemperatureWarning: {bit: 6, doc: Over Temperature Warning fault}
|
||
OvertemperatureShutdown: {bit: 7, doc: Over Temperature Shut Down fault}
|
||
PVddUndervoltage: {bit: 8, doc: Power supply Vdd Under Voltage fault}
|
||
GVddUndervoltage: {bit: 9, doc: DRV8301 Vdd Under Voltage fault}
|
||
GVddOvervoltage: {bit: 10, doc: DRV8301 Vdd Over Voltage fault}
|
||
# status_reg_1: readonly uint32
|
||
# status_reg_2: readonly uint32
|
||
# ctrl_reg_1: readonly uint32
|
||
# ctrl_reg_2: readonly uint32
|
||
motor: Motor
|
||
controller: Controller
|
||
encoder: Encoder
|
||
async_estimator: AsyncEstimator
|
||
sensorless_estimator: SensorlessEstimator
|
||
trap_traj: TrapezoidalTrajectory
|
||
min_endstop: Endstop
|
||
max_endstop: Endstop
|
||
mechanical_brake: MechanicalBrake
|
||
task_times:
|
||
c_is_class: False
|
||
attributes:
|
||
thermistor_update: TaskTimer
|
||
encoder_update: TaskTimer
|
||
sensorless_estimator_update: TaskTimer
|
||
endstop_update: TaskTimer
|
||
can_heartbeat: TaskTimer
|
||
controller_update: TaskTimer
|
||
open_loop_controller_update: TaskTimer
|
||
async_estimator_update: TaskTimer
|
||
motor_update: TaskTimer
|
||
current_controller_update: TaskTimer
|
||
dc_calib: TaskTimer
|
||
current_sense: TaskTimer
|
||
pwm_update: TaskTimer
|
||
functions:
|
||
watchdog_feed:
|
||
doc: Feed the watchdog to prevent watchdog timeouts.
|
||
|
||
ODrive.Axis.LockinConfig:
|
||
c_is_class: False
|
||
attributes:
|
||
current:
|
||
type: float32
|
||
unit: A
|
||
ramp_time:
|
||
type: float32
|
||
unit: s
|
||
ramp_distance:
|
||
type: float32
|
||
unit: rad
|
||
accel:
|
||
type: float32
|
||
unit: rad/s^2
|
||
vel:
|
||
type: float32
|
||
unit: rad/s
|
||
finish_distance:
|
||
type: float32
|
||
unit: rad
|
||
finish_on_vel: bool
|
||
finish_on_distance: bool
|
||
finish_on_enc_idx: bool
|
||
|
||
ODrive.Axis.CanConfig:
|
||
c_is_class: False
|
||
attributes:
|
||
node_id: uint32
|
||
is_extended: bool
|
||
heartbeat_rate_ms: uint32
|
||
encoder_rate_ms: uint32
|
||
|
||
ODrive.ThermistorCurrentLimiter:
|
||
c_is_class: False
|
||
|
||
ODrive.OnboardThermistorCurrentLimiter:
|
||
c_is_class: True
|
||
attributes:
|
||
temperature:
|
||
type: readonly float32
|
||
unit: °C
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
temp_limit_lower:
|
||
type: float32
|
||
doc: The lower limit when the controller starts limiting current.
|
||
temp_limit_upper:
|
||
type: float32
|
||
doc: The upper limit when current limit reaches 0 Amps and an over temperature error is triggered.
|
||
enabled: {type: bool, doc: Whether this thermistor is enabled. }
|
||
|
||
ODrive.OffboardThermistorCurrentLimiter:
|
||
c_is_class: True
|
||
attributes:
|
||
temperature:
|
||
type: readonly float32
|
||
unit: °C
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
gpio_pin: {type: uint16, c_setter: set_gpio_pin}
|
||
poly_coefficient_0: {type: float32, c_name: 'thermistor_poly_coeffs[0]'}
|
||
poly_coefficient_1: {type: float32, c_name: 'thermistor_poly_coeffs[1]'}
|
||
poly_coefficient_2: {type: float32, c_name: 'thermistor_poly_coeffs[2]'}
|
||
poly_coefficient_3: {type: float32, c_name: 'thermistor_poly_coeffs[3]'}
|
||
temp_limit_lower:
|
||
type: float32
|
||
doc: The lower limit when the controller starts limiting current.
|
||
temp_limit_upper:
|
||
type: float32
|
||
doc: The upper limit when current limit reaches 0 Amps and an over temperature error is triggered.
|
||
enabled: {type: bool, doc: Whether this thermistor is enabled. }
|
||
|
||
ODrive.Motor:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: None
|
||
flags:
|
||
PhaseResistanceOutOfRange:
|
||
brief: The measured motor phase resistance is outside of the plausible range.
|
||
doc: |
|
||
During calibration the motor resistance and
|
||
[inductance](https://en.wikipedia.org/wiki/Inductance) is measured.
|
||
If the measured motor resistance or inductance falls outside a set
|
||
range this error will be returned. Check that all motor leads are
|
||
connected securely.
|
||
|
||
The measured values can be viewed using odrivetool as is shown below:
|
||
```
|
||
In [2]: odrv0.axis0.motor.config.phase_inductance
|
||
Out[2]: 1.408751450071577e-05
|
||
|
||
In [3]: odrv0.axis0.motor.config.phase_resistance
|
||
Out[3]: 0.029788672924041748
|
||
```
|
||
Some motors will have a considerably different phase resistance
|
||
and inductance than this. For example, gimbal motors, some small
|
||
motors (e.g. < 10A peak current). If you think this applies to you
|
||
try increasing `config.resistance_calib_max_voltage` from
|
||
its default value of 1 using odrivetool and repeat the motor
|
||
calibration process. If your motor has a small peak current draw
|
||
(e.g. < 20A) you can also try decreasing
|
||
`config.calibration_current` from its default value of 10A.
|
||
|
||
In general, you need
|
||
```text
|
||
resistance_calib_max_voltage > calibration_current * phase_resistance
|
||
resistance_calib_max_voltage < 0.5 * vbus_voltage
|
||
```
|
||
PhaseInductanceOutOfRange:
|
||
brief: The measured motor phase inductance is outside of the plausible range.
|
||
doc: |
|
||
See `PhaseResistanceOutOfRange` for details.
|
||
DrvFault:
|
||
bit: 3
|
||
brief: The gate driver chip reported an error.
|
||
doc: |
|
||
The ODrive v3.4 is known to have a hardware issue whereby the
|
||
motors would stop operating when applying high currents to M0. The
|
||
reported error of both motors in this case is `ERROR_DRV_FAULT`.
|
||
|
||
The conjecture is that the high switching current creates large
|
||
ripples in the power supply of the DRV8301 gate driver chips, thus
|
||
tripping its under-voltage fault detection.
|
||
|
||
To resolve this issue you can limit the M0 current to 40A. The
|
||
lowest current at which the DRV fault was observed is 45A on one
|
||
test motor and 50A on another test motor. Refer to
|
||
[this post](https://discourse.odriverobotics.com/t/drv-fault-on-odrive-v3-4/558)
|
||
for instructions for a hardware fix.
|
||
ControlDeadlineMissed:
|
||
ModulationMagnitude:
|
||
bit: 7
|
||
doc: |
|
||
The bus voltage was insufficent to push the requested current
|
||
through the motor.
|
||
If you are getting this during motor calibration, make sure that
|
||
`config.resistance_calib_max_voltage` is no more than half
|
||
your bus voltage.
|
||
|
||
For gimbal motors, it is recommended to set the
|
||
`config.calibration_current` and `config.current_lim`
|
||
to half your bus voltage, or less.
|
||
CurrentSenseSaturation: {bit: 10}
|
||
CurrentLimitViolation: {bit: 12}
|
||
ModulationIsNan: {bit: 16}
|
||
MotorThermistorOverTemp: {doc: The motor thermistor measured a temperature above motor.motor_thermistor.config.temp_limit_upper}
|
||
FetThermistorOverTemp: {doc: The inverter thermistor measured a temperature above motor.fet_thermistor.config.temp_limit_upper}
|
||
TimerUpdateMissed: {doc: A timer update event was missed. Perhaps the previous timer update took too much time. This is not expected in official release firmware.}
|
||
CurrentMeasurementUnavailable: {doc: The phase current measurement is not available. The ADC failed to sample the current sensor in time. This is not expected in official release firmware.}
|
||
ControllerFailed: {doc: The motor was disarmed because the underlying controller failed. Usually this is the FOC controller.}
|
||
IBusOutOfRange:
|
||
doc: |
|
||
The DC current sourced/sunk by this motor exceeded the configured
|
||
hard limits. More specifically `i_bus` fell outside of the range
|
||
`config.i_bus_hard_min` ... `config.i_bus_hard_max`.
|
||
BrakeResistorDisarmed: {doc: An attempt was made to run the motor PWM while the brake resistor was enabled but disarmed.}
|
||
SystemLevel:
|
||
doc: |
|
||
The motor had to be disarmed because of a system level error.
|
||
See `ODrive.Error` for more details.
|
||
BadTiming: {doc: The main control loop got out of sync with the motor control loop. This could indicate that the main control loop got stuck.}
|
||
UnknownPhaseEstimate: {doc: The current controller did not get a valid angle input. Maybe you didn't calibrate the encoder.}
|
||
UnknownPhaseVel: {doc: The motor controller did not get a valid phase velocity input.}
|
||
UnknownTorque: {doc: The motor controller did not get a valid torque input.}
|
||
UnknownCurrentCommand: {doc: The current controller did not get a valid current setpoint. Maybe you didn't configure the controller correctly.}
|
||
UnknownCurrentMeasurement: {doc: The current controller did not get a valid current measurement.}
|
||
UnknownVbusVoltage: {doc: The current controller did not get a valid `vbus_voltage` measurement.}
|
||
UnknownVoltageCommand: {doc: The current controller did not get a valid feedforward voltage setpoint.}
|
||
UnknownGains: {doc: The current controller gains were not configured. Run motor calibration or set `config.phase_resistance` and `config.phase_inductance` manually.}
|
||
ControllerInitializing: {doc: Internal value used while the controller is not yet ready to generate PWM timings.}
|
||
is_armed: readonly bool
|
||
is_calibrated: readonly bool
|
||
current_meas_phA: {type: readonly float32, c_getter: 'current_meas_.value_or(Iph_ABC_t{0.0f, 0.0f, 0.0f}).phA'}
|
||
current_meas_phB: {type: readonly float32, c_getter: 'current_meas_.value_or(Iph_ABC_t{0.0f, 0.0f, 0.0f}).phB'}
|
||
current_meas_phC: {type: readonly float32, c_getter: 'current_meas_.value_or(Iph_ABC_t{0.0f, 0.0f, 0.0f}).phC'}
|
||
DC_calib_phA: {type: float32, c_name: DC_calib_.phA}
|
||
DC_calib_phB: {type: float32, c_name: DC_calib_.phB}
|
||
DC_calib_phC: {type: float32, c_name: DC_calib_.phC}
|
||
I_bus: {type: readonly float32, unit: A}
|
||
phase_current_rev_gain: float32
|
||
effective_current_lim: readonly float32
|
||
max_allowed_current:
|
||
type: readonly float32
|
||
unit: A
|
||
doc: |
|
||
Indicates the maximum current that can be measured by the current
|
||
sensors in the current hardware configuration. This value depends on
|
||
`config.requested_current_range`.
|
||
max_dc_calib: {type: readonly float32, unit: A}
|
||
fet_thermistor: OnboardThermistorCurrentLimiter
|
||
motor_thermistor: OffboardThermistorCurrentLimiter
|
||
current_control:
|
||
c_is_class: True
|
||
attributes:
|
||
p_gain: {type: readonly float32, c_getter: 'pi_gains_.value_or(float2D{0.0f, 0.0f}).first'}
|
||
i_gain: {type: readonly float32, c_getter: 'pi_gains_.value_or(float2D{0.0f, 0.0f}).second'}
|
||
I_measured_report_filter_k: float32
|
||
Id_setpoint: {type: readonly float32, c_getter: 'Idq_setpoint_.value_or(float2D{0.0f, 0.0f}).first'}
|
||
Iq_setpoint: {type: readonly float32, c_getter: 'Idq_setpoint_.value_or(float2D{0.0f, 0.0f}).second'}
|
||
Vd_setpoint: {type: readonly float32, c_getter: 'Vdq_setpoint_.value_or(float2D{0.0f, 0.0f}).first'}
|
||
Vq_setpoint: {type: readonly float32, c_getter: 'Vdq_setpoint_.value_or(float2D{0.0f, 0.0f}).second'}
|
||
phase: {type: readonly float32, c_getter: 'phase_.value_or(0.0f)'}
|
||
phase_vel: {type: readonly float32, c_getter: 'phase_vel_.value_or(0.0f)'}
|
||
Ialpha_measured: {type: readonly float32, c_getter: 'Ialpha_beta_measured_.value_or(float2D{0.0f, 0.0f}).first'}
|
||
Ibeta_measured: {type: readonly float32, c_getter: 'Ialpha_beta_measured_.value_or(float2D{0.0f, 0.0f}).second'}
|
||
Id_measured: readonly float32
|
||
Iq_measured: readonly float32
|
||
v_current_control_integral_d: float32
|
||
v_current_control_integral_q: float32
|
||
final_v_alpha: readonly float32
|
||
final_v_beta: readonly float32
|
||
n_evt_current_measurement: {type: readonly uint32, doc: Number of current measurement events since startup (modulo 2^32)}
|
||
n_evt_pwm_update: {type: readonly uint32, doc: Number of PWM update events since startup (modulo 2^32)}
|
||
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
pre_calibrated: {type: bool, c_setter: set_pre_calibrated}
|
||
pole_pairs: int32
|
||
calibration_current: float32
|
||
resistance_calib_max_voltage: float32
|
||
phase_inductance: {type: float32, c_setter: set_phase_inductance}
|
||
phase_resistance: {type: float32, c_setter: set_phase_resistance}
|
||
torque_constant: float32
|
||
motor_type: MotorType
|
||
current_lim: float32
|
||
current_lim_margin: float32
|
||
torque_lim: float32
|
||
inverter_temp_limit_lower: float32
|
||
inverter_temp_limit_upper: float32
|
||
requested_current_range: float32
|
||
current_control_bandwidth: {type: float32, c_setter: set_current_control_bandwidth}
|
||
acim_gain_min_flux: float32
|
||
acim_autoflux_min_Id: float32
|
||
acim_autoflux_enable: bool
|
||
acim_autoflux_attack_gain: float32
|
||
acim_autoflux_decay_gain: float32
|
||
R_wL_FF_enable: bool
|
||
bEMF_FF_enable: bool
|
||
I_bus_hard_min:
|
||
type: float32
|
||
unit: A
|
||
doc: |
|
||
If the controller fails to keep this motor's DC current (`I_bus`)
|
||
above this value the motor gets disarmed immediately. Most likely
|
||
you want a negative value here. Set to -inf to disable. Take noise
|
||
into account when chosing a value.
|
||
I_bus_hard_max:
|
||
type: float32
|
||
unit: A
|
||
doc: |
|
||
If the controller fails to keep this motor's DC current (`I_bus`)
|
||
below this value the motor gets disarmed immediately. Usually this
|
||
is set in conjunction with `I_bus_hard_min`. Set to inf to disable.
|
||
Take noise into account when chosing a value.
|
||
I_leak_max:
|
||
type: float32
|
||
unit: A
|
||
doc: |
|
||
In almost all scenarios, the currents on phase A, B and C should
|
||
add up to zero. A small amount of measurement noise is expected.
|
||
However if the sum of A, B, C currents exceeds this configuration
|
||
value, the motor gets disarmed immediately.
|
||
|
||
Note that this feature is only works on devices with three current
|
||
sensors.
|
||
dc_calib_tau: float32
|
||
|
||
ODrive.Oscilloscope:
|
||
c_is_class: True
|
||
attributes:
|
||
size: readonly uint32
|
||
functions:
|
||
get_val: {in: {index: uint32}, out: {val: float32}}
|
||
|
||
ODrive.AsyncEstimator:
|
||
c_is_class: True
|
||
attributes:
|
||
rotor_flux: {type: readonly float32, unit: A, doc: estimated magnitude of the rotor flux}
|
||
slip_vel:
|
||
type: readonly float32
|
||
unit: rad/s
|
||
doc: estimated slip between physical and electrical angular velocity}
|
||
c_getter: slip_vel_.get_any().value_or(0.0f)
|
||
phase_offset:
|
||
type: readonly float32
|
||
unit: rad
|
||
doc: estimate offset between physical and electrical angular position}
|
||
stator_phase_vel:
|
||
type: readonly float32
|
||
unit: rad/s
|
||
doc: calculated setpoint for the electrical velocity}
|
||
c_getter: stator_phase_vel_.get_any().value_or(0.0f)
|
||
stator_phase:
|
||
type: readonly float32
|
||
unit: rad
|
||
doc: calculated setpoint for the electrical phase}
|
||
c_getter: stator_phase_.get_any().value_or(0.0f)
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
slip_velocity: float32
|
||
|
||
ODrive.Controller:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: None
|
||
flags:
|
||
Overspeed:
|
||
doc: |
|
||
Try increasing `config.vel_limit`. The default of 2 turns per second
|
||
gives a motor speed of only 120 RPM. Note: Even if
|
||
you do not commanded your motor to exceed `config.vel_limit`
|
||
sudden changes in the load placed on a motor may cause this speed
|
||
to be temporarily exceeded, resulting in this error.
|
||
|
||
You can also try increasing `config.vel_limit_tolerance`. The
|
||
default value of 1.2 means it will only allow a 20% violation of
|
||
the speed limit. You can set the `config.vel_limit_tolerance` to 0
|
||
to disable the check altogether.
|
||
InvalidInputMode:
|
||
UnstableGain:
|
||
InvalidMirrorAxis:
|
||
InvalidLoadEncoder:
|
||
InvalidEstimate:
|
||
input_pos:
|
||
type: float32
|
||
unit: turn
|
||
c_setter: set_input_pos
|
||
input_vel:
|
||
type: float32
|
||
unit: turn/s
|
||
input_torque: float32
|
||
pos_setpoint: readonly float32
|
||
vel_setpoint: readonly float32
|
||
torque_setpoint: readonly float32
|
||
trajectory_done: readonly bool
|
||
vel_integrator_torque: float32
|
||
anticogging_valid: bool
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
gain_scheduling_width: float32
|
||
enable_vel_limit: bool
|
||
enable_current_mode_vel_limit:
|
||
type: bool
|
||
doc: Enable velocity limit in current control mode (requires a valid velocity estimator).
|
||
enable_gain_scheduling: bool
|
||
enable_overspeed_error: bool
|
||
control_mode: ControlMode
|
||
input_mode: InputMode
|
||
pos_gain:
|
||
type: float32
|
||
unit: (turn/s) / turn
|
||
doc: units = (turn/s) / turn, default = 20
|
||
vel_gain:
|
||
type: float32
|
||
unit: 'Nm/(turn/s)'
|
||
doc: units = 'Nm/(turn/s), default = 0.16
|
||
vel_integrator_gain:
|
||
type: float32
|
||
unit: Nm/(turn/s * s)
|
||
doc: units = Nm/(turn/s * s), default = 0.32
|
||
vel_limit:
|
||
type: float32
|
||
unit: turn/s
|
||
doc: Infinity to disable.
|
||
vel_limit_tolerance:
|
||
type: float32
|
||
doc: Ratio to `vel_limit`. Infinity to disable.
|
||
vel_ramp_rate: float32
|
||
torque_ramp_rate:
|
||
type: float32
|
||
unit: Nm / sec
|
||
circular_setpoints:
|
||
type: bool
|
||
circular_setpoint_range:
|
||
type: float32
|
||
doc: circular range in [turns] for position setpoints when circular_setpoints is True
|
||
homing_speed:
|
||
type: float32
|
||
unit: turns/s
|
||
inertia:
|
||
type: float32
|
||
unit: Nm/(turn/s^2)
|
||
axis_to_mirror: uint8
|
||
mirror_ratio: float32
|
||
load_encoder_axis:
|
||
type: uint8
|
||
# TODO: this is meaningless for a user. Should there be a separate developer note?
|
||
doc: Default depends on Axis number and is set in load_configuration()
|
||
input_filter_bandwidth:
|
||
type: float32
|
||
unit: 1/s
|
||
c_setter: set_input_filter_bandwidth
|
||
anticogging:
|
||
c_is_class: False
|
||
attributes:
|
||
index: readonly uint32
|
||
pre_calibrated: bool
|
||
calib_anticogging: readonly bool
|
||
calib_pos_threshold: float32
|
||
calib_vel_threshold: float32
|
||
cogging_ratio: readonly float32
|
||
anticogging_enabled: bool
|
||
functions:
|
||
move_incremental:
|
||
doc: Moves the axes' goal point by a specified increment.
|
||
in:
|
||
displacement: {type: float32, doc: The desired position change.}
|
||
from_input_pos: {type: bool, doc:
|
||
'If true, the increment is applied relative to `input_pos`.
|
||
If false, the increment is applied relative to `pos_setpoint`, which
|
||
usually corresponds roughly to the current position of the axis.'
|
||
}
|
||
start_anticogging_calibration:
|
||
|
||
|
||
ODrive.Encoder:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: None
|
||
flags:
|
||
UnstableGain:
|
||
CprPolepairsMismatch:
|
||
doc: |
|
||
Confirm you have entered the correct count per rotation (CPR) for
|
||
[your encoder](https://docs.odriverobotics.com/encoders). The
|
||
ODrive uses your supplied value for the motor pole pairs to
|
||
measure the CPR. So you should also double check this value.
|
||
|
||
Note that the AMT encoders are configurable using the micro-
|
||
switches on the encoder PCB and so you may need to check that
|
||
these are in the right positions. If your encoder lists its pulse
|
||
per rotation (PPR) multiply that number by four to get CPR.
|
||
NoResponse:
|
||
doc: |
|
||
Confirm that your encoder is plugged into the right pins on the
|
||
ODrive board.
|
||
UnsupportedEncoderMode:
|
||
IllegalHallState:
|
||
IndexNotFoundYet:
|
||
doc: |
|
||
Check that your encoder is a model that has an index pulse. If
|
||
your encoder does not have a wire connected to pin Z on your
|
||
ODrive then it does not output an index pulse.
|
||
AbsSpiTimeout:
|
||
AbsSpiComFail:
|
||
AbsSpiNotReady:
|
||
HallNotCalibratedYet:
|
||
is_ready: readonly bool
|
||
index_found: readonly bool
|
||
shadow_count: readonly int32
|
||
count_in_cpr: readonly int32
|
||
interpolation: readonly float32
|
||
phase: {type: readonly float32, c_getter: phase_.get_any().value_or(0.0f)}
|
||
pos_estimate: {type: readonly float32, c_getter: pos_estimate_.get_any().value_or(0.0f)}
|
||
pos_estimate_counts: readonly float32
|
||
pos_cpr_counts: readonly float32
|
||
delta_pos_cpr_counts: readonly float32
|
||
pos_circular: {type: readonly float32, c_getter: pos_circular_.get_any().value_or(0.0f)}
|
||
hall_state: readonly uint8
|
||
vel_estimate: {type: readonly float32, c_getter: vel_estimate_.get_any().value_or(0.0f)}
|
||
vel_estimate_counts: readonly float32
|
||
calib_scan_response: readonly float32
|
||
pos_abs: int32
|
||
spi_error_rate: readonly float32
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
mode: Mode
|
||
use_index: {type: bool, c_setter: set_use_index}
|
||
find_idx_on_lockin_only: {type: bool, c_setter: set_find_idx_on_lockin_only}
|
||
abs_spi_cs_gpio_pin: {type: uint16, c_setter: set_abs_spi_cs_gpio_pin, doc: Make sure that the GPIO is in `GPIO_MODE_DIGITAL`.}
|
||
zero_count_on_find_idx: bool
|
||
cpr: int32
|
||
phase_offset: int32
|
||
phase_offset_float: float32
|
||
direction: int32
|
||
pre_calibrated: {type: bool, c_setter: set_pre_calibrated}
|
||
enable_phase_interpolation: bool
|
||
bandwidth: {type: float32, c_setter: set_bandwidth}
|
||
calib_range: float32
|
||
calib_scan_distance: float32
|
||
calib_scan_omega: float32
|
||
ignore_illegal_hall_state: bool
|
||
hall_polarity: uint8
|
||
hall_polarity_calibrated: bool
|
||
sincos_gpio_pin_sin:
|
||
type: uint16
|
||
doc: Analog sine signal of a sin/cos encoder. The corresponding GPIO must be in `GPIO_MODE_ANALOG_IN`.
|
||
sincos_gpio_pin_cos:
|
||
type: uint16
|
||
doc: Analog cosine signal of a sin/cos encoder. The corresponding GPIO must be in `GPIO_MODE_ANALOG_IN`.
|
||
functions:
|
||
set_linear_count: {in: {count: int32}}
|
||
|
||
|
||
ODrive.SensorlessEstimator:
|
||
c_is_class: True
|
||
attributes:
|
||
error:
|
||
nullflag: None
|
||
flags:
|
||
UnstableGain:
|
||
UnknownCurrentMeasurement:
|
||
phase: {type: readonly float32, unit: rad, c_getter: phase_.get_any().value_or(0.0f)}
|
||
pll_pos: {type: readonly float32, unit: rad}
|
||
phase_vel: {type: readonly float32, unit: rad/s, c_getter: phase_vel_.get_any().value_or(0.0f)}
|
||
vel_estimate: {type: readonly float32, unit: turns/s, c_getter: vel_estimate_.get_any().value_or(0.0f)}
|
||
# pll_kp: float32
|
||
# pll_ki: float32
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
observer_gain: float32
|
||
pll_bandwidth: float32
|
||
pm_flux_linkage: float32
|
||
|
||
|
||
ODrive.TrapezoidalTrajectory:
|
||
c_is_class: True
|
||
attributes:
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
vel_limit: float32
|
||
accel_limit: float32
|
||
decel_limit: float32
|
||
|
||
ODrive.Endstop:
|
||
c_is_class: True
|
||
attributes:
|
||
endstop_state: readonly bool
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
gpio_num: {type: uint16, c_setter: set_gpio_num, doc: Make sure the corresponding GPIO is in `GPIO_MODE_DIGITAL`.}
|
||
enabled: {type: bool, c_setter: set_enabled}
|
||
offset: float32
|
||
is_active_high: bool
|
||
debounce_ms: {type: uint32, c_setter: set_debounce_ms}
|
||
|
||
ODrive.MechanicalBrake:
|
||
c_is_class: True
|
||
attributes:
|
||
config:
|
||
c_is_class: False
|
||
attributes:
|
||
gpio_num: {type: uint16, c_setter: set_gpio_num}
|
||
is_active_low: bool
|
||
functions:
|
||
engage:
|
||
doc: |
|
||
This function engages the mechanical brake if one is present and enabled.
|
||
release:
|
||
doc: |
|
||
This function releases the mecahncal brake if one is present and enabled.
|
||
|
||
ODrive.TaskTimer:
|
||
c_is_class: True
|
||
attributes:
|
||
start_time: readonly uint32
|
||
end_time: readonly uint32
|
||
length: readonly uint32
|
||
max_length: uint32
|
||
|
||
valuetypes:
|
||
ODrive.GpioMode:
|
||
values:
|
||
Digital:
|
||
doc: |
|
||
The pin can be used for one or more of these functions:
|
||
Step, dir, enable, encoder index, hall effect encoder, SPI encoder nCS (this one is exclusive).
|
||
DigitalPullUp:
|
||
doc: Same as `Digital` but with the internal pull-up resistor enabled.
|
||
DigitalPullDown:
|
||
doc: Same as `Digital` but with the internal pull-down resistor enabled.
|
||
AnalogIn:
|
||
doc: |
|
||
The pin can be used for one or more of these functions:
|
||
Sin/cos encoders, analog input, `get_adc_voltage`.
|
||
UartA: {doc: See `config.enable_uart_a`.}
|
||
UartB: {doc: This mode is not supported on ODrive v3.x.}
|
||
UartC: {doc: This mode is not supported on ODrive v3.x.}
|
||
CanA: {doc: See `config.enable_can_a`.}
|
||
I2cA: {doc: See `config.enable_i2c_a`.}
|
||
SpiA: {doc: Note that the SPI pins on ODrive v3.x are hardwired so they
|
||
cannot be configured through software. Consequently, even though SPI_A
|
||
is exposed, this mode is of no use on ODrive v3.x.}
|
||
Pwm: {doc: See `config.gpio0_pwm_mapping`.}
|
||
Enc0: {doc: The pin is used by quadrature encoder 0.}
|
||
Enc1: {doc: The pin is used by quadrature encoder 1.}
|
||
Enc2: {doc: This mode is not supported on ODrive v3.x.}
|
||
MechBrake: {doc: This is to support external mechanical brakes.}
|
||
|
||
ODrive.Can.Protocol:
|
||
values: {Simple: }
|
||
|
||
ODrive.Axis.AxisState: # TODO: remove redundant "Axis" in name
|
||
values:
|
||
Undefined:
|
||
doc: will fall through to idle
|
||
Idle:
|
||
brief: Disable motor PWM and do nothing.
|
||
StartupSequence:
|
||
brief: Run the startup procedure.
|
||
doc: the actual sequence is defined by the `config`.startup... flags
|
||
FullCalibrationSequence:
|
||
doc: Run motor calibration and then encoder offset calibration (or encoder
|
||
index search if `<axis>.encoder.config.use_index` is `True`).
|
||
MotorCalibration:
|
||
brief: Measure phase resistance and phase inductance of the motor.
|
||
doc: |
|
||
* To store the results set `motor.config.pre_calibrated` to `True`
|
||
and save the configuration (`save_configuration()`). After that you
|
||
don't have to run the motor calibration on the next start up.
|
||
* This modifies the variables `motor.config.phase_resistance` and
|
||
`motor.config.phase_inductance`.
|
||
EncoderIndexSearch:
|
||
brief: Turn the motor in one direction until the encoder index is traversed.
|
||
doc: This state can only be entered if `encoder.config.use_index` is `True`.
|
||
value: 6
|
||
EncoderOffsetCalibration:
|
||
brief: Turn the motor in one direction for a few seconds and then back to measure the offset between the encoder position and the electrical phase.
|
||
doc: |
|
||
* Can only be entered if the motor is calibrated (`motor.is_calibrated`).
|
||
* A successful encoder calibration will make the `encoder.is_ready`
|
||
go to true.
|
||
ClosedLoopControl:
|
||
brief: Run closed loop control.
|
||
doc: |
|
||
* The action depends on the `controller.config.control_mode`.
|
||
* Can only be entered if the motor is calibrated
|
||
(`motor.is_calibrated`) and the encoder is ready (`encoder.is_ready`).
|
||
LockinSpin:
|
||
brief: Run lockin spin.
|
||
doc: |
|
||
Can only be entered if the motor is calibrated (`motor.is_calibrated`)
|
||
or the motor direction is unspecified (`motor.config.direction` == 1)
|
||
EncoderDirFind:
|
||
brief: Run encoder direction search.
|
||
doc: |
|
||
Can only be entered if the motor is calibrated (`motor.is_calibrated`).
|
||
Homing:
|
||
brief: Run axis homing function.
|
||
doc:
|
||
Endstops must be enabled to use this feature.
|
||
EncoderHallPolarityCalibration:
|
||
brief: Rotate the motor in lockin and calibrate hall polarity
|
||
doc:
|
||
ODrive assumes 120 degree electrical hall spacing. This routine determines if that
|
||
is the case and sets the polarity if the halls are on 60 degree electrical spacing
|
||
EncoderHallOffsetCalibration:
|
||
brief: Rotate the motor for 30s to calibrate hall sensor edge offsets
|
||
doc:
|
||
The phase offset is not calibrated at this time, so the map is only relative
|
||
|
||
ODrive.Encoder.Mode:
|
||
values:
|
||
Incremental:
|
||
Hall:
|
||
Sincos:
|
||
SpiAbsCui:
|
||
value: 0x100
|
||
doc: compatible with CUI AMT23xx
|
||
SpiAbsAms:
|
||
value: 0x101
|
||
doc: compatible with AMS AS5047P, AS5048A/AS5048B (no daisy chain support)
|
||
SpiAbsAeat:
|
||
value: 0x102
|
||
doc: not yet implemented
|
||
SpiAbsRls:
|
||
value: 0x103
|
||
doc: RLS Encoders
|
||
|
||
ODrive.Controller.ControlMode:
|
||
values:
|
||
# Note: these should be sorted from lowest level of control to
|
||
# highest level of control, to allow "<" style comparisons.
|
||
VoltageControl:
|
||
doc: this one is not normally used
|
||
TorqueControl:
|
||
VelocityControl:
|
||
PositionControl:
|
||
|
||
ODrive.Controller.InputMode:
|
||
values:
|
||
Inactive:
|
||
brief: Disable inputs. Setpoints retain their last value.
|
||
Passthrough:
|
||
brief: Pass `input_xxx` through to `xxx_setpoint` directly.
|
||
doc: |
|
||
### Valid Inputs:
|
||
* `input_pos`
|
||
* `input_vel`
|
||
* `input_current`
|
||
|
||
### Valid Control modes:
|
||
* `CONTROL_MODE_VOLTAGE_CONTROL`
|
||
* `CONTROL_MODE_TORQUE_CONTROL`
|
||
* `CONTROL_MODE_VELOCITY_CONTROL`
|
||
* `CONTROL_MODE_POSITION_CONTROL`
|
||
VelRamp:
|
||
brief: Ramps a velocity command from the current value to the target value.
|
||
doc: |
|
||
### Configuration Values:
|
||
* `config.vel_ramp_rate` [turn/sec]
|
||
* `config.inertia` [Nm/(turn/s^2))]
|
||
|
||
### Valid inputs:
|
||
* `input_vel`
|
||
|
||
### Valid Control Modes:
|
||
* `CONTROL_MODE_VELOCITY_CONTROL`
|
||
PosFilter:
|
||
brief: Implements a 2nd order position tracking filter.
|
||
doc: |
|
||
Intended for use with step/dir interface, but can also be used with
|
||
position-only commands.
|
||
|
||

|
||
Result of a step command from 1000 to 0
|
||
|
||
### Configuration Values:
|
||
* `config.input_filter_bandwidth`
|
||
* `config.inertia`
|
||
|
||
### Valid inputs:
|
||
* `input_pos`
|
||
|
||
### Valid Control modes:
|
||
* `CONTROL_MODE_POSITION_CONTROL`
|
||
MixChannels:
|
||
brief: Not Implemented.
|
||
TrapTraj:
|
||
brief: Implementes an online trapezoidal trajectory planner.
|
||
doc: |
|
||

|
||
|
||
### Configuration Values:
|
||
* `trap_traj.config.vel_limit`
|
||
* `trap_traj.config.accel_limit`
|
||
* `trap_traj.config.decel_limit`
|
||
* `config.inertia`
|
||
|
||
### Valid Inputs:
|
||
* `input_pos`
|
||
|
||
### Valid Control Modes:
|
||
* `CONTROL_MODE_POSITION_CONTROL`
|
||
TorqueRamp:
|
||
brief: Ramp a torque command from the current value to the target value.
|
||
doc: |
|
||
### Configuration Values:
|
||
* `config.torque_ramp_rate`
|
||
|
||
### Valid Inputs:
|
||
* `input_current`
|
||
|
||
### Valid Control Modes:
|
||
* `CONTROL_MODE_TORQUE_CONTROL`
|
||
Mirror:
|
||
brief: Implements "electronic mirroring".
|
||
doc: |
|
||
This is like electronic camming, but you can only mirror exactly the
|
||
movements of the other motor, according to a fixed ratio.
|
||
|
||
[](http://www.youtube.com/watch?v=D4_vBtyVVzM "Example Mirroring Video")
|
||
|
||
### Configuration Values
|
||
* `config.axis_to_mirror`
|
||
* `config.mirror_ratio`
|
||
|
||
### Valid Inputs
|
||
* None. Inputs are taken directly from the other axis encoder estimates
|
||
|
||
### Valid Control modes
|
||
* `CONTROL_MODE_POSITION_CONTROL`
|
||
|
||
ODrive.Motor.MotorType:
|
||
values:
|
||
HighCurrent:
|
||
#LowCurrent: # not implemented
|
||
Gimbal: {value: 2}
|
||
Acim:
|