Skip to content
Merged
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
2 changes: 1 addition & 1 deletion UI/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ IMGUI_SRC := imgui\imgui.cpp \
implot3d\implot3d.cpp \
implot3d\implot3d_items.cpp

APP_SRC := main.cpp ui.cpp ui_components.cpp ui_graphs.cpp flight_data.cpp platform_win.cpp flight_commands.cpp
APP_SRC := main.cpp ui.cpp ui_components.cpp ui_graphs.cpp flight_data.cpp platform_win.cpp flight_commands.cpp port_selector.cpp flash_dump.cpp csr_trigger.cpp
SRC := $(APP_SRC) $(IMGUI_SRC)
BUILD_FOLDER := build

Expand Down
21 changes: 21 additions & 0 deletions UI/include/csr_trigger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include "platform_win.h"

// abstract:
// - file input for flight log
// - needs to trigger CSR by first calling make (to ensure csr executable is updated)
// - fail if CSR build fails
// - call csr executable
// - pass flight log file path, output file path, and optional csv file path
// - wait for csr to complete
// - fail if csr gives error code
// - switch to flight replay window and set the input file path to the csr output
namespace CSRTrigger {
extern char input_fp[MAX_PATH];
void render();

bool in_progress();

void update();

}; // namespace CSRTrigger
21 changes: 21 additions & 0 deletions UI/include/flash_dump.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once


// abstract:
// state variable
// button for beginning dump
// - prompt user for output file path
// - sends start command over fv serial
// - dump over selected dump serial, if none is selected then dump over fv serial
// upon completion, switch to CSR window
// - pre-fill the open file path with dump output
namespace FlashDump
{
bool is_in_progress();

void render();

// separate update and render functions exposed so that the dump can continue even if dump menu is closed
// should be called unconditionally every frame
void update();
};
18 changes: 11 additions & 7 deletions UI/include/flight_data_state.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef ASTRA_GS_FLIGHT_DATA_STATE
#define ASTRA_GS_FLIGHT_DATA_STATE

