Skip to content

Commit c2dc424

Browse files
l-joststojadin2701
authored andcommitted
[GS] Add data screen
1 parent 115e78a commit c2dc424

File tree

5 files changed

+238
-21
lines changed

5 files changed

+238
-21
lines changed

ground_station/src/hmi/bmp.hpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,6 @@ const unsigned char live_lat[] PROGMEM = {
5050
0x03, 0xf8, 0x00, 0x03, 0xf8, 0x00, 0x01, 0xf0, 0x00, 0x01, 0xf1, 0x80, 0x00, 0xe3, 0xc0, 0x00, 0xe7, 0xe0,
5151
0x00, 0xe1, 0x80, 0x00, 0x41, 0x80, 0x00, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5252

53-
// 'live_speed', 24x24px
54-
const unsigned char live_speed[] PROGMEM = {
55-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56-
0x01, 0xff, 0x80, 0x01, 0xff, 0x80, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x38, 0x00, 0x1c, 0x38, 0x00, 0x1c,
57-
0x60, 0x00, 0xc6, 0x60, 0x01, 0x86, 0x60, 0x03, 0x06, 0xc0, 0x06, 0x03, 0xc0, 0x0c, 0x03, 0xc0, 0x18, 0x03,
58-
0xc0, 0x30, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
59-
6053
// 'live_altitude', 24x24px
6154
const unsigned char live_altitude[] PROGMEM = {
6255
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -562,3 +555,39 @@ const unsigned char usb_logo[] PROGMEM = {
562555
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
563556
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564557
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
558+
559+
const unsigned char data_altitude_time[] PROGMEM = {
560+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x06, 0x00, 0x00,
561+
0x0f, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x3f, 0xc0, 0x00, 0x7f, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00,
562+
0x06, 0x0c, 0x00, 0x06, 0x0c, 0x00, 0x06, 0x1e, 0x00, 0x06, 0x1e, 0x00, 0x06, 0x0c, 0x00, 0x06, 0x0c, 0x00,
563+
0x1f, 0x8e, 0x00, 0x1f, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
564+
565+
const unsigned char data_altitude_peak[] PROGMEM = {
566+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x06, 0x00, 0x00,
567+
0x0f, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x3f, 0xc0, 0x00, 0x7f, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00,
568+
0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00,
569+
0x1f, 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
570+
571+
const unsigned char data_drogue_speed[] PROGMEM = {
572+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x1f, 0xc0, 0x00,
573+
0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80, 0x00,
574+
0x08, 0x80, 0x00, 0x05, 0x00, 0x00, 0x05, 0x06, 0x60, 0x02, 0x06, 0x60, 0x02, 0x06, 0x60, 0x02, 0x07, 0xe0,
575+
0x02, 0x03, 0xc0, 0x02, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
576+
577+
const unsigned char data_main_speed[] PROGMEM = {
578+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x0f, 0xfe, 0x00,
579+
0x1f, 0xff, 0x00, 0x3f, 0xff, 0x80, 0x7f, 0xff, 0xc0, 0x7f, 0xff, 0xc0, 0x20, 0x00, 0x80, 0x10, 0x01, 0x00,
580+
0x08, 0x02, 0x00, 0x04, 0x04, 0x00, 0x02, 0x08, 0xcc, 0x01, 0x10, 0xcc, 0x00, 0xa0, 0xcc, 0x00, 0x40, 0xfc,
581+
0x00, 0x40, 0x78, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
582+
583+
const unsigned char data_flight_time[] PROGMEM = {
584+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
585+
0x01, 0xff, 0x00, 0x03, 0x83, 0x80, 0x06, 0x10, 0xc0, 0x06, 0x10, 0xc0, 0x0c, 0x10, 0x60, 0x0c, 0x10, 0x60,
586+
0x0c, 0x1c, 0x60, 0x0c, 0x00, 0x60, 0x0c, 0x00, 0x60, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x03, 0x83, 0x80,
587+
0x01, 0xff, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
588+
589+
const unsigned char data_speed[] PROGMEM = {
590+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
591+
0x03, 0xff, 0x80, 0x07, 0x01, 0xc0, 0x0e, 0x00, 0xe0, 0x0c, 0x00, 0x60, 0x18, 0x00, 0x30, 0x18, 0x01, 0xb0,
592+
0x18, 0x03, 0x30, 0x18, 0x06, 0x30, 0x18, 0x0c, 0x30, 0x18, 0x38, 0x30, 0x0c, 0x38, 0x60, 0x0c, 0x00, 0x60,
593+
0x0f, 0xff, 0xe0, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

ground_station/src/hmi/hmi.cpp

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44

55
#include "hmi.hpp"
66

7+
#include <TimeLib.h>
8+
#include <algorithm>
9+
10+
#include <freertos/task.h>
11+
712
#include "console.hpp"
13+
#include "logging/flightStatistics.hpp"
814
#include "navigation.hpp"
915
#include "telemetry/telemetry.hpp"
1016
#include "utils.hpp"
1117

12-
#include <TimeLib.h>
13-
#include <freertos/task.h>
14-
1518
// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
1619
extern Telemetry link1;
1720
extern Telemetry link2;
@@ -317,12 +320,77 @@ void Hmi::testing() {
317320

318321
/* DATA */
319322

320-
void Hmi::initData() { window.initData(); }
323+
void Hmi::initData() {
324+
dataFileCount = recorder.getFileCount();
325+
326+
// The display can show a maximum of 11 entries, no scrolling implemented!
327+
// It is highly unlikely to get more than 11 flight logs because the flash is quite small
328+
dataFileCount = std::min<decltype(dataFileCount)>(dataFileCount, 11);
329+
330+
if (dataFileCount > 0) {
331+
window.initData(true);
332+
char fileName[30] = {};
333+
for (uint8_t i = 0; i < dataFileCount; i++) {
334+
recorder.getFileNameByIndex(i, fileName);
335+
if (i == dataIndex) {
336+
window.dataHighlight(fileName, i, true);
337+
} else {
338+
window.listFileName(fileName, i);
339+
}
340+
}
341+
} else {
342+
window.initData(false);
343+
}
344+
window.refresh();
345+
}
321346

322347
void Hmi::data() {
323-
if (backButton.wasPressed()) {
324-
state = MENU;
325-
window.initMenu(menuIndex);
348+
if (dataFlightStatistic) {
349+
if (backButton.wasPressed()) {
350+
dataFlightStatistic = false;
351+
initData();
352+
}
353+
} else {
354+
if (backButton.wasPressed()) {
355+
state = MENU;
356+
window.initMenu(menuIndex);
357+
dataIndex = 0;
358+
}
359+
if (downButton.wasPressed() && dataIndex < (dataFileCount - 1)) {
360+
dataIndex++;
361+
char fileName[30] = {};
362+
if (dataIndex >= 1) {
363+
recorder.getFileNameByIndex(dataIndex - 1, fileName);
364+
window.dataHighlight(fileName, dataIndex - 1, false);
365+
}
366+
recorder.getFileNameByIndex(dataIndex, fileName);
367+
window.dataHighlight(fileName, dataIndex, true);
368+
window.refresh();
369+
}
370+
if (upButton.wasPressed() && dataIndex > 0) {
371+
dataIndex--;
372+
char fileName[30] = {};
373+
if (dataIndex < (dataFileCount - 1)) {
374+
recorder.getFileNameByIndex(dataIndex + 1, fileName);
375+
window.dataHighlight(fileName, dataIndex + 1, false);
376+
}
377+
recorder.getFileNameByIndex(dataIndex, fileName);
378+
window.dataHighlight(fileName, dataIndex, true);
379+
window.refresh();
380+
}
381+
382+
if (okButton.wasPressed() && (dataFileCount > 0)) {
383+
FlightStatistics stats1;
384+
FlightStatistics stats2;
385+
char fileName[30] = {};
386+
// NOLINTNEXTLINE(cppcoreguidelines-init-variables) not sure why...
387+
const char *directory = recorder.getDirectory();
388+
recorder.getFileNameByIndex(dataIndex, fileName);
389+
stats1.parseFlightLog(directory, fileName, 1U);
390+
stats2.parseFlightLog(directory, fileName, 2U);
391+
dataFlightStatistic = true;
392+
window.dataShowFlightStatistics(stats1, stats2);
393+
}
326394
}
327395
}
328396

ground_station/src/hmi/hmi.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ class Hmi {
104104

105105
int16_t menuIndex = 0;
106106

107+
uint8_t dataIndex = 0;
108+
uint8_t dataFileCount = 0;
109+
bool dataFlightStatistic = false;
110+
107111
uint32_t flashFreeMemory = 100;
108112

109113
bool link1Log = false;

ground_station/src/hmi/window.cpp

Lines changed: 115 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void Window::initMenu(int16_t index) {
194194
drawCentreString("Sensors", 200, 233);
195195
drawCentreString("Settings", 325, 233);
196196

197-
for (int i = 0; i < 6; i++) {
197+
for (int16_t i = 0; i < 6; i++) {
198198
drawMenuHighlight(i, false);
199199
drawMenuBitmap(i, BLACK);
200200
}
@@ -261,7 +261,7 @@ void Window::initLive() {
261261
display.drawLine(0, 49, 400, 49, BLACK);
262262

263263
display.drawBitmap(5, 50, live_altitude, 24, 24, BLACK);
264-
display.drawBitmap(5, 75, live_speed, 24, 24, BLACK);
264+
display.drawBitmap(5, 75, data_speed, 24, 24, BLACK);
265265
display.drawBitmap(5, 100, live_lat, 24, 24, BLACK);
266266
display.drawBitmap(5, 125, live_lon, 24, 24, BLACK);
267267
display.drawBitmap(3, 150, live_battery, 24, 24, BLACK);
@@ -273,7 +273,7 @@ void Window::initLive() {
273273
display.drawBitmap(358, 149, live_two, 24, 24, BLACK);
274274

275275
display.drawBitmap(205, 50, live_altitude, 24, 24, BLACK);
276-
display.drawBitmap(205, 75, live_speed, 24, 24, BLACK);
276+
display.drawBitmap(205, 75, data_speed, 24, 24, BLACK);
277277
display.drawBitmap(205, 100, live_lat, 24, 24, BLACK);
278278
display.drawBitmap(205, 125, live_lon, 24, 24, BLACK);
279279
display.drawBitmap(203, 150, live_battery, 24, 24, BLACK);
@@ -842,10 +842,15 @@ void Window::updateTesting(int16_t index) {
842842
display.refresh();
843843
}
844844

845-
void Window::initData() {
845+
void Window::initData(bool fileAvailable) {
846846
clearMainScreen();
847-
drawCentreString("Coming soon...", 200, 100);
848-
display.refresh();
847+
if (!fileAvailable) {
848+
display.setTextSize(1);
849+
display.setFont(&FreeSans12pt7b);
850+
display.setTextColor(BLACK);
851+
drawCentreString("No flight logs found!", 200, 100);
852+
display.refresh();
853+
}
849854
}
850855

851856
void Window::initSensors() {
@@ -1348,3 +1353,107 @@ void Window::updateKeyboardText(char *text, uint16_t color) {
13481353
* Clears everything except the status bar.
13491354
*/
13501355
void Window::clearMainScreen() { display.fillRect(0, 19, 400, 222, WHITE); }
1356+
1357+
void Window::listFileName(const char *fileName, uint16_t index, uint16_t color) {
1358+
display.setFont(&FreeSans9pt7b);
1359+
display.setTextSize(1);
1360+
display.setTextColor(color);
1361+
display.setCursor(10, static_cast<int16_t>(33 + 20 * index));
1362+
display.print(fileName);
1363+
}
1364+
1365+
void Window::dataHighlight(const char *fileName, uint8_t index, bool highlight) {
1366+
display.fillRect(0, static_cast<int16_t>(19 + 20 * index), 400, 20, highlight ? BLACK : WHITE);
1367+
listFileName(fileName, index, highlight ? WHITE : BLACK);
1368+
}
1369+
1370+
void Window::dataShowFlightStatistics(FlightStatistics &stats1, FlightStatistics &stats2) {
1371+
clearMainScreen();
1372+
display.setTextColor(BLACK);
1373+
display.setTextSize(1);
1374+
display.setFont(&FreeSans12pt7b);
1375+
1376+
display.drawLine(199, 18, 199, 240, BLACK);
1377+
display.drawLine(200, 18, 200, 240, BLACK);
1378+
1379+
dataShowFlightStatisticsSide(stats1, 0);
1380+
dataShowFlightStatisticsSide(stats2, 1);
1381+
1382+
display.refresh();
1383+
}
1384+
1385+
void Window::dataShowFlightStatisticsSide(FlightStatistics &stats, uint16_t index) {
1386+
const auto xOffset = static_cast<int16_t>(index * 200);
1387+
1388+
// Max altitude
1389+
display.drawBitmap(static_cast<int16_t>(xOffset + 9), 25, data_altitude_peak, 24, 24, BLACK);
1390+
display.setCursor(static_cast<int16_t>(xOffset + 45), 45);
1391+
const int32_t altitude_m = stats.getMaxAltitude();
1392+
if (systemConfig.config.unitSystem == UnitSystem::kMetric) {
1393+
display.print(altitude_m);
1394+
display.print(" m");
1395+
} else {
1396+
display.print(Utils::MetersToFeet(altitude_m));
1397+
display.print(" ft");
1398+
}
1399+
1400+
// Time to apogee
1401+
display.drawBitmap(static_cast<int16_t>(xOffset + 9), 50, data_altitude_time, 24, 24, BLACK);
1402+
display.setCursor(static_cast<int16_t>(xOffset + 45), 70);
1403+
display.print(stats.getTimeToApogee(), 1);
1404+
display.print(" s");
1405+
1406+
// Max speed
1407+
display.drawBitmap(static_cast<int16_t>(xOffset + 5), 75, data_speed, 24, 24, BLACK);
1408+
display.setCursor(static_cast<int16_t>(xOffset + 45), 95);
1409+
const int32_t velocity_ms = stats.getMaxVelocity();
1410+
if (systemConfig.config.unitSystem == UnitSystem::kMetric) {
1411+
display.print(velocity_ms);
1412+
display.print(" m/s");
1413+
} else {
1414+
display.print(Utils::MetersToFeet(velocity_ms));
1415+
display.print(" ft/s");
1416+
}
1417+
1418+
// Drogue descent rate
1419+
display.drawBitmap(static_cast<int16_t>(xOffset + 8), 100, data_drogue_speed, 24, 24, BLACK);
1420+
display.setCursor(static_cast<int16_t>(xOffset + 45), 120);
1421+
const float drogue_velocity_ms = stats.getDrogueDescentRate();
1422+
if (systemConfig.config.unitSystem == UnitSystem::kMetric) {
1423+
display.print(drogue_velocity_ms, 1);
1424+
display.print(" m/s");
1425+
} else {
1426+
display.print(Utils::MetersToFeet(drogue_velocity_ms), 1);
1427+
display.print(" ft/s");
1428+
}
1429+
1430+
// Main descent rate
1431+
display.drawBitmap(static_cast<int16_t>(xOffset + 5), 125, data_main_speed, 24, 24, BLACK);
1432+
display.setCursor(static_cast<int16_t>(xOffset + 45), 145);
1433+
const float main_velocity_ms = stats.getMainDescentRate();
1434+
if (systemConfig.config.unitSystem == UnitSystem::kMetric) {
1435+
display.print(main_velocity_ms, 1);
1436+
display.print(" m/s");
1437+
} else {
1438+
display.print(Utils::MetersToFeet(main_velocity_ms), 1);
1439+
display.print(" ft/s");
1440+
}
1441+
1442+
// Latitude
1443+
display.drawBitmap(static_cast<int16_t>(xOffset + 5), 150, live_lat, 24, 24, BLACK);
1444+
display.setCursor(static_cast<int16_t>(xOffset + 45), 170);
1445+
display.print(stats.getLastLatitude(), 4);
1446+
display.print(" N");
1447+
1448+
// Longitude
1449+
display.drawBitmap(static_cast<int16_t>(xOffset + 5), 175, live_lon, 24, 24, BLACK);
1450+
display.setCursor(static_cast<int16_t>(xOffset + 45), 195);
1451+
display.print(stats.getLastLongitude(), 4);
1452+
display.print(" E");
1453+
1454+
// Flight Time
1455+
display.drawBitmap(static_cast<int16_t>(xOffset + 5), 200, data_flight_time, 24, 24, BLACK);
1456+
display.setCursor(static_cast<int16_t>(xOffset + 45), 220);
1457+
display.print(stats.getFlightTime(), 1);
1458+
display.print(" s");
1459+
}

ground_station/src/hmi/window.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <Adafruit_GFX.h>
88
#include <Adafruit_SharpMem.h>
99

10+
#include "logging/flightStatistics.hpp"
1011
#include "navigation.hpp"
1112
#include "settings.hpp"
1213
#include "telemetry/telemetryData.hpp"
@@ -59,7 +60,7 @@ class Window {
5960
void updateTesting(int16_t index);
6061
void initTestingBox(int16_t index);
6162

62-
void initData();
63+
void initData(bool fileAvailable);
6364

6465
void initSensors();
6566
void initSensorPrepareCalibrate();
@@ -77,6 +78,10 @@ class Window {
7778
void initKeyboard(char *text, uint32_t maxLength = 0);
7879
void updateKeyboard(char *text, int32_t keyHighlight, bool keyPressed = false);
7980

81+
void listFileName(const char *fileName, uint16_t index, uint16_t color = BLACK);
82+
void dataHighlight(const char *fileName, uint8_t index, bool highlight);
83+
void dataShowFlightStatistics(FlightStatistics &stats1, FlightStatistics &stats2);
84+
8085
void refresh() { display.refresh(); }
8186

8287
static constexpr uint8_t kShiftIdx = 29;
@@ -94,6 +99,8 @@ class Window {
9499
void highlightKeyboardKey(int32_t key, uint16_t color);
95100
void updateKeyboardText(char *text, uint16_t color);
96101

102+
void dataShowFlightStatisticsSide(FlightStatistics &stats, uint16_t index);
103+
97104
void clearMainScreen();
98105

99106
Adafruit_SharpMem display;

0 commit comments

Comments
 (0)