Skip to content

Commit 7757f0d

Browse files
mpkarpov-uiSuragNuthulapatydivijgargkbalaji4SZhOU-c
authored
Stargazer 1.4 FSM update (#72)
* initial safety changes * functionality * fig gpio bug * what is this buffer size bug * buzzer & LED checks * pyro reset & naming * reset fr this time * more change * transitions work * midas in flight control firing pyros * funny buzz * gitignore outputs * spreading factor and timeouts * manual cobine combiner code * trying to manually combine rx feather and this branch. DO NOT MERGE THIS CODE RIGHT NOW. IT DOES NOT WORK * new gss midas-commanding-flight changes * intermediate work * added potential orientation code, needs to be checked * Update Orientation.cpp * fixed syntax errors * Added Complimentary Filter to Orientation.cpp Co-authored-by: SZhOU-c <SZhOU-c@users.noreply.github.com> Co-authored-by: sh1shir <sh1shir@users.noreply.github.com> Co-authored-by: Rithvik Bhogavilli <rbhogavilli@gmail.com> * Fixed tilt, complementary filter not correct * landing buzzer (#71) * pls * added units --------- Co-authored-by: SuragNuthulapaty <77648585+SuragNuthulapaty@users.noreply.github.com> Co-authored-by: Divij <diviaops@gmail.com> Co-authored-by: keshavbalaji <keshavbalaji2397@gmail.com> Co-authored-by: SZhOU-c <SZhOU-c@users.noreply.github.com> Co-authored-by: sh1shir <sh1shir@users.noreply.github.com> Co-authored-by: Rithvik Bhogavilli <rbhogavilli@gmail.com>
1 parent c6977e0 commit 7757f0d

File tree

8 files changed

+147
-75
lines changed

8 files changed

+147
-75
lines changed

MIDAS/src/finite-state-machines/fsm.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
130130
state = FSMState::STATE_SAFE;
131131
}
132132

133-
134133
break;
135134

136135
case FSMState::STATE_IDLE:
@@ -181,6 +180,7 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
181180
break;
182181

183182
case FSMState::STATE_SUSTAINER_IGNITION:
183+
// This state probably does not need a pyro lockout, since we have a back-transition from STATE_SECOND_BOOST
184184
// another time transition into coast after a certain amount of time
185185
if ((current_time - sustainer_ignition_time) > sustainer_ignition_to_coast_timer_threshold) {
186186
coast_time = current_time;
@@ -240,7 +240,12 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
240240

241241
case FSMState::STATE_DROGUE_DEPLOY:
242242
// if detected a sharp change in jerk then go to next state
243-
if (abs(state_estimate.jerk) < sustainer_drogue_jerk_threshold) {
243+
// Drogue deploy should ALWAYS stay for at least some time, due to a lack of a back-transition from STATE_DROGUE
244+
if((current_time - drogue_time) < sustainer_pyro_firing_time_minimum) {
245+
break;
246+
}
247+
248+
if (abs(state_estimate.jerk) > sustainer_drogue_jerk_threshold) {
244249
state = FSMState::STATE_DROGUE;
245250
break;
246251
}
@@ -261,9 +266,15 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
261266
break;
262267

263268
case FSMState::STATE_MAIN_DEPLOY:
269+
// Main deploy should ALWAYS stay for at least some time, due to a lack of a back-transition from STATE_DROGUE
270+
if((current_time - drogue_time) < sustainer_pyro_firing_time_minimum) {
271+
break;
272+
}
273+
264274
// if detected a sharp change in jerk then go to the next state
265-
if (abs(state_estimate.jerk) < sustainer_main_jerk_threshold) {
275+
if (abs(state_estimate.jerk) > sustainer_main_jerk_threshold) {
266276
state = FSMState::STATE_MAIN;
277+
main_deployed_time = current_time;
267278
break;
268279
}
269280

@@ -275,13 +286,18 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
275286

276287
case FSMState::STATE_MAIN:
277288
// if slowed down enough then go on to the next state
278-
if (abs(state_estimate.vertical_speed) <= sustainer_landed_vertical_speed_threshold) {
289+
if ((abs(state_estimate.vertical_speed) <= sustainer_landed_vertical_speed_threshold) && (current_time - main_deployed_time) > sustainer_main_to_landed_lockout) {
279290
landed_time = current_time;
280291
state = FSMState::STATE_LANDED;
281292
}
282293
break;
283294

284295
case FSMState::STATE_LANDED:
296+
297+
if((current_time - landed_time) > sustainer_landed_time_lockout) {
298+
break;
299+
}
300+
285301
// if the slow speed was too brief then return to previous state
286302
if ((abs(state_estimate.vertical_speed) > sustainer_landed_vertical_speed_threshold) && ((current_time - landed_time) > sustainer_landed_timer_threshold)) {
287303
state = FSMState::STATE_MAIN;
@@ -423,7 +439,13 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
423439
break;
424440

425441
case FSMState::STATE_DROGUE_DEPLOY:
426-
if (abs(state_estimate.jerk) < booster_drogue_jerk_threshold) {
442+
443+
// Drogue deploy should ALWAYS stay for at least some time, due to a lack of a back-transition from STATE_DROGUE
444+
if((current_time - drogue_time) < booster_pyro_firing_time_minimum) {
445+
break;
446+
}
447+
448+
if (abs(state_estimate.jerk) > booster_drogue_jerk_threshold) {
427449
state = FSMState::STATE_DROGUE;
428450
break;
429451
}
@@ -441,8 +463,15 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
441463
break;
442464

443465
case FSMState::STATE_MAIN_DEPLOY:
444-
if (abs(state_estimate.jerk) < booster_main_jerk_threshold) {
466+
467+
// Main deploy should ALWAYS stay for at least some time, due to a lack of a back-transition from STATE_DROGUE
468+
if((current_time - main_time) < booster_pyro_firing_time_minimum) {
469+
break;
470+
}
471+
472+
if (abs(state_estimate.jerk) > booster_main_jerk_threshold) {
445473
state = FSMState::STATE_MAIN;
474+
main_deployed_time = current_time;
446475
break;
447476
}
448477

@@ -452,13 +481,18 @@ FSMState FSM::tick_fsm(FSMState& state, StateEstimate state_estimate, CommandFla
452481
break;
453482

454483
case FSMState::STATE_MAIN:
455-
if (abs(state_estimate.vertical_speed) <= booster_landed_vertical_speed_threshold) {
484+
if (abs(state_estimate.vertical_speed) <= booster_landed_vertical_speed_threshold && (current_time - main_deployed_time) > booster_main_to_landed_lockout) {
456485
landed_time = current_time;
457486
state = FSMState::STATE_LANDED;
458487
}
459488
break;
460489

461490
case FSMState::STATE_LANDED:
491+
492+
if((current_time - landed_time) > booster_landed_time_lockout) {
493+
break;
494+
}
495+
462496
if ((abs(state_estimate.vertical_speed) > booster_landed_vertical_speed_threshold) && ((current_time - landed_time) > booster_landed_timer_threshold)) {
463497
state = FSMState::STATE_MAIN;
464498
}

MIDAS/src/finite-state-machines/fsm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class FSM {
4343
double drogue_time;
4444
double apogee_time;
4545
double main_time;
46+
double main_deployed_time;
4647
double landed_time;
4748
double first_separation_time;
4849
double pyro_test_entry_time;

MIDAS/src/finite-state-machines/thresholds.h

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,69 +11,81 @@
1111
// SECOND STAGE THRESHOLDS
1212
// ----------------------------------
1313

14-
// Transition to FIRST_BOOST if acceleration is greater than this
14+
// Regardless of sensor inputs, stay on pyro firing states for at LEAST this time. (ms)
15+
#define sustainer_pyro_firing_time_minimum 200
16+
17+
// Transition to FIRST_BOOST if acceleration is greater than this (G)
1518
#define sustainer_idle_to_first_boost_acceleration_threshold 3
1619

1720
// Return state to IDLE if not boosting for this amount of time (ms)
1821
#define sustainer_idle_to_first_boost_time_threshold 1000
1922

20-
// Transition to SECOND_BOOST from SUSTAINER_IGNITION if acceleration greater than this
21-
#define sustainer_ignition_to_second_boost_acceleration_threshold 3
23+
// Transition to SECOND_BOOST from SUSTAINER_IGNITION if acceleration greater than this (G)
24+
#define sustainer_ignition_to_second_boost_acceleration_threshold 4
2225

2326
// Return state to SECOND_BOOST if not boosting for this amount of time (ms)
2427
#define sustainer_second_boost_to_coast_time_threshold 1000
2528

2629
// Transition to COAST if acceleration is less than this value (g)
2730
#define sustainer_coast_detection_acceleration_threshold 0.2
2831

29-
// Reach apogee state when vertical speed is less than or equal to this value
32+
// Reach apogee state when vertical speed is less than or equal to this value (m/s)
3033
#define sustainer_coast_to_apogee_vertical_speed_threshold 15
3134

32-
// Revert back to COAST if the vertical speed in apogee is too high (was 0 before which may have caused it keep jumping back to COAST)
35+
// Revert back to COAST if the vertical speed in apogee is too high (was 0 before which may have caused it keep jumping back to COAST) (m/s)
3336
#define sustainer_apogee_backto_coast_vertical_speed_threshold 10
3437

35-
// Revert back to COAST if apogee was too brief
38+
// Revert back to COAST if apogee was too brief (ms)
3639
#define sustainer_apogee_check_threshold 1000
3740

38-
// Move on to DROGUE_DEPLOT after being in apogee for this amount of time
41+
// Move on to DROGUE_DEPLOT after being in apogee for this amount of time (ms)
3942
#define sustainer_apogee_timer_threshold 1000
4043

41-
// Move on to DROGUE after a second of reaching apogee
44+
// Move on to DROGUE after a second of reaching apogee (ms)
4245
#define sustainer_drogue_timer_threshold 3000
4346

44-
// Move on to MAIN after passing this amount of time
47+
// Move on to MAIN after passing this amount of time (ms)
4548
#define sustainer_main_to_main_deploy_timer_threshold 3000
4649

47-
// Height required to deploy the main parachutes
48-
#define sustainer_main_deploy_altitude_threshold 3000
50+
// Height required to deploy the main parachutes (m)
51+
#define sustainer_main_deploy_altitude_threshold 1006
4952

5053
// Return to SUSTAINER_IGNITION if not in SECOND_BOOST for this amount of time (ms)
5154
#define sustainer_ignition_to_second_boost_time_threshold 1000
5255

53-
// Transition straight to coast after a certain amount of time not detecting second stage boost
56+
// Transition straight to coast after a certain amount of time not detecting second stage boost (ms)
5457
#define sustainer_ignition_to_coast_timer_threshold 5000
5558

56-
// Revert back to main if the landed was too short
59+
// Revert back to main if the landed was too short (ms)
5760
#define sustainer_landed_timer_threshold 5000
5861

5962
// Return state to FIRST_BOOST if not in BURNOUT for this amount of time (ms)
6063
#define sustainer_first_boost_to_burnout_time_threshold 1000
6164

62-
// Transition to LANDED from MAIN if vertical speed is less than this threshold
63-
#define sustainer_landed_vertical_speed_threshold 20
65+
// Transition to LANDED from MAIN if vertical speed is less than this threshold (m/s)
66+
#define sustainer_landed_vertical_speed_threshold 3
67+
68+
// Lock out further transitions from LANDED after this much time passes in the LANDED state. (ms)
69+
#define sustainer_landed_time_lockout 60000
6470

65-
// Stores a small jerk value
71+
// Prevent us from inadvertently entering the LANDED state when we're at a low velocity at main deploy. (ms)
72+
#define sustainer_main_to_landed_lockout 5000
73+
74+
// Stores a small jerk value (m/s^3)
6675
#define sustainer_drogue_jerk_threshold 200
6776

68-
// Stores a small jerk value
77+
// Stores a small jerk value (m/s^3)
6978
#define sustainer_main_jerk_threshold 300
7079

7180

7281
// ----------------------------------
7382
// FIRST STAGE THRESHOLDS
7483
// ----------------------------------
7584

76-
// Transition to FIRST_BOOST if acceleration is greater than this
85+
// Regardless of sensor inputs, stay on pyro firing states for at LEAST this time. (ms)
86+
#define booster_pyro_firing_time_minimum 200
87+
88+
// Transition to FIRST_BOOST if acceleration is greater than this (G)
7789
#define booster_idle_to_first_boost_acceleration_threshold 3
7890

7991
// Return state to IDLE if not boosting for this amount of time (ms)
@@ -85,43 +97,51 @@
8597
// Transition to COAST if acceleration is less than this value (g)
8698
#define booster_coast_detection_acceleration_threshold 0.2
8799

88-
// Reach apogee state when vertical speed is less than or equal to this value
100+
// Reach apogee state when vertical speed is less than or equal to this value (m/s)
89101
#define booster_coast_to_apogee_vertical_speed_threshold 20
90102

91-
// Revert back to COAST if apogee was too brief
103+
// Revert back to COAST if apogee was too brief (ms)
92104
#define booster_apogee_check_threshold 1000
93105

94-
// Move on to DROGUE_DEPLOT after being in apogee for this amount of time
106+
// Move on to DROGUE_DEPLOT after being in apogee for this amount of time (ms)
95107
#define booster_apogee_timer_threshold 1000
96108

97-
// Move on to DROGUE after a second of reaching apogee
109+
// Move on to DROGUE after a second of reaching apogee (ms)
98110
#define booster_drogue_timer_threshold 3000
99111

100-
// Move on to MAIN after passing this amount of time
112+
// Move on to MAIN after passing this amount of time (ms)
101113
#define booster_main_to_main_deploy_timer_threshold 3000
102114

103-
// Height required to deploy the main parachutes
104-
#define booster_main_deploy_altitude_threshold 3000
115+
// Height required to deploy the main parachutes (m)
116+
// [STARGAZER 1.4] This is a "dontcare" value --> The booster does not have a drogue, we transition immediately to MAIN
117+
#define booster_main_deploy_altitude_threshold 999999
118+
105119
// Return to SUSTAINER_IGNITION if not in SECOND_BOOST for this amount of time (ms)
106120
#define booster_ignition_to_second_boost_time_threshold 1000
107121

108-
// Transition straight to coast after a certain amount of time not detecting second stage boost
122+
// Transition straight to coast after a certain amount of time not detecting second stage boost (ms)
109123
#define booster_ignition_to_coast_timer_threshold 5000
110124

111-
// Revert back to main if the landed was too short
125+
// Revert back to main if the landed was too short (ms)
112126
#define booster_landed_timer_threshold 5000
113127

114128
// Return state to FIRST_BOOST if not in BURNOUT for this amount of time (ms)
115129
#define booster_first_boost_to_burnout_time_threshold 1000
116130

117-
// Transition to LANDED from MAIN if vertical speed is less than this threshold
118-
#define booster_landed_vertical_speed_threshold 20
131+
// Transition to LANDED from MAIN if vertical speed is less than this threshold (G)
132+
#define booster_landed_vertical_speed_threshold 4
133+
134+
// Lock out further transitions from LANDED after this much time passes in the LANDED state. (ms)
135+
#define booster_landed_time_lockout 60000
136+
137+
// Prevent us from inadvertently entering the LANDED state when we're at a low velocity at main deploy. (ms)
138+
#define booster_main_to_landed_lockout 5000
119139

120-
// Stores a small jerk value
140+
// Stores a small jerk value (m/s^3)
121141
#define booster_first_separation_jerk_threshold 300
122142

123-
// Stores a small jerk value
143+
// Stores a small jerk value (m/s^3)
124144
#define booster_drogue_jerk_threshold 200
125145

126-
// Stores a small jerk value
146+
// Stores a small jerk value (m/s^3)
127147
#define booster_main_jerk_threshold 300

MIDAS/src/hardware/Orientation.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include "sensor_data.h"
55
#include <cmath>
66

7-
87
// global static instance of the sensor
98
Adafruit_BNO08x imu(BNO086_RESET);
109
#define REPORT_INTERVAL_US 5000
@@ -34,6 +33,12 @@ ErrorCode OrientationSensor::init()
3433
return ErrorCode::NoError;
3534
}
3635

36+
float angle_between_quaternions(const Quaternion &q1, const Quaternion &q2)
37+
{
38+
float dot_product = Quaternion::dot(q1, q2);
39+
return 2.0f * std::acos(std::fabs(dot_product));
40+
}
41+
3742
/**
3843
* @brief Turns a quaternion into its corresponding Euler 3D vector representation
3944
*
@@ -87,6 +92,27 @@ Vec3 quaternionToEulerGI(sh2_GyroIntegratedRV_t *rotational_vector, bool degrees
8792
degrees);
8893
}
8994

95+
std::tuple<float, float, float> euler_to_vector(float pitch, float yaw)
96+
{
97+
float x = cos(pitch) * cos(yaw);
98+
float y = cos(pitch) * sin(yaw);
99+
float z = sin(pitch);
100+
return {x, y, z};
101+
}
102+
103+
float angular_difference(float pitch1, float yaw1, float pitch2, float yaw2)
104+
{
105+
auto [x1, y1, z1] = euler_to_vector(pitch1, yaw1);
106+
auto [x2, y2, z2] = euler_to_vector(pitch2, yaw2);
107+
108+
float mag1 = sqrt(x1 * x1 + y1 * y1 + z1 * z1);
109+
float mag2 = sqrt(x2 * x2 + y2 * y2 + z2 * z2);
110+
111+
float dot_product = x1 * x2 + y1 * y2 + z1 * z2;
112+
113+
return std::acos(dot_product / (mag1 * mag2));
114+
}
115+
90116
/**
91117
* @brief Generates a rotation matrix that transforms a vector by the rotations described in rpy_vec {roll, pitch, yaw} (in that order!)
92118
*/
@@ -156,6 +182,11 @@ Orientation OrientationSensor::read()
156182

157183
Orientation sensor_reading;
158184
sensor_reading.has_data = true;
185+
/*
186+
sensor_reading.yaw = -filtered_euler.y;
187+
sensor_reading.pitch = filtered_euler.x;
188+
sensor_reading.roll = filtered_euler.z;
189+
*/
159190

160191
sensor_reading.yaw = -euler.y;
161192
sensor_reading.pitch = euler.x;
@@ -179,6 +210,7 @@ Orientation OrientationSensor::read()
179210
if (initial_flag == 0)
180211
{
181212
initial_orientation = sensor_reading;
213+
initial_quaternion = quat;
182214
initial_flag = 1;
183215
}
184216

MIDAS/src/hardware/sensors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct VoltageSensor {
6767
*/
6868
struct OrientationSensor {
6969
Orientation initial_orientation;
70+
Quaternion initial_quaternion;
7071
uint8_t initial_flag;
7172

7273
float prev_x = 0;

MIDAS/src/sensor_data.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,17 @@ struct Magnetometer {
170170
float mz;
171171
};
172172

173+
struct Quaternion {
174+
float w, x, y, z;
175+
176+
static float dot(const Quaternion& q1, const Quaternion& q2) {
177+
return q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
178+
}
179+
180+
181+
182+
};
183+
173184
/**
174185
* @struct Orientation
175186
*

0 commit comments

Comments
 (0)