diff --git a/TARS/.gitignore b/TARS/.gitignore index 89cc49cb..383ca1c3 100644 --- a/TARS/.gitignore +++ b/TARS/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch + +src/mcu_main/gen/ \ No newline at end of file diff --git a/TARS/data-parse/data_parser.cpp b/TARS/data-parse/data_parser.cpp new file mode 100644 index 00000000..443820bb --- /dev/null +++ b/TARS/data-parse/data_parser.cpp @@ -0,0 +1,147 @@ +#if defined(__CLION_IDE__) || defined(__INTELLISENSE__) // to make the IDE happy +#include "common/packet.h" +#else +#include PACKET_INCLUDE_PATH +#endif + +#include +#include + + +int main(int argc, char** argv) { + std::ifstream input{argv[1], std::ios::binary}; + std::ostream& output = std::cout; + + input.ignore(41); + + output + << "has_lowG_data" << "," + << "lowG_data.ax" << "," + << "lowG_data.ay" << "," + << "lowG_data.az" << "," + << "lowG_data.gx" << "," + << "lowG_data.gy" << "," + << "lowG_data.gz" << "," + << "lowG_data.mx" << "," + << "lowG_data.my" << "," + << "lowG_data.mz" << "," + << "lowG_data.timeStamp_lowG" << ","; + + output + << "has_highG_data" << "," + << "highG_data.ax" << "," + << "highG_data.ay" << "," + << "highG_data.az" << "," + << "highG_data.timeStamp_highG" << ","; + + + output + << "has_gps_data" << "," + << "gps_data.altitude" << "," + << "gps_data.fix_type" << "," + << "gps_data.latitude" << "," + << "gps_data.longitude" << "," + << "gps_data.posLock" << "," + << "gps_data.siv_count" << "," + << "gps_data.timeStamp_GPS" << ","; + + output + << "has_barometer_data" << "," + << "barometer_data.temperature" << "," + << "barometer_data.altitude" << "," + << "barometer_data.pressure" << "," + << "barometer_data.timeStamp_barometer" << ","; + + output + << "has_rocketState_data" << ","; + for (int i = 0; i < 4; i++) { + output << "rocketState_data.rocketState" << i << ","; + } + output << "rocketState_data.timeStamp_RS" << ","; + + output + << "has_flap_data" << "," + << "flap_data.extension" << "," + << "flap_data.timeStamp_flaps" << ","; + + output + << "has_state_data" << "," + << "state_data.state_x" << "," + << "state_data.state_vx" << "," + << "state_data.state_ax" << "," + << "state_data.state_apo" << "," + << "state_data.timeStamp_state" << ","; + + output + << "has_voltage_data" << "," + << "voltage_data.v_battery" << "\n"; + + sensorDataStruct_t data; + while (input.read(reinterpret_cast(&data), sizeof(data))) { + output + << data.has_lowG_data << "," + << data.lowG_data.ax << "," + << data.lowG_data.ay << "," + << data.lowG_data.az << "," + << data.lowG_data.gx << "," + << data.lowG_data.gy << "," + << data.lowG_data.gz << "," + << data.lowG_data.mx << "," + << data.lowG_data.my << "," + << data.lowG_data.mz << "," + << data.lowG_data.timeStamp_lowG << ","; + + output + << data.has_highG_data << "," + << data.highG_data.hg_ax << "," + << data.highG_data.hg_ay << "," + << data.highG_data.hg_az << "," + << data.highG_data.timeStamp_highG << ","; + + + output + << data.has_gps_data << "," + << data.gps_data.altitude << "," + << data.gps_data.fix_type << "," + << data.gps_data.latitude << "," + << data.gps_data.longitude << "," + << data.gps_data.posLock << "," + << data.gps_data.siv_count << "," + << data.gps_data.timeStamp_GPS << ","; + + output + << data.has_barometer_data << "," + << data.barometer_data.temperature << "," + << data.barometer_data.altitude << "," + << data.barometer_data.pressure << "," + << data.barometer_data.timeStamp_barometer << ","; + + output + << data.has_rocketState_data << ","; + + for (int i = 0; i < 4; i++) { + output << (uint8_t) data.rocketState_data.rocketStates[i] << ","; + } + + output << data.rocketState_data.timestamp << ","; + + output + << data.has_flap_data << "," + << data.flap_data.extension << "," + << data.flap_data.timeStamp_flaps << ","; + + output + << data.has_kalman_data << "," + << data.kalman_data.kalman_x << "," + << data.kalman_data.kalman_vx << "," + << data.kalman_data.kalman_ax << "," + << data.kalman_data.kalman_apo << "," + << data.kalman_data.timeStamp_state << ","; + + output + << data.has_voltage_data << "," + << data.voltage_data.v_battery; + + output << '\n'; + } +} \ No newline at end of file diff --git a/TARS/data-parse/parse.py b/TARS/data-parse/parse.py new file mode 100644 index 00000000..d1540f54 --- /dev/null +++ b/TARS/data-parse/parse.py @@ -0,0 +1,57 @@ +import subprocess +import argparse +import pathlib +from typing import IO + +def parse_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("file", type=pathlib.Path) + parser.add_argument("-p", "--packet", type=pathlib.Path, default=None) + parser.add_argument("-v", "--verbose", action="store_true") + parser.add_argument("-e", "--emit", choices=["csv"], default="csv") + parser.add_argument("-o", "--out", type=pathlib.Path, default=None) + return parser.parse_args() + + +def main(): + arguments = parse_arguments() + if arguments.packet is None: + arguments.packet = pathlib.Path(__file__).parent.parent / "src" / "common" / "packet.h" + if arguments.verbose: + print(f"Note: No packet.h file was specified, defaulting to {arguments.packet}") + + if arguments.out is None: + arguments.out = arguments.file.with_suffix(".csv") # fix this if we support json at some point + if arguments.verbose: + print(f"Note: No output file was specified, defaulting to {arguments.out}") + + commit = subprocess.run(["git", "log", "-n", "1", "--pretty=format:%H", "--", arguments.packet], stdout=subprocess.PIPE).stdout.decode('utf-8') + if arguments.verbose: + print(f"Note: packet.h has version {commit}") + + with arguments.file.open("rb") as data_file: + data_file: IO + + raw_commit = data_file.read(41)[:40] + data_file_commit = raw_commit.decode("utf8") + if data_file_commit != commit: + print(f"Commits do not match (packet.h: {commit[:6]}, {arguments.file.name}: {data_file_commit[:6]})") + if arguments.verbose: + print(f"Note: {arguments.file.name} has raw version 0x{raw_commit.hex()}") + print(f"Note: This decodes to {data_file_commit}") + # return + + cpp_parser = pathlib.Path(__file__).parent / "data_parser.cpp" + cpp_compiled_parser = pathlib.Path(__file__).parent / "data_parser" + + if not cpp_compiled_parser.exists(): + subprocess.run(["g++", cpp_parser, "-o", cpp_compiled_parser, "-O0", f"-DPACKET_INCLUDE_PATH=\"{arguments.packet}\""]) + + csv_data = subprocess.run([cpp_compiled_parser, arguments.file], stdout=subprocess.PIPE).stdout.decode('utf8', errors="ignore") + csv_data = csv_data.replace("\r\n", "\n") + with arguments.out.open("w") as output_file: + output_file.write(csv_data) + + +if __name__ == '__main__': + main() diff --git a/TARS/generate_git_hash.py b/TARS/generate_git_hash.py new file mode 100644 index 00000000..417421ad --- /dev/null +++ b/TARS/generate_git_hash.py @@ -0,0 +1,31 @@ +# Script to generate `hash.h` file containing the latest commit hash that modified packet.h +# +# Autogenerates src/mcu_main/gen/git_hash.c + +import os, subprocess + +PACKET_H_PATH = "src/common/packet.h" +FILE_PATH = "src/mcu_main/gen/git_hash.c" + + +# Get the git hash of the latest commit that modified packet.h +git_command = ["git", "log", "-n", "1", "--pretty=format:%H", "--", PACKET_H_PATH] +git_hash = subprocess.run(git_command, stdout=subprocess.PIPE).stdout.decode('utf-8') +git_hash = git_hash[:-1] # get rid of trailing new line + + +# note: git hashes are always 40 characters +file_contents = f""" +/* + * Auto generated file containing the git hash of the latest commit that modified packet.h. + * + * See generate_git_hash.py + */ +char PACKET_H_GIT_HASH[41] = "{git_hash}"; +""" + +os.makedirs(os.path.dirname(FILE_PATH), exist_ok=True) +with open(FILE_PATH, "w") as f: + f.write(file_contents) + +print(f"Wrote hash {git_hash} to file {FILE_PATH}") \ No newline at end of file diff --git a/TARS/platformio.ini b/TARS/platformio.ini index d0c46095..979f7aa6 100644 --- a/TARS/platformio.ini +++ b/TARS/platformio.ini @@ -18,14 +18,14 @@ platform = teensy board = teensy41 framework = arduino upload_protocol = teensy-cli -extra_scripts = extra_script.py +extra_scripts = extra_script.py, generate_git_hash.py build_flags = -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-reorder ; turn off all the warnings from eigen lib_deps = PaulStoffregen/PWMServo greiman/ChRt@^1.3.0 sparkfun/SparkFun LSM9DS1 IMU@^2.0.0 -build_src_filter = + + +build_src_filter = + + - test_ignore = test_local ; lib_ldf_mode = chain+ diff --git a/TARS/src/common/packet.h b/TARS/src/common/packet.h index e2570a4c..d8b4421a 100644 --- a/TARS/src/common/packet.h +++ b/TARS/src/common/packet.h @@ -1,12 +1,16 @@ #pragma once -#include "ChRt.h" +//#include "ChRt.h" + +#include + +typedef uint32_t systime_t; /** * @brief Labels for each FSM state */ -enum class FSM_State { - STATE_INIT, +enum FSM_State { + STATE_INIT = 0, STATE_IDLE, STATE_LAUNCH_DETECT, STATE_BOOST, diff --git a/TARS/src/mcu_main/SDLogger.cpp b/TARS/src/mcu_main/SDLogger.cpp index e821041a..0b33f08f 100644 --- a/TARS/src/mcu_main/SDLogger.cpp +++ b/TARS/src/mcu_main/SDLogger.cpp @@ -78,6 +78,10 @@ void SDLogger::init() { sd_file = SD.open(data_name, FILE_WRITE_BEGIN); // print header to file on sd card that lists each variable that is logged // sd_file.println("binary logging of sensor_data_t"); + + // Write the git hash of packet.h to the start of the file + sd_file.write((const uint8_t*)PACKET_H_GIT_HASH, sizeof(PACKET_H_GIT_HASH)); + sd_file.flush(); Serial.println(sd_file.name()); diff --git a/TARS/src/mcu_main/SDLogger.h b/TARS/src/mcu_main/SDLogger.h index 5d55376d..92e965f3 100644 --- a/TARS/src/mcu_main/SDLogger.h +++ b/TARS/src/mcu_main/SDLogger.h @@ -5,6 +5,9 @@ #include "mcu_main/dataLog.h" +// Latest git hash of packet.h (see gen/git_hash.c) +extern char PACKET_H_GIT_HASH[41]; + class SDLogger; extern SDLogger sd_logger;