Skip to content

NTXSpace/Entropy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ENTROPY

ENTROPY is a real-time Hardware-in-the-Loop and Software-in-the-Loop telemetry injector for orbital-environment testing.

It generates a deterministic low Earth orbit telemetry stream at 100 Hz, sends it over UDP, exposes it through a TypeScript backend and WebSocket dashboard, and can optionally bridge data to hardware-oriented interfaces such as CAN, UART, SPI and I2C wrappers.

The project is designed for lab testing firmware, telemetry pipelines, dashboards, fault handling and repeatable debugging before real sensors or a complete test bench are available.

What This Software Is For

ENTROPY is useful when you need a controlled telemetry source that behaves like a spacecraft or orbital sensor environment.

Typical uses:

  • Firmware-in-the-loop testing for embedded controllers.
  • Hardware-in-the-loop telemetry injection into lab systems.
  • Backend telemetry ingestion testing over UDP.
  • WebSocket dashboard testing with live values.
  • Replayable debugging with deterministic binary recordings.
  • Fault-tolerance tests using anomaly commands and SEU event injection.
  • Real-time loop and jitter evaluation on Linux.
  • Sensor-bus integration experiments through CAN, serial, SPI and I2C wrappers.

ENTROPY is not a full orbital mechanics suite like GMAT, STK or Orekit. It is a deterministic telemetry and environment injector focused on integration testing, real-time behavior and system validation.

Repository Layout

entropy/
  core/
    CMakeLists.txt
    src/
      main.cpp
      simulator.hpp
      bus/
        shared_bus.hpp
        udp_sender.hpp
        command_receiver.hpp
        replay.hpp
        can_bus.hpp
        serial_bus.hpp
        spi_i2c.hpp
      physics/
        physics_engine.hpp
        atmosphere.hpp
        thermal.hpp
        imu.hpp
        magnetic.hpp
        seu.hpp
        nasa_constants.hpp
      rt/
        rt_loop.hpp
        jitter_logger.hpp
        watchdog.hpp
      security/
        hmac.hpp
        cmd_auth.hpp
    tests/
  backend/
    package.json
    tsconfig.json
    src/
      index.ts
      telemetry_receiver.ts
      websocket_server.ts
      influx_writer.ts
  dashboard/
    index.html

System Components

C++ Core

The C++ core is the real-time telemetry generator.

Main responsibilities:

  • Runs the simulation loop at 100 Hz.
  • Produces orbital telemetry frames.
  • Publishes frames through a lock-free-style seqlock shared bus.
  • Sends telemetry over UDP to 127.0.0.1:9000.
  • Listens for UDP commands on port 9001.
  • Supports binary record and replay.
  • Attempts real-time scheduling on Linux.
  • Logs loop jitter periodically.

Backend

The backend receives UDP packets from the core and broadcasts decoded telemetry to WebSocket clients.

Default ports:

  • UDP telemetry input: 9000
  • WebSocket output: 9010

It can also write telemetry to InfluxDB when the required environment variables are configured.

Dashboard

The dashboard is a static HTML page in dashboard/index.html.

It connects to the backend WebSocket on port 9010, displays live telemetry values and renders a simple orbit visualization.

Requirements

Required For Core

  • CMake >= 3.18
  • C++17 compiler
  • POSIX-like environment for sockets and threads

Tested-style commands assume:

  • macOS with Apple Clang, or
  • Linux with GCC/Clang

Required For Backend

  • Node.js
  • npm

Optional For Real-Time Linux Operation

For best deterministic behavior on Linux:

  • Linux kernel with POSIX real-time scheduling
  • Permission for SCHED_FIFO
  • Permission for mlockall
  • Optional /dev/watchdog
  • Optional SocketCAN device such as can0
  • Optional serial device such as /dev/ttyUSB0
  • Optional SPI/I2C devices such as /dev/spidev0.0 and /dev/i2c-1

On macOS, the software still runs, but Linux-specific real-time and hardware-bus features are unavailable or compiled as safe fallbacks.

Build The Core

From the repository root:

