FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
timing.cpp
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 timing.cpp
10 * @brief Implementation of timing sources.
11 */
12
13#include "timing.h"
14
15#include <stdexcept>
16
17#include "core/logging.h"
18#include "prototype_timing.h"
19
20using logging::Level;
21
22namespace timing
23{
24 Timing::Timing(std::string name, const unsigned seed, const SimId id) noexcept :
25 _name(std::move(name)), _id(id == 0 ? SimIdGenerator::instance().generateId(ObjectType::Timing) : id),
26 _rng(seed), _seed(seed)
27 {
28 }
29
30 // NOLINTNEXTLINE(readability-make-member-function-const)
31 void Timing::skipSamples(const std::size_t samples) noexcept
32 {
33 if (_enabled && _model)
34 {
35 _model->skipSamples(samples);
36 }
37 }
38
40 {
41 if (_model)
42 {
43 LOG(Level::WARNING, "Timing source '{}' already initialized. Skipping re-initialization.", _name);
44 return;
45 }
46
47 _prototype = timing;
48 _frequency = timing->getFrequency();
49
50 std::normal_distribution normal_dist{0.0, 1.0};
51
52 _freq_offset = timing->getFreqOffset().value_or(0);
53 if (const std::optional<RealType> random_freq_stdev = timing->getRandomFreqOffsetStdev(); random_freq_stdev)
54 {
55 LOG(Level::INFO, "Timing source '{}': applying random frequency offset with stdev {} Hz.", _name,
56 random_freq_stdev.value());
57 _freq_offset += normal_dist(_rng) * random_freq_stdev.value();
58 }
59
60 _phase_offset = timing->getPhaseOffset().value_or(0);
61 if (const std::optional<RealType> random_phase_stdev = timing->getRandomPhaseOffsetStdev(); random_phase_stdev)
62 {
63 LOG(Level::INFO, "Timing source '{}': applying random phase offset with stdev {} radians.", _name,
64 random_phase_stdev.value());
65 _phase_offset += normal_dist(_rng) * random_phase_stdev.value();
66 }
67
68 timing->copyAlphas(_alphas, _weights);
69
70 _model = std::make_unique<noise::ClockModelGenerator>(_rng, _alphas, _weights, _frequency, _phase_offset,
71 _freq_offset, 15);
72
73 if (timing->getFrequency() == 0.0)
74 {
75 LOG(Level::INFO, "Timing source frequency not set, results could be incorrect.");
76 }
77
78 _sync_on_pulse = timing->getSyncOnPulse();
79 _enabled = true;
80 }
81
82 std::unique_ptr<Timing> Timing::clone() const
83 {
84 if (_prototype == nullptr)
85 {
86 LOG(Level::FATAL, "Cannot clone a Timing object that has not been initialized from a prototype.");
87 throw std::logic_error("Cannot clone a Timing object that has not been initialized from a prototype.");
88 }
89 auto new_timing = std::make_unique<Timing>(_name, _seed, _id);
90 new_timing->initializeModel(_prototype);
91 return new_timing;
92 }
93}
static SimIdGenerator & instance()
Get the singleton instance of SimIdGenerator.
Definition sim_id.h:48
Manages timing properties such as frequency, offsets, and synchronization.
void initializeModel(const PrototypeTiming *timing) noexcept
Initializes the timing model.
Definition timing.cpp:39
void skipSamples(std::size_t samples) noexcept
Skips a number of samples in the timing model.
Definition timing.cpp:31
Timing(std::string name, unsigned seed, const SimId id=0) noexcept
Constructs a Timing object.
Definition timing.cpp:24
std::unique_ptr< Timing > clone() const
Creates a new Timing instance based on the same prototype.
Definition timing.cpp:82
Header file for the logging system.
#define LOG(level,...)
Definition logging.h:19
Header file for the PrototypeTiming class.
uint64_t SimId
64-bit Unique Simulation ID.
Definition sim_id.h:18
Timing source for simulation objects.