Source code for opengnc.simulation.realtime

import time
from typing import Any

from .simulator import MissionSimulator


[docs] class RealTimeSimulator(MissionSimulator): """ Real-time simulation synchronizing simulation time to wall-clock time. Supports Hardware-In-the-Loop (HIL) or Software-In-the-Loop (SIL) testing. """ def __init__(self, *args: Any, rtf: float = 1.0, **kwargs: Any) -> None: """ Initialize real-time simulator. Parameters ---------- rtf : float Real-Time Factor. rtf = 1.0 means simulation runs exactly at wall-clock speed. rtf = 2.0 means simulation runs twice as fast. *args : Any Passed to MissionSimulator. **kwargs : Any Passed to MissionSimulator. """ super().__init__(*args, **kwargs) self.rtf = rtf self.wall_clock_start = 0.0 self.sim_clock_start = 0.0
[docs] def initialize(self, t0: float, initial_state: Any) -> None: super().initialize(t0, initial_state) self.sim_clock_start = t0 self.wall_clock_start = time.time()
[docs] def run(self, t_end: float, dt: float) -> None: """ Runs the simulation loop until the end time, matching wall-clock pace. Parameters ---------- t_end : float Simulation end time. dt : float Simulation time step. """ while self.time <= t_end: # step logic super().step(dt) # calculate required delay elapsed_sim = self.time - self.sim_clock_start expected_wall_clock = elapsed_sim / self.rtf elapsed_wall = time.time() - self.wall_clock_start sleep_time = expected_wall_clock - elapsed_wall if sleep_time > 0: time.sleep(sleep_time) elif sleep_time < -dt: # Issue a warning if we consistenty fall behind schedule print(f"Warning: Real-time deadline missed by {-sleep_time:.3f}s")