Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b598175
Merge branch 'main' of https://github.com/CURocketEngineering/Avionic…
Jshepherd06 Oct 1, 2025
8bb12a4
feat: add fastlaunchdetector header and update implimentation
Jshepherd06 Oct 15, 2025
46e26c9
feat: added FastLaunchDetector update checks: already_launched, acl_t…
Jshepherd06 Oct 15, 2025
5583974
feat: added FastLaunchDetector reset()
Jshepherd06 Oct 15, 2025
1357657
Merge branch 'main' of https://github.com/CURocketEngineering/Avionic…
Jshepherd06 Oct 15, 2025
89409f2
fix: default fail added to update
Jshepherd06 Oct 15, 2025
0474a35
feat: add soft ascent state in StateMachine with FLD checking and LD …
Jshepherd06 Oct 29, 2025
b034453
add confirmation window to fld constructor and soft ascent comments
Jshepherd06 Oct 29, 2025
f37acf2
fix: statemachine resets fldLaunchTime_ms after no launch confirmation
Jshepherd06 Oct 29, 2025
6a92f7d
add clearpostlaunchmode default implementation and reset fld in state…
Jshepherd06 Oct 29, 2025
b4ddaea
fix: change states order for better testing
Jshepherd06 Nov 5, 2025
e0bab9d
Merge Basesm
Jshepherd06 Nov 5, 2025
f212b3f
Merge branch 'main' of https://github.com/CURocketEngineering/Avionic…
Jshepherd06 Nov 19, 2025
8c47c07
Merge branch 'main' of https://github.com/CURocketEngineering/Avionic…
Jshepherd06 Nov 19, 2025
dc008da
it Merge branch 'main' of https://github.com/CURocketEngineering/Avio…
Jshepherd06 Dec 3, 2025
24208dc
make statemachine STATE update flow more natural
Jshepherd06 Dec 3, 2025
1bc8111
Merge branch 'main' of https://github.com/CURocketEngineering/Avionic…
Jshepherd06 Jan 27, 2026
2cbc954
Merge branch 'fastlaunchdetector' of https://github.com/CURocketEngin…
Jshepherd06 Jan 27, 2026
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
5 changes: 5 additions & 0 deletions include/data_handling/DataSaver.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class IDataSaver {
// Default implementation does nothing
}

// default method that does nothing, can be overridden
virtual void clearPostLaunchMode(){
// default implementation does nothing
}

};


Expand Down
45 changes: 45 additions & 0 deletions include/state_estimation/FastLaunchDetector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef FAST_LAUNCH_DETECTOR_H
#define FAST_LAUNCH_DETECTOR_H
// need to figure out how to impliment checking for launch from LaunchDetector
#include "data_handling/CircularArray.h"
#include "data_handling/DataPoint.h"
#include "state_estimation/StateEstimationTypes.h"

// Potential returns from the update function
// Positive values are errors
// Negative values are warnings
enum FastLaunchDetectorStatus {
FLD_LAUNCH_DETECTED = 0,
FLD_ALREADY_LAUNCHED = -1,
FLD_ACL_TOO_LOW = -2, // The acceleration is too low for launch
FLD_DEFAULT_FAIL = 2,
};


class FastLaunchDetector
{
public:
/**
* Constructor
* @param accelerationThreshold_ms2: The threshold for acceleration to be considered a launch
* @param confirmationWindow_ms: The time window in ms to confirm the launch using LaunchDetector
*/
FastLaunchDetector(float accelerationThreshold, uint32_t confirmationWindow_ms = 500);

int update(AccelerationTriplet accel);

bool hasLaunched() const { return launched; }
uint32_t getLaunchedTime() const { return launchedTime_ms; }
uint32_t getConfirmationWindow() const { return confirmationWindow_ms; }
void reset();

private:
float accelerationThresholdSq_ms2;

bool launched;
uint32_t launchedTime_ms;
uint32_t confirmationWindow_ms;
};


#endif
5 changes: 4 additions & 1 deletion include/state_estimation/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "state_estimation/ApogeeDetector.h"
#include "state_estimation/LaunchDetector.h"
#include "state_estimation/VerticalVelocityEstimator.h"
#include "state_estimation/FastLaunchDetector.h"
#include "state_estimation/BaseStateMachine.h"

#include "data_handling/DataPoint.h"
Expand All @@ -27,7 +28,7 @@ class StateMachine : public BaseStateMachine {
* estimator/detector instances.
*/
StateMachine(IDataSaver* dataSaver, LaunchDetector* launchDetector, ApogeeDetector* apogeeDetector,
VerticalVelocityEstimator* verticalVelocityEstimator);
VerticalVelocityEstimator* verticalVelocityEstimator, FastLaunchDetector* fastLaunchDetector);

