diff --git a/.gitignore b/.gitignore index e536966d..7bc68002 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,4 @@ GUI/node_modules GUI/build docs/reStructuredText/_build/ +tools/odrive-cansimple.ini diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8ae5eb..3bc5d741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,42 @@ -# Unreleased Features -Please add a note of your changes below this heading if you make a Pull Request. -# Releases +## [0.5.6] - Unreleased + +### Fixed + +* Fixed race condition in homing sequence that was causing strange behaviour. Fixes [#634](https://github.com/odriverobotics/ODrive/issues/634)] +* When using a load encoder, CAN will report the correct position and velocity. +* When using a load encoder, homing will reset the correct linear position. Fixes [#651](https://github.com/odriverobotics/ODrive/issues/651) +* Implemented CAN controller error message, which was previously defined but not actually implemented. +* Get Vbus Voltage message updated to match ODrive Pro's CANSimple implementation. +* `vel_setpoint` and `torque_setpoint` will be clamped to `vel_limit` and the active torque limit. Fixes [#647](https://github.com/odriverobotics/ODrive/issues/647) + +### Added + +* Added public `controller.get_anticogging_value(uint32)` fibre function to index into the the cogging map. Fixes [#690](https://github.com/odriverobotics/ODrive/issues/690) +* Added Get ADC Voltage message to CAN (0x1C). Send the desired GPIO number in byte 1, and the ODrive will respond with the ADC voltage from that pin (if previously configured for analog) +* Added CAN heartbeat message flags for motor, controller, and encoder error. If flag is true, fetch the corresponding error with the respective message. +* Added scoped enums, e.g. `CONTROL_MODE_POSITION_CONTROL` can be used as `ControlMode.POSITION_CONTROL` +* Added more cyclic messages to can. Use the `rate_ms` values in `..config.can` to set the cycle rate of the message in milliseconds. Set a rate to 0 to disable sending. The following variables are avaialble: + +Command ID | Rate Variable | Message Name +:-- | :-- | :-- + 0x01 | `heartbeat_rate_ms` | Heartbeat + 0x09 | `encoder_rate_ms` | Get Encoder Estimates + 0x03 | `motor_error_rate_ms` | Get Motor Error + 0x04 | `encoder_error_rate_ms` | Get Encoder Error + 0x1D | `controller_error_rate_ms` | Get Controller Error + 0x05 | `sensorless_error_rate_ms` | Get Sensorless Error + 0x0A | `encoder_count_rate_ms` | Get Encoder Count + 0x14 | `iq_rate_ms` | Get Iq + 0x15 | `sensorless_rate_ms` | Get Sensorless Estimates + 0x17 | `bus_vi_rate_ms` | Get Bus Voltage Current + +### Changed + +* Improved can_generate_dbc.py file and resultant .dbc. Now supports 8 ODrive axes (0..7) natively +* Add units and value tables to every signal in odrive-cansimple.dbc +* Autogenerate odrive-cansimple.dbc on compile + ## [0.5.5] - 2022-08-11 * CANSimple messages which previously required the rtr bit to be set will now also respond if DLC = 0 diff --git a/Firmware/Makefile b/Firmware/Makefile index 0f09b14c..4dc1ff90 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -33,6 +33,7 @@ all: @tup --quiet -no-environ-check @$(PY_CMD) interface_generator_stub.py --definitions odrive-interface.yaml --template ../tools/enums_template.j2 --output ../tools/odrive/enums.py @$(PY_CMD) interface_generator_stub.py --definitions odrive-interface.yaml --template ../tools/arduino_enums_template.j2 --output ../Arduino/ODriveArduino/ODriveEnums.h + @cd ../tools/ && $(PY_CMD) create_can_dbc.py # Copy libfibre files to odrivetool if they were built @ ! test -f "fibre-cpp/build/libfibre-linux-amd64.so" || cp fibre-cpp/build/libfibre-linux-amd64.so ../tools/odrive/pyfibre/fibre/ diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index f11a9878..03735ce0 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -354,9 +354,6 @@ bool Axis::run_closed_loop_control_loop() { // Slowly drive in the negative direction at homing_speed until the min endstop is pressed // When pressed, set the linear count to the offset (default 0), and then go to position 0 bool Axis::run_homing() { - Controller::ControlMode stored_control_mode = controller_.config_.control_mode; - Controller::InputMode stored_input_mode = controller_.config_.input_mode; - // TODO: theoretically this check should be inside the update loop, // otherwise someone could disable the endstop while homing is in progress. if (!min_endstop_.config_.enabled) { @@ -424,13 +421,20 @@ bool Axis::run_homing() { return false; } - // Set the current position to 0. - encoder_.set_linear_count(0); - controller_.input_pos_ = 0; + // Set the current position to 0, the target to zero, and make sure we're path planning from 0 to 0 + encoder_.set_linear_count(0); + const auto load_encoder_axis = controller_.config_.load_encoder_axis; + if(load_encoder_axis != axis_num_ && load_encoder_axis < AXIS_COUNT) { + axes[load_encoder_axis].encoder_.set_linear_count(0); + } + controller_.input_pos_ = 0.0f; + controller_.pos_setpoint_ = 0.0f; + controller_.vel_setpoint_ = 0.0f; controller_.input_pos_updated(); - controller_.config_.control_mode = stored_control_mode; - controller_.config_.input_mode = stored_input_mode; + // Force encoder estimate to update + osDelay(1); + homing_.is_homed = true; return check_for_errors(); @@ -540,9 +544,13 @@ void Axis::run_state_machine_loop() { } break; case AXIS_STATE_HOMING: { - //if (odrv.any_error()) - // goto invalid_state_label; + Controller::ControlMode stored_control_mode = controller_.config_.control_mode; + Controller::InputMode stored_input_mode = controller_.config_.input_mode; + status = run_homing(); + + controller_.config_.control_mode = stored_control_mode; + controller_.config_.input_mode = stored_input_mode; } break; case AXIS_STATE_ENCODER_OFFSET_CALIBRATION: { diff --git a/Firmware/MotorControl/axis.hpp b/Firmware/MotorControl/axis.hpp index 14f05a63..1bfd58d9 100644 --- a/Firmware/MotorControl/axis.hpp +++ b/Firmware/MotorControl/axis.hpp @@ -56,6 +56,14 @@ public: bool is_extended = false; uint32_t heartbeat_rate_ms = 100; uint32_t encoder_rate_ms = 10; + uint32_t motor_error_rate_ms = 0; + uint32_t encoder_error_rate_ms = 0; + uint32_t controller_error_rate_ms = 0; + uint32_t sensorless_error_rate_ms = 0; + uint32_t encoder_count_rate_ms = 0; + uint32_t iq_rate_ms = 0; + uint32_t sensorless_rate_ms = 0; + uint32_t bus_vi_rate_ms = 0; }; struct Config_t { @@ -101,6 +109,14 @@ public: struct CAN_t { uint32_t last_heartbeat = 0; uint32_t last_encoder = 0; + uint32_t last_motor_error = 0; + uint32_t last_encoder_error = 0; + uint32_t last_controller_error = 0; + uint32_t last_sensorless_error = 0; + uint32_t last_encoder_count = 0; + uint32_t last_iq = 0; + uint32_t last_sensorless = 0; + uint32_t last_bus_vi = 0; }; Axis(int axis_num, diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index 4cf2700c..11c85b45 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -1,6 +1,7 @@ #include "odrive_main.h" #include +#include bool Controller::apply_config() { config_.parent = this; @@ -53,6 +54,20 @@ void Controller::start_anticogging_calibration() { } } +float Controller::remove_anticogging_bias() +{ + auto& cogmap = config_.anticogging.cogging_map; + + auto sum = std::accumulate(std::begin(cogmap), std::end(cogmap), 0.0f); + auto average = sum / std::size(cogmap); + + for(auto& val : cogmap) { + val -= average; + } + + return average; +} + /* * This anti-cogging implementation iterates through each encoder position, @@ -267,6 +282,13 @@ bool Controller::update() { } + // Never command a setpoint beyond its limit + if(config_.enable_vel_limit) { + vel_setpoint_ = std::clamp(vel_setpoint_, -config_.vel_limit, config_.vel_limit); + } + const float Tlim = axis_->motor_.max_available_torque(); + torque_setpoint_ = std::clamp(torque_setpoint_, -Tlim, Tlim); + // Position control // TODO Decide if we want to use encoder or pll position here float gain_scheduling_multiplier = 1.0f; @@ -373,7 +395,6 @@ bool Controller::update() { // Torque limiting bool limited = false; - float Tlim = axis_->motor_.max_available_torque(); if (torque > Tlim) { limited = true; torque = Tlim; diff --git a/Firmware/MotorControl/controller.hpp b/Firmware/MotorControl/controller.hpp index 2fc54861..2b78d6c5 100644 --- a/Firmware/MotorControl/controller.hpp +++ b/Firmware/MotorControl/controller.hpp @@ -81,7 +81,12 @@ public: // TODO: make this more similar to other calibration loops void start_anticogging_calibration(); + float remove_anticogging_bias(); bool anticogging_calibration(float pos_estimate, float vel_estimate); + + float get_anticogging_value(uint32_t index) { + return (index < 3600) ? config_.anticogging.cogging_map[index] : 0.0f; + } void update_filter_gains(); bool update(); diff --git a/Firmware/MotorControl/endstop.hpp b/Firmware/MotorControl/endstop.hpp index 5126f55c..21a640c2 100644 --- a/Firmware/MotorControl/endstop.hpp +++ b/Firmware/MotorControl/endstop.hpp @@ -18,7 +18,6 @@ class Endstop { void set_debounce_ms(uint32_t value) { debounce_ms = value; parent->apply_config(); } }; - Endstop() {} Endstop::Config_t config_; Axis* axis_ = nullptr; diff --git a/Firmware/Tupfile.lua b/Firmware/Tupfile.lua index f3f28c31..4158616c 100644 --- a/Firmware/Tupfile.lua +++ b/Firmware/Tupfile.lua @@ -328,9 +328,16 @@ boards = { -- Toolchain setup ------------------------------------------------------------- -CC='arm-none-eabi-gcc -std=c99' -CXX='arm-none-eabi-g++ -std=c++17 -Wno-register' -LINKER='arm-none-eabi-g++' +CCPATH = tup.getconfig('ARM_COMPILER_PATH') +if CCPATH == "" then + CCPATH='' +else + CCPATH = CCPATH..'/' +end + +CC=CCPATH..'arm-none-eabi-gcc -std=c99' +CXX=CCPATH..'arm-none-eabi-g++ -std=c++17 -Wno-register' +LINKER=CCPATH..'arm-none-eabi-g++' -- C-specific flags CFLAGS += '-D__weak="__attribute__((weak))"' @@ -440,13 +447,13 @@ tup.frule{ outputs={'build/ODriveFirmware.elf', extra_outputs={'build/ODriveFirmware.map'}} } -- display the size -tup.frule{inputs={'build/ODriveFirmware.elf'}, command='arm-none-eabi-size %f'} +tup.frule{inputs={'build/ODriveFirmware.elf'}, command=CCPATH..'arm-none-eabi-size %f'} -- create *.hex and *.bin output formats -tup.frule{inputs={'build/ODriveFirmware.elf'}, command='arm-none-eabi-objcopy -O ihex %f %o', outputs={'build/ODriveFirmware.hex'}} -tup.frule{inputs={'build/ODriveFirmware.elf'}, command='arm-none-eabi-objcopy -O binary -S %f %o', outputs={'build/ODriveFirmware.bin'}} +tup.frule{inputs={'build/ODriveFirmware.elf'}, command=CCPATH..'arm-none-eabi-objcopy -O ihex %f %o', outputs={'build/ODriveFirmware.hex'}} +tup.frule{inputs={'build/ODriveFirmware.elf'}, command=CCPATH..'arm-none-eabi-objcopy -O binary -S %f %o', outputs={'build/ODriveFirmware.bin'}} if tup.getconfig('ENABLE_DISASM') == 'true' then - tup.frule{inputs={'build/ODriveFirmware.elf'}, command='arm-none-eabi-objdump %f -dSC > %o', outputs={'build/ODriveFirmware.asm'}} + tup.frule{inputs={'build/ODriveFirmware.elf'}, command=CCPATH..'arm-none-eabi-objdump %f -dSC > %o', outputs={'build/ODriveFirmware.asm'}} end if tup.getconfig('DOCTEST') == 'true' then diff --git a/Firmware/communication/can/can_simple.cpp b/Firmware/communication/can/can_simple.cpp index 93b9f7bc..988c3c47 100644 --- a/Firmware/communication/can/can_simple.cpp +++ b/Firmware/communication/can/can_simple.cpp @@ -2,6 +2,7 @@ #include "can_simple.hpp" #include +#include bool CANSimple::init() { for (size_t i = 0; i < AXIS_COUNT; ++i) { @@ -135,9 +136,9 @@ void CANSimple::do_command(Axis& axis, const can_Message_t& msg) { case MSG_RESET_ODRIVE: NVIC_SystemReset(); break; - case MSG_GET_VBUS_VOLTAGE: + case MSG_GET_BUS_VOLTAGE_CURRENT: if (msg.rtr || msg.len == 0) - get_vbus_voltage_callback(axis); + get_bus_voltage_current_callback(axis); break; case MSG_CLEAR_ERRORS: clear_errors_callback(axis, msg); @@ -151,6 +152,12 @@ void CANSimple::do_command(Axis& axis, const can_Message_t& msg) { case MSG_SET_VEL_GAINS: set_vel_gains_callback(axis, msg); break; + case MSG_GET_ADC_VOLTAGE: + get_adc_voltage_callback(axis, msg); + break; + case MSG_GET_CONTROLLER_ERROR: + get_controller_error_callback(axis); + break; default: break; } @@ -200,6 +207,18 @@ bool CANSimple::get_sensorless_error_callback(const Axis& axis) { return canbus_->send_message(txmsg); } +bool CANSimple::get_controller_error_callback(const Axis& axis) { + can_Message_t txmsg; + txmsg.id = axis.config_.can.node_id << NUM_CMD_ID_BITS; + txmsg.id += MSG_GET_CONTROLLER_ERROR; // heartbeat ID + txmsg.isExt = axis.config_.can.is_extended; + txmsg.len = 8; + + can_setSignal(txmsg, axis.controller_.error_, 0, 32, true); + + return canbus_->send_message(txmsg); +} + void CANSimple::set_axis_nodeid_callback(Axis& axis, const can_Message_t& msg) { axis.config_.can.node_id = can_getSignal(msg, 0, 32, true); } @@ -219,8 +238,8 @@ bool CANSimple::get_encoder_estimates_callback(const Axis& axis) { txmsg.isExt = axis.config_.can.is_extended; txmsg.len = 8; - can_setSignal(txmsg, axis.encoder_.pos_estimate_.any().value_or(0.0f), 0, 32, true); - can_setSignal(txmsg, axis.encoder_.vel_estimate_.any().value_or(0.0f), 32, 32, true); + can_setSignal(txmsg, axis.controller_.pos_estimate_linear_src_.any().value_or(0.0f), 0, 32, true); + can_setSignal(txmsg, axis.controller_.vel_estimate_src_.any().value_or(0.0f), 32, 32, true); return canbus_->send_message(txmsg); } @@ -330,21 +349,40 @@ bool CANSimple::get_iq_callback(const Axis& axis) { return canbus_->send_message(txmsg); } -bool CANSimple::get_vbus_voltage_callback(const Axis& axis) { +bool CANSimple::get_bus_voltage_current_callback(const Axis& axis) { can_Message_t txmsg; txmsg.id = axis.config_.can.node_id << NUM_CMD_ID_BITS; - txmsg.id += MSG_GET_VBUS_VOLTAGE; + txmsg.id += MSG_GET_BUS_VOLTAGE_CURRENT; txmsg.isExt = axis.config_.can.is_extended; txmsg.len = 8; - uint32_t floatBytes; - static_assert(sizeof(vbus_voltage) == sizeof(floatBytes)); + static_assert(sizeof(float) == sizeof(vbus_voltage)); + static_assert(sizeof(float) == sizeof(ibus_)); can_setSignal(txmsg, vbus_voltage, 0, 32, true); + can_setSignal(txmsg, ibus_, 32, 32, true); return canbus_->send_message(txmsg); } +bool CANSimple::get_adc_voltage_callback(const Axis& axis, const can_Message_t& msg) { + can_Message_t txmsg; + + txmsg.id = axis.config_.can.node_id << NUM_CMD_ID_BITS; + txmsg.id += MSG_GET_ADC_VOLTAGE; + txmsg.isExt = axis.config_.can.is_extended; + txmsg.len = 8; + + auto gpio_num = can_getSignal(msg, 0, 8, true); + if (gpio_num < GPIO_COUNT) { + auto voltage = get_adc_voltage(get_gpio(gpio_num)); + can_setSignal(txmsg, voltage, 0, 32, true); + return canbus_->send_message(txmsg); + } else { + return false; + } +} + void CANSimple::clear_errors_callback(Axis& axis, const can_Message_t& msg) { odrv.clear_errors(); // TODO: might want to clear axis errors only } @@ -361,26 +399,38 @@ uint32_t CANSimple::service_stack() { } } - for (auto& a : axes) { - MEASURE_TIME(a.task_times_.can_heartbeat) { - if (a.config_.can.heartbeat_rate_ms > 0) { - if ((now - a.can_.last_heartbeat) >= a.config_.can.heartbeat_rate_ms) { - if (send_heartbeat(a)) - a.can_.last_heartbeat = now; + struct periodic { + const uint32_t& rate; + uint32_t& last_time; + bool (CANSimple::* callback)(const Axis& axis); + }; + + for (auto& axis : axes) { + std::array periodics = {{ + {axis.config_.can.heartbeat_rate_ms, axis.can_.last_heartbeat, &CANSimple::send_heartbeat}, + {axis.config_.can.encoder_rate_ms, axis.can_.last_encoder, &CANSimple::get_encoder_estimates_callback}, + {axis.config_.can.motor_error_rate_ms, axis.can_.last_motor_error, &CANSimple::get_motor_error_callback}, + {axis.config_.can.encoder_error_rate_ms, axis.can_.last_encoder_error, &CANSimple::get_encoder_error_callback}, + {axis.config_.can.controller_error_rate_ms, axis.can_.last_controller_error, &CANSimple::get_controller_error_callback}, + {axis.config_.can.sensorless_error_rate_ms, axis.can_.last_sensorless_error, &CANSimple::get_sensorless_error_callback}, + {axis.config_.can.encoder_count_rate_ms, axis.can_.last_encoder_count, &CANSimple::get_encoder_count_callback}, + {axis.config_.can.iq_rate_ms, axis.can_.last_iq, &CANSimple::get_iq_callback}, + {axis.config_.can.sensorless_rate_ms, axis.can_.last_sensorless, &CANSimple::get_sensorless_estimates_callback}, + {axis.config_.can.bus_vi_rate_ms, axis.can_.last_bus_vi, &CANSimple::get_bus_voltage_current_callback}, + }}; + + MEASURE_TIME(axis.task_times_.can_heartbeat) { + for (auto& msg : periodics) { + if (msg.rate > 0) { + if ((now - msg.last_time) >= msg.rate) { + if (std::invoke(msg.callback, this, axis)) { + msg.last_time = now; + } + } + + int nextAxisService = msg.last_time + msg.rate - now; + nextServiceTime = std::min(nextServiceTime, static_cast(std::max(0, nextAxisService))); } - - int nextAxisService = a.can_.last_heartbeat + a.config_.can.heartbeat_rate_ms - now; - nextServiceTime = std::min(nextServiceTime, static_cast(std::max(0, nextAxisService))); - } - - if (a.config_.can.encoder_rate_ms > 0) { - if ((now - a.can_.last_encoder) >= a.config_.can.encoder_rate_ms) { - if (get_encoder_estimates_callback(a)) - a.can_.last_encoder = now; - } - - int nextAxisService = a.can_.last_encoder + a.config_.can.encoder_rate_ms - now; - nextServiceTime = std::min(nextServiceTime, static_cast(std::max(0, nextAxisService))); } } } @@ -399,20 +449,19 @@ bool CANSimple::send_heartbeat(const Axis& axis) { can_setSignal(txmsg, uint8_t(axis.current_state_), 32, 8, true); // Motor flags - uint8_t motorFlags = 0; // reserved + uint8_t motorFlags = axis.motor_.error_ != 0; // Encoder flags - uint8_t encoderFlags = 0; // reserved + uint8_t encoderFlags = axis.encoder_.error_ != 0; // Controller flags - uint8_t controllerFlags = 0; + uint8_t controllerFlags =axis.controller_.error_ != 0; uint8_t trajDone = uint8_t(axis.controller_.trajectory_done_) << 7; controllerFlags |= trajDone; can_setSignal(txmsg, motorFlags, 40, 8, true); can_setSignal(txmsg, encoderFlags, 48, 8, true); can_setSignal(txmsg, controllerFlags, 56, 8, true); - // can_setSignal(txmsg, axis.current_state_, 32, 32, true); return canbus_->send_message(txmsg); } diff --git a/Firmware/communication/can/can_simple.hpp b/Firmware/communication/can/can_simple.hpp index 83cd0551..58b6982a 100644 --- a/Firmware/communication/can/can_simple.hpp +++ b/Firmware/communication/can/can_simple.hpp @@ -30,11 +30,13 @@ class CANSimple { MSG_GET_IQ, MSG_GET_SENSORLESS_ESTIMATES, MSG_RESET_ODRIVE, - MSG_GET_VBUS_VOLTAGE, + MSG_GET_BUS_VOLTAGE_CURRENT, MSG_CLEAR_ERRORS, MSG_SET_LINEAR_COUNT, MSG_SET_POS_GAIN, MSG_SET_VEL_GAINS, + MSG_GET_ADC_VOLTAGE, + MSG_GET_CONTROLLER_ERROR, MSG_CO_HEARTBEAT_CMD = 0x700, // CANOpen NMT Heartbeat SEND }; @@ -61,7 +63,9 @@ class CANSimple { bool get_encoder_count_callback(const Axis& axis); bool get_iq_callback(const Axis& axis); bool get_sensorless_estimates_callback(const Axis& axis); - bool get_vbus_voltage_callback(const Axis& axis); + bool get_bus_voltage_current_callback(const Axis& axis); + // msg.rtr bit must NOT be set + bool get_adc_voltage_callback(const Axis& axis, const can_Message_t& msg); // Set functions static void set_axis_nodeid_callback(Axis& axis, const can_Message_t& msg); @@ -106,4 +110,4 @@ class CANSimple { bool extended_node_ids_[AXIS_COUNT]; }; -#endif \ No newline at end of file +#endif diff --git a/Firmware/odrive-interface.yaml b/Firmware/odrive-interface.yaml index 77b997fe..34cb09d0 100644 --- a/Firmware/odrive-interface.yaml +++ b/Firmware/odrive-interface.yaml @@ -600,6 +600,14 @@ interfaces: is_extended: bool heartbeat_rate_ms: uint32 encoder_rate_ms: uint32 + motor_error_rate_ms: uint32 + encoder_error_rate_ms: uint32 + controller_error_rate_ms: uint32 + sensorless_error_rate_ms: uint32 + encoder_count_rate_ms: uint32 + iq_rate_ms: uint32 + sensorless_rate_ms: uint32 + bus_vi_rate_ms: uint32 ODrive.ThermistorCurrentLimiter: c_is_class: False @@ -1188,6 +1196,8 @@ interfaces: usually corresponds roughly to the current position of the axis.' } start_anticogging_calibration: + remove_anticogging_bias: {out: {val: float32}} + get_anticogging_value: {in: {index: uint32}, out: {val: float32}} ODrive.Encoder: diff --git a/Firmware/tup.config.default b/Firmware/tup.config.default index a4deb780..0ac01bd5 100644 --- a/Firmware/tup.config.default +++ b/Firmware/tup.config.default @@ -1,9 +1,12 @@ # Copy this file to tup.config and adapt it to your needs # make sure this fits your board -#CONFIG_BOARD_VERSION=v3.5-24V +#CONFIG_BOARD_VERSION=v3.6-56V CONFIG_DEBUG=false CONFIG_DOCTEST=false CONFIG_USE_LTO=false +# Path to the ARM compiler /bin folder (optional) +#CONFIG_ARM_COMPILER_PATH=C:/Tools/ARM/9-2019-q4-major/bin + # Uncomment this to error on compilation warnings #CONFIG_STRICT=true diff --git a/GUI/package-lock.json b/GUI/package-lock.json index 0d180081..e9530aab 100644 --- a/GUI/package-lock.json +++ b/GUI/package-lock.json @@ -3193,24 +3193,6 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "node_modules/app-builder-lib/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/app-builder-lib/node_modules/ejs": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", @@ -4289,24 +4271,6 @@ "node": ">=8.2.5" } }, - "node_modules/builder-util-runtime/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/builder-util/node_modules/ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -4363,24 +4327,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/builder-util/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/builder-util/node_modules/fs-extra": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", @@ -10598,15 +10544,15 @@ } }, "node_modules/jszip": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", - "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" + "setimmediate": "^1.0.5" } }, "node_modules/kew": { @@ -14512,15 +14458,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "node_modules/set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -21368,15 +21305,6 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "ejs": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", @@ -22293,15 +22221,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "fs-extra": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", @@ -22364,17 +22283,6 @@ "requires": { "debug": "^4.2.0", "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } } }, "builtin-status-codes": { @@ -27317,15 +27225,15 @@ } }, "jszip": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", - "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, "requires": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" + "setimmediate": "^1.0.5" } }, "kew": { @@ -30601,12 +30509,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", diff --git a/docs/analog-input.rst b/docs/analog-input.rst index 7df9b6df..21ad4bc8 100644 --- a/docs/analog-input.rst +++ b/docs/analog-input.rst @@ -10,3 +10,5 @@ To read the voltage on GPIO1 in odrivetool the following would be entered: :code Similar to RC PWM input, analog inputs can also be used to feed any of the numerical properties that are visible in :code:`odrivetool`. This is done by configuring :code:`odrv0.config.gpio3_analog_mapping` and :code:`odrv0.config.gpio4_analog_mapping`. Refer to :ref:`RC PWM ` for instructions on how to configure the mappings. + +You may also retrieve voltage measurements from analog inputs via the CAN protocol by sending the Get ADC Voltage message with the GPIO number of the analog input you wish to read. Refer to :ref: `CAN Protocol ` for guidance on how to use the CAN Protocol. \ No newline at end of file diff --git a/docs/can-protocol.rst b/docs/can-protocol.rst index 128228c9..5870c8c4 100644 --- a/docs/can-protocol.rst +++ b/docs/can-protocol.rst @@ -74,6 +74,7 @@ All multibyte values are little endian (aka Intel format, aka least significant * These messages are call & response. The Master node sends a message with the RTR bit set, and the axis responds with the same ID and specified payload. * These CANOpen messages are reserved to avoid bus collisions with CANOpen devices. They are not used by CAN Simple. * These messages can be sent to either address on a given ODrive board. + * You must send a valid GPIO pin number in the first byte to recieve coreect ADC voltage feedback. Since you're both sending and receiving data the RTR bit must be set to false. Cyclic Messages @@ -82,24 +83,73 @@ Cyclic Messages Cyclic messages are sent by ODrive on a timer without a request. As of firmware verion `0.5.4`, the Cyclic messsages are: .. list-table:: - :widths: 25 25 50 + :widths: 25 25 25 50 :header-rows: 1 * - ID - Name - - Rate (ms) - * - 0x001 - - ODrive Heartbeat Message + - Config Variable + - Default Rate (ms) + * - 0x01 + - Heartbeat + - `heartbeat_rate_ms` - 100 - * - 0x009 - - Encoder Estimates + * - 0x09 + - Get Encoder Estimates + - `encoder_rate_ms` - 10 + * - 0x03 + - Get Motor Error + - `motor_error_rate_ms` + - 0 + * - 0x04 + - Get Encoder Error + - `encoder_error_rate_ms` + - 0 + * - 0x1D + - Get Controller Error + - `controller_error_rate_ms` + - 0 + * - 0x05 + - Get Sensorless Error + - `sensorless_error_rate_ms` + - 0 + * - 0x0A + - Get Encoder Count + - `encoder_count_rate_ms` + - 0 + * - 0x14 + - Get Iq + - `iq_rate_ms` + - 0 + * - 0x15 + - Get Sensorless Estimates + - `sensorless_rate_ms` + - 0 + * - 0x17 + - Get Bus Voltage Current + - `bus_vi_rate_ms` + - 0 + .. ID | Name | Rate (ms) .. --: | :-- | :-- .. 0x001 | ODrive Heartbeat Message | 100 .. 0x009 | Encoder Estimates | 10 +.. Command ID | Message Name +.. :-- | :-- | :-- + .. 0x01 | `heartbeat_rate_ms` | Heartbeat + .. 0x09 | `encoder_rate_ms` | Get Encoder Estimates + .. 0x03 | `motor_error_rate_ms` | Get Motor Error + .. 0x04 | `encoder_error_rate_ms` | Get Encoder Error + .. 0x1D | `controller_error_rate_ms` | Get Controller Error + .. 0x05 | `sensorless_error_rate_ms` | Get Sensorless Error + .. 0x0A | `encoder_count_rate_ms` | Get Encoder Count + .. 0x14 | `iq_rate_ms` | Get Iq + .. 0x15 | `sensorless_rate_ms` | Get Sensorless Estimates + .. 0x17 | `bus_vi_rate_ms` | Get Bus Voltage Current + These can be configured for each axis, see e.g. :code:`axis.config.can`. diff --git a/docs/figures/can-protocol.csv b/docs/figures/can-protocol.csv index f00da301..6104c5b6 100644 --- a/docs/figures/can-protocol.csv +++ b/docs/figures/can-protocol.csv @@ -2,16 +2,34 @@ CMD ID,Name,Sender,Signals,Start byte,Signal Type,Bits,Factor,Offset 0x000,CANOpen NMT Message**,Master,-,-,-,-,-,- 0x001,ODrive Heartbeat Message,Axis,"Axis Error Axis Current State -Controller Status","0 +Motor Error Flag +Encoder Error Flag +Controller Error Flag +Trajectory Done Flag","0 4 -7","Unsigned Int +5.0 +6.0 +7.0 +7.7","Unsigned Int Unsigned Int -Bitfield","32 +Unsigned Int +Unsigned Int +Unsigned Int +Unsigned Int","32 8 -8","- +1 +1 +1 +1","- +- +- +- - -","- - +- +- +- -" 0x002,ODrive Estop Message,Master,-,-,-,-,-,- 0x003,Get Motor Error*,Axis,Motor Error,0,Unsigned Int,64,1,0 @@ -93,7 +111,13 @@ IEEE 754 Float","32 1","0 0" 0x016,Reboot ODrive,Master***,-,-,-,-,-,- -0x017,Get Vbus Voltage,Master***,Vbus Voltage,0,IEEE 754 Float,32,1,0 +0x017,Get Bus Voltage and Current,Master***,"Bus Voltage +Bus Current","0 +4","IEEE 754 Float +IEEE 754 Float","32 +32","1 +1","0 +0" 0x018,Clear Errors,Master,-,-,-,-,-,- 0x019,Set Linear Count,Master,Position,0,Signed Int,32,1,0 0x01A,Set Position Gain,Master,Pos Gain,0,IEEE 754 Float,32,1,0 @@ -104,4 +128,6 @@ IEEE 754 Float","32 32","1 1","0 0" +0x01C,Get ADC Voltage****,Master***,ADC Voltage,0,IEEE 754 Float,32,1,0 +0x01D,Get Controller Error*,Axis,Controller Error,0,Unsigned Int,32,1,0 0x700,CANOpen Heartbeat Message**,Slave,-,-,-,-,-,- \ No newline at end of file diff --git a/tools/create_can_dbc.py b/tools/create_can_dbc.py index ccc0f5b5..0336e305 100644 --- a/tools/create_can_dbc.py +++ b/tools/create_can_dbc.py @@ -1,166 +1,184 @@ -import cantools +from cantools.database import * +from odrive.enums import * -# 0x00 - NMT Message (Reserved) +msgList = [] +nodes = [can.Node('Master')] +buses = [can.Bus('ODrive', None, 100000)] -# 0x001 - Heartbeat -axisError = cantools.database.can.Signal("Axis_Error", 0, 32) -axisState = cantools.database.can.Signal("Axis_State", 32, 8) -motorFlags = cantools.database.can.Signal("Motor_Flags", 40, 8) -encoderFlags = cantools.database.can.Signal("Encoder_Flags", 48, 8) -controllerFlags = cantools.database.can.Signal("Controller_Flags", 56, 8) +for axisID in range(0, 8): + newNode = can.Node(f"ODrive_Axis{axisID}") + nodes.append(newNode) -heartbeatMsg = cantools.database.can.Message( - 0x001, "Heartbeat", 8, [axisError, axisState, motorFlags, encoderFlags, controllerFlags] -) + # 0x00 - NMT Message (Reserved) -# 0x002 - E-Stop Message -estopMsg = cantools.database.can.Message(0x002, "Estop", 0, []) + # 0x001 - Heartbeat + axisError = can.Signal("Axis_Error", 0, 32, receivers=['Master'], choices={error.value: error.name for error in AxisError}) + axisState = can.Signal("Axis_State", 32, 8, receivers=['Master'], choices={state.value: state.name for state in AxisState}) + motorErrorFlag = can.Signal("Motor_Error_Flag", 40, 1, receivers=['Master']) + encoderErrorFlag = can.Signal("Encoder_Error_Flag", 48, 1, receivers=['Master']) + controllerErrorFlag = can.Signal("Controller_Error_Flag", 56, 1, receivers=['Master']) + trajectoryDoneFlag = can.Signal("Trajectory_Done_Flag", 63, 1, receivers=['Master']) -# 0x003 - Motor Error -motorError = cantools.database.can.Signal("Motor_Error", 0, 32) -motorErrorMsg = cantools.database.can.Message(0x003, "Get_Motor_Error", 8, [motorError]) + heartbeatMsg = can.Message( + 0x001, "Heartbeat", 8, + [ + axisError, + axisState, + motorErrorFlag, + encoderErrorFlag, + controllerErrorFlag, + trajectoryDoneFlag + ], send_type='cyclic', cycle_time=100, senders=[newNode.name] + ) -# 0x004 - Encoder Error -encoderError = cantools.database.can.Signal("Encoder_Error", 0, 32) -encoderErrorMsg = cantools.database.can.Message( - 0x004, "Get_Encoder_Error", 8, [encoderError] -) + # 0x002 - E-Stop Message + estopMsg = can.Message(0x002, "Estop", 0, [], senders=['Master']) -# 0x005 - Sensorless Error -sensorlessError = cantools.database.can.Signal("Sensorless_Error", 0, 32) -sensorlessErrorMsg = cantools.database.can.Message( - 0x005, "Get_Sensorless_Error", 8, [sensorlessError] -) + # 0x003 - Motor Error + motorError = can.Signal("Motor_Error", 0, 32, receivers=['Master'], choices={error.value: error.name for error in MotorError}) + motorErrorMsg = can.Message(0x003, "Get_Motor_Error", 8, [motorError], senders=[newNode.name]) -# 0x006 - Axis Node ID -axisNodeID = cantools.database.can.Signal("Axis_Node_ID", 0, 32) -axisNodeMsg = cantools.database.can.Message(0x006, "Set_Axis_Node_ID", 8, [axisNodeID]) + # 0x004 - Encoder Error + encoderError = can.Signal("Encoder_Error", 0, 32, receivers=['Master'], choices={error.value: error.name for error in EncoderError}) + encoderErrorMsg = can.Message( + 0x004, "Get_Encoder_Error", 8, [encoderError], senders=[newNode.name] + ) -# 0x007 - Requested State -axisRequestedState = cantools.database.can.Signal("Axis_Requested_State", 0, 32) -setAxisState = cantools.database.can.Message( - 0x007, "Set_Axis_State", 8, [axisRequestedState] -) + # 0x005 - Sensorless Error + sensorlessError = can.Signal("Sensorless_Error", 0, 32, receivers=['Master'], choices={error.value: error.name for error in SensorlessEstimatorError}) + sensorlessErrorMsg = can.Message( + 0x005, "Get_Sensorless_Error", 8, [sensorlessError], senders=[newNode.name] + ) -# 0x008 - Startup Config (Reserved) + # 0x006 - Axis Node ID + axisNodeID = can.Signal("Axis_Node_ID", 0, 32, receivers=[newNode.name]) + axisNodeMsg = can.Message(0x006, "Set_Axis_Node_ID", 8, [axisNodeID], senders=['Master']) -# 0x009 - Encoder Estimates -encoderPosEstimate = cantools.database.can.Signal("Pos_Estimate", 0, 32, is_float=True) -encoderVelEstimate = cantools.database.can.Signal("Vel_Estimate", 32, 32, is_float=True) -encoderEstimates = cantools.database.can.Message( - 0x009, "Get_Encoder_Estimates", 8, [encoderPosEstimate, encoderVelEstimate] -) + # 0x007 - Requested State + axisRequestedState = can.Signal("Axis_Requested_State", 0, 32, receivers=[newNode.name], choices={state.value: state.name for state in AxisState}) + setAxisState = can.Message( + 0x007, "Set_Axis_State", 8, [axisRequestedState], senders=['Master'] + ) + # 0x008 - Startup Config (Reserved) -# 0x00A - Get Encoder Count -encoderShadowCount = cantools.database.can.Signal("Shadow_Count", 0, 32) -encoderCountInCPR = cantools.database.can.Signal("Count_in_CPR", 32, 32) -encoderCountMsg = cantools.database.can.Message( - 0x00A, "Get_Encoder_Count", 8, [encoderShadowCount, encoderCountInCPR] -) + # 0x009 - Encoder Estimates + encoderPosEstimate = can.Signal("Pos_Estimate", 0, 32, is_float=True, receivers=['Master'], unit='rev') + encoderVelEstimate = can.Signal("Vel_Estimate", 32, 32, is_float=True, receivers=['Master'], unit='rev/s') + encoderEstimates = can.Message( + 0x009, "Get_Encoder_Estimates", 8, [encoderPosEstimate, encoderVelEstimate], senders=[newNode.name], send_type='cyclic', cycle_time=10 + ) -# 0x00B - Set Controller Modes -controlMode = cantools.database.can.Signal("Control_Mode", 0, 32) -inputMode = cantools.database.can.Signal("Input_Mode", 32, 32) -setControllerModeMsg = cantools.database.can.Message( - 0x00B, "Set_Controller_Mode", 8, [controlMode, inputMode] -) + # 0x00A - Get Encoder Count + encoderShadowCount = can.Signal("Shadow_Count", 0, 32, receivers=['Master'], unit='counts') + encoderCountInCPR = can.Signal("Count_in_CPR", 32, 32, receivers=['Master'], unit='counts') + encoderCountMsg = can.Message( + 0x00A, "Get_Encoder_Count", 8, [encoderShadowCount, encoderCountInCPR], senders=[newNode.name] + ) -# 0x00C - Set Input Pos -inputPos = cantools.database.can.Signal("Input_Pos", 0, 32, is_float=True) -velFF = cantools.database.can.Signal("Vel_FF", 32, 16, is_signed=True, scale=0.001) -torqueFF = cantools.database.can.Signal( - "Torque_FF", 48, 16, is_signed=True, scale=0.001 -) -setInputPosMsg = cantools.database.can.Message( - 0x00C, "Set_Input_Pos", 8, [inputPos, velFF, torqueFF] -) + # 0x00B - Set Controller Modes + controlMode = can.Signal("Control_Mode", 0, 32, receivers=[newNode.name], choices={state.value: state.name for state in ControlMode}) + inputMode = can.Signal("Input_Mode", 32, 32, receivers=[newNode.name], choices={state.value: state.name for state in InputMode}) + setControllerModeMsg = can.Message( + 0x00B, "Set_Controller_Mode", 8, [controlMode, inputMode], senders=['Master'] + ) -# 0x00D - Set Input Vel -inputVel = cantools.database.can.Signal("Input_Vel", 0, 32, is_float=True) -inputTorqueFF = cantools.database.can.Signal("Input_Torque_FF", 32, 32, is_float=True) -setInputVelMsg = cantools.database.can.Message( - 0x00D, "Set_Input_Vel", 8, [inputVel, inputTorqueFF] -) + # 0x00C - Set Input Pos + inputPos = can.Signal("Input_Pos", 0, 32, is_float=True, receivers=[newNode.name], unit='rev') + velFF = can.Signal("Vel_FF", 32, 16, is_signed=True, scale=0.001, receivers=[newNode.name], unit='rev/s') + torqueFF = can.Signal("Torque_FF", 48, 16, is_signed=True, scale=0.001, receivers=[newNode.name], unit='Nm') + setInputPosMsg = can.Message( + 0x00C, "Set_Input_Pos", 8, [inputPos, velFF, torqueFF], senders=['Master'] + ) -# 0x00E - Set Input Torque -inputTorque = cantools.database.can.Signal("Input_Torque", 0, 32, is_float=True) -setInputTqMsg = cantools.database.can.Message( - 0x00E, "Set_Input_Torque", 8, [inputTorque] -) + # 0x00D - Set Input Vel + inputVel = can.Signal("Input_Vel", 0, 32, is_float=True, receivers=[newNode.name], unit='rev') + inputTorqueFF = can.Signal("Input_Torque_FF", 32, 32, is_float=True, receivers=[newNode.name], unit='rev/s') + setInputVelMsg = can.Message( + 0x00D, "Set_Input_Vel", 8, [inputVel, inputTorqueFF], senders=['Master'] + ) -# 0x00F - Set Velocity Limit -velLimit = cantools.database.can.Signal("Velocity_Limit", 0, 32, is_float=True) -currentLimit = cantools.database.can.Signal("Current_Limit", 32, 32, is_float=True) -setVelLimMsg = cantools.database.can.Message( - 0x00F, "Set_Limits", 8, [velLimit, currentLimit] -) + # 0x00E - Set Input Torque + inputTorque = can.Signal("Input_Torque", 0, 32, is_float=True, receivers=[newNode.name], unit='Nm') + setInputTqMsg = can.Message( + 0x00E, "Set_Input_Torque", 8, [inputTorque], senders=['Master'] + ) -# 0x010 - Start Anticogging -startAnticoggingMsg = cantools.database.can.Message(0x010, "Start_Anticogging", 0, []) + # 0x00F - Set Velocity Limit + velLimit = can.Signal("Velocity_Limit", 0, 32, is_float=True, receivers=[newNode.name], unit='rev/s') + currentLimit = can.Signal("Current_Limit", 32, 32, is_float=True, receivers=[newNode.name], unit='A') + setVelLimMsg = can.Message( + 0x00F, "Set_Limits", 8, [velLimit, currentLimit], senders=['Master'] + ) -# 0x011 - Set Traj Vel Limit -trajVelLim = cantools.database.can.Signal("Traj_Vel_Limit", 0, 32, is_float=True) -setTrajVelMsg = cantools.database.can.Message( - 0x011, "Set_Traj_Vel_Limit", 8, [trajVelLim] -) + # 0x010 - Start Anticogging + startAnticoggingMsg = can.Message(0x010, "Start_Anticogging", 0, [], senders=['Master']) -# 0x012 - Set Traj Accel Limits -trajAccelLim = cantools.database.can.Signal("Traj_Accel_Limit", 0, 32, is_float=True) -trajDecelLim = cantools.database.can.Signal("Traj_Decel_Limit", 32, 32, is_float=True) -setTrajAccelMsg = cantools.database.can.Message( - 0x012, "Set_Traj_Accel_Limits", 8, [trajAccelLim, trajDecelLim] -) + # 0x011 - Set Traj Vel Limit + trajVelLim = can.Signal("Traj_Vel_Limit", 0, 32, is_float=True, receivers=[newNode.name], unit='rev/s') + setTrajVelMsg = can.Message( + 0x011, "Set_Traj_Vel_Limit", 8, [trajVelLim], senders=['Master'] + ) -# 0x013 - Set Traj Inertia -trajInertia = cantools.database.can.Signal("Traj_Inertia", 0, 32, is_float=True) -trajInertiaMsg = cantools.database.can.Message( - 0x013, "Set_Traj_Inertia", 8, [trajInertia] -) + # 0x012 - Set Traj Accel Limits + trajAccelLim = can.Signal("Traj_Accel_Limit", 0, 32, is_float=True, receivers=[newNode.name], unit='rev/s^2') + trajDecelLim = can.Signal("Traj_Decel_Limit", 32, 32, is_float=True, receivers=[newNode.name], unit='rev/s^2') + setTrajAccelMsg = can.Message( + 0x012, "Set_Traj_Accel_Limits", 8, [trajAccelLim, trajDecelLim], senders=['Master'] + ) -# 0x014 - Get Iq -iqSetpoint = cantools.database.can.Signal("Iq_Setpoint", 0, 32, is_float=True) -iqMeasured = cantools.database.can.Signal("Iq_Measured", 32, 32, is_float=True) -getIqMsg = cantools.database.can.Message(0x014, "Get_Iq", 8, [iqSetpoint, iqMeasured]) + # 0x013 - Set Traj Inertia + trajInertia = can.Signal("Traj_Inertia", 0, 32, is_float=True, receivers=[newNode.name], unit='Nm / (rev/s^2)') + trajInertiaMsg = can.Message( + 0x013, "Set_Traj_Inertia", 8, [trajInertia], senders=['Master'] + ) -# 0x015 - Get Sensorless Estimates -sensorlessPosEstimate = cantools.database.can.Signal( - "Sensorless_Pos_Estimate", 0, 32, is_float=True -) -sensorlessVelEstimate = cantools.database.can.Signal( - "Sensorless_Vel_Estimate", 32, 32, is_float=True -) -getSensorlessEstMsg = cantools.database.can.Message( - 0x015, "Get_Sensorless_Estimates", 8, [sensorlessPosEstimate, sensorlessVelEstimate] -) + # 0x014 - Get Iq + iqSetpoint = can.Signal("Iq_Setpoint", 0, 32, is_float=True, receivers=['Master'], unit='A') + iqMeasured = can.Signal("Iq_Measured", 32, 32, is_float=True, receivers=['Master'], unit='A') + getIqMsg = can.Message(0x014, "Get_Iq", 8, [iqSetpoint, iqMeasured], senders=[newNode.name]) -# 0x016 - Reboot ODrive -rebootMsg = cantools.database.can.Message(0x016, "Reboot", 0, []) + # 0x015 - Get Sensorless Estimates + sensorlessPosEstimate = can.Signal("Sensorless_Pos_Estimate", 0, 32, is_float=True, receivers=['Master'], unit='rev') + sensorlessVelEstimate = can.Signal("Sensorless_Vel_Estimate", 32, 32, is_float=True, receivers=['Master'], unit='rev/s') + getSensorlessEstMsg = can.Message(0x015, "Get_Sensorless_Estimates", 8, [sensorlessPosEstimate, sensorlessVelEstimate], senders=[newNode.name]) -# 0x017 - Get vbus Voltage -vbusVoltage = cantools.database.can.Signal("Vbus_Voltage", 0, 32, is_float=True) -getVbusVMsg = cantools.database.can.Message(0x017, "Get_Vbus_Voltage", 8, [vbusVoltage]) + # 0x016 - Reboot ODrive + rebootMsg = can.Message(0x016, "Reboot", 0, [], senders=['Master']) -# 0x018 - Clear Errors -clearErrorsMsg = cantools.database.can.Message(0x018, "Clear_Errors", 0, []) + # 0x017 - Get vbus Voltage and Current + busVoltage = can.Signal("Bus_Voltage", 0, 32, is_float=True, receivers=['Master'], unit='V') + busCurrent = can.Signal("Bus_Current", 32, 32, is_float=True, receivers=['Master'], unit='A') + getVbusVCMsg = can.Message(0x017, "Get_Bus_Voltage_Current", 8, [busVoltage, busCurrent], senders=[newNode.name]) -# 0x019 - Set Linear Count -position = cantools.database.can.Signal("Position", 0, 32, is_signed=True) -setLinearCountMsg = cantools.database.can.Message(0x019, "Set_Linear_Count", 8, [position]) + # 0x018 - Clear Errors + clearErrorsMsg = can.Message(0x018, "Clear_Errors", 0, [], senders=['Master']) -# 0x01A - Set Pos gain -posGain = cantools.database.can.Signal("Pos_Gain", 0, 32, is_float=True) -setPosGainMsg = cantools.database.can.Message(0x01A, "Set_Pos_Gain", 8, [posGain]) + # 0x019 - Set Linear Count + position = can.Signal("Position", 0, 32, is_signed=True, receivers=[newNode.name], unit='counts') + setLinearCountMsg = can.Message(0x019, "Set_Linear_Count", 8, [position], senders=['Master']) -# 0x01B - Set Vel Gains -velGain = cantools.database.can.Signal("Vel_Gain", 0, 32, is_float=True) -velIntGain = cantools.database.can.Signal("Vel_Integrator_Gain", 32, 32, is_float=True) -setVelGainsMsg = cantools.database.can.Message(0x01B, "Set_Vel_gains", 8, [velGain, velIntGain]) + # 0x01A - Set Pos gain + posGain = can.Signal("Pos_Gain", 0, 32, is_float=True, receivers=[newNode.name], unit='(rev/s) / rev') + setPosGainMsg = can.Message(0x01A, "Set_Pos_Gain", 8, [posGain], senders=['Master']) -db = cantools.database.can.Database( - [ + # 0x01B - Set Vel Gains + velGain = can.Signal("Vel_Gain", 0, 32, is_float=True, receivers=[newNode.name], unit='Nm / (rev/s)') + velIntGain = can.Signal("Vel_Integrator_Gain", 32, 32, is_float=True, receivers=[newNode.name], unit='(Nm / (rev/s)) / s') + setVelGainsMsg = can.Message(0x01B, "Set_Vel_Gains", 8, [velGain, velIntGain], senders=['Master']) + + # 0x01C - Get ADC Voltage + adcVoltage = can.Signal("ADC_Voltage", 0, 32, is_float=True, receivers=['Master'], unit='V') + getADCVoltageMsg = can.Message(0x01C, "Get_ADC_Voltage", 8, [adcVoltage], senders=[newNode.name]) + + # 0x01D - Controller Error + controllerError = can.Signal("Controller_Error", 0, 32, receivers=['Master'], choices={error.value: error.name for error in ControllerError}) + controllerErrorMsg = can.Message( + 0x01D, "Get_Controller_Error", 8, [controllerError], senders=[newNode.name] + ) + + axisMsgs = [ heartbeatMsg, - estopMsg, motorErrorMsg, encoderErrorMsg, sensorlessErrorMsg, @@ -180,14 +198,35 @@ db = cantools.database.can.Database( getIqMsg, getSensorlessEstMsg, rebootMsg, - getVbusVMsg, + getVbusVCMsg, clearErrorsMsg, setLinearCountMsg, setPosGainMsg, - setVelGainsMsg + setVelGainsMsg, + getADCVoltageMsg, + controllerErrorMsg, ] -) -cantools.database.dump_file(db, "odrive-cansimple.dbc") -db = cantools.database.load_file("odrive-cansimple.dbc") -print(db) + masterMsgs = [ + estopMsg, + ] + + # Prepend Axis ID to each message name + for msg in axisMsgs: + msg.name = f"Axis{axisID}_{msg.name}" + msg.frame_id |= (axisID << 5) + # for signal in msg.signals: + # signal.name = f"{signal.name}_Axis{axisID}" + # signal.name = f"Axis{axisID}_{signal.name}" + + msgList.append(axisMsgs) + + +from itertools import chain +msgList = list(chain.from_iterable(msgList)) + +db = can.Database(msgList, nodes, buses, version='0.5.6') + +dump_file(db, "odrive-cansimple.dbc") +db = load_file("odrive-cansimple.dbc") +# print(db) diff --git a/tools/enums_template.j2 b/tools/enums_template.j2 index 58d5bfc3..e3b0422b 100644 --- a/tools/enums_template.j2 +++ b/tools/enums_template.j2 @@ -3,6 +3,8 @@ # To regenerate this file, nagivate to the top level of the ODrive repository and run: # python Firmware/interface_generator_stub.py --definitions Firmware/odrive-interface.yaml --template tools/enums_template.j2 --output tools/odrive/enums.py +import enum + [%- for _, enum in value_types.items() %] [%- if enum.is_enum %] @@ -13,3 +15,11 @@ [%- endif %] [%- endfor %] +[%- for _, enum in value_types.items() %] +[%- if enum.is_enum %] +class [[(enum.parent.name if enum.name in ['Error', 'Mode', 'Protocol'] else '') + enum.name]][% if enum.is_flags %](enum.IntFlag)[% else %](enum.Enum)[% endif %]: +[%- for k, value in enum['values'].items() %] + [[((k | to_macro_case)).ljust(40)]] = [% if enum.is_flags %]0x[['%08x' | format(value.value)]][% else %][[value.value]][% endif %] +[%- endfor %] +[%- endif %] +[%- endfor %] diff --git a/tools/odrive-cansimple.dbc b/tools/odrive-cansimple.dbc index 01b9b816..43142b20 100644 --- a/tools/odrive-cansimple.dbc +++ b/tools/odrive-cansimple.dbc @@ -1,4 +1,4 @@ -VERSION "" +VERSION "0.5.6" NS_ : @@ -33,106 +33,863 @@ NS_ : BS_: -BU_: +BU_: Master ODrive_Axis0 ODrive_Axis1 ODrive_Axis2 ODrive_Axis3 ODrive_Axis4 ODrive_Axis5 ODrive_Axis6 ODrive_Axis7 -BO_ 1 Heartbeat: 8 Vector__XXX - SG_ Controller_Flags : 56|8@1+ (1,0) [0|0] "" Vector__XXX - SG_ Encoder_Flags : 48|8@1+ (1,0) [0|0] "" Vector__XXX - SG_ Motor_Flags : 40|8@1+ (1,0) [0|0] "" Vector__XXX - SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Vector__XXX - SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 1 Axis0_Heartbeat: 8 ODrive_Axis0 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master -BO_ 2 Estop: 0 Vector__XXX +BO_ 3 Axis0_Get_Motor_Error: 8 ODrive_Axis0 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master -BO_ 3 Get_Motor_Error: 8 Vector__XXX - SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 4 Axis0_Get_Encoder_Error: 8 ODrive_Axis0 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master -BO_ 4 Get_Encoder_Error: 8 Vector__XXX - SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 5 Axis0_Get_Sensorless_Error: 8 ODrive_Axis0 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master -BO_ 5 Get_Sensorless_Error: 8 Vector__XXX - SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 6 Axis0_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis0 -BO_ 6 Set_Axis_Node_ID: 8 Vector__XXX - SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 7 Axis0_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis0 -BO_ 7 Set_Axis_State: 8 Vector__XXX - SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 9 Axis0_Get_Encoder_Estimates: 8 ODrive_Axis0 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master -BO_ 9 Get_Encoder_Estimates: 8 Vector__XXX - SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 10 Axis0_Get_Encoder_Count: 8 ODrive_Axis0 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master -BO_ 10 Get_Encoder_Count: 8 Vector__XXX - SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 11 Axis0_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis0 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis0 -BO_ 11 Set_Controller_Mode: 8 Vector__XXX - SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 12 Axis0_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis0 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis0 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis0 -BO_ 12 Set_Input_Pos: 8 Vector__XXX - SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "" Vector__XXX - SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "" Vector__XXX - SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 13 Axis0_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis0 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis0 -BO_ 13 Set_Input_Vel: 8 Vector__XXX - SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 14 Axis0_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis0 -BO_ 14 Set_Input_Torque: 8 Vector__XXX - SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 15 Axis0_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis0 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis0 -BO_ 15 Set_Limits: 8 Vector__XXX - SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 16 Axis0_Start_Anticogging: 0 Master -BO_ 16 Start_Anticogging: 0 Vector__XXX +BO_ 17 Axis0_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis0 -BO_ 17 Set_Traj_Vel_Limit: 8 Vector__XXX - SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 18 Axis0_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis0 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis0 -BO_ 18 Set_Traj_Accel_Limits: 8 Vector__XXX - SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 19 Axis0_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis0 -BO_ 19 Set_Traj_Inertia: 8 Vector__XXX - SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 20 Axis0_Get_Iq: 8 ODrive_Axis0 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master -BO_ 20 Get_Iq: 8 Vector__XXX - SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 21 Axis0_Get_Sensorless_Estimates: 8 ODrive_Axis0 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master -BO_ 21 Get_Sensorless_Estimates: 8 Vector__XXX - SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 22 Axis0_Reboot: 0 Master -BO_ 22 Reboot: 0 Vector__XXX +BO_ 23 Axis0_Get_Bus_Voltage_Current: 8 ODrive_Axis0 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master -BO_ 23 Get_Vbus_Voltage: 8 Vector__XXX - SG_ Vbus_Voltage : 0|32@1+ (1,0) [0|0] "" Vector__XXX - -BO_ 24 Clear_Errors: 0 Vector__XXX - -BO_ 25 Set_Linear_Count: 8 Vector__XXX - SG_ Position : 0|32@1- (1,0) [0|0] "" Vector__XXX - -BO_ 26 Set_Pos_Gain: 8 Vector__XXX - SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "" Vector__XXX - -BO_ 27 Set_Vel_gains: 8 Vector__XXX - SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "" Vector__XXX - SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "" Vector__XXX +BO_ 24 Axis0_Clear_Errors: 0 Master +BO_ 25 Axis0_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis0 +BO_ 26 Axis0_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis0 +BO_ 27 Axis0_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis0 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis0 +BO_ 28 Axis0_Get_ADC_Voltage: 8 ODrive_Axis0 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 29 Axis0_Get_Controller_Error: 8 ODrive_Axis0 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 33 Axis1_Heartbeat: 8 ODrive_Axis1 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 35 Axis1_Get_Motor_Error: 8 ODrive_Axis1 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 36 Axis1_Get_Encoder_Error: 8 ODrive_Axis1 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 37 Axis1_Get_Sensorless_Error: 8 ODrive_Axis1 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 38 Axis1_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis1 + +BO_ 39 Axis1_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis1 + +BO_ 41 Axis1_Get_Encoder_Estimates: 8 ODrive_Axis1 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 42 Axis1_Get_Encoder_Count: 8 ODrive_Axis1 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 43 Axis1_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis1 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis1 + +BO_ 44 Axis1_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis1 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis1 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis1 + +BO_ 45 Axis1_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis1 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis1 + +BO_ 46 Axis1_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis1 + +BO_ 47 Axis1_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis1 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis1 + +BO_ 48 Axis1_Start_Anticogging: 0 Master + +BO_ 49 Axis1_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis1 + +BO_ 50 Axis1_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis1 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis1 + +BO_ 51 Axis1_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis1 + +BO_ 52 Axis1_Get_Iq: 8 ODrive_Axis1 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 53 Axis1_Get_Sensorless_Estimates: 8 ODrive_Axis1 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 54 Axis1_Reboot: 0 Master + +BO_ 55 Axis1_Get_Bus_Voltage_Current: 8 ODrive_Axis1 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 56 Axis1_Clear_Errors: 0 Master + +BO_ 57 Axis1_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis1 + +BO_ 58 Axis1_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis1 + +BO_ 59 Axis1_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis1 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis1 + +BO_ 60 Axis1_Get_ADC_Voltage: 8 ODrive_Axis1 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 61 Axis1_Get_Controller_Error: 8 ODrive_Axis1 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 65 Axis2_Heartbeat: 8 ODrive_Axis2 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 67 Axis2_Get_Motor_Error: 8 ODrive_Axis2 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 68 Axis2_Get_Encoder_Error: 8 ODrive_Axis2 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 69 Axis2_Get_Sensorless_Error: 8 ODrive_Axis2 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 70 Axis2_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis2 + +BO_ 71 Axis2_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis2 + +BO_ 73 Axis2_Get_Encoder_Estimates: 8 ODrive_Axis2 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 74 Axis2_Get_Encoder_Count: 8 ODrive_Axis2 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 75 Axis2_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis2 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis2 + +BO_ 76 Axis2_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis2 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis2 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis2 + +BO_ 77 Axis2_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis2 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis2 + +BO_ 78 Axis2_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis2 + +BO_ 79 Axis2_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis2 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis2 + +BO_ 80 Axis2_Start_Anticogging: 0 Master + +BO_ 81 Axis2_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis2 + +BO_ 82 Axis2_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis2 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis2 + +BO_ 83 Axis2_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis2 + +BO_ 84 Axis2_Get_Iq: 8 ODrive_Axis2 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 85 Axis2_Get_Sensorless_Estimates: 8 ODrive_Axis2 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 86 Axis2_Reboot: 0 Master + +BO_ 87 Axis2_Get_Bus_Voltage_Current: 8 ODrive_Axis2 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 88 Axis2_Clear_Errors: 0 Master + +BO_ 89 Axis2_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis2 + +BO_ 90 Axis2_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis2 + +BO_ 91 Axis2_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis2 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis2 + +BO_ 92 Axis2_Get_ADC_Voltage: 8 ODrive_Axis2 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 93 Axis2_Get_Controller_Error: 8 ODrive_Axis2 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 97 Axis3_Heartbeat: 8 ODrive_Axis3 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 99 Axis3_Get_Motor_Error: 8 ODrive_Axis3 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 100 Axis3_Get_Encoder_Error: 8 ODrive_Axis3 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 101 Axis3_Get_Sensorless_Error: 8 ODrive_Axis3 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 102 Axis3_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis3 + +BO_ 103 Axis3_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis3 + +BO_ 105 Axis3_Get_Encoder_Estimates: 8 ODrive_Axis3 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 106 Axis3_Get_Encoder_Count: 8 ODrive_Axis3 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 107 Axis3_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis3 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis3 + +BO_ 108 Axis3_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis3 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis3 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis3 + +BO_ 109 Axis3_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis3 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis3 + +BO_ 110 Axis3_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis3 + +BO_ 111 Axis3_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis3 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis3 + +BO_ 112 Axis3_Start_Anticogging: 0 Master + +BO_ 113 Axis3_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis3 + +BO_ 114 Axis3_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis3 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis3 + +BO_ 115 Axis3_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis3 + +BO_ 116 Axis3_Get_Iq: 8 ODrive_Axis3 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 117 Axis3_Get_Sensorless_Estimates: 8 ODrive_Axis3 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 118 Axis3_Reboot: 0 Master + +BO_ 119 Axis3_Get_Bus_Voltage_Current: 8 ODrive_Axis3 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 120 Axis3_Clear_Errors: 0 Master + +BO_ 121 Axis3_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis3 + +BO_ 122 Axis3_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis3 + +BO_ 123 Axis3_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis3 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis3 + +BO_ 124 Axis3_Get_ADC_Voltage: 8 ODrive_Axis3 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 125 Axis3_Get_Controller_Error: 8 ODrive_Axis3 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 129 Axis4_Heartbeat: 8 ODrive_Axis4 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 131 Axis4_Get_Motor_Error: 8 ODrive_Axis4 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 132 Axis4_Get_Encoder_Error: 8 ODrive_Axis4 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 133 Axis4_Get_Sensorless_Error: 8 ODrive_Axis4 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 134 Axis4_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis4 + +BO_ 135 Axis4_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis4 + +BO_ 137 Axis4_Get_Encoder_Estimates: 8 ODrive_Axis4 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 138 Axis4_Get_Encoder_Count: 8 ODrive_Axis4 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 139 Axis4_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis4 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis4 + +BO_ 140 Axis4_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis4 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis4 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis4 + +BO_ 141 Axis4_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis4 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis4 + +BO_ 142 Axis4_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis4 + +BO_ 143 Axis4_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis4 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis4 + +BO_ 144 Axis4_Start_Anticogging: 0 Master + +BO_ 145 Axis4_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis4 + +BO_ 146 Axis4_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis4 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis4 + +BO_ 147 Axis4_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis4 + +BO_ 148 Axis4_Get_Iq: 8 ODrive_Axis4 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 149 Axis4_Get_Sensorless_Estimates: 8 ODrive_Axis4 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 150 Axis4_Reboot: 0 Master + +BO_ 151 Axis4_Get_Bus_Voltage_Current: 8 ODrive_Axis4 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 152 Axis4_Clear_Errors: 0 Master + +BO_ 153 Axis4_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis4 + +BO_ 154 Axis4_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis4 + +BO_ 155 Axis4_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis4 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis4 + +BO_ 156 Axis4_Get_ADC_Voltage: 8 ODrive_Axis4 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 157 Axis4_Get_Controller_Error: 8 ODrive_Axis4 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 161 Axis5_Heartbeat: 8 ODrive_Axis5 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 163 Axis5_Get_Motor_Error: 8 ODrive_Axis5 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 164 Axis5_Get_Encoder_Error: 8 ODrive_Axis5 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 165 Axis5_Get_Sensorless_Error: 8 ODrive_Axis5 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 166 Axis5_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis5 + +BO_ 167 Axis5_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis5 + +BO_ 169 Axis5_Get_Encoder_Estimates: 8 ODrive_Axis5 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 170 Axis5_Get_Encoder_Count: 8 ODrive_Axis5 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 171 Axis5_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis5 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis5 + +BO_ 172 Axis5_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis5 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis5 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis5 + +BO_ 173 Axis5_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis5 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis5 + +BO_ 174 Axis5_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis5 + +BO_ 175 Axis5_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis5 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis5 + +BO_ 176 Axis5_Start_Anticogging: 0 Master + +BO_ 177 Axis5_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis5 + +BO_ 178 Axis5_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis5 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis5 + +BO_ 179 Axis5_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis5 + +BO_ 180 Axis5_Get_Iq: 8 ODrive_Axis5 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 181 Axis5_Get_Sensorless_Estimates: 8 ODrive_Axis5 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 182 Axis5_Reboot: 0 Master + +BO_ 183 Axis5_Get_Bus_Voltage_Current: 8 ODrive_Axis5 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 184 Axis5_Clear_Errors: 0 Master + +BO_ 185 Axis5_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis5 + +BO_ 186 Axis5_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis5 + +BO_ 187 Axis5_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis5 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis5 + +BO_ 188 Axis5_Get_ADC_Voltage: 8 ODrive_Axis5 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 189 Axis5_Get_Controller_Error: 8 ODrive_Axis5 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 193 Axis6_Heartbeat: 8 ODrive_Axis6 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 195 Axis6_Get_Motor_Error: 8 ODrive_Axis6 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 196 Axis6_Get_Encoder_Error: 8 ODrive_Axis6 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 197 Axis6_Get_Sensorless_Error: 8 ODrive_Axis6 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 198 Axis6_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis6 + +BO_ 199 Axis6_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis6 + +BO_ 201 Axis6_Get_Encoder_Estimates: 8 ODrive_Axis6 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 202 Axis6_Get_Encoder_Count: 8 ODrive_Axis6 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 203 Axis6_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis6 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis6 + +BO_ 204 Axis6_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis6 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis6 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis6 + +BO_ 205 Axis6_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis6 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis6 + +BO_ 206 Axis6_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis6 + +BO_ 207 Axis6_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis6 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis6 + +BO_ 208 Axis6_Start_Anticogging: 0 Master + +BO_ 209 Axis6_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis6 + +BO_ 210 Axis6_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis6 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis6 + +BO_ 211 Axis6_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis6 + +BO_ 212 Axis6_Get_Iq: 8 ODrive_Axis6 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 213 Axis6_Get_Sensorless_Estimates: 8 ODrive_Axis6 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 214 Axis6_Reboot: 0 Master + +BO_ 215 Axis6_Get_Bus_Voltage_Current: 8 ODrive_Axis6 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 216 Axis6_Clear_Errors: 0 Master + +BO_ 217 Axis6_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis6 + +BO_ 218 Axis6_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis6 + +BO_ 219 Axis6_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis6 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis6 + +BO_ 220 Axis6_Get_ADC_Voltage: 8 ODrive_Axis6 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 221 Axis6_Get_Controller_Error: 8 ODrive_Axis6 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 225 Axis7_Heartbeat: 8 ODrive_Axis7 + SG_ Trajectory_Done_Flag : 63|1@1+ (1,0) [0|0] "" Master + SG_ Controller_Error_Flag : 56|1@1+ (1,0) [0|0] "" Master + SG_ Encoder_Error_Flag : 48|1@1+ (1,0) [0|0] "" Master + SG_ Motor_Error_Flag : 40|1@1+ (1,0) [0|0] "" Master + SG_ Axis_State : 32|8@1+ (1,0) [0|0] "" Master + SG_ Axis_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 227 Axis7_Get_Motor_Error: 8 ODrive_Axis7 + SG_ Motor_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 228 Axis7_Get_Encoder_Error: 8 ODrive_Axis7 + SG_ Encoder_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 229 Axis7_Get_Sensorless_Error: 8 ODrive_Axis7 + SG_ Sensorless_Error : 0|32@1+ (1,0) [0|0] "" Master + +BO_ 230 Axis7_Set_Axis_Node_ID: 8 Master + SG_ Axis_Node_ID : 0|32@1+ (1,0) [0|0] "" ODrive_Axis7 + +BO_ 231 Axis7_Set_Axis_State: 8 Master + SG_ Axis_Requested_State : 0|32@1+ (1,0) [0|0] "" ODrive_Axis7 + +BO_ 233 Axis7_Get_Encoder_Estimates: 8 ODrive_Axis7 + SG_ Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 234 Axis7_Get_Encoder_Count: 8 ODrive_Axis7 + SG_ Count_in_CPR : 32|32@1+ (1,0) [0|0] "counts" Master + SG_ Shadow_Count : 0|32@1+ (1,0) [0|0] "counts" Master + +BO_ 235 Axis7_Set_Controller_Mode: 8 Master + SG_ Input_Mode : 32|32@1+ (1,0) [0|0] "" ODrive_Axis7 + SG_ Control_Mode : 0|32@1+ (1,0) [0|0] "" ODrive_Axis7 + +BO_ 236 Axis7_Set_Input_Pos: 8 Master + SG_ Torque_FF : 48|16@1- (0.001,0) [0|0] "Nm" ODrive_Axis7 + SG_ Vel_FF : 32|16@1- (0.001,0) [0|0] "rev/s" ODrive_Axis7 + SG_ Input_Pos : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis7 + +BO_ 237 Axis7_Set_Input_Vel: 8 Master + SG_ Input_Torque_FF : 32|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis7 + SG_ Input_Vel : 0|32@1+ (1,0) [0|0] "rev" ODrive_Axis7 + +BO_ 238 Axis7_Set_Input_Torque: 8 Master + SG_ Input_Torque : 0|32@1+ (1,0) [0|0] "Nm" ODrive_Axis7 + +BO_ 239 Axis7_Set_Limits: 8 Master + SG_ Current_Limit : 32|32@1+ (1,0) [0|0] "A" ODrive_Axis7 + SG_ Velocity_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis7 + +BO_ 240 Axis7_Start_Anticogging: 0 Master + +BO_ 241 Axis7_Set_Traj_Vel_Limit: 8 Master + SG_ Traj_Vel_Limit : 0|32@1+ (1,0) [0|0] "rev/s" ODrive_Axis7 + +BO_ 242 Axis7_Set_Traj_Accel_Limits: 8 Master + SG_ Traj_Decel_Limit : 32|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis7 + SG_ Traj_Accel_Limit : 0|32@1+ (1,0) [0|0] "rev/s^2" ODrive_Axis7 + +BO_ 243 Axis7_Set_Traj_Inertia: 8 Master + SG_ Traj_Inertia : 0|32@1+ (1,0) [0|0] "Nm / (rev/s^2)" ODrive_Axis7 + +BO_ 244 Axis7_Get_Iq: 8 ODrive_Axis7 + SG_ Iq_Measured : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Iq_Setpoint : 0|32@1+ (1,0) [0|0] "A" Master + +BO_ 245 Axis7_Get_Sensorless_Estimates: 8 ODrive_Axis7 + SG_ Sensorless_Vel_Estimate : 32|32@1+ (1,0) [0|0] "rev/s" Master + SG_ Sensorless_Pos_Estimate : 0|32@1+ (1,0) [0|0] "rev" Master + +BO_ 246 Axis7_Reboot: 0 Master + +BO_ 247 Axis7_Get_Bus_Voltage_Current: 8 ODrive_Axis7 + SG_ Bus_Current : 32|32@1+ (1,0) [0|0] "A" Master + SG_ Bus_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 248 Axis7_Clear_Errors: 0 Master + +BO_ 249 Axis7_Set_Linear_Count: 8 Master + SG_ Position : 0|32@1- (1,0) [0|0] "counts" ODrive_Axis7 + +BO_ 250 Axis7_Set_Pos_Gain: 8 Master + SG_ Pos_Gain : 0|32@1+ (1,0) [0|0] "(rev/s) / rev" ODrive_Axis7 + +BO_ 251 Axis7_Set_Vel_Gains: 8 Master + SG_ Vel_Integrator_Gain : 32|32@1+ (1,0) [0|0] "(Nm / (rev/s)) / s" ODrive_Axis7 + SG_ Vel_Gain : 0|32@1+ (1,0) [0|0] "Nm / (rev/s)" ODrive_Axis7 + +BO_ 252 Axis7_Get_ADC_Voltage: 8 ODrive_Axis7 + SG_ ADC_Voltage : 0|32@1+ (1,0) [0|0] "V" Master + +BO_ 253 Axis7_Get_Controller_Error: 8 ODrive_Axis7 + SG_ Controller_Error : 0|32@1+ (1,0) [0|0] "" Master +BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535; +BA_DEF_DEF_ "GenMsgCycleTime" 0; +BA_ "GenMsgCycleTime" BO_ 1 100; +BA_ "GenMsgCycleTime" BO_ 9 10; +BA_ "GenMsgCycleTime" BO_ 33 100; +BA_ "GenMsgCycleTime" BO_ 41 10; +BA_ "GenMsgCycleTime" BO_ 65 100; +BA_ "GenMsgCycleTime" BO_ 73 10; +BA_ "GenMsgCycleTime" BO_ 97 100; +BA_ "GenMsgCycleTime" BO_ 105 10; +BA_ "GenMsgCycleTime" BO_ 129 100; +BA_ "GenMsgCycleTime" BO_ 137 10; +BA_ "GenMsgCycleTime" BO_ 161 100; +BA_ "GenMsgCycleTime" BO_ 169 10; +BA_ "GenMsgCycleTime" BO_ 193 100; +BA_ "GenMsgCycleTime" BO_ 201 10; +BA_ "GenMsgCycleTime" BO_ 225 100; +BA_ "GenMsgCycleTime" BO_ 233 10; +VAL_ 1 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 1 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 3 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 4 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 5 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 7 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 11 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 11 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 29 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 33 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 33 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 35 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 36 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 37 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 39 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 43 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 43 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 61 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 65 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 65 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 67 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 68 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 69 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 71 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 75 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 75 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 93 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 97 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 97 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 99 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 100 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 101 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 103 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 107 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 107 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 125 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 129 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 129 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 131 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 132 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 133 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 135 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 139 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 139 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 157 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 161 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 161 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 163 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 164 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 165 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 167 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 171 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 171 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 189 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 193 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 193 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 195 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 196 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 197 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 199 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 203 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 203 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 221 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; +VAL_ 225 Axis_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 225 Axis_Error 0 "NONE" 1 "INVALID_STATE" 64 "MOTOR_FAILED" 128 "SENSORLESS_ESTIMATOR_FAILED" 256 "ENCODER_FAILED" 512 "CONTROLLER_FAILED" 2048 "WATCHDOG_TIMER_EXPIRED" 4096 "MIN_ENDSTOP_PRESSED" 8192 "MAX_ENDSTOP_PRESSED" 16384 "ESTOP_REQUESTED" 131072 "HOMING_WITHOUT_ENDSTOP" 262144 "OVER_TEMP" 524288 "UNKNOWN_POSITION" ; +VAL_ 227 Motor_Error 0 "NONE" 1 "PHASE_RESISTANCE_OUT_OF_RANGE" 2 "PHASE_INDUCTANCE_OUT_OF_RANGE" 8 "DRV_FAULT" 16 "CONTROL_DEADLINE_MISSED" 128 "MODULATION_MAGNITUDE" 1024 "CURRENT_SENSE_SATURATION" 4096 "CURRENT_LIMIT_VIOLATION" 65536 "MODULATION_IS_NAN" 131072 "MOTOR_THERMISTOR_OVER_TEMP" 262144 "FET_THERMISTOR_OVER_TEMP" 524288 "TIMER_UPDATE_MISSED" 1048576 "CURRENT_MEASUREMENT_UNAVAILABLE" 2097152 "CONTROLLER_FAILED" 4194304 "I_BUS_OUT_OF_RANGE" 8388608 "BRAKE_RESISTOR_DISARMED" 16777216 "SYSTEM_LEVEL" 33554432 "BAD_TIMING" 67108864 "UNKNOWN_PHASE_ESTIMATE" 134217728 "UNKNOWN_PHASE_VEL" 268435456 "UNKNOWN_TORQUE" 536870912 "UNKNOWN_CURRENT_COMMAND" 1073741824 "UNKNOWN_CURRENT_MEASUREMENT" 2147483648 "UNKNOWN_VBUS_VOLTAGE" 4294967296 "UNKNOWN_VOLTAGE_COMMAND" 8589934592 "UNKNOWN_GAINS" 17179869184 "CONTROLLER_INITIALIZING" 34359738368 "UNBALANCED_PHASES" ; +VAL_ 228 Encoder_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "CPR_POLEPAIRS_MISMATCH" 4 "NO_RESPONSE" 8 "UNSUPPORTED_ENCODER_MODE" 16 "ILLEGAL_HALL_STATE" 32 "INDEX_NOT_FOUND_YET" 64 "ABS_SPI_TIMEOUT" 128 "ABS_SPI_COM_FAIL" 256 "ABS_SPI_NOT_READY" 512 "HALL_NOT_CALIBRATED_YET" ; +VAL_ 229 Sensorless_Error 0 "NONE" 1 "UNSTABLE_GAIN" 2 "UNKNOWN_CURRENT_MEASUREMENT" ; +VAL_ 231 Axis_Requested_State 0 "UNDEFINED" 1 "IDLE" 2 "STARTUP_SEQUENCE" 3 "FULL_CALIBRATION_SEQUENCE" 4 "MOTOR_CALIBRATION" 6 "ENCODER_INDEX_SEARCH" 7 "ENCODER_OFFSET_CALIBRATION" 8 "CLOSED_LOOP_CONTROL" 9 "LOCKIN_SPIN" 10 "ENCODER_DIR_FIND" 11 "HOMING" 12 "ENCODER_HALL_POLARITY_CALIBRATION" 13 "ENCODER_HALL_PHASE_CALIBRATION" ; +VAL_ 235 Input_Mode 0 "INACTIVE" 1 "PASSTHROUGH" 2 "VEL_RAMP" 3 "POS_FILTER" 4 "MIX_CHANNELS" 5 "TRAP_TRAJ" 6 "TORQUE_RAMP" 7 "MIRROR" 8 "TUNING" ; +VAL_ 235 Control_Mode 0 "VOLTAGE_CONTROL" 1 "TORQUE_CONTROL" 2 "VELOCITY_CONTROL" 3 "POSITION_CONTROL" ; +VAL_ 253 Controller_Error 0 "NONE" 1 "OVERSPEED" 2 "INVALID_INPUT_MODE" 4 "UNSTABLE_GAIN" 8 "INVALID_MIRROR_AXIS" 16 "INVALID_LOAD_ENCODER" 32 "INVALID_ESTIMATE" 64 "INVALID_CIRCULAR_RANGE" 128 "SPINOUT_DETECTED" ; SIG_VALTYPE_ 9 Pos_Estimate : 1; SIG_VALTYPE_ 9 Vel_Estimate : 1; SIG_VALTYPE_ 12 Input_Pos : 1; @@ -149,9 +906,165 @@ SIG_VALTYPE_ 20 Iq_Setpoint : 1; SIG_VALTYPE_ 20 Iq_Measured : 1; SIG_VALTYPE_ 21 Sensorless_Pos_Estimate : 1; SIG_VALTYPE_ 21 Sensorless_Vel_Estimate : 1; -SIG_VALTYPE_ 23 Vbus_Voltage : 1; +SIG_VALTYPE_ 23 Bus_Voltage : 1; +SIG_VALTYPE_ 23 Bus_Current : 1; SIG_VALTYPE_ 26 Pos_Gain : 1; SIG_VALTYPE_ 27 Vel_Gain : 1; SIG_VALTYPE_ 27 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 28 ADC_Voltage : 1; +SIG_VALTYPE_ 41 Pos_Estimate : 1; +SIG_VALTYPE_ 41 Vel_Estimate : 1; +SIG_VALTYPE_ 44 Input_Pos : 1; +SIG_VALTYPE_ 45 Input_Vel : 1; +SIG_VALTYPE_ 45 Input_Torque_FF : 1; +SIG_VALTYPE_ 46 Input_Torque : 1; +SIG_VALTYPE_ 47 Velocity_Limit : 1; +SIG_VALTYPE_ 47 Current_Limit : 1; +SIG_VALTYPE_ 49 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 50 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 50 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 51 Traj_Inertia : 1; +SIG_VALTYPE_ 52 Iq_Setpoint : 1; +SIG_VALTYPE_ 52 Iq_Measured : 1; +SIG_VALTYPE_ 53 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 53 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 55 Bus_Voltage : 1; +SIG_VALTYPE_ 55 Bus_Current : 1; +SIG_VALTYPE_ 58 Pos_Gain : 1; +SIG_VALTYPE_ 59 Vel_Gain : 1; +SIG_VALTYPE_ 59 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 60 ADC_Voltage : 1; +SIG_VALTYPE_ 73 Pos_Estimate : 1; +SIG_VALTYPE_ 73 Vel_Estimate : 1; +SIG_VALTYPE_ 76 Input_Pos : 1; +SIG_VALTYPE_ 77 Input_Vel : 1; +SIG_VALTYPE_ 77 Input_Torque_FF : 1; +SIG_VALTYPE_ 78 Input_Torque : 1; +SIG_VALTYPE_ 79 Velocity_Limit : 1; +SIG_VALTYPE_ 79 Current_Limit : 1; +SIG_VALTYPE_ 81 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 82 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 82 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 83 Traj_Inertia : 1; +SIG_VALTYPE_ 84 Iq_Setpoint : 1; +SIG_VALTYPE_ 84 Iq_Measured : 1; +SIG_VALTYPE_ 85 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 85 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 87 Bus_Voltage : 1; +SIG_VALTYPE_ 87 Bus_Current : 1; +SIG_VALTYPE_ 90 Pos_Gain : 1; +SIG_VALTYPE_ 91 Vel_Gain : 1; +SIG_VALTYPE_ 91 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 92 ADC_Voltage : 1; +SIG_VALTYPE_ 105 Pos_Estimate : 1; +SIG_VALTYPE_ 105 Vel_Estimate : 1; +SIG_VALTYPE_ 108 Input_Pos : 1; +SIG_VALTYPE_ 109 Input_Vel : 1; +SIG_VALTYPE_ 109 Input_Torque_FF : 1; +SIG_VALTYPE_ 110 Input_Torque : 1; +SIG_VALTYPE_ 111 Velocity_Limit : 1; +SIG_VALTYPE_ 111 Current_Limit : 1; +SIG_VALTYPE_ 113 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 114 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 114 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 115 Traj_Inertia : 1; +SIG_VALTYPE_ 116 Iq_Setpoint : 1; +SIG_VALTYPE_ 116 Iq_Measured : 1; +SIG_VALTYPE_ 117 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 117 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 119 Bus_Voltage : 1; +SIG_VALTYPE_ 119 Bus_Current : 1; +SIG_VALTYPE_ 122 Pos_Gain : 1; +SIG_VALTYPE_ 123 Vel_Gain : 1; +SIG_VALTYPE_ 123 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 124 ADC_Voltage : 1; +SIG_VALTYPE_ 137 Pos_Estimate : 1; +SIG_VALTYPE_ 137 Vel_Estimate : 1; +SIG_VALTYPE_ 140 Input_Pos : 1; +SIG_VALTYPE_ 141 Input_Vel : 1; +SIG_VALTYPE_ 141 Input_Torque_FF : 1; +SIG_VALTYPE_ 142 Input_Torque : 1; +SIG_VALTYPE_ 143 Velocity_Limit : 1; +SIG_VALTYPE_ 143 Current_Limit : 1; +SIG_VALTYPE_ 145 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 146 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 146 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 147 Traj_Inertia : 1; +SIG_VALTYPE_ 148 Iq_Setpoint : 1; +SIG_VALTYPE_ 148 Iq_Measured : 1; +SIG_VALTYPE_ 149 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 149 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 151 Bus_Voltage : 1; +SIG_VALTYPE_ 151 Bus_Current : 1; +SIG_VALTYPE_ 154 Pos_Gain : 1; +SIG_VALTYPE_ 155 Vel_Gain : 1; +SIG_VALTYPE_ 155 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 156 ADC_Voltage : 1; +SIG_VALTYPE_ 169 Pos_Estimate : 1; +SIG_VALTYPE_ 169 Vel_Estimate : 1; +SIG_VALTYPE_ 172 Input_Pos : 1; +SIG_VALTYPE_ 173 Input_Vel : 1; +SIG_VALTYPE_ 173 Input_Torque_FF : 1; +SIG_VALTYPE_ 174 Input_Torque : 1; +SIG_VALTYPE_ 175 Velocity_Limit : 1; +SIG_VALTYPE_ 175 Current_Limit : 1; +SIG_VALTYPE_ 177 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 178 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 178 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 179 Traj_Inertia : 1; +SIG_VALTYPE_ 180 Iq_Setpoint : 1; +SIG_VALTYPE_ 180 Iq_Measured : 1; +SIG_VALTYPE_ 181 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 181 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 183 Bus_Voltage : 1; +SIG_VALTYPE_ 183 Bus_Current : 1; +SIG_VALTYPE_ 186 Pos_Gain : 1; +SIG_VALTYPE_ 187 Vel_Gain : 1; +SIG_VALTYPE_ 187 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 188 ADC_Voltage : 1; +SIG_VALTYPE_ 201 Pos_Estimate : 1; +SIG_VALTYPE_ 201 Vel_Estimate : 1; +SIG_VALTYPE_ 204 Input_Pos : 1; +SIG_VALTYPE_ 205 Input_Vel : 1; +SIG_VALTYPE_ 205 Input_Torque_FF : 1; +SIG_VALTYPE_ 206 Input_Torque : 1; +SIG_VALTYPE_ 207 Velocity_Limit : 1; +SIG_VALTYPE_ 207 Current_Limit : 1; +SIG_VALTYPE_ 209 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 210 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 210 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 211 Traj_Inertia : 1; +SIG_VALTYPE_ 212 Iq_Setpoint : 1; +SIG_VALTYPE_ 212 Iq_Measured : 1; +SIG_VALTYPE_ 213 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 213 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 215 Bus_Voltage : 1; +SIG_VALTYPE_ 215 Bus_Current : 1; +SIG_VALTYPE_ 218 Pos_Gain : 1; +SIG_VALTYPE_ 219 Vel_Gain : 1; +SIG_VALTYPE_ 219 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 220 ADC_Voltage : 1; +SIG_VALTYPE_ 233 Pos_Estimate : 1; +SIG_VALTYPE_ 233 Vel_Estimate : 1; +SIG_VALTYPE_ 236 Input_Pos : 1; +SIG_VALTYPE_ 237 Input_Vel : 1; +SIG_VALTYPE_ 237 Input_Torque_FF : 1; +SIG_VALTYPE_ 238 Input_Torque : 1; +SIG_VALTYPE_ 239 Velocity_Limit : 1; +SIG_VALTYPE_ 239 Current_Limit : 1; +SIG_VALTYPE_ 241 Traj_Vel_Limit : 1; +SIG_VALTYPE_ 242 Traj_Accel_Limit : 1; +SIG_VALTYPE_ 242 Traj_Decel_Limit : 1; +SIG_VALTYPE_ 243 Traj_Inertia : 1; +SIG_VALTYPE_ 244 Iq_Setpoint : 1; +SIG_VALTYPE_ 244 Iq_Measured : 1; +SIG_VALTYPE_ 245 Sensorless_Pos_Estimate : 1; +SIG_VALTYPE_ 245 Sensorless_Vel_Estimate : 1; +SIG_VALTYPE_ 247 Bus_Voltage : 1; +SIG_VALTYPE_ 247 Bus_Current : 1; +SIG_VALTYPE_ 250 Pos_Gain : 1; +SIG_VALTYPE_ 251 Vel_Gain : 1; +SIG_VALTYPE_ 251 Vel_Integrator_Gain : 1; +SIG_VALTYPE_ 252 ADC_Voltage : 1; diff --git a/tools/odrive/enums.py b/tools/odrive/enums.py index 5feb5423..365facb8 100644 --- a/tools/odrive/enums.py +++ b/tools/odrive/enums.py @@ -3,6 +3,8 @@ # To regenerate this file, nagivate to the top level of the ODrive repository and run: # python Firmware/interface_generator_stub.py --definitions Firmware/odrive-interface.yaml --template tools/enums_template.j2 --output tools/odrive/enums.py +import enum + # ODrive.GpioMode GPIO_MODE_DIGITAL = 0 GPIO_MODE_DIGITAL_PULL_UP = 1 @@ -165,3 +167,151 @@ ENCODER_ERROR_HALL_NOT_CALIBRATED_YET = 0x00000200 SENSORLESS_ESTIMATOR_ERROR_NONE = 0x00000000 SENSORLESS_ESTIMATOR_ERROR_UNSTABLE_GAIN = 0x00000001 SENSORLESS_ESTIMATOR_ERROR_UNKNOWN_CURRENT_MEASUREMENT = 0x00000002 +class GpioMode(enum.Enum): + DIGITAL = 0 + DIGITAL_PULL_UP = 1 + DIGITAL_PULL_DOWN = 2 + ANALOG_IN = 3 + UART_A = 4 + UART_B = 5 + UART_C = 6 + CAN_A = 7 + I2C_A = 8 + SPI_A = 9 + PWM = 10 + ENC0 = 11 + ENC1 = 12 + ENC2 = 13 + MECH_BRAKE = 14 + STATUS = 15 +class StreamProtocolType(enum.Enum): + FIBRE = 0 + ASCII = 1 + STDOUT = 2 + ASCII_AND_STDOUT = 3 +class CanProtocol(enum.IntFlag): + SIMPLE = 0x00000001 +class AxisState(enum.Enum): + UNDEFINED = 0 + IDLE = 1 + STARTUP_SEQUENCE = 2 + FULL_CALIBRATION_SEQUENCE = 3 + MOTOR_CALIBRATION = 4 + ENCODER_INDEX_SEARCH = 6 + ENCODER_OFFSET_CALIBRATION = 7 + CLOSED_LOOP_CONTROL = 8 + LOCKIN_SPIN = 9 + ENCODER_DIR_FIND = 10 + HOMING = 11 + ENCODER_HALL_POLARITY_CALIBRATION = 12 + ENCODER_HALL_PHASE_CALIBRATION = 13 +class EncoderMode(enum.Enum): + INCREMENTAL = 0 + HALL = 1 + SINCOS = 2 + SPI_ABS_CUI = 256 + SPI_ABS_AMS = 257 + SPI_ABS_AEAT = 258 + SPI_ABS_RLS = 259 + SPI_ABS_MA732 = 260 +class ControlMode(enum.Enum): + VOLTAGE_CONTROL = 0 + TORQUE_CONTROL = 1 + VELOCITY_CONTROL = 2 + POSITION_CONTROL = 3 +class InputMode(enum.Enum): + INACTIVE = 0 + PASSTHROUGH = 1 + VEL_RAMP = 2 + POS_FILTER = 3 + MIX_CHANNELS = 4 + TRAP_TRAJ = 5 + TORQUE_RAMP = 6 + MIRROR = 7 + TUNING = 8 +class MotorType(enum.Enum): + HIGH_CURRENT = 0 + GIMBAL = 2 + ACIM = 3 +class ODriveError(enum.IntFlag): + NONE = 0x00000000 + CONTROL_ITERATION_MISSED = 0x00000001 + DC_BUS_UNDER_VOLTAGE = 0x00000002 + DC_BUS_OVER_VOLTAGE = 0x00000004 + DC_BUS_OVER_REGEN_CURRENT = 0x00000008 + DC_BUS_OVER_CURRENT = 0x00000010 + BRAKE_DEADTIME_VIOLATION = 0x00000020 + BRAKE_DUTY_CYCLE_NAN = 0x00000040 + INVALID_BRAKE_RESISTANCE = 0x00000080 +class CanError(enum.IntFlag): + NONE = 0x00000000 + DUPLICATE_CAN_IDS = 0x00000001 +class AxisError(enum.IntFlag): + NONE = 0x00000000 + INVALID_STATE = 0x00000001 + MOTOR_FAILED = 0x00000040 + SENSORLESS_ESTIMATOR_FAILED = 0x00000080 + ENCODER_FAILED = 0x00000100 + CONTROLLER_FAILED = 0x00000200 + WATCHDOG_TIMER_EXPIRED = 0x00000800 + MIN_ENDSTOP_PRESSED = 0x00001000 + MAX_ENDSTOP_PRESSED = 0x00002000 + ESTOP_REQUESTED = 0x00004000 + HOMING_WITHOUT_ENDSTOP = 0x00020000 + OVER_TEMP = 0x00040000 + UNKNOWN_POSITION = 0x00080000 +class MotorError(enum.IntFlag): + NONE = 0x00000000 + PHASE_RESISTANCE_OUT_OF_RANGE = 0x00000001 + PHASE_INDUCTANCE_OUT_OF_RANGE = 0x00000002 + DRV_FAULT = 0x00000008 + CONTROL_DEADLINE_MISSED = 0x00000010 + MODULATION_MAGNITUDE = 0x00000080 + CURRENT_SENSE_SATURATION = 0x00000400 + CURRENT_LIMIT_VIOLATION = 0x00001000 + MODULATION_IS_NAN = 0x00010000 + MOTOR_THERMISTOR_OVER_TEMP = 0x00020000 + FET_THERMISTOR_OVER_TEMP = 0x00040000 + TIMER_UPDATE_MISSED = 0x00080000 + CURRENT_MEASUREMENT_UNAVAILABLE = 0x00100000 + CONTROLLER_FAILED = 0x00200000 + I_BUS_OUT_OF_RANGE = 0x00400000 + BRAKE_RESISTOR_DISARMED = 0x00800000 + SYSTEM_LEVEL = 0x01000000 + BAD_TIMING = 0x02000000 + UNKNOWN_PHASE_ESTIMATE = 0x04000000 + UNKNOWN_PHASE_VEL = 0x08000000 + UNKNOWN_TORQUE = 0x10000000 + UNKNOWN_CURRENT_COMMAND = 0x20000000 + UNKNOWN_CURRENT_MEASUREMENT = 0x40000000 + UNKNOWN_VBUS_VOLTAGE = 0x80000000 + UNKNOWN_VOLTAGE_COMMAND = 0x100000000 + UNKNOWN_GAINS = 0x200000000 + CONTROLLER_INITIALIZING = 0x400000000 + UNBALANCED_PHASES = 0x800000000 +class ControllerError(enum.IntFlag): + NONE = 0x00000000 + OVERSPEED = 0x00000001 + INVALID_INPUT_MODE = 0x00000002 + UNSTABLE_GAIN = 0x00000004 + INVALID_MIRROR_AXIS = 0x00000008 + INVALID_LOAD_ENCODER = 0x00000010 + INVALID_ESTIMATE = 0x00000020 + INVALID_CIRCULAR_RANGE = 0x00000040 + SPINOUT_DETECTED = 0x00000080 +class EncoderError(enum.IntFlag): + NONE = 0x00000000 + UNSTABLE_GAIN = 0x00000001 + CPR_POLEPAIRS_MISMATCH = 0x00000002 + NO_RESPONSE = 0x00000004 + UNSUPPORTED_ENCODER_MODE = 0x00000008 + ILLEGAL_HALL_STATE = 0x00000010 + INDEX_NOT_FOUND_YET = 0x00000020 + ABS_SPI_TIMEOUT = 0x00000040 + ABS_SPI_COM_FAIL = 0x00000080 + ABS_SPI_NOT_READY = 0x00000100 + HALL_NOT_CALIBRATED_YET = 0x00000200 +class SensorlessEstimatorError(enum.IntFlag): + NONE = 0x00000000 + UNSTABLE_GAIN = 0x00000001 + UNKNOWN_CURRENT_MEASUREMENT = 0x00000002 \ No newline at end of file