FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
sim_threading.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2006-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file sim_threading.h
10 * @brief Header file for the main simulation runner.
11 *
12 * This file contains the declarations for the high-level function and engine that
13 * orchestrates and manages the event-driven radar simulation.
14 */
15
16#pragma once
17
18#include <chrono>
19#include <functional>
20#include <memory>
21#include <mutex>
22#include <string>
23#include <thread>
24#include <vector>
25
26#include "core/config.h"
28#include "core/sim_events.h"
29
30namespace pool
31{
32 class ThreadPool;
33}
34
35namespace radar
36{
37 class Receiver;
38 class Transmitter;
39}
40
41namespace serial
42{
43 class Response;
44}
45
46namespace core
47{
48 class World;
49
50 /**
51 * @class ProgressReporter
52 * @brief A thread-safe wrapper for the simulation progress callback.
53 *
54 * Allows multiple worker threads to report progress concurrently without race conditions.
55 */
57 {
58 public:
59 /**
60 * @typedef Callback
61 * @brief Defines the signature for the progress reporting callback function.
62 */
63 using Callback = std::function<void(const std::string&, int, int)>;
64
65 /**
66 * @brief Constructs a ProgressReporter with the given callback.
67 * @param cb The callback function to wrap.
68 */
69 explicit ProgressReporter(Callback cb) : _callback(std::move(cb)) {}
70
71 /**
72 * @brief Safely reports progress to the underlying callback.
73 * @param msg The status message to report.
74 * @param current The current progress value.
75 * @param total The total progress value.
76 */
77 void report(const std::string& msg, int current, int total)
78 {
79 if (_callback)
80 {
81 std::scoped_lock lock(_mutex);
82 _callback(msg, current, total);
83 }
84 }
85
86 private:
87 std::mutex _mutex; ///< Mutex to ensure thread-safe access to the callback.
88 Callback _callback; ///< The underlying callback function.
89 };
90
91 /**
92 * @class SimulationEngine
93 * @brief Encapsulates the state and logic of the event-driven simulation loop.
94 *
95 * Breaking the simulation loop into this class allows for easily testable,
96 * focused functions with low cyclomatic complexity.
97 */
99 {
100 public:
101 /**
102 * @brief Constructs the simulation engine.
103 * @param world Pointer to the simulation world containing all entities.
104 * @param pool Reference to the thread pool for asynchronous tasks.
105 * @param reporter Shared pointer to the thread-safe progress reporter.
106 * @param output_dir Output directory for the simulation files.
107 */
108 SimulationEngine(World* world, pool::ThreadPool& pool, std::shared_ptr<ProgressReporter> reporter,
109 std::string output_dir, std::shared_ptr<OutputMetadataCollector> metadata_collector = nullptr);
110
111 /**
112 * @brief Starts and runs the main simulation loop until completion.
113 */
114 void run();
115
116 /**
117 * @brief Advances the time-stepped inner loop for active continuous-wave (CW) systems.
118 * @param t_event The timestamp of the next discrete event to process up to.
119 */
120 void processCwPhysics(RealType t_event);
121
122 /**
123 * @brief Dispatches a discrete simulation event to its specific handler.
124 * @param event The event to process.
125 */
126 void processEvent(const Event& event);
127
128 /**
129 * @brief Handles the start of a pulsed transmission.
130 * @param tx Pointer to the transmitting radar object.
131 * @param t_event The timestamp of the transmission event.
132 */
134
135 /**
136 * @brief Handles the opening of a pulsed receiver's listening window.
137 * @param rx Pointer to the receiving radar object.
138 * @param t_event The timestamp of the window opening event.
139 */
141
142 /**
143 * @brief Handles the closing of a pulsed receiver's listening window, triggering finalization.
144 * @param rx Pointer to the receiving radar object.
145 * @param t_event The timestamp of the window closing event.
146 */
148
149 /**
150 * @brief Handles a continuous-wave transmitter turning on.
151 * @param tx Pointer to the transmitting radar object.
152 */
154
155 /**
156 * @brief Handles a continuous-wave transmitter turning off.
157 * @param tx Pointer to the transmitting radar object.
158 */
160
161 /**
162 * @brief Handles a continuous-wave receiver starting to record.
163 * @param rx Pointer to the receiving radar object.
164 */
166
167 /**
168 * @brief Handles a continuous-wave receiver stopping recording.
169 * @param rx Pointer to the receiving radar object.
170 */
172
173 /**
174 * @brief Calculates the total complex I/Q sample for a receiver at a specific time step.
175 * @param rx Pointer to the receiving radar object.
176 * @param t_step The exact simulation time for the sample.
177 * @param cw_sources A list of currently active continuous-wave transmitters.
178 * @return The calculated complex I/Q sample combining direct and reflected paths.
179 */
180 [[nodiscard]] ComplexType calculateCwSample(radar::Receiver* rx, RealType t_step,
181 const std::vector<radar::Transmitter*>& cw_sources) const;
182
183 private:
184 /**
185 * @brief Starts dedicated finalizer threads for all pulsed receivers.
186 */
187 void initializeFinalizers();
188
189 /**
190 * @brief Routes a calculated radar response to the appropriate receiver inbox or log.
191 * @param rx Pointer to the receiving radar object.
192 * @param response The calculated response to route.
193 */
194 void routeResponse(radar::Receiver* rx, std::unique_ptr<serial::Response> response) const;
195
196 /**
197 * @brief Throttles and emits progress updates to the reporter.
198 */
199 void updateProgress();
200
201 /**
202 * @brief Initiates the shutdown phase, waiting for all asynchronous tasks to complete.
203 */
204 void shutdown();
205
206 World* _world; ///< Pointer to the simulation world state.
207 pool::ThreadPool& _pool; ///< Reference to the global thread pool.
208 std::shared_ptr<ProgressReporter> _reporter; ///< Shared progress reporter instance.
209 std::vector<std::jthread> _finalizer_threads; ///< Collection of dedicated pulsed finalizer threads.
210 std::shared_ptr<OutputMetadataCollector> _metadata_collector;
211
212 std::chrono::steady_clock::time_point _last_report_time; ///< Timestamp of the last progress report.
213 int _last_reported_percent = -1; ///< The last reported percentage to prevent redundant updates.
214
215 std::string _output_dir; ///< Output directory for the simulation files.
216 };
217
218 /**
219 * @brief Runs the unified, event-driven radar simulation.
220 *
221 * This function is the core entry point of the simulator. It advances time by
222 * processing events from a global priority queue. It handles both pulsed
223 * and continuous-wave (CW) physics, dispatching finalization tasks to
224 * worker threads for asynchronous processing.
225 *
226 * @param world A pointer to the simulation world containing all entities and state.
227 * @param pool A reference to the thread pool for executing tasks.
228 * @param progress_callback An optional callback function for reporting progress.
229 * @param output_dir Output directory for the simulation files.
230 */
232 const std::function<void(const std::string&, int, int)>& progress_callback,
233 const std::string& output_dir);
234}
A thread-safe wrapper for the simulation progress callback.
ProgressReporter(Callback cb)
Constructs a ProgressReporter with the given callback.
std::function< void(const std::string &, int, int)> Callback
Defines the signature for the progress reporting callback function.
void report(const std::string &msg, int current, int total)
Safely reports progress to the underlying callback.
Encapsulates the state and logic of the event-driven simulation loop.
ComplexType calculateCwSample(radar::Receiver *rx, RealType t_step, const std::vector< radar::Transmitter * > &cw_sources) const
Calculates the total complex I/Q sample for a receiver at a specific time step.
void handleRxCwStart(radar::Receiver *rx)
Handles a continuous-wave receiver starting to record.
void handleRxPulsedWindowEnd(radar::Receiver *rx, RealType t_event)
Handles the closing of a pulsed receiver's listening window, triggering finalization.
void handleTxCwEnd(radar::Transmitter *tx)
Handles a continuous-wave transmitter turning off.
void handleTxCwStart(radar::Transmitter *tx)
Handles a continuous-wave transmitter turning on.
void handleRxPulsedWindowStart(radar::Receiver *rx, RealType t_event)
Handles the opening of a pulsed receiver's listening window.
void run()
Starts and runs the main simulation loop until completion.
void processEvent(const Event &event)
Dispatches a discrete simulation event to its specific handler.
void processCwPhysics(RealType t_event)
Advances the time-stepped inner loop for active continuous-wave (CW) systems.
void handleRxCwEnd(radar::Receiver *rx)
Handles a continuous-wave receiver stopping recording.
void handleTxPulsedStart(radar::Transmitter *tx, RealType t_event)
Handles the start of a pulsed transmission.
The World class manages the simulator environment.
Definition world.h:39
A simple thread pool implementation.
Definition thread_pool.h:29
Manages radar signal reception and response processing.
Definition receiver.h:37
Represents a radar transmitter system.
Definition transmitter.h:33
Global configuration file for the project.
double RealType
Type for real numbers.
Definition config.h:27
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
OutputMetadata runEventDrivenSim(World *world, pool::ThreadPool &pool, const std::function< void(const std::string &, int, int)> &progress_callback, const std::string &output_dir)
Runs the unified, event-driven radar simulation.
Defines the core structures for the event-driven simulation engine.
Represents a single event in the simulation's time-ordered queue.
Definition sim_events.h:43