···11+cmake_minimum_required(VERSION 3.15)
22+project(Aethelix VERSION 0.2.0 LANGUAGES C CXX)
33+44+# Setup dual-core architecture profiles
55+option(PROFILE_LEON3 "Target the sparc-unknown-none-elf architecture (LEON3 Industry Standard)" ON)
66+option(PROFILE_SHAKTI "Target the riscv32imac-unknown-none-elf architecture (Shakti/RISC-V New Norm)" OFF)
77+88+if(PROFILE_LEON3 AND PROFILE_SHAKTI)
99+ message(FATAL_ERROR "Cannot select both PROFILE_LEON3 and PROFILE_SHAKTI simultaneously.")
1010+endif()
1111+1212+if(PROFILE_SHAKTI)
1313+ set(RUST_TARGET "riscv32imac-unknown-none-elf")
1414+ message(STATUS "Aethelix-PnP: Configuring for RISC-V Shakti/IRIS architecture (${RUST_TARGET})")
1515+else()
1616+ set(RUST_TARGET "sparc-unknown-none-elf")
1717+ message(STATUS "Aethelix-PnP: Configuring for LEON3 SPARC architecture (${RUST_TARGET})")
1818+endif()
1919+2020+# Fetch Corrosion (Rust <-> CMake bridge)
2121+include(FetchContent)
2222+FetchContent_Declare(
2323+ Corrosion
2424+ GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
2525+ GIT_TAG v0.5.0
2626+)
2727+FetchContent_MakeAvailable(Corrosion)
2828+2929+# Import the Rust core (aethelix_core)
3030+corrosion_import_crate(MANIFEST_PATH rust_core/Cargo.toml
3131+ TARGET_CLIMBED aethelix_core
3232+ FLAGS --target ${RUST_TARGET} --features flight --no-default-features)
3333+3434+# Define the C/C++ interface library
3535+add_library(aethelix INTERFACE)
3636+target_include_directories(aethelix INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
3737+target_link_libraries(aethelix INTERFACE aethelix_core)
3838+3939+# For easy consumption via FetchContent by other projects
4040+add_library(Aethelix::aethelix ALIAS aethelix)
4141+4242+message(STATUS "Aethelix FDIR Framework successfully registered. Target 'Aethelix::aethelix' is ready for linking.")
+31
Dockerfile
···11+FROM python:3.10-slim
22+33+WORKDIR /app
44+55+# Install system dependencies required for Rust compilation and Python packages
66+RUN apt-get update && apt-get install -y \
77+ build-essential \
88+ curl \
99+ git \
1010+ graphviz \
1111+ && rm -rf /var/lib/apt/lists/*
1212+1313+# Install Rust toolchain to compile Aethelix core via Maturin
1414+RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
1515+ENV PATH="/root/.cargo/bin:${PATH}"
1616+1717+# Install Python dependencies and Maturin
1818+COPY requirements.txt .
1919+RUN pip install --no-cache-dir -r requirements.txt maturin
2020+2121+# Copy the entire project
2222+COPY . .
2323+2424+# Build and install the Aethelix python package (including the Rust core via Maturin)
2525+RUN pip install --no-cache-dir -e .
2626+2727+# Expose Streamlit default port
2828+EXPOSE 8501
2929+3030+# Run the Mission Control Dashboard
3131+ENTRYPOINT ["streamlit", "run", "dashboard/app.py", "--server.port=8501", "--server.address=0.0.0.0"]
+66-25
README.md
···147147148148---
149149150150-### Installation
150150+### 1. Ground Segment (Data Center & Python)
151151152152+**Mission Control in a Box (Docker)**
153153+The easiest way to launch Aethelix is via Docker Compose, which spins up the Streamlit dashboard and pipeline instantly.
152154```bash
153153-# Clone the repository
154155git clone https://github.com/rudywasfound/aethelix
155156cd aethelix
157157+docker-compose up -d
158158+```
159159+The dashboard starts dynamically on port `8501`. You can drop realistic PCoE datasets directly into the mapped `/data` folder.
156160157157-# Recommended: setup virtual environment
158158-python -m venv venv
159159-source venv/bin/activate # venv\Scripts\activate on Windows
161161+**Native Python Package**
162162+Aethelix is packaged with `maturin` and PyO3. Install it natively as a Python module:
163163+```bash
164164+# Inside a virtual environment
165165+pip install -e .
166166+```
160167161161-# Install all dependencies
162162-pip install -r requirements.txt
168168+### 2. Space Segment (Flight Software)
169169+170170+Aethelix targets two dominant architectures as part of the "Strategic Autonomy" Dual-Core strategy: the legacy **LEON3 (SPARC)** fleet, and the next-generation **Shakti (RISC-V)** missions.
171171+172172+**C/C++ Integration (CMake)**
173173+Drop Aethelix into your embedded flight codebase simply using CMake's `FetchContent` or `add_subdirectory`. Select your compiler target:
174174+```bash
175175+# LEON3 (SPARC) Industry Standard Profile
176176+cmake -DPROFILE_LEON3=ON ..
177177+178178+# RISC-V (Shakti) New Norm Profile
179179+cmake -DPROFILE_SHAKTI=ON ..
163180```
164181182182+**Ada Integration (Alire/GNAT)**
183183+Aerospace middlewares relying on Ada can include `aethelix.gpr` directly in their Alire workspace. GNAT will instantly resolve the bindings natively.
184184+185185+---
186186+187187+## Active Recovery (Sentinel Gap)
188188+189189+Aethelix is not just a passive diagnostic tool; it possesses an **Active Recovery Callback Interface**. Through the C/Ada FFI, your FDIR middleware can register a recovery function that Aethelix will trigger *the exact moment* a root cause is successfully isolated.
190190+191191+```c
192192+// Example: Active Recovery execution on Deep Space Node
193193+void critical_recovery(int fault_id) {
194194+ if (fault_id == AETHELIX_FAULT_BATTERY_THERMAL) {
195195+ // Trigger emergency bus cooling mechanisms
196196+ }
197197+}
198198+199199+// Bind to Aethelix FDIR Framework
200200+register_recovery_handler(critical_recovery);
201201+```
202202+203203+---
204204+165205### Quick Run
166206```bash
167167-python main.py
207207+python dashboard/app.py
168208```
169209This runs the full diagnostic pipeline on a simulated multi-fault scenario (Solar + Battery aging).
170210···270310271311## Roadmap: Phases 3-4
272312273273-### Phase 3: Expand Subsystems (Weeks 5-6)
274274-- [x] Add thermal subsystem to causal graph
275275-- [x] Update propagation paths (power ↔ thermal ↔ payload)
276276-- [x] Multi-fault scenarios (e.g., thermal drift + solar degradation)
277277-- [x] Improved telemetry plots and textual explanations
313313+### Completed Phases (1-4)
314314+- [x] Integrate high-performance C/Ada flight FFI boundary.
315315+- [x] Extend causal graph to power-thermal coupling.
316316+- [x] Multi-fault scenarios and cycle-level continuous KS-testing.
317317+- [x] Dual-Core execution framework via CMake (LEON3 + RISC-V).
318318+- [x] Dockerization and seamless Python `pip` packaging.
319319+- [x] Sentinel Gap closure via Active Recovery Callback (`register_recovery_handler`).
278320279279-### Phase 4: Experimental Validation (Weeks 7-8)
280280-- [x] Benchmark: Correlation vs. rule-based vs. Bayesian reasoning
281281- - *Metric:* Accuracy of root cause ranking
282282- - *Condition:* Vary missing data, noise levels, simultaneous faults
283283-- [x] Paper-style report (ICRA/AIAA format)
284284-- [x] Public GitHub repo with reproducible notebooks
321321+### Phase 5: Orbital Autonomy (Weeks 9-10)
322322+- [ ] Connect with Core Flight System (cFS) components.
323323+- [ ] Communications subsystem monitoring (payload health checks).
324324+- [ ] Fleet-wide causal telemetry syncing mechanism for constellation awareness.
285325286326---
287327···289329290330```text
291331aethelix/
332332+├── ada/ # Ada 2012 FDIR bindings and GNAT project
292333├── analysis/ # Deviation quantification
293334├── causal_graph/ # DAG definitions & Bayesian inference
335335+├── dashboard/ # Streamlit frontend & Mission Control GUI
294336├── data/ # Telemetry datasets
295337├── docs/ # Detailed documentation and diagrams
296338├── examples/ # Example workflows (e.g., GSAT-6A)
297297-├── forensics/ # Post-mission analysis tools
298298-├── operational/ # Real-time operator integration
299299-├── rust_core/ # High-performance Rust backend
339339+├── include/ # C headers for Flight FFI (aethelix.h)
340340+├── rust_core/ # High-performance bare-metal Rust Core
300341├── scripts/ # Local build and benchmark scripts
301342├── simulator/ # Subsystem simulation
302302-├── tests/ # Unit and integration tests
303303-├── visualization/ # Plotters and renderers
304304-├── main.py # Entry point for local runs
343343+├── Dockerfile # Mission-Control-in-a-Box container
344344+├── CMakeLists.txt # Embedded FSW Dual-Core compilation build
345345+├── pyproject.toml # pip dependency structure & Maturin compiler
305346└── README.md
306347```
307348
+10
ada/aethelix_binding.ads
···117117 Convention => C,
118118 External_Name => "aethelix_reset_state";
119119120120+ -- Recovery handler callback type
121121+ type Recovery_Handler_Ptr is access procedure (Fault_Id : Int)
122122+ with Convention => C;
123123+124124+ -- Register an active recovery handler callback for the FDIR framework.
125125+ procedure Register_Recovery_Handler (Handler : Recovery_Handler_Ptr)
126126+ with Import => True,
127127+ Convention => C,
128128+ External_Name => "register_recovery_handler";
129129+120130end Aethelix_Binding;
+20
aethelix.gpr
···11+project Aethelix is
22+33+ for Languages use ("Ada");
44+ for Source_Dirs use ("ada");
55+ for Object_Dir use "obj";
66+ for Library_Dir use "lib";
77+ for Library_Name use "aethelix_ada_binding";
88+ for Library_Kind use "static";
99+1010+ package Compiler is
1111+ for Default_Switches ("Ada") use
1212+ ("-g", "-O2", "-gnat12", "-gnatwa");
1313+ end Compiler;
1414+1515+ package Linker is
1616+ -- Link against the static library compiled by cargo
1717+ for Linker_Options use ("-L../rust_core/target/sparc-unknown-none-elf/release", "-laethelix_core");
1818+ end Linker;
1919+2020+end Aethelix;
···11+version: '3.8'
22+33+services:
44+ mission-control:
55+ build: .
66+ container_name: aethelix-mission-control
77+ ports:
88+ - "8501:8501"
99+ volumes:
1010+ # Mount the data directory so operators can drop CSVs into it and
1111+ # the Streamlit dashboard sees them instantly.
1212+ - ./data:/app/data
1313+ environment:
1414+ - STREAMLIT_THEME_BASE=dark
1515+ restart: unless-stopped
+21-12
include/aethelix.h
···44 * Compatible with: LEON3 (SPARC V8), RTEMS, VxWorks, bare-metal C/Ada FDIR.
55 * Generated from Rust source (rust_core/src/ffi.rs) via cbindgen.
66 *
77- * ── Quick start (C) ──────────────────────────────────────────────────────────
77+ * Quick start (C)
88 *
99 * #include "aethelix.h"
1010 * #include <string.h>
···2121 * handle_fault(&alert);
2222 * }
2323 *
2424- * ── Quick start (Ada) ────────────────────────────────────────────────────────
2424+ * Quick start (Ada)
2525 * See ada/aethelix_binding.ads for a type-safe Ada 2012 thin binding.
2626 *
2727- * ── ECSS references ──────────────────────────────────────────────────────────
2727+ * ECSS references
2828 * ECSS-E-ST-10-03C CCSDS Space Packet Protocol
2929 * ECSS-E-ST-40C Software Engineering (req. basis for formal verification)
3030 * ECSS-Q-ST-80C Software Product Assurance
···4040#include <stdint.h>
4141#include <stddef.h>
42424343-/* ── Version ──────────────────────────────────────────────────────────────── */
4343+/* Version*/
4444#define AETHELIX_VERSION_MAJOR 0U
4545#define AETHELIX_VERSION_MINOR 2U
4646#define AETHELIX_VERSION_PATCH 0U
47474848-/* ── Alert level severity ─────────────────────────────────────────────────── */
4848+/* Alert level severity */
4949#define AETHELIX_LEVEL_NONE 0U /**< Nominal — no fault detected */
5050#define AETHELIX_LEVEL_WARNING 1U /**< Sub-threshold anomaly; monitor */
5151#define AETHELIX_LEVEL_CAUTION 2U /**< Anomaly confirmed; prepare action */
5252#define AETHELIX_LEVEL_CRITICAL 3U /**< Immediate FDIR action required */
53535454-/* ── Telemetry channel indices (bit positions in evidence_mask) ───────────── */
5454+/* Telemetry channel indices (bit positions in evidence_mask) */
5555#define AETHELIX_CH_SOLAR_INPUT 0U /**< Solar input power (W) */
5656#define AETHELIX_CH_BATTERY_VOLT 1U /**< Battery voltage (mV) */
5757#define AETHELIX_CH_BATTERY_SOC 2U /**< Battery state-of-charge (%) */
···6161#define AETHELIX_CH_PAYLOAD_TEMP 6U /**< Payload temperature (0.01°C) */
6262#define AETHELIX_CH_BUS_CURRENT 7U /**< Bus current (mA) */
63636464-/* ── CCSDS APID assignments (configure to match your spacecraft) ──────────── */
6464+/* CCSDS APID assignments (configure to match your spacecraft) */
6565#define AETHELIX_APID_SOLAR_INPUT 0x001U
6666#define AETHELIX_APID_BATTERY_VOLT 0x002U
6767#define AETHELIX_APID_BATTERY_SOC 0x003U
···7171#define AETHELIX_APID_PAYLOAD_TEMP 0x007U
7272#define AETHELIX_APID_BUS_CURRENT 0x008U
73737474-/* ── Root-cause fault IDs (auto-generated from causal_graph.bin) ─────────── */
7474+/* ── Root-cause fault IDs (auto-generated from causal_graph.bin) */
7575/* Include aethelix_graph_ids.h for the full enumeration. */
7676#include "aethelix_graph_ids.h"
77777878-/* ── Return codes ─────────────────────────────────────────────────────────── */
7878+/* Return codes */
7979#define AETHELIX_OK 0 /**< Success */
8080#define AETHELIX_ERR_TOO_SHORT 1 /**< Buffer < 6 bytes (no CCSDS header) */
8181#define AETHELIX_ERR_BAD_LEN 2 /**< Payload length mismatch in header */
8282#define AETHELIX_ERR_NULL_PTR (-1) /**< Null pointer argument */
83838484-/* ── FDIR Alert (12 bytes, packed, C ABI compatible) ─────────────────────── */
8484+/* FDIR Alert (12 bytes, packed, C ABI compatible) */
8585typedef struct __attribute__((packed)) {
8686 uint8_t level; /**< AETHELIX_LEVEL_* severity */
8787 uint8_t root_cause_id; /**< AETHELIX_FAULT_* or 0xFF = no fault */
···9595/* Compile-time size assertion (14 bytes with __packed__) */
9696typedef char _aethelix_alert_size_check[sizeof(AethelixAlert) == 12 ? 1 : -1];
97979898-/* ── Opaque persistent state ──────────────────────────────────────────────── */
9898+/* Opaque persistent state */
9999/* Caller must allocate >= aethelix_state_size() bytes and zero the buffer */
100100/* before the first call to aethelix_process_frame(). */
101101typedef struct AethelixState AethelixState;
102102103103-/* ── API ──────────────────────────────────────────────────────────────────── */
103103+/* API */
104104105105/**
106106 * Process one CCSDS Space Packet through the Aethelix diagnostic engine.
···135135 * @return Exact byte size of AethelixState in this firmware build.
136136 */
137137uint32_t aethelix_state_size(void);
138138+139139+/**
140140+ * Register an active recovery handler callback for the FDIR framework.
141141+ * This instructs Aethelix to actively call the function pointer supplied
142142+ * the moment a root cause fault is isolated.
143143+ *
144144+ * @param handler Function pointer taking an integer fault_id to execute recovery
145145+ */
146146+void register_recovery_handler(void (*handler)(int fault_id));
138147139148#ifdef __cplusplus
140149}
···3939# Set SPARC sysroot if using BCC2
4040# SYSROOT = "/opt/bcc2/sparc-gaisler-elf"
41414242-# ── Build settings ───────────────────────────────────────────────────────────────
4343-4442[build]
4543# Default target for `cargo build` remains the host (ground station)
4644# Use --target explicitly for cross-compilation