-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Welcome to the AresPayload wiki!
Update: Dec 19, 2025 Author: Mann Patel Note: Documentation reflects the Osiris Payload
- Ares Payload
- System Architecture
- Data Flow
- Task Details
- State Machine Details
- Communication Interfaces
- Getting Started
- Example Usage
- Key Design Patterns
- Development Notes
- Hardware Naming Convention
- Future Enhancements
The Osiris Payload System is an embedded flight computer designed for rocket payloads. It runs on an STM32H7 microcontroller using FreeRTOS and manages sensor data collection, state transitions, and hardware control throughout a rocket's flight.
The system follows a task-based architecture using FreeRTOS, where different subsystems run as independent tasks that communicate via command queues. A state machine manages the flight phases and controls hardware accordingly.
flowchart TD
A[Main System<br/>main_system.cpp]
A -->|Initializes all tasks| B[Tasks]
A -->|Initializes all tasks| C[Drivers]
Sensors are named after Nintendo characters (God knows why?) :(
- Mario & Luigi: LPS22HH barometer
- Bowser: MS5611 barometer
- Toopy & Binoo: LSM6DSO IMUs
The system uses multiple FreeRTOS tasks that run concurrently:
| Task | Priority | Purpose |
|---|---|---|
| FlightTask | 2 | Main flight logic and state machine coordination |
| IMUTask | 2 | Reads IMU (Inertial Measurement Unit) data |
| BaroTask | 2 | Reads barometer/pressure sensor data |
| DebugTask | 2 | Handles debug output via UART |
| CubeTask | 2 | Framework task (Cube++ RTOS wrapper) |
s The flight computer transitions through 5 states during operation:
PRELAUNCH -> LAUNCH -> DROGUE -> MAIN -> POSTLAUNCH
Each state controls different hardware peripherals and responds to different commands.
- LPS22HH (x2): "Mario" and "Luigi" - SPI-based pressure/temperature sensors
- MS5611 ("Bowser"): I2C-based pressure/temperature sensor
- LSM6DSO (x2): "Toopy" (I2C) and "Binoo" (SPI) - Accelerometer and gyroscope sensors
The system controls various hardware via GPIO pins:
- SOL1, SOL2, SOL3: Solenoid valves
- COMPRESSOR: Air compressor control
- LED_GREEN, LED_BLUE: Status indicators
flowchart LR
S[Sensors]
T[Tasks]
C[Commands]
SM[State Machine]
HC[Hardware Control]
DS[Data Structures]
S --> T
T --> C
C --> SM
SM --> HC
SM -->|reads/writes| DS
S -->|writes| DS
Tasks communicate using a Command object with:
- Command Type: REQUEST_COMMAND, DATA_COMMAND, CONTROL_ACTION, etc.
- Task Command: Specific action identifier
- Data Payload: Optional data (e.g., sensor readings)
typedef struct BarometerData {
float marioPressure; // LPS22HH U3
float marioTemperature;
float luigiPressure; // LPS22HH U4
float luigiTemperature;
uint32_t bowserPressure; // MS5611
uint32_t bowserTemperature;
} BarometerData;
typedef struct IMUData {
float xAccel;
float yAccel;
float zAccel;
} IMUData;- Purpose: Coordinates overall flight logic
- Key Responsibility: Manages the OsirisSM state machine
- Communication: Receives data from IMUTask and BaroTask
- Purpose: Reads acceleration and gyroscope data
- Sensors: LSM6DSO (Toopy on I2C, Binoo on SPI)
-
Commands:
-
IMU_REQUEST_LIN_ACC: Request linear acceleration -
IMU_REQUEST_ANG_ACC: Request angular acceleration
-
-
Output: Sends
IMUDatato FlightTask
- Purpose: Reads pressure and temperature data
-
Sensors:
- LPS22HH (Mario and Luigi on SPI)
- MS5611 (Bowser on I2C)
-
Commands:
-
BARO_REQUEST_NEW_SAMPLE: Read all sensors -
BARO_REQUEST_DEBUG: Print sensor values -
BARO_REQUEST_FLASH_LOG: Log data to flash memory
-
-
Output: Sends
BarometerDatato FlightTask
- Purpose: Handles UART debug output
-
Interface: USART6 (accessible via
Driver::uart6)
flowchart TD
PRE[PRELAUNCH]
LAUNCH[LAUNCH]
DROGUE[DROGUE]
MAIN[MAIN]
POST[POSTLAUNCH]
PRE -->|OSC_PRELAUNCH_TO_LAUNCH| LAUNCH
LAUNCH -->|OSC_LAUNCH_TO_DROGUE| DROGUE
DROGUE -->|OSC_DROGUE_TO_MAIN| MAIN
MAIN -->|OSC_MAIN_TO_POSTLAUNCH| POST
- Hardware: All peripherals OFF (safe state)
- Control: Can control SOL1, SOL2, SOL3, and COMPRESSOR
- LED: Green LED ON
- Purpose: Ground operations and testing
- Hardware: All peripherals OFF
- Purpose: Rocket is ascending
- Transitions to: DROGUE (typically at apogee)
- Hardware: Can control SOL1, SOL2, SOL3, and COMPRESSOR
- Purpose: Drogue parachute deployed, descending
- Transitions to: MAIN (at specific altitude)
- Hardware: Can control SOL3 and COMPRESSOR only
- Purpose: Main parachute deployed
- Transitions to: POSTLAUNCH (after landing)
- Hardware: All peripherals OFF
- Purpose: Landed, safe state
From any state, you can return to PRELAUNCH using:
OSC_ANY_TO_PRELAUNCH- SPI2: LPS22HH sensors (Mario and Luigi)
- SPI6: LSM6DSO sensor (Binoo)
- I2C2: MS5611 (Bowser) and LSM6DSO (Toopy)
-
USART6: Debug output (configured in
Driver::uart6)
The system boots through main_system.cpp:
void run_main() {
// 1. Initialize all tasks
CubeTask::Inst().InitTask();
DebugTask::Inst().InitTask();
FlightTask::Inst().InitTask();
IMUTask::Inst().InitTask();
BaroTask::Inst().InitTask();
// 2. Print boot info
SOAR_PRINT("\n-- SOAR SYSTEM --\n");
// 3. Test sensors (example)
Command testIMU(REQUEST_COMMAND, IMU_REQUEST_LIN_ACC);
IMUTask::Inst().GetEventQueue()->Send(testIMU);
// 4. Start FreeRTOS scheduler
osKernelStart();
}Task priorities and stack sizes are defined in SystemDefines.hpp:
// All tasks currently have priority 2
constexpr uint8_t FLIGHT_TASK_RTOS_PRIORITY = 2;
constexpr uint8_t IMU_TASK_RTOS_PRIORITY = 2;
constexpr uint8_t BARO_TASK_RTOS_PRIORITY = 2;
// Stack sizes (in words)
constexpr uint16_t FLIGHT_TASK_STACK_DEPTH_WORDS = 512;
constexpr uint16_t IMU_TASK_STACK_DEPTH_WORDS = 512;
constexpr uint16_t BARO_TASK_STACK_DEPTH_WORDS = 512;// Create a command to request linear acceleration
Command cmd(REQUEST_COMMAND, IMU_REQUEST_LIN_ACC);
// Send to IMU task
IMUTask::Inst().GetEventQueue()->Send(cmd);
// IMUTask will respond by sending IMUData to FlightTask// Open solenoid valve 1
Command cmd(CONTROL_ACTION, OSC_OPEN_SOL1);
FlightTask::Inst().GetEventQueue()->Send(cmd);
// Close solenoid valve 1
Command cmd2(CONTROL_ACTION, OSC_CLOSE_SOL1);
FlightTask::Inst().GetEventQueue()->Send(cmd2);// Request new barometer sample
Command cmd(REQUEST_COMMAND, BARO_REQUEST_NEW_SAMPLE);
BaroTask::Inst().GetEventQueue()->Send(cmd);
// Request debug output of barometer values
Command cmd2(REQUEST_COMMAND, BARO_REQUEST_DEBUG);
BaroTask::Inst().GetEventQueue()->Send(cmd2);Each task uses Task::Inst() to access a single instance:
FlightTask::Inst().GetEventQueue()->Send(command);All inter-task communication uses Command objects with specific command types
Flight logic organized into distinct states with entry/exit handlers
GPIO operations wrapped in namespace functions:
GPIO::LED_GREEN::On();
GPIO::SOL1::Off();