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 Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ HTML_STYLESHEET =
# documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_EXTRA_STYLESHEET =
HTML_EXTRA_STYLESHEET = docs/clemson.css

# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The following systems integrate Avionics as a submodule:

## Documentation

- Doxygen: run `doxygen Doxyfile` from the repository root. HTML output is placed in `build/doxygen/index.html` (README is used as the main page).
- Doxygen: run `doxygen Doxyfile` from the repository root. HTML output is placed in `build/doxygen/index.html` (README is used as the main page). You can then use Python to serve the files locally: `python -m http.server --directory build/doxygen 8000` and navigate to `http://localhost:8000` in your browser. We have a workflow that will autogenerate and deploy the docs to GitHub Pages on each push to main.
- High-level notes: data logging constraints and Byte5 format are summarized in `docs/FlashDataSaving.md`.
- Flight history: see `docs/FlightTests.md` for vehicles and dates that have flown with this codebase.
- Target Audience: The documentation is written for compsci students with very little background in C++ or embedded systems.
Expand All @@ -89,6 +89,8 @@ The following systems integrate Avionics as a submodule:

Unit tests are managed by the [Native](https://github.com/CURocketEngineering/Native) repository, allowing for module testing without requiring embedded hardware.

Never in the Avionics repo should you `#include <Arduino.h>` or any other Arduino-specific headers. Instead, always include `ArduinoHAL.h` from the `hal` directory, which will either pull in the real Arduino core (when compiling for an Arduino target) or a mock implementation (when compiling for Native). This ensures that Avionics can be tested via the Native repo on a laptop without any Arduino dependencies.

## License

This project is licensed under the [MIT License](LICENSE). Please review the LICENSE file for complete details.
278 changes: 278 additions & 0 deletions docs/clemson.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
/* Clemson-themed Doxygen skin (dark-mode only)
Drop into HTML via: HTML_EXTRA_STYLESHEET = clemson.css
*/

:root{
/* Clemson-ish palette */
--clemson-orange: #F56600;
--clemson-purple: #522D80;

/* Dark-only neutrals */
--bg: #0f1115;
--bg-soft: #0f1115;
--text: #e6e6e6;
--muted: #b1b6c2;
--border: #2a2f3a;

--card: #141823;
--card-2: #101421;
--shadow: 0 10px 26px rgba(0,0,0,.45);

/* Links */
--link: #c9b3ff;
--link-hover: #f2d1b8;

/* Code */
--code-bg: #0b1020; /* deep navy */
--code-text: #e9edf6;

/* Tree-view palette (NOT purple-heavy) */
--nav-bg: #0f1320; /* slightly cooler, lighter than purple */
--nav-border: #232a3a;
--nav-hover: rgba(245,102,0,.10);
--nav-selected: rgba(245,102,0,.14); /* orange-tinted selection instead of purple */
--nav-text: #d8dbea;
--nav-text-muted: #a9afc4;

--radius: 12px;
--radius-sm: 10px;
}

/* Base */
html, body {
background: var(--bg-soft);
color: var(--text);
}

body, table, div, p, dl {
font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
line-height: 1.5;
}

/* Links */
a, a:visited {
color: var(--link);
text-decoration: none;
}
a:hover, a:focus {
color: var(--link-hover);
text-decoration: underline;
}

/* Top bar / title area */
#top {
background: linear-gradient(90deg, var(--clemson-purple), #31194f);
border-bottom: 4px solid var(--clemson-orange);
}

#titlearea {
background: transparent;
color: #fff;
border: 0;
}

#projectname {
color: #fff;
font-weight: 800;
letter-spacing: .2px;
}
#projectbrief, #projectnumber {
color: rgba(255,255,255,.85);
}

/* Tabs (nav rows) */
.tabs, .tabs2, .tabs3 {
background: transparent;
border: 0;
}

.tablist li a {
background: rgba(255,255,255,.10);
border: 1px solid rgba(255,255,255,.18);
border-bottom: 0;
color: #fff;
border-top-left-radius: var(--radius-sm);
border-top-right-radius: var(--radius-sm);
padding: 8px 12px;
}
.tablist li a:hover {
background: rgba(245,102,0,.18);
border-color: rgba(245,102,0,.35);
color: #fff;
text-decoration: none;
}
.tablist li.current a {
background: var(--card);
color: var(--link);
border-color: var(--border);
}

/* Breadcrumb / navpath */
.navpath {
background: var(--card);
border-bottom: 1px solid var(--border);
}
.navpath ul {
padding: 10px 12px;
}
.navpath li {
color: var(--muted);
}

/* Main content container feel */
#doc-content, .contents, .header, .footer {
background: transparent;
}

.contents {
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 18px 18px;
margin: 16px 10px;
}

/* Headings */
h1, h2, h3 {
color: var(--link);
letter-spacing: .1px;
}
h1 {
border-bottom: 2px solid rgba(245,102,0,.35);
padding-bottom: 8px;
}