cd /Volumes/WDElements/ntxspace-website/ntx-space-web/entropy
cmake -S core -B core/build -DENTROPY_ENABLE_TESTS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build core/build

Run tests:

ctest --test-dir core/build --output-on-failure

The core binary is produced at:

core/build/entropy

Run The Full System

Use three terminals.

Terminal 1: Backend

cd /Volumes/WDElements/ntxspace-website/ntx-space-web/entropy/backend
npm install
npm run build
npm start

Expected output includes:

[WebSocket] listening on 9010
[Telemetry] UDP listening on 9000

Terminal 2: Dashboard

Open the static file directly:

open /Volumes/WDElements/ntxspace-website/ntx-space-web/entropy/dashboard/index.html

Or serve it over HTTP:

cd /Volumes/WDElements/ntxspace-website/ntx-space-web/entropy
python3 -m http.server 8080 -d dashboard

Then open:

http://localhost:8080

Terminal 3: Core

cd /Volumes/WDElements/ntxspace-website/ntx-space-web/entropy
./core/build/entropy

Recommended startup order:

  1. Backend
  2. Dashboard
  3. Core

The core sends UDP telemetry to the backend, the backend broadcasts it over WebSocket, and the dashboard renders it live.

Core CLI

Normal Live Simulation

./core/build/entropy

Record A Session

./core/build/entropy --record run.bin

This writes binary FullTelemetryFrame records to run.bin.

Replay A Session

./core/build/entropy --replay run.bin

This reads frames from run.bin and republishes them at the normal loop cadence.

Record And Replay Notes

  • Replay publishes stored telemetry frames through the same SharedBus.
  • UDP output still works during replay.
  • Replay stops when the file ends.
  • Recording and replay files are raw binary and intended for this project version.

Runtime Ports And Protocols

Port Direction Protocol Purpose
9000 core to backend UDP Telemetry stream
9001 external to core UDP Command input
9010 backend to browser WebSocket Live dashboard telemetry

Backend ports can be changed with environment variables:

ENTROPY_UDP_PORT=9100 ENTROPY_WS_PORT=9110 npm start

The C++ core currently uses compile-time defaults in core/src/simulator.hpp:

udp_host = "127.0.0.1"
udp_port = 9000
cmd_udp_port = 9001
loop_hz = 100
rt_priority = 90
rt_cpu = 1

Telemetry Packet Format

UDP telemetry packets use a small versioned header followed by a payload.

Wire Header

struct WireHeader {
  uint32_t magic;       // 0x45544e50, "ETNP"
  uint16_t version;     // 1
  uint16_t payloadSize; // 40 or 104 bytes
};

Base Telemetry Frame

Size: 40 bytes

struct TelemetryFrame {
  uint64_t sequenceNumber;
  double pressurePa;
  double temperatureK;
  double altitudeKm;
  double altitudeDelta;
};

Full Telemetry Frame

Size: 104 bytes

struct FullTelemetryFrame {
  TelemetryFrame base;
  double accelerationMps2[3];
  double imuBias;
  double magneticFieldUt[3];
  uint32_t seuEvents;
  uint32_t reserved;
};

The TypeScript backend accepts:

  • 8 + 104 byte framed full packets
  • 8 + 40 byte framed legacy packets
  • 104 byte raw full packets
  • 40 byte raw legacy packets

Command Input

The core listens on UDP port 9001.

Current command bytes:

Byte Action
1 Enable anomaly injection
2 Reset simulation state and clear anomaly

Examples:

printf '\x01' | nc -u -w0 127.0.0.1 9001
printf '\x02' | nc -u -w0 127.0.0.1 9001

The command receiver polls with a short timeout so shutdown does not wait on a long blocking read.

Physics And Environment Models

The physics code lives in core/src/physics.

Implemented components:

  • NASA Glenn style atmospheric pressure and density model.
  • Thermal equilibrium model using solar constant, albedo, Earth IR flux and Stefan-Boltzmann constant.
  • Deterministic IMU acceleration model with noise and bias drift.
  • Earth magnetic dipole approximation scaled by altitude.
  • Deterministic SEU event injection.
  • Altitude oscillation between 400 km and 450 km.
  • Anomaly mode that increases pressure and temperature.

