OpenFlight Software Architecture Overview
This document provides a high-level overview of the OpenFlight simulator's architecture, intended for developers looking to understand, maintain, or extend the project.
1. Core Architecture: Client-Server Model
OpenFlight employs a client-server architecture:
Backend (Server): A Julia application responsible for the core flight simulation, physics calculations, and state management.
Frontend (Client): A web-based application using HTML, CSS, and JavaScript (with Babylon.js) for 3D rendering, user interaction, and visualization.
Communication: Real-time, bidirectional communication between the backend and frontend is handled via WebSockets.
2. Backend (Julia) - OpenFlight.jl and src/🟣JULIA🟣/
The Julia backend is the simulation's brain. Its primary responsibilities include:
Physics Engine:
Integrates the aircraft's state over time using a Runge-Kutta 4 (RK4) integrator (2.1_⭐_Runge_Kutta_4_integrator.jl).
Solves the 6-Degrees-of-Freedom (6-DOF) equations of motion (2.2_🤸♀️_compute_6DOF_equations_of_motion.jl), considering forces and moments.
Aerodynamic & Propulsive Modeling:
Loads aircraft-specific parameters (mass, inertia, dimensions, control derivatives, etc.) from YAML files located in 🏭_HANGAR/📜_Aero_data/ (0.1_📊..., 0.2.4_📈...).
Calculates aerodynamic forces (Lift, Drag, Sideforce) and moments (Roll, Pitch, Yaw) based on the current flight state (Mach, altitude, angle of attack, sideslip angle) and control surface deflections (0.2.1_▶..., 0.2.2_⏩...). Uses interpolation for table lookups.
Calculates engine thrust (0.2.3_🚀...).
Atmosphere & Environment:
Models the International Standard Atmosphere (ISA) to determine air density, pressure, temperature, and speed of sound based on altitude (4.2_🌍_ISA76.jl).
Includes physical constants (4.1_🎯...) and anemometry calculations (4.3_🕑...).
System Dynamics:
Simulates first-order dynamics for control actuators and engine spooling to model delays and rate limits (5.1_➰...).
State Management & Communication:
Maintains the authoritative state of the aircraft (position, velocity, orientation, angular rates).
Hosts a WebSocket server (3.1_🤝...) listening on an automatically determined free port (🔌_Find_free_port.jl).
Receives JSON messages containing client state estimates and pilot control inputs.
Runs the simulation step (3.2_🔁...).
Sends the updated, authoritative state back to the client as a JSON object, including the current simulation time (server_time).
Configuration & Initialization:
Loads mission parameters (initial conditions, recording times, aircraft selection) from default_mission.yaml.
Synchronizes key parameters from the mission YAML to the JavaScript client's initialization file (✨_sync_mission_data_to_javascript.jl).
Manages Julia package dependencies (🎁_load_required_packages.jl).
Launches the client web browser (3.0_🌐...).
Data Logging:
Records a wide range of simulation variables (state, forces, moments, coefficients, control inputs) to a timestamped CSV file during a configured time window (3.3_📈...).
3. Frontend (JavaScript/Babylon.js) - src/🟡JAVASCRIPT🟡/
The JavaScript frontend handles the user interface and visualization. Its key roles are:
3D Rendering Engine:
Utilizes Babylon.js for all 3D rendering tasks.
Sets up the core Babylon engine and scene (6.1_♻..., 6.2_🌄...).
Scene Construction:
Creates lighting (hemispheric, directional) and shadow generation (cascaded shadow maps) (6.3_💡...).
Sets up multiple camera perspectives (ArcRotate, Follow, Cockpit, Wing) and manages the active camera (6.4_🎦...).
Generates the 3D world, including procedural terrain, runway, sky, fog, and various static/animated world objects (trees, buildings, lighthouses, turbines) (4.* modules).
Aircraft Visualization:
Displays either a default geometric aircraft model or loads user-provided .glb models (4.1_✈..., 4.3_🔼...).
Applies necessary transformations (scaling, rotation, translation) based on the loaded model.
Attaches and positions visual elements like navigation/strobe lights and an animated propeller to the aircraft model.
Updates the visual position and orientation of the aircraft model based on data received from the Julia backend.
User Interface (UI):
Uses Babylon.GUI to create interactive elements (2.1_📟...).
Displays real-time flight data (altitude, speed, attitude, etc.).
Provides buttons for simulation control (pause, load model) and camera selection.
Input Handling:
Captures keyboard and gamepad/joystick inputs (3.1_🕹...).
Maps inputs to control demands (pitch, roll, yaw, thrust) and simulation actions (pause, reset, camera change).
WebSocket Client:
Establishes a WebSocket connection to the Julia backend (1.1_🔁...).
Sends pilot inputs and the current client-side state estimate (position, velocity, orientation, etc.) as a JSON object to the server on each frame (or at a regular interval). Includes a deltaTime value.
Receives the authoritative state update JSON from the server and applies it to the visual aircraft model and GUI displays.
Data Visualization:
Optionally draws debug lines representing velocity and force vectors (5.1_📐...).
Creates a visual trail (using thin instances for performance) representing the aircraft's trajectory (5.2_➰...).
4. Communication Protocol (WebSockets)
Format: Data is exchanged as JSON strings.
Client -> Server: The client sends a JSON object containing its current estimated state (position, velocity, orientation, angular rates) and the current pilot control demands (raw inputs and attained values based on client-side actuator simulation), plus the deltaTime since its last message.
Server -> Client: The server sends a JSON object containing the authoritative, updated aircraft state (position, velocity, orientation, angular rates) after running one integration step, along with other relevant data like global forces, aerodynamic angles, attained control surface positions/thrust, and the current server_time (representing the backend's simulation time).
5. Configuration (YAML)
default_mission.yaml: Defines high-level simulation parameters like the aircraft model to use (aircraft_name), initial flight conditions, and the time window for data recording. This file's parameters are synced to the JavaScript client on startup.
🏭_HANGAR/📜_Aero_data/*.yaml: Contains detailed aerodynamic coefficients, physical properties (mass, inertia, dimensions), control derivatives, and propulsion characteristics for specific aircraft models. The file specified by aircraft_name in the mission YAML is loaded by the Julia backend.
6. Data Flow (Simplified Loop)
Client: Captures user input (keyboard/gamepad).
Client: Updates its local representation of control demands (considering simple actuator limits if implemented client-side).
Client: Sends its current state estimate and control demands (as JSON) to the server via WebSocket. Includes deltaTime.
Server: Receives client JSON data.
Server: Updates simulation time using client's deltaTime.
Server: Runs the RK4 integrator for one step, using the received state and control demands as input. This involves:
Calculating current flight conditions (alpha, beta, Mach, etc.).
Calculating aerodynamic and propulsive forces/moments.
Simulating actuator/engine dynamics to get attained control values.
Solving 6-DOF equations.
Server: Records flight data to internal DataFrame if within the recording time window.
Server: Sends the new, authoritative state (and other telemetry) back to the client (as JSON) via WebSocket, including server_time.
Client: Receives authoritative state JSON from the server.
Client: Updates the 3D aircraft model's position/orientation.
Client: Updates GUI elements with new data.
Client: Renders the 3D scene.
Loop: Repeats from step 1.
7. Key Design Principles
Modularity: Code is organized into separate files based on functionality (e.g., atmosphere, aerodynamics, controls, rendering components).
Separation of Concerns: Physics simulation (Julia) is clearly separated from visualization and UI (JavaScript).
Performance: Julia is chosen for computationally intensive backend tasks. Techniques like thin instances are used in the frontend for rendering many objects (trees, trajectory).
Customization: Aircraft models (.glb) and their aerodynamic characteristics (.yaml) can be easily swapped or added.
Real-time Synchronization: WebSockets provide low-latency communication for a responsive simulation feel.