From 8a20901d827ea0f2785585af9313d498eaad91d0 Mon Sep 17 00:00:00 2001 From: Sahil Kale <32375512+sahil-kale@users.noreply.github.com> Date: Sun, 31 Dec 2023 16:03:38 +0800 Subject: [PATCH] [Docs] Update README.md and enum classes - Also add timestamp to FOC debug var so the exact frame can be plotted --- README.md | 17 ++++- .../bldc/brushless_6step_commutation.hpp | 8 +-- control_loop/bldc/brushless_control_loop.cpp | 1 + control_loop/bldc/brushless_control_loop.hpp | 70 +++++++++---------- control_loop/bldc/brushless_foc.hpp | 23 +++--- 5 files changed, 67 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 8fa785c..e94b149 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,21 @@ The following were, at one point, WIP, but are deprioritized in favour of a focu - Stepper Motor Commutation (Note: SW commutation of stepper motors should be avoided as the motor will commutate far slower) - Brushed Motor (Torque and Open-Loop Speed) -## Architecture -TBC +## Library Architecture +![image](https://github.com/sahil-kale/basilisk-actuator-control-lib/assets/32375512/a86fd9e6-1148-4635-a11f-be8f48c2e8cb) + +The components shown in blue are implemented in this library; the user must implement the other modules as per their application. This affords flexibility when implementing the library as the user can adapt the various modules as required by the specific application. + +## Development +The following commands are intended to be run on an Ubuntu 22.04 machine (and what is done right now in CI/CD). https://github.com/sahil-kale/basilisk-actuator-control-lib/issues/31 will track an eventual build system containerization. Follow the steps below for development: +1. Clone this repository +2. Run `bash scripts/setup.sh` - this will install packages on the system that are required for development. +3. Run `bash scripts/test.sh` to build the test cases. +4. Run `bash scripts/format.sh` to format the source code. +5. Run `bash scripts/linter.sh` to run the linter. + +### PR Submissions +Submit PR's against `main`. PR's that modify the source code's functionality without a unit test will not be accepted unless determined that the functionality does not require one. ## References See the simulation hook-in here that employs Simulink. It is very scrappy at the moment and was used primarily for elementary modelling exposure and verification of actuator control strategies implemented in this library off-target. https://github.com/sahil-kale/basilisk-control-loop-sim diff --git a/control_loop/bldc/brushless_6step_commutation.hpp b/control_loop/bldc/brushless_6step_commutation.hpp index e247d1e..fe55a1e 100644 --- a/control_loop/bldc/brushless_6step_commutation.hpp +++ b/control_loop/bldc/brushless_6step_commutation.hpp @@ -7,10 +7,10 @@ namespace control_loop { namespace Bldc6Step { enum class CommutationSignal { - HIGH, - LOW, - Z_RISING, - Z_FALLING, + HIGH, // The phase's DC voltage is set to high (desired voltage) + LOW, // The phase's DC voltage is set to low (ground) + Z_RISING, // The phase is set to high impedance (floating) and the voltage is rising (used for zero crossing detection) + Z_FALLING, // The phase is set to high impedance (floating) and the voltage is falling (used for zero crossing detection) }; typedef union { diff --git a/control_loop/bldc/brushless_control_loop.cpp b/control_loop/bldc/brushless_control_loop.cpp index 3a591a5..bcbd6bd 100644 --- a/control_loop/bldc/brushless_control_loop.cpp +++ b/control_loop/bldc/brushless_control_loop.cpp @@ -400,6 +400,7 @@ void BrushlessControlLoop::run_foc(float speed, utime_t current_time_us, utime_t V_alpha_beta_ = result.V_alpha_beta; // Set the debug vars + foc_debug_vars_.timestamp = current_time_us; foc_debug_vars_.theta_e = rotor_position_; foc_debug_vars_.i_direct_quad = i_direct_quad_; foc_debug_vars_.i_alpha_beta = i_alpha_beta_; diff --git a/control_loop/bldc/brushless_control_loop.hpp b/control_loop/bldc/brushless_control_loop.hpp index 843ba77..afa6bb3 100644 --- a/control_loop/bldc/brushless_control_loop.hpp +++ b/control_loop/bldc/brushless_control_loop.hpp @@ -19,19 +19,19 @@ namespace control_loop { class BrushlessControlLoop : public ControlLoop { public: enum class BrushlessControlLoopState { - STOP, - RUN, + STOP, /// The control loop is stopped + RUN, /// The control loop is running }; // Define a control loop type enum class BrushlessControlLoopType { - OPEN_LOOP, - CLOSED_LOOP, + OPEN_LOOP, /// The control loop is open loop (not relying on rotor position estimation) + CLOSED_LOOP, /// The control loop is closed loop control }; enum class BrushlessControlLoopCommutationType { - TRAPEZOIDAL, - FOC, + TRAPEZOIDAL, /// The control loop is using trapezoidal commutation + FOC, /// The control loop using current FOC commutation }; // Define FOC control-loop specific parameters @@ -39,45 +39,45 @@ class BrushlessControlLoop : public ControlLoop { public: float current_control_bandwidth_rad_per_sec; // The bandwidth of the current control loop - float phase_resistance; - float phase_inductance; - float pm_flux_linkage; + float phase_resistance; // The phase resistance of the motor (ohms) + float phase_inductance; // The phase inductance of the motor (henries) + float pm_flux_linkage; // The flux linkage of the permanent magnet (weber) - utime_t foc_start_timeout_period_us; - bool disable_ki; // Disable the ki term of the current controller + utime_t foc_start_timeout_period_us; // The timeout period for the foc start (us) + bool disable_ki; // Disable the ki term of the current controller - float speed_to_iq_gain; // Converts speed to iq reference - float i_d_reference_default; + float speed_to_iq_gain; // Converts speed to iq reference + float i_d_reference_default; // The default d current reference float current_lpf_fc; // The cutoff frequency of the low pass filter for the current controller - BldcFoc::BrushlessFocPwmControlType pwm_control_type; + BldcFoc::BrushlessFocPwmControlType pwm_control_type; // The pwm control type to use }; class BrushlessControlLoopParams { public: - BrushlessControlLoopCommutationType commutation_type; - BrushlessFocControLoopParams foc_params; - float open_loop_full_speed_theta_velocity; // rad/s + BrushlessControlLoopCommutationType commutation_type; // The commutation type to use + BrushlessFocControLoopParams foc_params; // The FOC control loop parameters + float open_loop_full_speed_theta_velocity; // The speed at which the open loop control loop is at full speed (rad/s) }; class BrushlessControlLoopStatus : public ControlLoopStatus { public: enum class BrushlessControlLoopError : uint8_t { - NO_ERROR, - PARAMS_NOT_SET, - ROTOR_ESTIMATION_FAILED, - NO_VALID_ROTOR_POSITION_ESTIMATOR, - CURRENT_CONTROL_NOT_SUPPORTED, - BUS_VOLTAGE_READ_FAILURE, - PHASE_COMMAND_FAILURE, - TOTAL_ERROR_COUNT, + NO_ERROR, /// No error + PARAMS_NOT_SET, /// The control loop parameters are not set (the pointer is null) + ROTOR_ESTIMATION_FAILED, /// The rotor estimation failed + NO_VALID_ROTOR_POSITION_ESTIMATOR, /// There is no valid rotor position estimator (primary or secondary) + CURRENT_CONTROL_NOT_SUPPORTED, /// The current control mode is not supported as the control loop type is not FOC + BUS_VOLTAGE_READ_FAILURE, /// The bus voltage read failed while running the control loop with FOC + PHASE_COMMAND_FAILURE, /// The phase duty cycle set command failed + TOTAL_ERROR_COUNT, /// The total number of errors }; enum class BrushlessControlLoopWarning : uint8_t { - NO_WARNING, - PRIMARY_ROTOR_ESTIMATOR_NOT_VALID, - ROTOR_ESTIMATOR_UPDATE_FAILURE, - TOTAL_WARNING_COUNT, + NO_WARNING, /// No warning + PRIMARY_ROTOR_ESTIMATOR_NOT_VALID, /// The primary rotor estimator is not valid + ROTOR_ESTIMATOR_UPDATE_FAILURE, /// The rotor estimator update failed + TOTAL_WARNING_COUNT, /// The total number of warnings }; BrushlessControlLoopStatus() : ControlLoopStatus() {} @@ -212,14 +212,14 @@ class BrushlessControlLoop : public ControlLoop { float desired_rotor_angle_open_loop_ = 0.0f; // FOC variables - math::alpha_beta_t i_alpha_beta_; - math::direct_quad_t i_direct_quad_; - math::direct_quad_t V_direct_quad_; - math::alpha_beta_t V_alpha_beta_; - float i_d_reference_ = 0.0f; + math::alpha_beta_t i_alpha_beta_; // The Ialpha and Ibeta current + math::direct_quad_t i_direct_quad_; // Iq and Id current + math::direct_quad_t V_direct_quad_; // Vq and Vd voltage + math::alpha_beta_t V_alpha_beta_; // The Valpha and Vbeta voltage + float i_d_reference_ = 0.0f; // The desired d current // FOC debug variables - BldcFoc::FOCDebugVars foc_debug_vars_; + BldcFoc::FOCDebugVars foc_debug_vars_; // Control Loop FOC debug variables /** * @brief Get the desired state of the control loop diff --git a/control_loop/bldc/brushless_foc.hpp b/control_loop/bldc/brushless_foc.hpp index 046ed95..ae3e9d7 100644 --- a/control_loop/bldc/brushless_foc.hpp +++ b/control_loop/bldc/brushless_foc.hpp @@ -8,19 +8,19 @@ namespace BldcFoc { // Define a pwm control type (Sine or Space-Vector) enum class BrushlessFocPwmControlType { - SINE, - SPACE_VECTOR, + SINE, // Sine PWM control + SPACE_VECTOR, // Space-Vector PWM control }; // Define a struct to hold the result of the duty cycle computation for FOC, alongside // other useful values class FocDutyCycleResult { public: - float duty_cycle_u_h = 0.0f; - float duty_cycle_v_h = 0.0f; - float duty_cycle_w_h = 0.0f; + float duty_cycle_u_h = 0.0f; // Duty cycle for phase u + float duty_cycle_v_h = 0.0f; // Duty cycle for phase v + float duty_cycle_w_h = 0.0f; // Duty cycle for phase w - math::alpha_beta_t V_alpha_beta; + math::alpha_beta_t V_alpha_beta; // The alpha/beta voltage vector }; /** @@ -76,15 +76,16 @@ svpwm_duty_cycle svpwm(float Vd, float Vq, float theta_el, float Vbus); class FOCDebugVars { public: // Inputs - float theta_e = 0.0f; - math::direct_quad_t i_direct_quad; + utime_t timestamp; // The timestamp of the FOC calculation + float theta_e = 0.0f; // The electrical theta (radians) + math::direct_quad_t i_direct_quad; // The direct/quadrature current vector // Note: it is possible to calculate i_alpha and i_beta from i_direct and i_quadrature, // but we want to capture the actual values we calculated. - math::alpha_beta_t i_alpha_beta; + math::alpha_beta_t i_alpha_beta; // The alpha/beta current vector // Outputs - math::direct_quad_t V_direct_quad; - FocDutyCycleResult duty_cycle_result; + math::direct_quad_t V_direct_quad; // The direct/quadrature voltage vector + FocDutyCycleResult duty_cycle_result; // The duty cycle result }; } // namespace BldcFoc