From a9b90eb11a5d5d12384ec1066dd4eb69833624a6 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 24 Jun 2020 20:34:44 -0400 Subject: [PATCH 1/7] Add RLS SPI encoder (single-turn) --- Firmware/MotorControl/encoder.cpp | 7 +++++++ Firmware/MotorControl/encoder.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index d1545fc1..c9f27a36 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -311,6 +311,7 @@ void Encoder::sample_now() { case MODE_SPI_ABS_AMS: case MODE_SPI_ABS_CUI: case MODE_SPI_ABS_AEAT: + case MODE_SPI_ABS_RLS: { axis_->motor_.log_timing(Motor::TIMING_LOG_SAMPLE_NOW); // Do nothing @@ -400,6 +401,11 @@ void Encoder::abs_spi_cb(){ pos = rawVal & 0x3fff; } break; + case MODE_SPI_ABS_RLS: { + uint16_t rawVal = abs_spi_dma_rx_[0]; + pos = (rawVal >> 2) & 0x3fff; + } break; + default: { set_error(ERROR_UNSUPPORTED_ENCODER_MODE); return; @@ -469,6 +475,7 @@ bool Encoder::update() { delta_enc -= 6283; } break; + case MODE_SPI_ABS_RLS: case MODE_SPI_ABS_AMS: case MODE_SPI_ABS_CUI: case MODE_SPI_ABS_AEAT: { diff --git a/Firmware/MotorControl/encoder.hpp b/Firmware/MotorControl/encoder.hpp index fcf94101..99f93e0f 100644 --- a/Firmware/MotorControl/encoder.hpp +++ b/Firmware/MotorControl/encoder.hpp @@ -27,6 +27,7 @@ public: MODE_SPI_ABS_CUI = 0x100, //!< compatible with CUI AMT23xx MODE_SPI_ABS_AMS = 0x101, //!< compatible with AMS AS5047P, AS5048A/AS5048B (no daisy chain support) MODE_SPI_ABS_AEAT = 0x102, //!< not yet implemented + MODE_SPI_ABS_RLS = 0x103, }; const uint32_t MODE_FLAG_ABS = 0x100; From 462bdfb99ed5090a7a97d9dd3b47ef2deb0f7a75 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Jul 2020 22:19:58 -0400 Subject: [PATCH 2/7] Force position control when using ASCII `t` command --- Firmware/communication/ascii_protocol.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/communication/ascii_protocol.cpp b/Firmware/communication/ascii_protocol.cpp index a5c5d623..22761c4a 100644 --- a/Firmware/communication/ascii_protocol.cpp +++ b/Firmware/communication/ascii_protocol.cpp @@ -170,6 +170,7 @@ void ASCII_protocol_process_line(const uint8_t* buffer, size_t len, StreamSink& } else { Axis* axis = axes[motor_number]; axis->controller_.config_.input_mode = Controller::INPUT_MODE_TRAP_TRAJ; + axis->controller_.config_.control_mode = Controller::CTRL_MODE_POSITION_CONTROL; axis->controller_.input_pos_ = goal_point; axis->controller_.input_pos_updated(); axis->watchdog_feed(); From 4d7bf9ec2130607bde0bb4c8ac9a419cebec5314 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Sat, 11 Jul 2020 16:41:03 -0400 Subject: [PATCH 3/7] Fix image extension case --- docs/input_modes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/input_modes.md b/docs/input_modes.md index 32d7df86..ad248979 100644 --- a/docs/input_modes.md +++ b/docs/input_modes.md @@ -51,7 +51,7 @@ Ramps a velocity command from the current value to the target value. ## INPUT_MODE_POS_FILTER Implements a 2nd order position tracking filter. Inteded for use with step/dir interface, but can also be used with position-only commands. -![POS Filter Response](secondOrderResponse.png) +![POS Filter Response](secondOrderResponse.PNG) Result of a step command from 1000 to 0 ### Configuration Values: @@ -71,7 +71,7 @@ Not Implemented. ## INPUT_MODE_TRAP_TRAJ Implementes an online trapezoidal trajectory planner. -![Trapezoidal Planner Response](TrapTrajPosVel.png) +![Trapezoidal Planner Response](TrapTrajPosVel.PNG) ### Configuration Values: * `.trap_traj.config.vel_limit` From 883dd27a17ece18a2c76ff86dc6af1756d05390a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 11 Jul 2020 22:19:41 -0400 Subject: [PATCH 4/7] Fix static in encoder.cpp, constexpr the things --- Firmware/MotorControl/encoder.cpp | 4 ++-- Firmware/MotorControl/low_level.cpp | 8 ++++---- Firmware/MotorControl/motor.cpp | 6 +++--- Firmware/communication/can_simple.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index d1545fc1..de3b7330 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -181,8 +181,8 @@ bool Encoder::run_direction_find() { // and the encoder state 0. // TODO: Do the scan with current, not voltage! bool Encoder::run_offset_calibration() { - static const float start_lock_duration = 1.0f; - static const int num_steps = (int)(config_.calib_scan_distance / config_.calib_scan_omega * (float)current_meas_hz); + const float start_lock_duration = 1.0f; + const int num_steps = (int)(config_.calib_scan_distance / config_.calib_scan_omega * (float)current_meas_hz); // Require index found if enabled if (config_.use_index && !index_found_) { diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index 0dcc8754..2949ac64 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -28,8 +28,8 @@ /* Private macros ------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ /* Global constant data ------------------------------------------------------*/ -const float adc_full_scale = (float)(1 << 12); -const float adc_ref_voltage = 3.3f; +constexpr float adc_full_scale = static_cast(1UL << 12UL); +constexpr float adc_ref_voltage = 3.3f; /* Global variables ----------------------------------------------------------*/ // This value is updated by the DC-bus reading ADC. @@ -439,7 +439,7 @@ float get_adc_voltage(GPIO_TypeDef* GPIO_port, uint16_t GPIO_pin) { //-------------------------------- void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { - static const float voltage_scale = adc_ref_voltage * VBUS_S_DIVIDER_RATIO / adc_full_scale; + constexpr float voltage_scale = adc_ref_voltage * VBUS_S_DIVIDER_RATIO / adc_full_scale; // Only one conversion in sequence, so only rank1 uint32_t ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1); vbus_voltage = ADCValue * voltage_scale; @@ -478,7 +478,7 @@ static void decode_hall_samples(Encoder& enc, uint16_t GPIO_samples[num_GPIO]) { // TODO: Document how the phasing is done, link to timing diagram void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { #define calib_tau 0.2f //@TOTO make more easily configurable - static const float calib_filter_k = CURRENT_MEAS_PERIOD / calib_tau; + constexpr float calib_filter_k = CURRENT_MEAS_PERIOD / calib_tau; // Ensure ADCs are expected ones to simplify the logic below if (!(hadc == &hadc2 || hadc == &hadc3)) { diff --git a/Firmware/MotorControl/motor.cpp b/Firmware/MotorControl/motor.cpp index ac03e863..c599d9f6 100644 --- a/Firmware/MotorControl/motor.cpp +++ b/Firmware/MotorControl/motor.cpp @@ -73,9 +73,9 @@ void Motor::DRV8301_setup() { // Solve for exact gain, then snap down to have equal or larger range as requested // or largest possible range otherwise - static const float kMargin = 0.90f; - static const float kTripMargin = 1.0f; // Trip level is at edge of linear range of amplifer - static const float max_output_swing = 1.35f; // [V] out of amplifier + constexpr float kMargin = 0.90f; + constexpr float kTripMargin = 1.0f; // Trip level is at edge of linear range of amplifer + constexpr float max_output_swing = 1.35f; // [V] out of amplifier float max_unity_gain_current = kMargin * max_output_swing * hw_config_.shunt_conductance; // [A] float requested_gain = max_unity_gain_current / config_.requested_current_range; // [V/V] diff --git a/Firmware/communication/can_simple.cpp b/Firmware/communication/can_simple.cpp index b00b13e0..69b84f78 100644 --- a/Firmware/communication/can_simple.cpp +++ b/Firmware/communication/can_simple.cpp @@ -4,7 +4,7 @@ #include -static const uint8_t NUM_NODE_ID_BITS = 6; +static constexpr uint8_t NUM_NODE_ID_BITS = 6; static constexpr uint8_t NUM_CMD_ID_BITS = 11 - NUM_NODE_ID_BITS; void CANSimple::handle_can_message(can_Message_t& msg) { From bdb935ee99e2eb372c7419b75f9604e07d7fa838 Mon Sep 17 00:00:00 2001 From: Stephen Mounioloux Date: Mon, 6 Jul 2020 12:39:37 -0700 Subject: [PATCH 5/7] Added pos_abs_ latch in encoder::update() --- Firmware/MotorControl/encoder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index d1545fc1..52775826 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -434,6 +434,7 @@ void Encoder::abs_spi_cs_pin_init(){ bool Encoder::update() { // update internal encoder state. int32_t delta_enc = 0; + int32_t pos_abs_latched = pos_abs_; //LATCH switch (mode_) { case MODE_INCREMENTAL: { @@ -483,7 +484,7 @@ bool Encoder::update() { } abs_spi_pos_updated_ = false; - delta_enc = pos_abs_ - count_in_cpr_; + delta_enc = pos_abs_latched - count_in_cpr_; //LATCH delta_enc = mod(delta_enc, config_.cpr); if (delta_enc > config_.cpr/2) { delta_enc -= config_.cpr; @@ -501,7 +502,7 @@ bool Encoder::update() { count_in_cpr_ = mod(count_in_cpr_, config_.cpr); if(mode_ & MODE_FLAG_ABS) - count_in_cpr_ = pos_abs_; + count_in_cpr_ = pos_abs_latched; //// run pll (for now pll is in units of encoder counts) // Predict current pos From d996f02df10bbb4df492a91647c4b1b7c88ae78b Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 31 Jul 2020 15:35:05 -0400 Subject: [PATCH 6/7] Add missing input_pos_updated call on transition to closed loop --- Firmware/MotorControl/axis.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index 6130f782..7775d97d 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -303,6 +303,7 @@ bool Axis::run_closed_loop_control_loop() { // To avoid any transient on startup, we intialize the setpoint to be the current position controller_.pos_setpoint_ = *controller_.pos_estimate_src_; controller_.input_pos_ = *controller_.pos_estimate_src_; + controller_.input_pos_updated(); // Avoid integrator windup issues controller_.vel_integrator_current_ = 0.0f; From 48449f23482b802f49fde04566148a5ae47ef196 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 3 Aug 2020 20:02:24 -0700 Subject: [PATCH 7/7] release v0.5.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86db8832..faa908de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Unreleased Features Please add a note of your changes below this heading if you make a Pull Request. +# Releases +## [0.5.0] - 2020-08-03 ### Added * AC Induction Motor support. * Tracking of rotor flux through rotor time constant @@ -42,7 +44,6 @@ Please add a note of your changes below this heading if you make a Pull Request. * Change `motor.get_inverter_temp()` to use a property which was already being sampled at `motor.inverter_temp` * Fixed a numerical issue in the trajectory planner that could cause sudden jumps of the position setpoint -# Releases ## [0.4.12] - 2020-05-06 ### Fixed * Fixed a numerical issue in the trajectory planner that could cause sudden jumps of the position setpoint