/* Member documentation blocks */
.memitem, .memproto, .memdoc, .memtitle, .groupheader {
border-color: var(--border) !important;
}
.memtitle {
background: linear-gradient(90deg, rgba(82,45,128,.22), rgba(245,102,0,.10));
border-radius: var(--radius-sm);
padding: 10px 12px;
color: #e6dcff;
font-weight: 750;
}
.memitem {
background: var(--card);
border-radius: var(--radius-sm);
overflow: hidden;
}
.memproto, .memdoc {
background: var(--card);
}

/* Tables */
table.doxtable, table.markdownTable, table.fieldtable {
border: 1px solid var(--border);
border-radius: var(--radius-sm);
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,.18);
}
table.doxtable th, table.markdownTable th, table.fieldtable th {
background: rgba(82,45,128,.22);
color: #e6dcff;
font-weight: 750;
border-bottom: 1px solid var(--border);
}
table.doxtable td, table.markdownTable td, table.fieldtable td {
border-bottom: 1px solid var(--border);
}

/* Code blocks */
div.fragment, pre.fragment, div.line, .line {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
div.fragment, pre.fragment {
background: var(--code-bg) !important;
color: var(--code-text) !important;
border: 1px solid rgba(245,102,0,.28);
border-radius: var(--radius-sm);
box-shadow: 0 8px 24px rgba(0,0,0,.30);
}
code, .inlinecode, tt {
background: rgba(245,102,0,.14);
border: 1px solid rgba(245,102,0,.22);
border-radius: 8px;
padding: 1px 6px;
}

/* Search */
#MSearchBox {
background: rgba(255,255,255,.10);
border: 1px solid rgba(255,255,255,.16);
border-radius: 999px;
}
#MSearchField {
color: #fff !important;
}
#MSearchField::placeholder {
color: rgba(255,255,255,.70);
}

/* Tree view sidebar (lighter, cooler, not purple-heavy) */
#side-nav, #nav-tree, #nav-tree-contents {
background: var(--nav-bg) !important;
}
#nav-tree {
border-right: 1px solid var(--nav-border) !important;
}

#nav-tree .label a,
#nav-tree a {
color: var(--nav-text) !important;
}
#nav-tree .label {
color: var(--nav-text-muted) !important;
}

#nav-tree .item:hover,
#nav-tree .label a:hover {
background: var(--nav-hover) !important;
text-decoration: none;
}

/* Selected item: orange accent + subtle highlight (no purple block) */
#nav-tree .selected,
#nav-tree .selected a {
background: var(--nav-selected) !important;
color: #fff !important;
}
#nav-tree .selected {
border-left: 4px solid var(--clemson-orange);
}

/* Tree expand/collapse icons sometimes inherit colors oddly */
#nav-tree img {
filter: brightness(1.2) contrast(1.1);
opacity: .9;
}

/* Footer */
.footer, #nav-path, #nav-path ul {
background: transparent;
}
.footer {
color: var(--muted);
}

/* Small polish */
hr {
border: 0;
border-top: 1px solid var(--border);
}
dl.note, dl.warning, dl.attention, dl.todo {
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: var(--card);
box-shadow: 0 2px 10px rgba(0,0,0,.18);
}
dl.warning > dt {
background: rgba(245,102,0,.16);
color: #ffd3b6;
}
dl.note > dt {
background: rgba(82,45,128,.22);
color: #e6dcff;
}
18 changes: 18 additions & 0 deletions hal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# hal Directory

The HAL directory defines a hardware abstraction layer (HAL) which sits between Avionics and the Arduino core platform. This layer allows Avionics to be tested via the Native repo on a laptop without any Arduino dependencies.

## The RULE

Avionics must never `#include <Arduino.h>` or any other Arduino-specific headers. Instead you must include `ArdinoHAL.h` from this directory which will either pull in the real Arduino core (when compiling for an Arduino target) or a mock implementation (when compiling for Native).

If you ever try to inlucde an Arduino header directly in Avionics, then the Native tests will fail to compile because Native isn't an Arduino project and doesn't have access to Arduino headers.

## How it works

When you include `ArduinoHAL.h`, it checks if the `ARDUINO` macro is defined. If it is, then it includes the real Arduino core headers. If not, then it includes mock implementations of the Arduino functions and classes that Avionics uses. It is meant to be a drop-in replacement for the Arduino core.
Things have been added to the ArduinoHAL mock as needed to support Avionics unit tests in Native. If you find that a function or class is missing from the mock, you can add it to the mock implementation files in this directory.

For example, the `serial_mock.h` defines a `Serial` object that mimics the Arduino `Serial` object. It has the same methods (e.g., `begin`, `print`, `println`, etc.) but they just print to the stdout instead of a real serial port.

`ArduinoHAL.h` is the entry point and will include other headers in this directory as needed.
23 changes: 23 additions & 0 deletions include/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# include Directory

This directory contains all the header files for the Avionics library. Each header file declares classes, functions, and constants that are used throughout the library. In essence, you can treat each header file as a discrete module/tool that can be utilized in your flight computer software.

