Skip to content

Commit d017096

Browse files
authoredMar 7, 2022
logic fixes
1 parent 5e340f3 commit d017096

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed
 

‎src/main.cpp

+276
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
/*
2+
Model Rocket Telemetry Logger
3+
4+
Copyright (C) 2021 Danilo Nascimento
5+
GNU General Public License v3.0
6+
Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications,
7+
which include larger works using a licensed work, under the same license.
8+
Copyright and license notices must be preserved. Contributors provide an express grant of patent rights.
9+
10+
Contact information
11+
-------------------
12+
E-mail: ndanilo8@hotmail.com
13+
Website: daniloonspace.com
14+
*/
15+
16+
#define SOFTWARE_VERSION 1.00
17+
18+
#include <Arduino.h>
19+
#include <Wire.h>
20+
21+
// Config Files
22+
#include <global.h>
23+
#include <config.h>
24+
#include <data.h>
25+
26+
// AHRS
27+
//#include <KalmanFilter/kalman.h>
28+
#include "IMU/imu.h"
29+
30+
#include "Altimeter/altimeter.h"
31+
#include "Altimeter/pyro.h"
32+
33+
// Logging and Downlink
34+
#include "telemetry.h"
35+
#include "sd.h"
36+
37+
// State indicators and battery feedback
38+
#include "battery.h"
39+
#include "led.h"
40+
41+
// EKF ekf;
42+
IMU imu;
43+
Altimeter altimeter;
44+
Pyro pyro;
45+
Telemetry telemetry;
46+
SDLogger sdLoggger;
47+
EPS battery;
48+
LED led;
49+
50+
unsigned long prevLoopTime, currentLoopTime, startTime;
51+
52+
Chrono ekfTimer;
53+
Chrono liftoffTimer; // time taken to detect positive liftoff
54+
55+
void setup()
56+
{
57+
int delayPeriod = 400; // ms
58+
// goToState(IDLE);
59+
// initialize debuging
60+
#if is_DEBUG
61+
62+
goToState(TEST);
63+
Serial.begin(SERIAL_BAUD);
64+
while (!Serial)
65+
{
66+
; // pause till we open our serial monitor
67+
}
68+
Serial.println("*-*-*-*-*-*-*-*-*-*-*\nModel Rocket Telemetry Logger\nSoftware Version: " + String(SOFTWARE_VERSION) + "\n*-*-*-*-*-*-*-*-*-*-*");
69+
delay(delayPeriod);
70+
#endif
71+
72+
Wire.begin();
73+
SPI.begin();
74+
75+
bool startupError = false;
76+
// delays make it easier to read
77+
if (!led.begin())
78+
startupError = true;
79+
80+
#if is_RADIO
81+
delay(delayPeriod);
82+
if (!telemetry.begin())
83+
startupError = true;
84+
#endif
85+
86+
delay(delayPeriod);
87+
if (!imu.begin())
88+
startupError = true;
89+
90+
delay(delayPeriod);
91+
if (!pyro.begin())
92+
startupError = true;
93+
94+
delay(delayPeriod);
95+
if (!altimeter.begin())
96+
startupError = true;
97+
98+
delay(delayPeriod);
99+
if (!battery.begin())
100+
startupError = true;
101+
102+
#if is_LOGGING
103+
delay(delayPeriod);
104+
if (!sdLoggger.begin())
105+
startupError = true;
106+
#endif
107+
108+
delay(delayPeriod);
109+
110+
// ekf.initkalman();
111+
112+
while (startupError == true)
113+
{
114+
// beep and light red LED
115+
// led.led_ON();
116+
;
117+
}
118+
}
119+
120+
void loop()
121+
{
122+
// Timing
123+
currentLoopTime = micros();
124+
data.delta_t = float(currentLoopTime - prevLoopTime) / 1000000.0f;
125+
prevLoopTime = currentLoopTime;
126+
127+
// this is the flight timestamp
128+
if (data.state < LIFTOFF)
129+
{
130+
data.flightTime = 0.0;
131+
startTime = millis();
132+
}
133+
else if (data.state > LIFTOFF || data.state < LANDED)
134+
{
135+
data.flightTime = float((millis() - startTime) / 1000.0f);
136+
}
137+
else if (data.state == LANDED)
138+
{
139+
data.flightTime = data.flightTime;
140+
}
141+
142+
// functions to run every loop
143+
imu.update(); // updates the IMU when new data is available
144+
altimeter.update(); // updates the barometric sensor when new data is available
145+
battery.readVoltate(); // reads the battery voltage
146+
147+
/*float accel = (data.imu.accel.x - 9.81); // accel - gravity -> read 0 ms-2 whe at rest
148+
ekf.predict(accel); // predicts system state according to acceleration data (x axis)
149+
150+
if (ekfTimer.hasPassed(EKF_UPDATE_TIME))
151+
{
152+
ekf.updateBaro(data.altimeter.altitude); // update ekf with barometric data
153+
ekfTimer.restart(); // restart timer for next update
154+
}
155+
*/
156+
157+
switch (data.state)
158+
{
159+
case IDLE:
160+
// add a radio receiver function to change state or a physical button when pressed or not pressed it changes to liftoff state (remove before flight kinda thing)
161+
// right now it will just forward to liftoff detection mode
162+
163+
// Checks continuity every (check config.h for timer)
164+
pyro.checkContinuity();
165+
goToState(LIFTOFF);
166+
break;
167+
168+
case LIFTOFF:
169+
#if is_DEBUG
170+
Serial.println("LIFTOFF!");
171+
#endif
172+
if ((data.imu.accel.x - EARTH_ACCEL) >= LAUNCH_ACCEL_THRESHOLD || data.altimeter.altitude >= LIFTOFF_ALTITUDE_THRESHOLD)
173+
{
174+
if (liftoffTimer.hasPassed(LAUNCH_ACCEL_TIME_THRESHOLD)) // noise safe timer so liftoff is only detect if a accel threshold is exceded for some particular time
175+
goToState(POWERED_ASCENT);
176+
}
177+
break;
178+
179+
case POWERED_ASCENT:
180+
#if is_DEBUG
181+
Serial.println("POWERED_ASCENT!");
182+
#endif
183+
// FIXME
184+
// calculate total accel of the vehicle = sqrt(x^2 + y^2 + z^2)
185+
data.imu.accelTotal = (sqrt(sq(data.imu.accel.x) + sq(data.imu.accel.y) + sq(data.imu.accel.z)));
186+
187+
if (data.imu.accelTotal < ACCEL_UNPOWERED_THRESHOLD)
188+
goToState(MECU);
189+
190+
break;
191+
192+
case MECU:
193+
if (altimeter.detectApogge())
194+
goToState(APOGGE);
195+
196+
break;
197+
198+
case APOGGE:
199+
#if is_DEBUG
200+
Serial.println("APOGGE!");
201+
#endif
202+
if (pyro.fire())
203+
goToState(PARACHUTE_DESCENT);
204+
205+
break;
206+
207+
case PARACHUTE_DESCENT:
208+
#if is_DEBUG
209+
Serial.println("PARACHUTE_DESCENT!");
210+
#endif
211+
212+
pyro.allOff(); // just to make sure the pyro channels go off
213+
// TODO find a better way
214+
if (data.altimeter.altitude <= LIFTOFF_ALTITUDE_THRESHOLD) // this might not work if we stay above the pre-set AGL altitute, then the threshold will never be reached and the system will be kept in this state: to mitigate this we could check the rocket attitute to see if its stationary or not
215+
goToState(LANDED);
216+
217+
break;
218+
219+
case LANDED:
220+
// BEEP and blink LED: make it easier to find!
221+
#if is_DEBUG
222+
Serial.println("LANDED!");
223+
#endif
224+
led.blinkSlow();
225+
break;
226+
227+
case ABORT:
228+
// not much we could do besides firing the parachute...
229+
230+
break;
231+
232+
case TEST: // debug mode
233+
234+
#if is_DEBUG
235+
// Serial.print("Yaw: ");
236+
// Serial.print(data.imu.eulerAngles.yaw);
237+
// Serial.print(" , Pitch: ");
238+
// Serial.print(data.imu.eulerAngles.pitch);
239+
// Serial.print(" , Roll: ");
240+
// Serial.print(data.imu.eulerAngles.roll);
241+
242+
// Serial.print(" Accel x: ");
243+
// Serial.print(data.imu.accel.x);
244+
// Serial.print(", y: ");
245+
// Serial.print(data.imu.accel.y);
246+
// Serial.print(", z: ");
247+
// Serial.print(data.imu.accel.z);
248+
249+
// Serial.print(" Gyro x: ");
250+
// Serial.print(data.imu.gyro.x);
251+
// Serial.print(", y: ");
252+
// Serial.print(data.imu.gyro.y);
253+
// Serial.print(", z:");
254+
// Serial.print(data.imu.gyro.z);
255+
256+
// data.imu.accelTotal = (sqrt(sq(data.imu.accel.x) + sq(data.imu.accel.y) + sq(data.imu.accel.z))-EARTH_ACCEL);
257+
// Serial.printf("totalAccel: %g", data.imu.accelTotal);
258+
Serial.print(" Altitude: ");
259+
Serial.print(data.altimeter.altitude);
260+
// Serial.print(" , Temperature: ");
261+
// Serial.print(data.altimeter.temperature);
262+
// Serial.print(" , verticalSpeed: ");
263+
// Serial.print(data.altimeter.verticalVelocity);
264+
Serial.println();
265+
#endif
266+
break;
267+
}
268+
269+
#if is_RADIO
270+
telemetry.send2radio();
271+
#endif
272+
273+
#if is_LOGGING
274+
sdLoggger.logData(); // Log Data to SD Card when not on IDLE or LANDED state
275+
#endif
276+
}

0 commit comments

Comments
 (0)
Please sign in to comment.