/**
* @brief Process new sensor data and transition states if thresholds are met.
Expand All @@ -49,6 +50,8 @@ class StateMachine : public BaseStateMachine {
LaunchDetector* launchDetector;
ApogeeDetector* apogeeDetector;
VerticalVelocityEstimator* verticalVelocityEstimator;
FastLaunchDetector* fastLaunchDetector;
uint32_t fldLaunchTime_ms = 0;
};


Expand Down
3 changes: 2 additions & 1 deletion include/state_estimation/States.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
enum FlightState {
STATE_UNARMED,
STATE_ARMED,
STATE_SOFT_ASCENT,
STATE_ASCENT,
STATE_POWERED_ASCENT,
STATE_COAST_ASCENT,
STATE_DESCENT,
STATE_DROGUE_DEPLOYED,
STATE_MAIN_DEPLOYED,
STATE_LANDED
STATE_LANDED,
};

#endif
53 changes: 53 additions & 0 deletions src/state_estimation/FastLaunchDetector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "state_estimation/FastLaunchDetector.h"

// #define DEBUG
#ifdef DEBUG
#include "ArduinoHAL.h"
#endif

FastLaunchDetector::FastLaunchDetector(float accelerationThreshold_ms2, uint32_t confirmationWindow_ms)
: accelerationThresholdSq_ms2(accelerationThreshold_ms2 * accelerationThreshold_ms2),
launched(false),
launchedTime_ms(0),
confirmationWindow_ms(confirmationWindow_ms)
{}

int FastLaunchDetector::update(AccelerationTriplet accel){

// Calculate the magnitude of the acceleration squared
const float aclMagSq = accel.x.data * accel.x.data + accel.y.data * accel.y.data + accel.z.data * accel.z.data;

// Take the average of the timestamps
// Ideally these should all be the same
const uint32_t time_ms = (accel.x.timestamp_ms + accel.y.timestamp_ms + accel.z.timestamp_ms) / 3;

//if launch already detected, ignore further data
if (launched){
#ifdef DEBUG
Serial.println("FastLaunchDetector: Data point ignored because already launched");
#endif
return FLD_ALREADY_LAUNCHED;
}

//if accel higher than threshold, launch detected
if (aclMagSq > accelerationThresholdSq_ms2){
launched = true;
launchedTime_ms = time_ms;
return FLD_LAUNCH_DETECTED;
}

//if accel lower than threshold, acl too low
if (aclMagSq < accelerationThresholdSq_ms2) {
#ifdef DEBUG
Serial.println("FastLaunchDetector: Acceloration below threshold");
#endif
return FLD_ACL_TOO_LOW;
}

return FLD_DEFAULT_FAIL;
}

void FastLaunchDetector::reset(){
launched = false;
launchedTime_ms = 0;
}
67 changes: 66 additions & 1 deletion src/state_estimation/StateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@
StateMachine::StateMachine(IDataSaver* dataSaver,
LaunchDetector* launchDetector,
ApogeeDetector* apogeeDetector,
VerticalVelocityEstimator* verticalVelocityEstimator)
VerticalVelocityEstimator* verticalVelocityEstimator,
FastLaunchDetector* fastLaunchDetector)
: dataSaver(dataSaver),
launchDetector(launchDetector),
apogeeDetector(apogeeDetector),
verticalVelocityEstimator(verticalVelocityEstimator),
fastLaunchDetector(fastLaunchDetector),
state(STATE_ARMED)
{
}

int StateMachine::update(const AccelerationTriplet& accel, const DataPoint& alt) {
// Update the state
int lpStatus = LP_DEFAULT_FAIL;
int fldStatus = FLD_DEFAULT_FAIL;

switch (state) {
case STATE_ARMED:
// Serial.println("lp update");
lpStatus = launchDetector->update(accel);
fldStatus = fastLaunchDetector->update(accel);
// Serial.println(lpStatus);
if (launchDetector->isLaunched()) {
// Change state to ascent
Expand All @@ -45,7 +49,68 @@ int StateMachine::update(const AccelerationTriplet& accel, const DataPoint& alt)
// Update the vertical velocity estimator
verticalVelocityEstimator->update(accel, alt);
}
if (fastLaunchDetector->hasLaunched()) {
// Change state to soft ascent
state = STATE_SOFT_ASCENT;

// Save the FLD launch time
fldLaunchTime_ms = fastLaunchDetector->getLaunchedTime();

// Log the state change
dataSaver->saveDataPoint(
DataPoint(accel.x.timestamp_ms, STATE_SOFT_ASCENT),
STATE_CHANGE
);

// Put the data saver into post-launch mode
dataSaver->launchDetected(fastLaunchDetector->getLaunchedTime());
}
break;

case STATE_SOFT_ASCENT:
/*
* In soft ascent, we are waiting for confirmation of launch from the LaunchDetector.
* If LaunchDetector confirms launch within the confirmation window, we transition to ASCENT.
* If the confirmation window passes without confirmation, we revert to ARMED
* and clear post-launch mode.
*/
// Serial.println("lp update");
lpStatus = launchDetector->update(accel);
// Serial.println(lpStatus);
if (launchDetector->isLaunched()) {
// Change state to ascent
state = STATE_ASCENT;

// Log the state change
dataSaver->saveDataPoint(
DataPoint(accel.x.timestamp_ms, STATE_ASCENT),
STATE_CHANGE
);

// Start the apogee detection system
apogeeDetector->init({alt.data, alt.timestamp_ms});

// Update the vertical velocity estimator
verticalVelocityEstimator->update(accel, alt);
}
if (accel.x.timestamp_ms - fldLaunchTime_ms > fastLaunchDetector->getConfirmationWindow()) {
// If the confirmation window has passed without launch detected by LaunchDetector,
// revert to ARMED state
state = STATE_ARMED;
fldLaunchTime_ms = 0;
fastLaunchDetector->reset();

// Log the state change
dataSaver->saveDataPoint(
DataPoint(accel.x.timestamp_ms, STATE_ARMED),
STATE_CHANGE
);

// Clear post-launch mode
dataSaver->clearPostLaunchMode();
}
break;

case STATE_ASCENT:
// Serial.println("apogee update");
// Update the vertical velocity estimator
Expand Down
Loading