38 void World::add(std::unique_ptr<Platform> plat)
noexcept { _platforms.push_back(std::move(plat)); }
40 void World::add(std::unique_ptr<Transmitter> trans)
noexcept { _transmitters.push_back(std::move(trans)); }
42 void World::add(std::unique_ptr<Receiver> recv)
noexcept { _receivers.push_back(std::move(recv)); }
44 void World::add(std::unique_ptr<Target> target)
noexcept { _targets.push_back(std::move(target)); }
48 const SimId id = waveform->getId();
49 if (_waveforms.contains(
id))
51 throw std::runtime_error(
"A waveform with the ID " + std::to_string(
id) +
" already exists.");
53 _waveforms[id] = std::move(waveform);
59 if (_antennas.contains(
id))
61 throw std::runtime_error(
"An antenna with the ID " + std::to_string(
id) +
" already exists.");
63 _antennas[id] = std::move(
antenna);
69 if (_timings.contains(
id))
71 throw std::runtime_error(
"A timing source with the ID " + std::to_string(
id) +
" already exists.");
73 _timings[id] = std::move(
timing);
78 const auto it = _waveforms.find(
id);
79 return it != _waveforms.end() ? it->second.get() :
nullptr;
84 const auto it = _antennas.find(
id);
85 return it != _antennas.end() ? it->second.get() :
nullptr;
90 const auto it = _timings.find(
id);
91 return it != _timings.end() ? it->second.get() :
nullptr;
96 for (
auto& p : _platforms)
106 for (
auto& tx : _transmitters)
107 if (tx->getId() == id)
114 for (
auto& rx : _receivers)
115 if (rx->getId() == id)
122 for (
auto& tgt : _targets)
123 if (tgt->getId() == id)
131 for (
auto& t : _targets)
133 if (t->getId() == id)
135 t = std::move(target);
139 _targets.push_back(std::move(target));
147 std::unique_ptr<Antenna> old_owned;
148 const Antenna* old_ptr =
nullptr;
150 if (
auto it = _antennas.find(
id); it != _antennas.end())
152 old_owned = std::move(it->second);
153 old_ptr = old_owned.get();
154 it->second = std::move(
antenna);
158 _antennas[id] = std::move(
antenna);
161 if ((old_ptr !=
nullptr) && old_ptr != new_ptr)
163 for (
auto& tx : _transmitters)
164 if (tx->getAntenna() == old_ptr)
165 tx->setAntenna(new_ptr);
167 for (
auto& rx : _receivers)
168 if (rx->getAntenna() == old_ptr)
169 rx->setAntenna(new_ptr);
175 const SimId id = waveform->getId();
178 std::unique_ptr<RadarSignal> old_owned;
181 if (
auto it = _waveforms.find(
id); it != _waveforms.end())
183 old_owned = std::move(it->second);
184 old_ptr = old_owned.get();
185 it->second = std::move(waveform);
189 _waveforms[id] = std::move(waveform);
192 if ((old_ptr !=
nullptr) && old_ptr != new_ptr)
194 for (
auto& tx : _transmitters)
195 if (tx->getSignal() == old_ptr)
196 tx->setSignal(new_ptr);
205 std::unique_ptr<PrototypeTiming> old_owned;
208 if (
auto it = _timings.find(
id); it != _timings.end())
210 old_owned = std::move(it->second);
211 old_ptr = old_owned.get();
212 it->second = std::move(
timing);
216 _timings[id] = std::move(
timing);
219 auto refresh_timing = [id, new_ptr](
auto& radar_obj)
221 const auto current_timing = radar_obj->getTiming();
222 if (!current_timing || (current_timing->getId() !=
id))
228 std::make_shared<timing::Timing>(new_ptr->
getName(), current_timing->getSeed(), new_ptr->
getId());
229 refreshed->initializeModel(new_ptr);
230 radar_obj->setTiming(refreshed);
233 if ((old_ptr !=
nullptr) && old_ptr != new_ptr)
235 for (
auto& tx : _transmitters)
238 for (
auto& rx : _receivers)
246 _transmitters.clear();
253 _simulation_state = {};
261 for (
const auto& transmitter : _transmitters)
266 if (
auto start_time = transmitter->getNextPulseTime(sim_start); start_time)
268 if (*start_time <= sim_end)
276 const auto& schedule = transmitter->getSchedule();
277 if (schedule.empty())
285 for (
const auto& period : schedule)
288 const RealType start = std::max(sim_start, period.start);
289 const RealType end = std::min(sim_end, period.end);
301 for (
const auto& receiver : _receivers)
306 const RealType nominal_start = receiver->getWindowStart(0);
307 if (
auto start = receiver->getNextWindowTime(nominal_start); start && *start <
params::endTime())
314 const auto& schedule = receiver->getSchedule();
315 if (schedule.empty())
323 for (
const auto& period : schedule)
340 if (_event_queue.empty())
342 return "Event Queue is empty.\n";
345 std::stringstream ss;
346 ss << std::fixed << std::setprecision(6);
348 const std::string separator =
"--------------------------------------------------------------------";
349 const std::string title =
"| Event Queue Contents (" + std::to_string(_event_queue.size()) +
" events)";
350 if (separator.size() >
static_cast<std::size_t
>(std::numeric_limits<int>::max()))
352 throw std::runtime_error(
"Separator width exceeds stream formatting limits.");
354 const int title_width =
static_cast<int>(separator.size()) - 1;
356 ss << separator <<
"\n"
357 << std::left << std::setw(title_width) << title <<
"|\n"
359 <<
"| " << std::left << std::setw(12) <<
"Timestamp" <<
" | " << std::setw(21) <<
"Event Type" <<
" | "
360 << std::setw(25) <<
"Source Object" <<
" |\n"
361 << separator <<
"\n";
363 auto queue_copy = _event_queue;
365 while (!queue_copy.empty())
367 const auto [timestamp, event_type, source_object] = queue_copy.top();
370 ss <<
"| " << std::right << std::setw(12) << timestamp <<
" | " << std::left << std::setw(21)
371 <<
toString(event_type) <<
" | " << std::left << std::setw(25) << source_object->getName() <<
" |\n";
373 ss << separator <<
"\n";
Header file defining various types of antennas and their gain patterns.
Abstract base class representing an antenna.
void scheduleInitialEvents()
Populates the event queue with the initial events for the simulation.
void add(std::unique_ptr< radar::Platform > plat) noexcept
Adds a radar platform to the simulation world.
void replace(std::unique_ptr< radar::Target > target)
Replaces an existing target, updating internal pointers.
fers_signal::RadarSignal * findWaveform(const SimId id)
Finds a radar signal by ID.
radar::Target * findTarget(const SimId id)
Finds a target by ID.
radar::Receiver * findReceiver(const SimId id)
Finds a receiver by ID.
radar::Transmitter * findTransmitter(const SimId id)
Finds a transmitter by ID.
void clear() noexcept
Clears all objects and assets from the simulation world.
timing::PrototypeTiming * findTiming(const SimId id)
Finds a timing source by ID.
antenna::Antenna * findAntenna(const SimId id)
Finds an antenna by ID.
std::string dumpEventQueue() const
Dumps the current state of the event queue to a string for debugging.
radar::Platform * findPlatform(const SimId id)
Finds a platform by ID.
Class representing a radar signal with associated properties.
Manages radar signal reception and response processing.
Base class for radar targets.
SimId getId() const noexcept
Gets the unique ID of the target.
Represents a radar transmitter system.
Manages timing properties such as frequency, offsets, and synchronization.
std::string getName() const
Gets the name of the timing source.
SimId getId() const noexcept
Gets the unique ID of the timing source.
double RealType
Type for real numbers.
std::string toString(const EventType type)
Converts an EventType enum to its string representation.
@ RX_PULSED_WINDOW_START
A pulsed receiver opens its listening window.
@ TX_CW_START
A continuous-wave transmitter starts transmitting.
@ TX_CW_END
A continuous-wave transmitter stops transmitting.
@ TX_PULSED_START
A pulsed transmitter begins emitting a pulse.
@ RX_CW_END
A continuous-wave receiver stops listening.
@ RX_CW_START
A continuous-wave receiver starts listening.
RealType endTime() noexcept
Get the end time for the simulation.
RealType startTime() noexcept
Get the start time for the simulation.
@ PULSED_MODE
The component operates in a pulsed mode.
Defines the Parameters struct and provides methods for managing simulation parameters.
Header file for the PrototypeTiming class.
Defines the Radar class and associated functionality.
Classes for handling radar waveforms and signals.
Defines the core structures for the event-driven simulation engine.
uint64_t SimId
64-bit Unique Simulation ID.
Timing source for simulation objects.
Header file for the World class in the simulator.