Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions AirbrakesDriver/Inc/airbrakes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define _AIRBRAKES_HPP_

#include "stm32g4xx.h"
#define AIRBRAKES_NUM_DEPLOYMENT_LEVELS 10
#define AIRBRAKES_MAX_CURRENT_AMPS 3.0
#define AIRBRAKES_NUM_DEPLOYMENT_LEVELS 9
#define AIRBRAKES_MAX_CURRENT_AMPS 10.0

class AirbrakesDriver {
public:
Expand All @@ -24,6 +24,8 @@ class AirbrakesDriver {
return enabled;
}

bool OverrideCurrentLevel(uint16_t lvl);


private:
TIM_HandleTypeDef* servoPWMTimer;
Expand Down Expand Up @@ -57,6 +59,19 @@ class AirbrakesDriver {

const float hz;

bool hit = false;

void SetHardwareCycle() {
servoPWMTimer->Instance->CCR1 = round(servoPWMTimer->Instance->ARR * currentDutyCycle);
}


constexpr static float MAX_VELOCITY = 0.0008;
constexpr static float MAX_ACCEL = 0.00002;

constexpr static float ABS_MIN = 0.000515;
constexpr static float ABS_MAX = 0.002485 / 2.1;


};

Expand Down
53 changes: 46 additions & 7 deletions AirbrakesDriver/airbrakes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ AirbrakesDriver::AirbrakesDriver(TIM_HandleTypeDef* servoPWMTimerHandle,
* Resets current latch and monitors for runaway current for 250ms.
*/
void AirbrakesDriver::Enable() {
if(enabled) {
return;
}

HAL_TIM_PWM_Start(servoPWMTimer, TIM_CHANNEL_1);
HAL_ADC_Start(servoADCHandle);

Expand All @@ -34,23 +38,28 @@ void AirbrakesDriver::Enable() {
HAL_Delay(10);

// Immediately stop if current starts running away
for(uint16_t i = 0; i < 250; i++) {
for(uint16_t i = 0; i < 100; i++) {
if(!CurrentGood()) {
Disable();
return;
}
HAL_Delay(1);
}
vel = 0;
enabled = true;
}

/* @brief Disables the driver. Stops ADC sampling and PWM output and disables current.
*/
void AirbrakesDriver::Disable() {
if(!enabled) {
return;
}
HAL_GPIO_WritePin(servoENPort, servoENPin, GPIO_PIN_RESET);
HAL_TIM_PWM_Stop(servoPWMTimer, TIM_CHANNEL_1);
HAL_ADC_Stop(servoADCHandle);
HAL_GPIO_WritePin(servoLatchResetPort, servoLatchResetPin, GPIO_PIN_RESET);
vel = 0;
enabled = false;
}

Expand All @@ -63,7 +72,9 @@ bool AirbrakesDriver::SetTargetLevel(uint8_t level) {
return false;
}

return SetTargetDutyCycle(static_cast<float>(level)/(AIRBRAKES_NUM_DEPLOYMENT_LEVELS-1)*(0.0025*hz-0.0005*hz)+0.0005*hz);
hit = false;
vel = 0;
return SetTargetDutyCycle(static_cast<float>(level)/(AIRBRAKES_NUM_DEPLOYMENT_LEVELS-1)*(0.0025*hz-0.0005*hz)/2.1+0.0005*hz);
}

/* @brief Set the airbrake target duty cycle directly.
Expand All @@ -76,6 +87,8 @@ bool AirbrakesDriver::SetTargetDutyCycle(float dutyFrac) {
return false;
}
targetDutyCycle = dutyFrac;
hit = false;
vel = 0;
return true;
}

Expand All @@ -98,17 +111,23 @@ float AirbrakesDriver::ReadVoltsADC() {
*/
bool AirbrakesDriver::TickControlLoop() {

if(!CurrentGood() || !IsEnabled()) {
if(!IsEnabled()) {
return false;
}

if(!CurrentGood()) {
Disable();
return false;
}

if(hit) {
return true;
}


const static float MAX_VELOCITY = 0.04;
const static float MAX_ACCEL = 0.0007;

float distance = targetDutyCycle - currentDutyCycle;
float ideal_vel = sqrtf(2.0 * MAX_ACCEL * fabsf(distance))-MAX_ACCEL;
float ideal_vel = sqrtf(2.0 * MAX_ACCEL * fabsf(distance));

if (distance < 0) {
ideal_vel = -ideal_vel;
Expand All @@ -134,7 +153,19 @@ bool AirbrakesDriver::TickControlLoop() {

currentDutyCycle += vel;

servoPWMTimer->Instance->CCR1 = round(servoPWMTimer->Instance->ARR * currentDutyCycle);
if(currentDutyCycle < ABS_MIN*hz) {
currentDutyCycle = ABS_MIN*hz;
}
if(currentDutyCycle > ABS_MAX*hz) {
currentDutyCycle = ABS_MAX*hz;
}

SetHardwareCycle();

if(abs(currentDutyCycle-targetDutyCycle) < MAX_VELOCITY) {
hit = true;
vel = 0;
}

return true;

Expand Down Expand Up @@ -166,6 +197,14 @@ bool AirbrakesDriver::CurrentGood() {
return CheckComparatorGood() && (ADCVoltsToCurrent(ReadVoltsADC()) <= AIRBRAKES_MAX_CURRENT_AMPS);
}

bool AirbrakesDriver::OverrideCurrentLevel(uint16_t lvl) {
if(SetTargetLevel(lvl)) {
currentDutyCycle = targetDutyCycle;
SetHardwareCycle();
return true;
}
return false;
}

/* @brief Checks the state of the hardware failsafe latch.
* @return true if the latch is good, i.e. current limit has not been triggered
Expand Down