Guidance for human and AI coding agents working in this repository.
If you are an AI agent, say "I read the AGENTS.md" at the start of the chat, to acknowledge that you have read and understand these instructions.
These instructions apply to the entire repo unless a deeper AGENTS.md overrides them.
- For broad safety-critical coding principles, refer to
context/P10.md.
- Deliver a reusable avionics toolbox that can be utilized across multiple rocket platforms.
- Maintain hardware-agnostic logic so it can be extended to any device running Arduino core, or run natively on a host machine via the custom HAL mocks in
hal/. - Prioritize simple, obvious, clear code over clever or over-engineered solutions. The project is maintained by students with beginner-to-intermediate C++ knowledge, and there is high turnover, so it must be easy for new members to start contributing without needing to understand complex design patterns or advanced C++ features.
Avionics is our modular C++ (Arduino-core compatible) library used for all of our flight computers. Core areas:
include/state_estimation+src/state_estimation: launch/burnout/apogee/state logic.include/data_handling+src/data_handling: logging, telemetry, sensor data handling.hal/: hardware abstraction layer for Arduino vs native host testing.test/: host-native Unity tests.data/: CSV fixtures used by many tests.
- Never include Arduino headers directly (
<Arduino.h>, etc.) from Avionics code. - Always include
ArduinoHAL.hfromhal/for Arduino-facing APIs. - Keep host-native tests buildable; avoid adding dependencies that only exist on embedded targets.
- Maintain
include/andsrc/parity for non-header-only modules. - Keep changes compatible with the repo's C++ standard (
-std=c++11inplatformio.ini).
-
Use
camelCasefor variables and functions. -
Use
PascalCasefor class and struct names. -
Use
kConstantNamefor constants. -
Use a trailing underscore for private member variables (for example,
privateVar_andprivateTimestamp_ms_). -
Add unit suffixes with an underscore when a name represents a physical quantity, time value, size, rate, or other semantically meaningful measured quantity (for example,
timestamp_ms,altitude_m,velocity_mps,gravity_mps2,packetSize_bytes). -
Prefer exact units like
_bytesand_bitswhen the exact count matters. -
Use unambiguous binary storage suffixes like
_KiBand_MiBwhen a quantity is naturally expressed that way. -
Use unambiguous data-rate suffixes like
_kbpsand_Mbps. -
Avoid ambiguous suffixes such as
_MB,_mB, or_Mbunless the meaning is completely clear in context. -
Avoid abbreviations unless they are widely understood in the project context or domain (for example,
imu,gps,crc,uart). -
Prefer descriptive names over shortened ones when there is any chance of confusion.
-
Use a
_insuffix for function parameters that would otherwise match member variables to avoid shadowing. For example,DataPoint(uint32_t timestamp_ms_in, float data_in) : timestamp_ms(timestamp_ms_in), data(data_in) {}.
Run from repo root:
# Install toolchain (if needed)
pip install -U platformio
# It may already be installed at `~/.platformio/penv/bin/pio` use the full path if `pio` is not in your PATH.
# Run unit tests (same environment as CI)
pio test -e native
# Run static analysis (same tool as CI)
pio check -e native --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high
# Clear the build, so a fresh one can be done (good to ensure all build warnings reappear)
pio run -t cleanTarget a specific test directory when iterating:
pio test -e native -f test_apogee_detector- Doxygen is configured via
Doxyfileat the repo root. - Generate docs locally with:
doxygen Doxyfile
python -m http.server --directory build/doxygen 8000- Local output is
build/doxygen/(openbuild/doxygen/index.html). - Docs are deployed automatically by
.github/workflows/doxygen.yml:- Trigger: pushes to
main(and manualworkflow_dispatch) - Deploy target:
gh-pagesbranch - Published folder:
build/doxygen
- Trigger: pushes to
- If code changes affect public behavior/API, update doc comments and relevant Markdown docs in the same change.
- Don't use a return type of
voidin doc comments; just omit the@returnline if there is no return value.
- Many tests require CSV files in
data/; these are flight data from previous launches. - If fixtures are missing, use the same dataset source CI uses (
CURocketEngineering/Rocket-Test-Data, release tagv1.0.0) or project-approved local equivalents. - Do not rename/remove existing CSV fixtures unless the task explicitly requires it.
- Prefer small, focused patches.
- If behavior changes, update or add tests in
test/to cover it. - If you are patching a bug, add a regression test that fails without the fix and passes with it.
- Preserve public API names unless the task explicitly asks for a breaking change.
- Keep docs in sync when changing module behavior:
- top-level
README.mdfor high-level behavior, docs/*.mdfor detailed formats/protocols.
- top-level
Before finishing, verify:
pio test -e nativepasses (or explain why not run/failing).pio check -e native ...is clean for touched code (or explain remaining findings).- No direct Arduino includes were introduced.
- New logic has test coverage for nominal and edge behavior.