FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
target.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2007-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 target.cpp
10 * @brief Defines classes for radar targets and their Radar Cross-Section (RCS) models.
11 */
12
13#include "target.h"
14
15#include <cmath>
16#include <optional>
17#include <stdexcept>
18
19#include "core/logging.h"
20#include "math/geometry_ops.h"
22
23using math::SVec3;
24
25namespace
26{
27 /**
28 * @brief Load the target gain axis from an XML element.
29 *
30 * @param set The interpolation set to insert the samples into.
31 * @param axisXml The XML element containing the gain samples.
32 */
33 void loadTargetGainAxis(const interp::InterpSet* set, const XmlElement& axisXml) noexcept
34 {
35 XmlElement tmp = axisXml.childElement("rcssample");
36 while (tmp.isValid())
37 {
38 XmlElement angle_element = tmp.childElement("angle", 0);
39
40 if (XmlElement gain_element = tmp.childElement("rcs", 0); angle_element.isValid() && gain_element.isValid())
41 {
42 const RealType angle = std::stof(angle_element.getText());
43 const RealType gain = std::stof(gain_element.getText());
44 set->insertSample(angle, gain);
45 }
46
47 tmp = XmlElement(tmp.getNode()->next);
48 }
49 }
50}
51
52namespace radar
53{
54 RealType IsoTarget::getRcs(SVec3& /*inAngle*/, SVec3& /*outAngle*/, RealType /*time*/) const noexcept
55 {
56 return _model ? _rcs * _model->sampleModel() : _rcs;
57 }
58
59 FileTarget::FileTarget(Platform* platform, std::string name, const std::string& filename, const unsigned seed) :
60 Target(platform, std::move(name), seed), _azi_samples(std::make_unique_for_overwrite<interp::InterpSet>()),
61 _elev_samples(std::make_unique_for_overwrite<interp::InterpSet>()), _filename(filename)
62 {
63 XmlDocument doc;
64 if (!doc.loadFile(filename))
65 {
66 throw std::runtime_error("Could not load target description from " + filename);
67 }
68
69 const XmlElement root(doc.getRootElement());
70
71 loadTargetGainAxis(_elev_samples.get(), root.childElement("elevation", 0));
72 loadTargetGainAxis(_azi_samples.get(), root.childElement("azimuth", 0));
73 }
74
75 RealType FileTarget::getRcs(SVec3& inAngle, SVec3& outAngle, const RealType time) const
76 {
77 // TODO: the handling of arbitrary rcs models needs to be validated and expanded to cover edge cases.
78 // 1. Calculate the bistatic angle bisector in the GLOBAL frame.
79 const SVec3 global_bisector_angle = inAngle + outAngle;
80
81 // 2. Get the target's own rotation at the current time.
82 const SVec3 target_rotation = getRotation(time);
83
84 // 3. Transform the global angle into the target's LOCAL frame for lookup.
85 const SVec3 local_aspect_angle = global_bisector_angle - target_rotation;
86
87 // 4. Use the local aspect angle (bisector is halved) to look up RCS.
88 const auto azi_value = _azi_samples->getValueAt(local_aspect_angle.azimuth / 2.0);
89
90 if (const auto elev_value = _elev_samples->getValueAt(local_aspect_angle.elevation / 2.0);
91 azi_value && elev_value)
92 {
93 // Return the raw RCS value (proportional to power), not its square root.
94 const RealType rcs = *azi_value * *elev_value;
95 return _model ? rcs * _model->sampleModel() : rcs;
96 }
97
98 LOG(logging::Level::FATAL, "Could not get RCS value for target");
99 throw std::runtime_error("Could not get RCS value for target");
100 }
101}
Class for managing XML documents.
XmlElement getRootElement() const
Get the root element of the document.
bool loadFile(std::string_view filename)
Load an XML file into the document.
Class representing a node in an XML document.
XmlElement childElement(const std::string_view name="", const unsigned index=0) const noexcept
Retrieve a child element by name and index.
bool isValid() const noexcept
Check if the XML element is valid.
xmlNodePtr getNode() const noexcept
Get the underlying XML node pointer.
std::string getText() const
Get the text content of the XML element.
Wrapper class for managing interpolation sets using smart pointers.
A class representing a vector in spherical coordinates.
RealType elevation
The elevation angle of the vector.
RealType azimuth
The azimuth angle of the vector.
RealType getRcs(math::SVec3 &inAngle, math::SVec3 &outAngle, RealType time) const override
Gets the RCS value from file-based data for a specific bistatic geometry and time.
Definition target.cpp:75
FileTarget(Platform *platform, std::string name, const std::string &filename, unsigned seed)
Constructs a file-based radar target.
Definition target.cpp:59
RealType getRcs(math::SVec3 &, math::SVec3 &, RealType) const noexcept override
Gets the constant RCS value.
Definition target.cpp:54
math::SVec3 getRotation(const RealType time) const
Retrieves the rotation of the object.
Definition object.h:54
Represents a simulation platform with motion and rotation paths.
Definition platform.h:31
Base class for radar targets.
Definition target.h:117
std::unique_ptr< RcsModel > _model
The RCS fluctuation model for the target.
Definition target.h:162
double RealType
Type for real numbers.
Definition config.h:27
Classes and operations for 3D geometry.
Wrapper for managing XML documents and elements using libxml2.
Header file for the logging system.
#define LOG(level,...)
Definition logging.h:19
@ FATAL
Fatal level for severe error events.
Defines classes for radar targets and their Radar Cross-Section (RCS) models.