Important constants are centralized in:

core/src/physics/nasa_constants.hpp

This is suitable for integration testing. It is not a replacement for a high-fidelity orbital propagation and atmosphere stack.

Real-Time Behavior

The loop target is:

100 Hz
10 ms period

On Linux, the core attempts:

  • clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ...)
  • SCHED_FIFO with priority 90
  • CPU affinity to CPU 1
  • mlockall(MCL_CURRENT | MCL_FUTURE)
  • /dev/watchdog kick when available

If SCHED_FIFO fails, the program continues and prints a warning.

To grant the binary permission for real-time scheduling on Linux:

sudo setcap cap_sys_nice+ep ./core/build/entropy

For more deterministic operation:

  • Run on Linux rather than macOS.
  • Use an isolated CPU core.
  • Avoid running the dashboard/browser on the same isolated core.
  • Disable CPU frequency scaling if your lab setup allows it.
  • Keep I/O off the RT thread.

SharedBus Design

SharedBus is the handoff between the real-time producer and sender thread.

It uses a manual seqlock:

  • Writer marks sequence odd.
  • Writer copies the frame.
  • Writer marks sequence even.
  • Reader retries until it sees a stable even sequence.
  • Reader falls back to the last valid frame after bounded spinning.

This avoids std::atomic<FullTelemetryFrame> because large atomic structs are generally not lock-free and may use hidden locks.

Backend

The backend is TypeScript/Node.

Install and build:

cd backend
npm install
npm run build

Run:

npm start

Environment Variables

Variable Default Purpose
ENTROPY_UDP_PORT 9000 UDP telemetry receiver port
ENTROPY_WS_PORT 9010 WebSocket server port
INFLUX_URL unset InfluxDB endpoint
INFLUX_TOKEN unset InfluxDB auth token
INFLUX_ORG unset InfluxDB organization
INFLUX_BUCKET unset InfluxDB bucket

If all Influx variables are present, telemetry is written to InfluxDB. If they are missing, Influx writing is disabled and the backend still runs normally.

Dashboard

Dashboard file:

dashboard/index.html

It displays:

  • Sequence number
  • Altitude
  • Pressure
  • Temperature
  • IMU acceleration
  • Magnetic field
  • SEU event count
  • Orbit visualization
  • WebSocket connection status

By default it connects to:

ws://<current-host>:9010

If opened directly as a file, most browsers use an empty host. The dashboard falls back to 127.0.0.1.

Hardware Interfaces

The project includes hardware-bus wrappers. They are available to integrate into lab-specific sender paths.

SocketCAN / CAN FD

File:

core/src/bus/can_bus.hpp

Linux only.

Expected interface:

can0

Example Linux setup:

sudo modprobe can
sudo modprobe can_raw
sudo ip link set can0 up type can bitrate 1000000 dbitrate 2000000 fd on

UART / RS-422 Style Serial

File:

core/src/bus/serial_bus.hpp

Supports common baud rates such as:

  • 9600
  • 19200
  • 38400
  • 57600
  • 115200

Example devices:

/dev/ttyUSB0
/dev/ttyS0

SPI and I2C

File:

core/src/bus/spi_i2c.hpp

Linux device examples:

/dev/spidev0.0
/dev/i2c-1

These wrappers provide low-level access primitives. They are not automatically active in main.cpp; connect them where your lab hardware requires.

Security Notes

The project includes HMAC helpers in:

core/src/security/

Current command receiver behavior is still byte-command based on UDP port 9001. The HMAC helpers are available for authenticated command packet expansion, but the default command path is intentionally simple for lab control.

Do not expose command or telemetry ports to untrusted networks.

InfluxDB Integration

To enable InfluxDB:

cd backend
export INFLUX_URL=http://localhost:8086
export INFLUX_TOKEN=your-token
export INFLUX_ORG=your-org
export INFLUX_BUCKET=your-bucket
npm start

