SDF Runtime Data Flow
This page complements the system architecture overview. The architecture page explains which subsystems exist and how responsibilities are separated; this page focuses on how configuration, commands, forces, state, reference frames, telemetry, and recorded simulation data move through the running application.
1. Configuration to Authoritative Runtime State
Spacecraft configuration describes how the initial position and velocity are expressed. It does not define the runtime propagation frame. Current SDF supports two consistent initialization modes: ENU/ENU and MCI/MCI. Mixed position and velocity frame combinations are rejected by the configuration reader.
JSON spacecraft configuration
↓
jsonConfigReader
↓
customSpacecraft + MissionContext
↓
Mission-frame initialization
↓
Configured initial-state resolution
↓
Authoritative StateVector
(MCI position + MCI velocity)Landing-site-relative ENU
Landing Site (MSC)
↓
MCMF landing-site state
↓
Landing-site ENU frame
↓
Configured ENU state
↓
ENU → MCMF → MCI
↓
StateVectorENU is an input and mission/navigation representation. It is resolved once during initialization.
Direct MCI
Configured MCI state
↓
Direct assignment
↓
StateVectorDirect MCI initialization remains available for orbital, low-level, analytical, and verification scenarios.
2. Control Input to Actuation
Frontend input and automated control produce commands, not forces. The propulsion subsystem owns conversion from those commands into main-engine and RCS actuator states. Main-engine automation, translational RCS control, and rotational RCS control are resolved as separate command channels.
Manual RCS axes ─→ inputmapper ─────┐
│
Kill Rotation / Stabilize buttons ────┤
Main-engine / autopilot controls ─────┘
↓
FlightCommandDTO
↓
cockpitPage
↓
SimulationWorkerTelemetryMapper
↓
ControlCommand
├─ mainEngine
├─ translation
├─ rotation
├─ autopilotActive
├─ killRotation
└─ stabilizeUser ControlCommand
↓
InputArbiter
├─ main-engine authority
├─ translation remains manual
└─ rotation authority
↑
│
simcontrol::runAutopilot(dt)
├─ AdaptiveDescentController
│ ↓
│ auto main-engine command
│
└─ AttitudeController
├─ Kill Rotation
└─ Stabilize
↓
auto rotation command
↓
InputArbiter::chooseCommand()
↓
simcontrol::processCommands()
↓
Main engine + RCS target commands
↓
Thrust / RCSControlAllocatorThe visual grouping marks the application boundaries explicitly: UI input and worker scheduling remain in the frontend/application layer, TelemetryMapper and the DTO/domain-command translation form the interface boundary, and arbitration, automatic control, simulation orchestration, and propulsion are backend responsibilities.
Rotational-control authority
Manual rotational input is used while neither automatic attitude mode is active. WhenkillRotation or stabilize is active, InputArbiter replaces only the rotational channel with the command generated by AttitudeController. Translational RCS input remains manual, and main-engine automation remains independently controlled by the autopilot flag.
Neither attitude mode active:
user rotation ─────────────────────────────→ active rotation
Kill Rotation active:
SBF angular velocity
↓
AttitudeController::killRotation()
↓
autoCmd.rotation ──────────────────────────→ active rotation
Stabilize active:
IB attitude + SBF angular velocity
↓
AttitudeController::stabilize()
├─ capture target attitude on activation
├─ quaternion attitude-error feedback
├─ angular-rate damping
└─ hysteresis state
↓
autoCmd.rotation ──────────────────────────→ active rotationBackend step order
The automatic-control command is evaluated from the current spacecraft state before actuation targets are applied and before the physical state advances. The resulting telemetry snapshot is generated only after the completed spacecraft update.
Frontend command transfer
↓
simcontrol::runSimulation(dt)
↓
runAutopilot(currentState, dt)
├─ descent-control calculation
└─ attitude-control calculation
↓
processCommands()
└─ InputArbiter::chooseCommand()
↓
set target main-engine / RCS commands
↓
spacecraft::updateStep(dt)
↓
getFullSimulationData()
↓
append active attitude-mode flags
↓
TelemetryMapper → TelemetryDTO
↓
append telemetry history
↓
emit stateUpdated(...)3. Propulsion Force Generation to Physics
Main-engine and RCS models generate forces and torques in the spacecraft body frame. The Thrust orchestrator aggregates those outputs before the translational force vector is transformed into MCI.
Main Engine + RCS
↓
Thrust Orchestrator
(SBF forces + torques)
↓
Current spacecraft attitude
↓
SBF → MCI force transform
↓
physics::computeAcc()
↓
BasicMoonGravityModel
↓
Gravity + thrust / mass
↓
Total MCI acceleration4. Physics Calculation to State Propagation
spacecraft::updateMovementData() coordinates dynamics and integration. The physics and integrator layers compute updated quantities, while spacecraft commits them to the authoritative state.
Authoritative StateVector
↓
spacecraft::updateMovementData()
↓
Current-attitude SBF thrust → MCI
↓
Translational acceleration
↓
EulerIntegrator
↓
MCI velocity + position
SBF torque
↓
Rotational physics
↓
Angular acceleration
↓
EulerIntegrator
↓
SBF angular velocity + IB attitude
↓
StateVector commit
↓
spacecraft::updateFrames(time)Derived frame representations are reconstructed only after the current step has been committed.SimulationFrameContext therefore represents one coherent snapshot of the authoritative state.
5. Mission Context and Derived Runtime Frames
SDF separates stable mission references from state-dependent frame representations.MissionContext contains mission-level references; SimulationFrameContextcontains frame representations derived from the current spacecraft state.
MissionContext
- Canonical landing site in MSC
- Derived landing-site state in MCMF
- Derived landing-site state in MCI
- Landing-site ENU frame
These are persistent mission references, not propagated spacecraft state.
SimulationFrameContext
- MCI spacecraft state
- MCMF spacecraft state
- MSC latitude / longitude / altitude
- ENU spacecraft state and ENU frame
- LVLH spacecraft state and LVLH frame
- SBF frame derived from current attitude and origin
Authoritative StateVector
↓
spacecraft::updateFrames(time)
↓
MCI_State
↓
MCMF_State
├──→ MSC_State
└──→ ENU_State
MCI_State
└──→ LVLH_State
StateVector attitude + origin
└──→ SBF_Frame6. Backend State to Frontend Telemetry
Backend domain state remains inside the simulation engine. After each completed step, one coherent backend snapshot is mapped into a frontend-facing TelemetryDTO.
spacecraft::time ───────────┐
StateVector ─────────────────┤
SimulationFrameContext ──────┼──→ simData
MissionContext ──────────────┤
propulsion / tanks / sensors ┤
InputArbiter mode flags ─────┘TelemetryMapper
↓
TelemetryDTOSimulationWorker
├──→ telemetry history
└──→ stateUpdated(...)
↓
Qt thread boundary
↓
cockpit / visualizationThe same layer colors are intentionally reused in the reverse direction. Backend state is aggregated intosimData, translated at the interface boundary into TelemetryDTO, and then consumed by the worker/application layer for history recording and UI delivery.
Attitude-control mode telemetry
The active rotational automation mode is read from InputArbiter after the spacecraft step and added to the same simData snapshot. The interface layer maps these values into the dedicatedTelemetryDTO::Automation group.
InputArbiter
├─ isKillRotationActive()
└─ isStabilizeActive()
↓
simData
├─ killRotationActive
└─ stabilizeActive
↓
TelemetryMapper
↓
TelemetryDTO::Automation
├─ killRotationActive
└─ stabilizeActive
↓
Cockpit history / XML exportAuthoritative simulation time
spacecraft::time
↓
simData::time
↓
TelemetryMapper
↓
TelemetryDTO::time
↓
Cockpit / ExportThe worker does not maintain a second simulation clock. The backend time used for time-dependent frame derivation is the same time exposed to telemetry consumers and scientific export.
7. Telemetry Recording and XML Export
Scientific export reuses the same TelemetryDTO snapshots consumed by the frontend. Recording is owned by SimulationWorker; XML serialization is delegated toTelemetryXmlExporter.
simData
↓
TelemetryMapper
↓
TelemetryDTO
↓
SimulationWorker
├──→ stateUpdated → Cockpit / Visualization
└──→ telemetryHistory_
↓ export request
TelemetryXmlExporter
↓
XML telemetry fileThe XML snapshot preserves the automatic attitude-control state explicitly:
<automation>
<killRotationActive>true|false</killRotationActive>
<stabilizeActive>true|false</stabilizeActive>
</automation>This allows controller activation, settling behavior, and RCS response to be correlated precisely during telemetry-based verification without inferring the control mode indirectly from thruster activity.
- One snapshot is recorded after each completed backend simulation step.
- Pause adds no snapshots because no backend steps are executed.
- Stop terminates the active session but does not silently overwrite recorded history.
- Starting a new run with existing history requires explicit overwrite confirmation before clearing it.
TelemetryXmlExporterserializes existing history; it does not generate simulation state.
8. Simulation Lifecycle
The runtime lifecycle distinguishes initial start, pause/resume, and stop/reset. Resume continues the existing backend state; it must not reinitialize the spacecraft.
Configuration available
↓
Start requested
↓
initialized?
├── no ─→ existing history?
│ ├── yes → overwrite confirmation → clear history
│ └── no
│ ↓
│ backend initialize
│ ↓
└── yes ─────────→ start QTimer
↓
simulation steps
Pause → stop QTimer only
↓
preserve backend state + time + fuel + attitude
+ active controller state
↓
Resume → start QTimer, no reinitialization
Stop → stop QTimer
→ reset UI telemetry
→ backend reset
→ initialized = false- Initial start: creates and initializes the backend simulation session.
- Pause: freezes the step timer while preserving the complete backend state.
- Resume: continues the existing initialized session.
- Stop: terminates/resets the active simulation session.
- Restart after stop: creates a new session from configuration after any required history confirmation.
9. State Ownership Summary
Authoritative runtime state
StateVector is owned by spacecraft and is the source of truth for propagated position, velocity, attitude, and angular velocity.
Simulation time
spacecraft::time is the authoritative backend simulation clock and is propagated through simData into TelemetryDTO.
Mission references
MissionContext holds stable mission-specific navigation references such as the landing site and its derived reference frames.
Derived frame state
SimulationFrameContext is reconstructed from the authoritative state after each commit and is not independently integrated.
Control authority
InputArbiter owns the current manual/automatic authority flags for main-engine, Kill Rotation, and Stabilize command selection.
Attitude-control state
AttitudeController owns the captured Stabilize target quaternion and its internal hysteresis/correction state. It does not own or directly modify spacecraft physical state.
Telemetry snapshot
simData aggregates one backend step into the frontend/export-facing TelemetryDTO contract.
Recorded telemetry
SimulationWorker owns the telemetry history. TelemetryXmlExporterserializes that history without owning simulation state.
Contributor-Level Reference
This website presents the stable architectural view. The code-near reference, including detailed subsystem responsibilities and implementation-oriented data-flow notes, is maintained with the simulation source in docs/data-flow-diagrams.md.
Return to the SDF Architecture overview for subsystem structure, physics, propulsion, frontend, and backend architecture.