FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
receiver.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 receiver.cpp
10 * @brief Implementation of the Receiver class.
11 */
12
13#include "receiver.h"
14
15#include <algorithm>
16#include <utility>
17
18#include "core/parameters.h"
19#include "serial/response.h"
20
21namespace radar
22{
23 Receiver::Receiver(Platform* platform, std::string name, const unsigned seed, const OperationMode mode) noexcept :
24 Radar(platform, std::move(name)), _mode(mode), _rng(seed)
25 {
26 }
27
28 void Receiver::addResponseToInbox(std::unique_ptr<serial::Response> response) noexcept
29 {
30 std::lock_guard lock(_inbox_mutex);
31 _inbox.push_back(std::move(response));
32 }
33
34 void Receiver::addInterferenceToLog(std::unique_ptr<serial::Response> response) noexcept
35 {
36 std::lock_guard lock(_interference_log_mutex);
37 _pulsed_interference_log.push_back(std::move(response));
38 }
39
40 std::vector<std::unique_ptr<serial::Response>> Receiver::drainInbox() noexcept
41 {
42 std::lock_guard lock(_inbox_mutex);
43 std::vector<std::unique_ptr<serial::Response>> drained_responses;
44 drained_responses.swap(_inbox);
45 return drained_responses;
46 }
47
49 {
50 {
51 std::lock_guard lock(_finalizer_queue_mutex);
52 _finalizer_queue.push(std::move(job));
53 }
54 _finalizer_queue_cv.notify_one();
55 }
56
58 {
59 std::unique_lock lock(_finalizer_queue_mutex);
60 _finalizer_queue_cv.wait(lock, [this] { return !_finalizer_queue.empty(); });
61
62 job = std::move(_finalizer_queue.front());
63 _finalizer_queue.pop();
64
65 // Check for shutdown signal (negative duration)
66 if (job.duration < 0.0)
67 {
68 return false; // Shutdown signal
69 }
70 return true;
71 }
72
74 {
75 return _noise_temperature + Radar::getNoiseTemperature(angle);
76 }
77
79 {
80 if (temp < -EPSILON)
81 {
82 LOG(logging::Level::FATAL, "Noise temperature for receiver {} is negative", getName());
83 throw std::runtime_error("Noise temperature must be positive");
84 }
85 _noise_temperature = temp;
86 }
87
88 void Receiver::setWindowProperties(const RealType length, const RealType prf, const RealType skip) noexcept
89 {
90 const auto rate = params::rate() * params::oversampleRatio();
91 _window_length = length;
92 _window_prf = 1 / (std::floor(rate / prf) / rate);
93 _window_skip = std::floor(rate * skip) / rate;
94 }
95
96 unsigned Receiver::getWindowCount() const noexcept
97 {
99 const RealType pulses = time * _window_prf;
100 return static_cast<unsigned>(std::ceil(pulses));
101 }
102
103 RealType Receiver::getWindowStart(const unsigned window) const
104 {
105 const RealType stime = static_cast<RealType>(window) / _window_prf + _window_skip;
106 if (!_timing)
107 {
108 LOG(logging::Level::FATAL, "Receiver must be associated with timing source");
109 throw std::logic_error("Receiver must be associated with timing source");
110 }
111 return stime;
112 }
113
114 void Receiver::prepareCwData(const size_t numSamples)
115 {
116 std::lock_guard lock(_cw_mutex);
117 _cw_iq_data.resize(numSamples);
118 }
119
120 void Receiver::setCwSample(const size_t index, const ComplexType sample)
121 {
122 if (index < _cw_iq_data.size())
123 {
124 _cw_iq_data[index] += sample;
125 }
126 }
127
128 void Receiver::setSchedule(std::vector<SchedulePeriod> schedule) { _schedule = std::move(schedule); }
129
130 std::optional<RealType> Receiver::getNextWindowTime(RealType time) const
131 {
132 // If no schedule is defined, assume always on.
133 if (_schedule.empty())
134 {
135 return time;
136 }
137 for (const auto& period : _schedule)
138 {
139 // If time is within this period, it's valid.
140 if (time >= period.start && time <= period.end)
141 {
142 return time;
143 }
144 // If time is before this period, skip to the start of this period.
145 if (time < period.start)
146 {
147 return period.start;
148 }
149 // If time is after this period, continue to next period.
150 }
151 // Time is after the last scheduled period.
152 return std::nullopt;
153 }
154}
A class representing a vector in spherical coordinates.
const std::string & getName() const noexcept
Retrieves the name of the object.
Definition object.h:68
Represents a simulation platform with motion and rotation paths.
Definition platform.h:31
Represents a radar system on a platform.
Definition radar_obj.h:46
std::shared_ptr< timing::Timing > _timing
Timing source for the radar.
Definition radar_obj.h:129
virtual RealType getNoiseTemperature(const math::SVec3 &angle) const noexcept
Gets the noise temperature of the radar.
Definition radar_obj.cpp:31
void addInterferenceToLog(std::unique_ptr< serial::Response > response) noexcept
Adds a pulsed interference response to the receiver's CW-mode log.
Definition receiver.cpp:34
void setCwSample(size_t index, ComplexType sample)
Sets a single IQ sample at a specific index for CW simulation.
Definition receiver.cpp:120
Receiver(Platform *platform, std::string name, unsigned seed, OperationMode mode) noexcept
Constructs a Receiver object.
Definition receiver.cpp:23
std::vector< std::unique_ptr< serial::Response > > drainInbox() noexcept
Moves all responses from the inbox into a RenderingJob.
Definition receiver.cpp:40
unsigned getWindowCount() const noexcept
Gets the number of radar windows.
Definition receiver.cpp:96
RealType getWindowStart(unsigned window) const
Retrieves the start time of a specific radar window.
Definition receiver.cpp:103
std::optional< RealType > getNextWindowTime(RealType time) const
Determines the next valid window start time at or after the given time.
Definition receiver.cpp:130
void prepareCwData(size_t numSamples)
Prepares the internal storage for CW IQ data.
Definition receiver.cpp:114
void setSchedule(std::vector< SchedulePeriod > schedule)
Sets the active schedule for the receiver.
Definition receiver.cpp:128
void enqueueFinalizerJob(core::RenderingJob &&job)
Adds a completed RenderingJob to the finalizer queue.
Definition receiver.cpp:48
RealType getNoiseTemperature() const noexcept
Retrieves the noise temperature of the receiver.
Definition receiver.h:93
bool waitAndDequeueFinalizerJob(core::RenderingJob &job)
Waits for and dequeues a RenderingJob from the finalizer queue.
Definition receiver.cpp:57
void setWindowProperties(RealType length, RealType prf, RealType skip) noexcept
Sets the properties for radar windows.
Definition receiver.cpp:88
void addResponseToInbox(std::unique_ptr< serial::Response > response) noexcept
Adds a response to the receiver's pulsed-mode inbox.
Definition receiver.cpp:28
void setNoiseTemperature(RealType temp)
Sets the noise temperature of the receiver.
Definition receiver.cpp:78
double RealType
Type for real numbers.
Definition config.h:27
constexpr RealType EPSILON
Machine epsilon for real numbers.
Definition config.h:51
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
#define LOG(level,...)
Definition logging.h:19
@ FATAL
Fatal level for severe error events.
RealType endTime() noexcept
Get the end time for the simulation.
Definition parameters.h:97
RealType rate() noexcept
Get the rendering sample rate.
Definition parameters.h:109
RealType startTime() noexcept
Get the start time for the simulation.
Definition parameters.h:91
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
Definition parameters.h:139
OperationMode
Defines the operational mode of a radar component.
Definition radar_obj.h:36
Defines the Parameters struct and provides methods for managing simulation parameters.
Radar Receiver class for managing signal reception and response handling.
Classes for managing radar signal responses.
A data packet containing all information needed to process one receive window.
RealType duration
The duration of the receive window in seconds.