Measurement name:

entropy_telemetry

Fields include:

  • sequence
  • pressure_pa
  • temperature_k
  • altitude_km
  • altitude_delta
  • imu_bias
  • seu_events

Common Workflows

Run A Live Demo

cmake -S core -B core/build -DENTROPY_ENABLE_TESTS=ON
cmake --build core/build

cd backend
npm install
npm run build
npm start

In another terminal:

open dashboard/index.html
./core/build/entropy

Record A Fault Scenario

./core/build/entropy --record fault-run.bin

Inject anomaly:

printf '\x01' | nc -u -w0 127.0.0.1 9001

Reset:

printf '\x02' | nc -u -w0 127.0.0.1 9001

Replay later:

./core/build/entropy --replay fault-run.bin

Backend Only Decoder Test

If you have another telemetry source that emits ENTROPY-compatible packets:

cd backend
npm start

Send packets to UDP port 9000.

Troubleshooting

cmake: command not found

Install CMake:

brew install cmake

or on Debian/Ubuntu:

sudo apt-get install cmake build-essential

SCHED_FIFO unavailable

On Linux:

sudo setcap cap_sys_nice+ep ./core/build/entropy

You may also need to check system real-time limits.

Dashboard Shows reconnecting

Check that the backend is running:

cd backend
npm start

Check WebSocket port:

lsof -i :9010

Backend Receives Nothing

Check core is running:

./core/build/entropy

Check UDP port:

lsof -i UDP:9000

Check that the core still targets 127.0.0.1:9000 in:

core/src/simulator.hpp

InfluxDB Writes Nothing

Confirm all four variables are set:

echo "$INFLUX_URL"
echo "$INFLUX_TOKEN"
echo "$INFLUX_ORG"
echo "$INFLUX_BUCKET"

If any are missing, Influx writing is disabled by design.

SocketCAN Fails

Confirm you are on Linux and can0 exists:

ip link show can0

Bring it up:

sudo ip link set can0 up type can bitrate 1000000 dbitrate 2000000 fd on

Replay Ends Immediately

The replay file may be empty or from an incompatible frame layout. Record a fresh session:

./core/build/entropy --record run.bin

Then replay:

./core/build/entropy --replay run.bin

Development Notes

  • C++ standard: C++17
  • Backend TypeScript target: ES2020 / Node16 module resolution
  • Core tests live in core/tests
  • Build artifacts should stay under core/build
  • compile_commands.json is ignored at the repository root/core level
  • The dashboard is static and does not require a frontend build step

Limitations

  • The orbital model is intentionally simple and deterministic.
  • NASA/JPL constants and NASA Glenn style atmosphere values are used for integration-test realism, not mission analysis precision.
  • Hardware bus wrappers exist, but main.cpp currently sends live telemetry over UDP by default.
  • HMAC helpers exist, but default command UDP packets are simple one-byte lab commands.
  • Real-time scheduling quality depends on the operating system, permissions and hardware.
  • macOS is suitable for development, but Linux is the intended target for RT and hardware bus use.

Quick Command Reference

# Build core
cmake -S core -B core/build -DENTROPY_ENABLE_TESTS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build core/build

# Test core
ctest --test-dir core/build --output-on-failure

# Backend
cd backend
npm install
npm run build
npm start

# Core live
./core/build/entropy

# Record
./core/build/entropy --record run.bin

# Replay
./core/build/entropy --replay run.bin

# Dashboard via HTTP
python3 -m http.server 8080 -d dashboard

# Inject anomaly
printf '\x01' | nc -u -w0 127.0.0.1 9001

# Reset
printf '\x02' | nc -u -w0 127.0.0.1 9001

=======

Entropy

Real-time Hardware-in-the-Loop orbital telemetry injector — 100Hz LEO simulation over UDP, WebSocket dashboard, C++17 + TypeScript

About

Real-time Hardware-in-the-Loop orbital telemetry injector — 100Hz LEO simulation over UDP, WebSocket dashboard, C++17 + TypeScript

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors