From cc0f083bf0b65c58f62ee3b75824c49bc94bc672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20H=C3=A4ggstr=C3=B6m?= Date: Thu, 13 Sep 2018 13:54:55 +0200 Subject: [PATCH 1/4] Poll analog inputs to drive a configured endpoint. --- Firmware/MotorControl/low_level.cpp | 31 +++++++++++++++++++++++- Firmware/MotorControl/low_level.h | 2 ++ Firmware/MotorControl/main.cpp | 2 ++ Firmware/MotorControl/odrive_main.h | 1 + Firmware/communication/communication.cpp | 7 ++++-- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index ffeeeadd..8d233188 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -724,4 +724,33 @@ void pwm_in_cb(int channel, uint32_t timestamp) { last_timestamp[gpio_num - 1] = timestamp; last_pin_state[gpio_num - 1] = current_pin_state; last_sample_valid[gpio_num - 1] = true; -} \ No newline at end of file +} + + +/* Analog speed control input */ + +static void update_analog_endpoint(const struct PWMMapping_t *map, int gpio) +{ + float fraction = get_adc_voltage(get_gpio_port_by_pin(gpio), get_gpio_pin_by_pin(gpio)) / 3.3f; + float value = map->min + (fraction * (map->max - map->min)); + get_endpoint(map->endpoint)->set_from_float(value); +} + +static void analog_polling_thread(void *) +{ + while (true) { + for (int i = 0; i < GPIO_COUNT; i++) { + struct PWMMapping_t *map = &board_config.analog_mappings[i]; + + if (is_endpoint_ref_valid(map->endpoint)) + update_analog_endpoint(map, i + 1); + } + osDelay(200); + } +} + +void start_analog_thread() +{ + osThreadDef(thread_def, analog_polling_thread, osPriorityLow, 0, 4*512); + osThreadCreate(osThread(thread_def), NULL); +} diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 4af6e3e0..e098c75f 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -53,6 +53,8 @@ void pwm_in_init(); void update_brake_current(); +void start_analog_thread(); + #ifdef __cplusplus } #endif diff --git a/Firmware/MotorControl/main.cpp b/Firmware/MotorControl/main.cpp index 18b88433..4766cf54 100644 --- a/Firmware/MotorControl/main.cpp +++ b/Firmware/MotorControl/main.cpp @@ -208,6 +208,8 @@ int odrive_main(void) { axes[i]->start_thread(); } + start_analog_thread(); + system_stats_.fully_booted = true; return 0; } diff --git a/Firmware/MotorControl/odrive_main.h b/Firmware/MotorControl/odrive_main.h index 4e4db160..00be19f0 100644 --- a/Firmware/MotorControl/odrive_main.h +++ b/Firmware/MotorControl/odrive_main.h @@ -75,6 +75,7 @@ struct BoardConfig_t { //make_protocol_definitions()), make_protocol_object("axis1", axes[1]->make_protocol_definitions()), make_protocol_object("can", can1_ctx.make_protocol_definitions()), From 414f84a2ce16b2616141809368ef778329586551 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Thu, 6 Dec 2018 20:21:00 -0800 Subject: [PATCH 2/4] add dump errors util function --- CHANGELOG.md | 3 +++ docs/troubleshooting.md | 16 ++----------- tools/odrive/enums.py | 52 ++++++++++++++++++++++++++++++++--------- tools/odrive/shell.py | 5 ++-- tools/odrive/utils.py | 42 ++++++++++++++++++++++++++++++--- 5 files changed, 88 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d77a003e..6b001221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Unreleased Features Please add a note of your changes below this heading if you make a Pull Request. +### Added +* `dump_errors()` utility function in odrivetool to dump, decode and optionally clear errors. + # Releases ## [0.4.7] - 2018-11-28 ### Added diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index c05c7f92..c5556d02 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -14,21 +14,9 @@ Table of Contents: ## Error codes -If your ODrive is not working as expected, run `odrivetool` and type `hex(.error)` Enter where `` is the axis that isn't working. This will display a [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) representation of the error code. Each bit represents one error flag. - -
Example
-Say you got this error output: -```python -In [1]: hex(odrv0.axis0.error) -Out[1]: '0x6' -``` - -Written in binary, the number `0x6` corresponds to `110`, that means bits 1 and 2 are set (counting starts at 0). -Looking at the reference below, this means that both `ERROR_DC_BUS_UNDER_VOLTAGE` and `ERROR_DC_BUS_OVER_VOLTAGE` occurred. -
- -The axis error may say that some other component has failed. Say it reports `ERROR_ENCODER_FAILED`, then you need to go check the encoder error: `hex(.encoder.error)`. +If your ODrive is not working as expected, run `odrivetool` and type `dump_errors(odrv0)` Enter. This will dump a list of all the errors that are present. To also clear all the errors, you can run `dump_errors(odrv0, True)`. +The following sections will give some guidance on the most common errors. You may also check the code for the full list of errors: * Axis error flags defined [here](../Firmware/MotorControl/axis.hpp). * Motor error flags defined [here](../Firmware/MotorControl/motor.hpp). * Encoder error flags defined [here](../Firmware/MotorControl/encoder.hpp). diff --git a/tools/odrive/enums.py b/tools/odrive/enums.py index 19572c90..26e0f816 100644 --- a/tools/odrive/enums.py +++ b/tools/odrive/enums.py @@ -11,17 +11,47 @@ AXIS_STATE_ENCODER_INDEX_SEARCH = 6 AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7 AXIS_STATE_CLOSED_LOOP_CONTROL = 8 -AXIS_ERROR_NONE = 0 -AXIS_ERROR_INVALID_STATE = 1 -#AXIS_ERROR_DC_BUS_UNDER_VOLTAGE = 2 -#AXIS_ERROR_DC_BUS_OVER_VOLTAGE = 3 -#AXIS_ERROR_CURRENT_MEASUREMENT_TIMEOUT = 4 -#AXIS_ERROR_CONTROL_LOOP_TIMEOUT = 5 -#AXIS_ERROR_MOTOR_FAILED = 6 -#AXIS_ERROR_SENSORLESS_ESTIMATOR_FAILED = 7 -#AXIS_ERROR_ENCODER_FAILED = 8 -#AXIS_ERROR_CONTROLLER_FAILED = 9 -#AXIS_ERROR_POS_CTRL_DURING_SENSORLESS = 10 +class errors: + class axis: + ERROR_NONE = 0x00 + ERROR_INVALID_STATE = 0x01 # Date: Mon, 17 Dec 2018 13:51:03 -0800 Subject: [PATCH 3/4] add ignore_illegal_hall_state --- Firmware/MotorControl/encoder.cpp | 6 ++++-- Firmware/MotorControl/encoder.hpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index 8c0691f8..9b964f21 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -271,8 +271,10 @@ bool Encoder::update() { if (delta_enc > 3) delta_enc -= 6; } else { - set_error(ERROR_ILLEGAL_HALL_STATE); - return false; + if (!config_.ignore_illegal_hall_state) { + set_error(ERROR_ILLEGAL_HALL_STATE); + return false; + } } } break; diff --git a/Firmware/MotorControl/encoder.hpp b/Firmware/MotorControl/encoder.hpp index 78f8f4f6..96e1a914 100644 --- a/Firmware/MotorControl/encoder.hpp +++ b/Firmware/MotorControl/encoder.hpp @@ -37,6 +37,7 @@ public: float offset_float = 0.0f; // Sub-count phase alignment offset float calib_range = 0.02f; float bandwidth = 1000.0f; + bool ignore_illegal_hall_state = false; }; Encoder(const EncoderHardwareConfig_t& hw_config, @@ -106,7 +107,8 @@ public: make_protocol_property("offset_float", &config_.offset_float), make_protocol_property("bandwidth", &config_.bandwidth, [](void* ctx) { static_cast(ctx)->update_pll_gains(); }, this), - make_protocol_property("calib_range", &config_.calib_range) + make_protocol_property("calib_range", &config_.calib_range), + make_protocol_property("ignore_illegal_hall_state", &config_.ignore_illegal_hall_state) ) ); } From 6e34beba9fa88e13610e46c586869ccf3084da97 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 17 Dec 2018 14:19:55 -0800 Subject: [PATCH 4/4] increase analog polling to 100Hz --- Firmware/MotorControl/low_level.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index 7748d6f4..e8fe62a4 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -734,7 +734,7 @@ static void analog_polling_thread(void *) if (is_endpoint_ref_valid(map->endpoint)) update_analog_endpoint(map, i + 1); } - osDelay(200); + osDelay(10); } }