File Antenna.cpp¶
File List > astrea > trace > trace > platforms > sensors > Antenna.cpp
Go to the documentation of this file
/*
* The GNU Lesser General Public License (LGPL)
*
* Copyright (c) 2025 Jay Iuliano
*
* This file is part of Astrea.
* Astrea is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* Astrea is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should
* have received a copy of the GNU General Public License along with Astrea. If not, see <https://www.gnu.org/licenses/>.
*/
#include <trace/platforms/sensors/Antenna.hpp>
#include <stdexcept>
#include <mp-units/math.h>
#include <mp-units/systems/angular.h>
#include <mp-units/systems/isq_angle.h>
#include <mp-units/systems/si.h>
#include <astro/frames/CartesianVector.hpp>
#include <astro/frames/frames.hpp>
namespace astrea {
namespace trace {
using mp_units::one;
using mp_units::pow;
using mp_units::angular::sin;
using mp_units::isq_angle::cotes_angle;
CNR Antenna::carrier_to_noise_ratio(const Antenna& receiver, const Distance& range, const Angle& offsetAngle) const
{
throw std::runtime_error("CNR calculation not yet implemented.");
// return recieved_power(receiver, range, offsetAngle) / receiver.system_noise_temperature() / boltzmann_constant * _noiseBandwidth;
}
CNR Antenna::carrier_to_noise_density(const Antenna& receiver, const Distance& range, const Angle& offsetAngle) const
{
throw std::runtime_error("CND calculation not yet implemented.");
// return recieved_power(receiver, range, offsetAngle) / receiver.system_noise_temperature() / boltzmann_constant;
}
Power Antenna::recieved_power(const Antenna& receiver, const Distance& range, const Angle& offsetAngle) const
{
return _parameters.get_eirp() * receiver.gain() * free_space_loss(range) * system_loss(receiver, offsetAngle);
}
Gain Antenna::free_space_loss(const Distance& range) const
{
static const auto fixedLoss = pow<2>(1.0 / (4.0 * std::numbers::pi) * one);
return fixedLoss * pow<2>(_parameters.get_wavelength() / range);
}
Gain Antenna::system_loss(const Antenna& receiver, const Angle& offsetAngle) const
{
return _parameters.get_transmit_loss() * mispointing_loss(receiver, offsetAngle) * atmospheric_loss() * receiver.receiver_loss();
}
Gain Antenna::mispointing_loss(const Antenna& receiver, const Angle& offsetAngle) const
{
// Including polarization losses here
Gain mispointingLoss;
switch (_parameters.get_pattern()) {
case (PatternApproximation::BESSEL): {
mispointingLoss = bessel_loss_approximation(offsetAngle);
break;
}
case (PatternApproximation::SINC_SQUARED): {
mispointingLoss = sinc_loss_approximation(offsetAngle);
break;
}
default: throw std::runtime_error("Unrecognized pattern approximation for mispointing losses.");
}
return mispointingLoss * polarization_loss(receiver);
}
Gain Antenna::polarization_loss(const Antenna& receiver) const
{
return 1.0; // Ideal, but generally considered true as they are typically small or zero (exactly zero for circular polarization)
}
Gain Antenna::atmospheric_loss() const
{
return 1.0; // Ideal, definitely not true
}
Gain Antenna::gain() const { return _parameters.get_gain(); }
Temperature Antenna::system_noise_temperature() const { return _parameters.get_system_noise_temperature(); }
Gain Antenna::receiver_loss() const { return _parameters.get_receiver_loss(); }
Gain Antenna::transmit_loss() const { return _parameters.get_transmit_loss(); }
void Antenna::set_pattern_approximation(const PatternApproximation& pattern) { _parameters.set_pattern(pattern); }
Gain Antenna::bessel_loss_approximation(const Angle& offsetAngle) const
{
const auto u = mispointing_loss_approximation_argument(offsetAngle);
return 64.0 * pow<2>(math::cyl_bessel_j(2.0, u) / pow<2>(u));
}
Gain Antenna::sinc_loss_approximation(const Angle& offsetAngle) const
{
const auto u = mispointing_loss_approximation_argument(offsetAngle);
const auto sincU = math::sinc(0.690 * u * cotes_angle);
return sincU * sincU;
}
Gain Antenna::mispointing_loss_approximation_argument(const Angle& offsetAngle) const
{
static const auto ratio = std::numbers::pi * _parameters.get_diameter() / _parameters.get_wavelength();
return ratio * sin(offsetAngle);
}
} // namespace trace
} // namespace astrea