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) noexcept : _name(std::move(name)), _rng(seed), _seed(seed) {}
25
26 // NOLINTNEXTLINE(readability-make-member-function-const)
27 void Timing::skipSamples(const long long samples) noexcept
28 {
29 if (_enabled && _model)
30 {
31 _model->skipSamples(samples);
32 }
33 }
34
36 {
37 if (_model)
38 {
39 LOG(Level::WARNING, "Timing source '{}' already initialized. Skipping re-initialization.", _name);
40 return;
41 }
42
43 _prototype = timing;
44 _frequency = timing->getFrequency();
45
46 std::normal_distribution normal_dist{0.0, 1.0};
47
48 _freq_offset = timing->getFreqOffset().value_or(0);
49 if (const std::optional<RealType> random_freq_stdev = timing->getRandomFreqOffsetStdev(); random_freq_stdev)
50 {
51 LOG(Level::INFO, "Timing source '{}': applying random frequency offset with stdev {} Hz.", _name,
52 random_freq_stdev.value());
53 _freq_offset += normal_dist(_rng) * random_freq_stdev.value();
54 }
55
56 _phase_offset = timing->getPhaseOffset().value_or(0);
57 if (const std::optional<RealType> random_phase_stdev = timing->getRandomPhaseOffsetStdev(); random_phase_stdev)
58 {
59 LOG(Level::INFO, "Timing source '{}': applying random phase offset with stdev {} radians.", _name,
60 random_phase_stdev.value());
61 _phase_offset += normal_dist(_rng) * random_phase_stdev.value();
62 }
63
64 timing->copyAlphas(_alphas, _weights);
65
66 _model = std::make_unique<noise::ClockModelGenerator>(_rng, _alphas, _weights, _frequency, _phase_offset,
67 _freq_offset, 15);
68
69 if (timing->getFrequency() == 0.0f)
70 {
71 LOG(Level::INFO, "Timing source frequency not set, results could be incorrect.");
72 }
73
74 _sync_on_pulse = timing->getSyncOnPulse();
75 _enabled = true;
76 }
77
78 std::unique_ptr<Timing> Timing::clone() const
79 {
80 if (!_prototype)
81 {
82 LOG(Level::FATAL, "Cannot clone a Timing object that has not been initialized from a prototype.");
83 throw std::logic_error("Cannot clone a Timing object that has not been initialized from a prototype.");
84 }
85 auto new_timing = std::make_unique<Timing>(_name, _seed);
86 new_timing->initializeModel(_prototype);
87 return new_timing;
88 }
89}
Manages timing properties such as frequency, offsets, and synchronization.
void initializeModel(const PrototypeTiming *timing) noexcept
Initializes the timing model.
Definition timing.cpp:35
void skipSamples(long long samples) noexcept
Skips a number of samples in the timing model.
Definition timing.cpp:27
Timing(std::string name, unsigned seed) 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:78
Header file for the logging system.
#define LOG(level,...)
Definition logging.h:19
Header file for the PrototypeTiming class.
Timing source for simulation objects.