## Files
- `CommandNames.h`: Defines integer constants to represent various commands that can be sent to the flight computer.
- `PowerManagement.h`: Declares a tool for reading ADC pins to monitor battery voltage.
- `UARTCommandHandler.h`: Declares a tool for creating a shell-like interface over UART to send commands and receive status messages from the flight computer. The flight computer can declare and register commands with this interface.


## Subdirectories

### data_handling

The data_handling subdirectory contains all tools pertaining to data management. It includes tools for logging data to various storage mediums as well as sending data for a radio.

### simulation

The simulation subdirectory contains tools for simulating sensors in order to perform full code tests without an actual launch. It offers simulated drivers for various sensors that can drop-in replace the real sensor drivers. Overtime, the number of simulated sensors will grow to cover all sensors utilized by our club's flight computers.

### state_estimation

The state_estimation subdirectory contains tools for estimating the rocket's state. The client simply initalizes these tools and then calls `update` functions with new data. In return, the tools provide current estimate states of the rocket or stage of flight.
15 changes: 15 additions & 0 deletions include/data_handling/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# data_handling Directory

Tools for collecting, rate-limiting, persisting, and downlinking sensor data.

## Files
- `CircularArray.h`: Fixed-size circular buffer for recent samples with quickselect-based median support.
- `DataNames.h`: List of 8-bit integer constants that identify each data channel for both data logging and telemetry purposes. This must stay in sync with the ground station's data names YAML file.
- `DataPoint.h`: Lightweight class that holds a single float with a timestamp. Instead of throwing raw floats around, we use `DataPoint` to keep track of when samples were taken which allows for better filters to be used in the `state_estimation` side of tools. If you have a list of float's you don't know when they were take, a list of `DataPoint`'s is preferred.
- `DataSaver.h`: Abstract `IDataSaver` interface plus convenience overloads and hooks for initialization and launch events.
- `DataSaverBigSD.h`: Buffered CSV logger to large SD cards via SdFat, batching writes and managing stream file paths.
- `DataSaverPrint.h`: `IDataSaver` that prints channel/timestamp/value to stdout for debugging and tests.
- `DataSaverSDSerial.h`: Streams CSV-formatted samples over UART to an external serial data logger.
- `DataSaverSPI.h`: SPI flash logger with timestamp compression, post-launch write protection, and dump/erase utilities. Use this to write to an onboard flash chip with very little storage space. This is the most space-efficient data saver we have, but it is also the most complex to use.
- `SensorDataHandler.h`: Buffers sensor samples, enforces minimum save intervals, and forwards data to an `IDataSaver`.
- `Telemetry.h`: Builds fixed-size packets from `SensorDataHandler` streams and transmits them over UART at set frequencies.
8 changes: 8 additions & 0 deletions include/simulation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# simulation Directory

These tools are meant to act as drop-in replacements for the real sensor drivers.

`Serial_Sim.h` is the central piece. It collects simulated data from the serial port and updates its internal data.
The simulated sensors (e.g. `Serial_Sim_BMP390.h`, ...) then pull data from `Serial_Sim.h` instead of the real sensors.

In your main code of the flight computer you can simply include these sensor drivers instead of the real ones when you want to run a simulation. You'll have to run `simulation.py` on a computer connected to the flight computer's serial port to send the simulated data once the flight computer starts running.
15 changes: 15 additions & 0 deletions include/state_estimation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# state_estimation Directory

Tools for detecting flight events, fusing sensors, and managing rocket flight-state transitions.

## Files
- `ApogeeDetector.h`: Detects apogee when filtered altitude peaks and velocity goes negative. More robust than zero-velocity crossing, especially with noisy baro data.
- `ApogeePredictor.h`: Projects time/altitude to apogee using current velocity and deceleration; use for active-aero or adaptive control while still climbing.
- `BaseStateMachine.h`: Abstract interface for flight state machines.
- `BurnoutStateMachine.h`: State machine variant with an explicit burnout phase before coast; use when burnout-specific logic or logging matters.
- `GroundLevelEstimator.h`: Learns launch-site altitude pre-launch, then converts ASL to AGL after launch; use to normalize baro data.
- `LaunchDetector.h`: Sliding-window accelerometer detector that marks liftoff when sustained acceleration exceeds a threshold; use to gate launch-critical events.
- `StateEstimationTypes.h`: Shared data structures (e.g., `AccelerationTriplet`) passed among estimators and state machines.
- `StateMachine.h`: Nominal flight state machine that advances through phases using launch/apogee detectors and logs transitions.
- `States.h`: Enum of discrete flight states used across state machines they are all ordered from sequentially (earliest to latest) but not all states are used by all state machines but if STATE_A > STATE_B then STATE_A always occurs after STATE_B.
- `VerticalVelocityEstimator.h`: 1D Kalman filter fusing accelerometer and barometer to estimate altitude, vertical velocity, and inertial acceleration; feed its outputs to detectors and state machines.
Loading