#include "port_selector.h"
#include "serial.h"
#include <memory>
#include <stdio.h>
#include <string>
#include <vector>
Expand All @@ -15,18 +18,19 @@ struct ComPortInfo {

#define MODE_SERIAL_INPUT 0
#define MODE_FILE_INPUT 1
#define MODE_FLASH_DUMP 2
#define MODE_CSR_TRIGGER 3

struct flight_data_state_t {
int data_input_mode;

// serial input mode
std::vector<ComPortInfo> ports;
int fv_serial_idx; // serial index for flight vehicle radio
int rtk_serial_idx; // serial index for GPS RTK source
bool fv_serial_port_open; // used for opening/closing ports and communicating status back to user
bool rtk_serial_port_open; // used for opening/closing ports and communicating status back to user
HANDLE fv_serial = INVALID_HANDLE_VALUE;
HANDLE rtk_serial = INVALID_HANDLE_VALUE;
int fv_serial_idx; // serial index for flight vehicle radio
int rtk_serial_idx; // serial index for GPS RTK source

PortSelector fv_serial = PortSelector("Vehicle: ", "##fv_serial_picker", "##fv_serial_open");
PortSelector rtk_serial = PortSelector("RTK: ", "##rtk_serial_picker", "##rtk_serial_open");

// file input mode
char selected_file_path[260] = "";
Expand All @@ -35,7 +39,7 @@ struct flight_data_state_t {
int file_read_progress;
bool file_reading_paused;

uint64_t replay_play_start_us; // the time when the play button was last pressed
uint64_t replay_play_start_us; // the time when the play button was last pressed
uint64_t replay_pause_offset_us; // the time "accumulated" before the play button was last pressed
};

Expand Down
25 changes: 21 additions & 4 deletions UI/include/platform_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,28 @@
void OpenFileDialog(char *path);
const char *get_filename_from_path(const char *full_path);
std::vector<ComPortInfo> enumerate_ports();
void open_serial_port(HANDLE *hSerial, const char *com_port);
void close_serial_port(HANDLE *hSerial);
void read_from_serial_port(HANDLE *hSerial, bool *open_flag, char *read_buf, size_t MAX_READ_LEN, int *bytes_read);
void write_to_serial_port(HANDLE *hSerial, bool *open_flag, const char *msg, size_t len, bool end_with_newline);

Serial *open_serial_port(const char *name);
unsigned long long get_time_us();
void platform_begin();

void SaveFileDialog(char *path);
void SaveFileDialog(char *path, const char *file_specs[], const char *spec_names[], unsigned int n_specs, unsigned int default_spec_idx);

// triggers a build of the csr code
void* spawn_csr_make();

// spawns csr process
void* spawn_csr(const char* input_fp, const char* output_fp, const char* output_csv_fp = nullptr);


struct Process_Status
{
bool running;
int exit_code;
};
Process_Status check_process_status(void *handle);

void close_process(void* handle);

#endif
33 changes: 33 additions & 0 deletions UI/include/port_selector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "Serial.h"

class PortSelector {
public:
PortSelector(const char *name, const char *combo_id, const char *checkbox_id);

void render();

bool is_open();

void close();

~PortSelector();

// return 0 on error
int write(const char *data, unsigned int len, bool end_with_newline = false);

// return # of bytes read, -1 on error
int read(char *data, unsigned int max_len);

private:
Serial *active_port = nullptr;
char *_name;
char *_combo_id;
char *_checkbox_id;
int _index = 0;
};


// renders a refresh button for refreshing the available ports list in FlightDataState
void render_port_refresh_button();
17 changes: 17 additions & 0 deletions UI/include/serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>

class Serial {
public:
virtual bool is_open() = 0;

// return 0 on error
virtual int write(const char* data, unsigned int len, bool end_with_newline = false) = 0;

// return # of bytes read, -1 on error
virtual int read(char* data, unsigned int max_len) = 0;

virtual void close() = 0;

virtual ~Serial() = default; // intended to be overwritten by inheriting class
};
126 changes: 126 additions & 0 deletions UI/src/csr_trigger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include "csr_trigger.h"
#include "flight_data_state.h"
#include "imgui.h"
#include "platform_win.h"
#include "flight_data.h"

namespace CSRTrigger {
bool _in_progress = false;

char input_fp[MAX_PATH]{};
char output_fp[MAX_PATH]{};
char output_csv_fp[MAX_PATH]{};

bool output_csv = false;

enum Stage { MAKE = 0, CSR = 1 };

Stage stage = Stage::MAKE;
void *current_handle = nullptr;
char *success_message = nullptr;

void render() {
if (in_progress()) {
// just display a status
if (stage == Stage::MAKE) {
ImGui::Text("Building CSR...");
} else {
ImGui::Text("Running CSR...");
}
} else {
// select input file
if (ImGui::Button("Choose Input File")) {
OpenFileDialog(input_fp);
}

if (input_fp[0]) {
ImGui::Text("%s", get_filename_from_path(input_fp));
}

// select output file
if (ImGui::Button("Choose CSR Output")) {
const char *specs[] = {"*.bin", "*.*"};
const char *labels[] = {"Binary File", "All Files"};
SaveFileDialog(output_fp, specs, labels, 2, 0);
}

if (output_fp[0]) {
ImGui::Text("%s", get_filename_from_path(output_fp));
}

// optional - select csv output file
ImGui::Checkbox("Output CSV", &output_csv);

if (output_csv) {
if (ImGui::Button("Choose CSV Output")) {
const char *specs[] = {"*.csv", "*.*"};
const char *labels[] = {"Comma Separated Values File", "All Files"};
SaveFileDialog(output_csv_fp, specs, labels, 2, 0);
}

if (output_csv_fp[0]) {
ImGui::Text("%s", get_filename_from_path(output_csv_fp));
}
}

if (input_fp[0] && output_fp[0] && (!output_csv || output_csv_fp[0])) {
if (ImGui::Button("Begin CSR")) {
_in_progress = true;

stage = Stage::MAKE;
// trigger a CSR build
current_handle = spawn_csr_make();
}
}

if (success_message) {
ImGui::Text("%s", success_message);
}
}
}

bool in_progress() {
return _in_progress;
}

void update() {
if (!in_progress()) {
return;
}

Process_Status status = check_process_status(current_handle);

if (status.running) {
return;
}

close_process(current_handle);
current_handle = nullptr;

if (stage == Stage::MAKE) {
if (status.exit_code == 0) // build succeeded
{
stage = Stage::CSR;
current_handle = spawn_csr(input_fp, output_fp, output_csv ? output_csv_fp : nullptr);
} else {
success_message = "ERROR: BUILD FAILED";
_in_progress = false;
return;
}
} else { // stage == Stage::CSR
if (status.exit_code == 0) // csr succeeded
{
success_message = "CSR Finished Successfully";

FlightDataState.data_input_mode = MODE_FILE_INPUT;
strcpy(FlightDataState.selected_file_path, output_fp);
load_flight_replay();
} else {
success_message = "ERROR: CSR FAILED";
}
_in_progress = false;
return;
}
}

}; // namespace CSRTrigger
Loading
Loading