17#include "ns3/angles.h" 
   18#include "ns3/antenna-model.h" 
   19#include "ns3/double.h" 
   21#include "ns3/mobility-model.h" 
   22#include "ns3/net-device.h" 
   24#include "ns3/object.h" 
   25#include "ns3/packet-burst.h" 
   26#include "ns3/packet.h" 
   27#include "ns3/propagation-delay-model.h" 
   28#include "ns3/propagation-loss-model.h" 
   29#include "ns3/simulator.h" 
   51    for (
auto it = rhs.begin(); it != rhs.end(); ++it)
 
   53        for (
auto jt = it->second.m_spectrumConverterMap.begin();
 
   54             jt != it->second.m_spectrumConverterMap.end();
 
   57            lhs << 
"(" << it->first << 
"," << jt->first << 
") ";
 
 
   91    static TypeId tid = 
TypeId(
"ns3::MultiModelSpectrumChannel")
 
   93                            .SetGroupName(
"Spectrum")
 
 
  113        auto phyIt = std::find(rxInfoIterator->second.m_rxPhys.begin(),
 
  114                               rxInfoIterator->second.m_rxPhys.end(),
 
  116        if (phyIt != rxInfoIterator->second.m_rxPhys.end())
 
  118            rxInfoIterator->second.m_rxPhys.erase(phyIt);
 
 
  133                  "phy->GetRxSpectrumModel () returned 0. Please check that the RxSpectrumModel is " 
  134                  "already set for the phy before calling MultiModelSpectrumChannel::AddRx (phy)");
 
  136    const auto rxSpectrumModelUid = rxSpectrumModel->GetUid();
 
  142    auto [rxInfoIterator, inserted] =
 
  147    rxInfoIterator->second.m_rxPhys.push_back(phy);
 
  156            auto txSpectrumModel = txInfoIterator->second.m_txSpectrumModel;
 
  157            const auto txSpectrumModelUid = txSpectrumModel->GetUid();
 
  159            if (rxSpectrumModelUid != txSpectrumModelUid &&
 
  160                !txSpectrumModel->IsOrthogonal(*rxSpectrumModel))
 
  162                NS_LOG_LOGIC(
"Creating converter between SpectrumModelUid " 
  163                             << txSpectrumModel->GetUid() << 
" and " << rxSpectrumModelUid);
 
  165                auto ret2 = txInfoIterator->second.m_spectrumConverterMap.insert(
 
  166                    std::make_pair(rxSpectrumModelUid, converter));
 
 
  173TxSpectrumModelInfoMap_t::const_iterator
 
  178    const auto txSpectrumModelUid = txSpectrumModel->GetUid();
 
  188        txInfoIterator = ret.first;
 
  195            auto rxSpectrumModel = rxInfoIterator->second.m_rxSpectrumModel;
 
  196            const auto rxSpectrumModelUid = rxSpectrumModel->GetUid();
 
  198            if (rxSpectrumModelUid != txSpectrumModelUid &&
 
  199                !txSpectrumModel->IsOrthogonal(*rxSpectrumModel))
 
  201                NS_LOG_LOGIC(
"Creating converter between SpectrumModelUid " 
  202                             << txSpectrumModelUid << 
" and " << rxSpectrumModelUid);
 
  205                auto ret2 = txInfoIterator->second.m_spectrumConverterMap.insert(
 
  206                    std::make_pair(rxSpectrumModelUid, converter));
 
  213        NS_LOG_LOGIC(
"SpectrumModelUid " << txSpectrumModelUid << 
" already present");
 
  215    return txInfoIterator;
 
 
  225    auto txParamsTrace = txParams->Copy(); 
 
  230    auto refTxMobility = txParams->txPhy->GetMobility();
 
  231    auto txMobility = refTxMobility;
 
  232    const auto txSpectrumModelUid = txParams->psd->GetSpectrumModelUid();
 
  233    NS_LOG_LOGIC(
"txSpectrumModelUid " << txSpectrumModelUid);
 
  235    const auto txInfoIterator =
 
  239    NS_LOG_LOGIC(
"converter map for TX SpectrumModel with Uid " << txInfoIterator->first);
 
  240    NS_LOG_LOGIC(
"converter map size: " << txInfoIterator->second.m_spectrumConverterMap.size());
 
  242                 << txInfoIterator->second.m_spectrumConverterMap.begin()->first);
 
  244    std::map<SpectrumModelUid_t, Ptr<SpectrumValue>> convertedPsds{};
 
  249        const auto rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid();
 
  250        NS_LOG_LOGIC(
"rxSpectrumModelUids " << rxSpectrumModelUid);
 
  253        if (txSpectrumModelUid == rxSpectrumModelUid)
 
  256            convertedTxPowerSpectrum = txParams->psd;
 
  260            NS_LOG_LOGIC(
"converting txPowerSpectrum SpectrumModelUids " 
  261                         << txSpectrumModelUid << 
" --> " << rxSpectrumModelUid);
 
  262            auto rxConverterIterator =
 
  263                txInfoIterator->second.m_spectrumConverterMap.find(rxSpectrumModelUid);
 
  264            if (rxConverterIterator == txInfoIterator->second.m_spectrumConverterMap.end())
 
  269            convertedTxPowerSpectrum = rxConverterIterator->second.Convert(txParams->psd);
 
  271        convertedPsds.emplace(rxSpectrumModelUid, convertedTxPowerSpectrum);
 
  278        const auto rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid();
 
  280        if ((txSpectrumModelUid != rxSpectrumModelUid) &&
 
  281            !txInfoIterator->second.m_spectrumConverterMap.contains(rxSpectrumModelUid))
 
  287        for (
auto rxPhyIterator = rxInfoIterator->second.m_rxPhys.begin();
 
  288             rxPhyIterator != rxInfoIterator->second.m_rxPhys.end();
 
  291            NS_ASSERT_MSG((*rxPhyIterator)->GetRxSpectrumModel()->GetUid() == rxSpectrumModelUid,
 
  292                          "SpectrumModel change was not notified to MultiModelSpectrumChannel " 
  293                          "(i.e., AddRx should be called again after model is changed)");
 
  295            auto txAntennaGain{0.0};
 
  296            if ((*rxPhyIterator) != txParams->txPhy)
 
  298                auto rxNetDevice = (*rxPhyIterator)->GetDevice();
 
  299                auto txNetDevice = txParams->txPhy->GetDevice();
 
  301                if (rxNetDevice && txNetDevice)
 
  304                    if (rxNetDevice->GetNode()->GetId() == txNetDevice->GetNode()->GetId())
 
  307                            "Skipping the pathloss calculation among different antennas of the " 
  308                            "same node, not supported yet by any pathloss model in ns-3.");
 
  319                auto rxParams = txParams->Copy();
 
  323                auto receiverMobility = (*rxPhyIterator)->GetMobility();
 
  325                if (txMobility && receiverMobility)
 
  331                            wraparound->GetVirtualMobilityModel(refTxMobility, receiverMobility);
 
  333                    rxParams->txMobility = txMobility;
 
  335                    if (rxParams->txAntenna)
 
  337                        Angles txAngles(receiverMobility->GetPosition(), txMobility->GetPosition());
 
  338                        txAntennaGain = rxParams->txAntenna->GetGainDb(txAngles);
 
  339                        NS_LOG_LOGIC(
"txAntennaGain = " << txAntennaGain << 
" dB");
 
  350                    auto dstNode = rxNetDevice->GetNode()->GetId();
 
 
  382    double txAntennaGain,
 
  389    const auto rxSpectrumModelUid = params->psd->GetSpectrumModelUid();
 
  390    const auto phySpectrumModelUid = receiver->GetRxSpectrumModel()->GetUid();
 
  391    NS_LOG_LOGIC(
"rxSpectrumModelUid " << rxSpectrumModelUid << 
" phySpectrumModelUid " 
  392                                       << phySpectrumModelUid);
 
  394    if (rxSpectrumModelUid != phySpectrumModelUid)
 
  396        NS_LOG_LOGIC(
"SpectrumModelUid changed since TX started");
 
  398        const auto itConvertedPsd = availableConvertedPsds.find(phySpectrumModelUid);
 
  399        if (itConvertedPsd != availableConvertedPsds.cend())
 
  401            NS_LOG_LOGIC(
"converted PSD already exists for " << phySpectrumModelUid);
 
  402            params->psd = itConvertedPsd->second;
 
  406            const auto txInfoIterator =
 
  410            const auto txSpectrumModelUid = txPsd->GetSpectrumModelUid();
 
  411            NS_LOG_LOGIC(
"converting txPowerSpectrum SpectrumModelUids " 
  412                         << txSpectrumModelUid << 
" --> " << phySpectrumModelUid);
 
  413            const auto rxConverterIterator =
 
  414                txInfoIterator->second.m_spectrumConverterMap.find(phySpectrumModelUid);
 
  415            if (rxConverterIterator == txInfoIterator->second.m_spectrumConverterMap.cend())
 
  422                params->psd = rxConverterIterator->second.Convert(txPsd);
 
  427    auto txMobility = params->txMobility;
 
  428    auto rxMobility = receiver->GetMobility();
 
  429    if (txMobility && rxMobility)
 
  431        auto pathLossDb{-txAntennaGain};
 
  432        auto rxAntennaGain{0.0};
 
  433        auto propagationGainDb{0.0};
 
  437            Angles rxAngles(txMobility->GetPosition(), rxMobility->GetPosition());
 
  438            rxAntennaGain = rxAntenna->GetGainDb(rxAngles);
 
  439            NS_LOG_LOGIC(
"rxAntennaGain = " << rxAntennaGain << 
" dB");
 
  440            pathLossDb -= rxAntennaGain;
 
  443        if (
m_propagationLoss && (txMobility->GetPosition() != rxMobility->GetPosition()))
 
  446            NS_LOG_LOGIC(
"propagationGainDb = " << propagationGainDb << 
" dB");
 
  447            pathLossDb -= propagationGainDb;
 
  450        NS_LOG_LOGIC(
"total pathLoss = " << pathLossDb << 
" dB");
 
  469        const auto pathLossLinear = std::pow(10.0, (-pathLossDb) / 10.0);
 
  470        *(params->psd) *= pathLossLinear;
 
  484                          "PhasedArrayModel instances should be installed at both TX and RX " 
  485                          "SpectrumPhy in order to use PhasedArraySpectrumPropagationLoss.");
 
  496    receiver->StartRx(params);
 
 
  522        for (
const auto& phyIt : rxInfoIterator->second.m_rxPhys)
 
  526                return (*phyIt).GetDevice();
 
 
Class holding the azimuth and inclination angles of spherical coordinates.
This SpectrumChannel implementation can handle the presence of SpectrumPhy instances which can use di...
void RemoveRx(Ptr< SpectrumPhy > phy) override
Remove a SpectrumPhy from a channel.
virtual void StartRx(Ptr< SpectrumValue > txPsd, double txAntennaGain, Ptr< SpectrumSignalParameters > params, Ptr< SpectrumPhy > receiver, const std::map< SpectrumModelUid_t, Ptr< SpectrumValue > > &availableConvertedPsds)
Used internally to reschedule transmission after the propagation delay.
Ptr< NetDevice > GetDevice(std::size_t i) const override
std::size_t GetNDevices() const override
void AddRx(Ptr< SpectrumPhy > phy) override
Add a SpectrumPhy to a channel, so it can receive packets.
TxSpectrumModelInfoMap_t m_txSpectrumModelInfoMap
Data structure holding, for each TX SpectrumModel, all the converters to any RX SpectrumModel,...
std::size_t m_numDevices
Number of devices connected to the channel.
void DoDispose() override
Destructor implementation.
void StartTx(Ptr< SpectrumSignalParameters > params) override
Used by attached PHY instances to transmit signals on the channel.
TxSpectrumModelInfoMap_t::const_iterator FindAndEventuallyAddTxSpectrumModel(Ptr< const SpectrumModel > txSpectrumModel)
This method checks if m_rxSpectrumModelInfoMap contains an entry for the given TX SpectrumModel.
static TypeId GetTypeId()
Get the type ID.
MultiModelSpectrumChannel()
RxSpectrumModelInfoMap_t m_rxSpectrumModelInfoMap
Data structure holding, for each RX spectrum model, all the corresponding SpectrumPhy instances.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Smart pointer class similar to boost::intrusive_ptr.
The Rx spectrum model information.
RxSpectrumModelInfo(Ptr< const SpectrumModel > rxSpectrumModel)
Constructor.
Ptr< const SpectrumModel > m_rxSpectrumModel
Rx Spectrum model.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
TracedCallback< Ptr< SpectrumSignalParameters > > m_txSigParamsTrace
Traced callback for SpectrumSignalParameters in StartTx requests.
void DoDispose() override
Destructor implementation.
Ptr< SpectrumTransmitFilter > m_filter
Transmit filter to be used with this channel.
SpectrumChannel()
constructor
Ptr< PropagationDelayModel > m_propagationDelay
Propagation delay model to be used with this channel.
Ptr< SpectrumPropagationLossModel > m_spectrumPropagationLoss
Frequency-dependent propagation loss model to be used with this channel.
Ptr< PhasedArraySpectrumPropagationLossModel > m_phasedArraySpectrumPropagationLoss
Frequency-dependent propagation loss model to be used with this channel.
TracedCallback< Ptr< const SpectrumPhy >, Ptr< const SpectrumPhy >, double > m_pathLossTrace
The PathLoss trace source.
TracedCallback< Ptr< const MobilityModel >, Ptr< const MobilityModel >, double, double, double, double > m_gainTrace
The Gain trace source.
Ptr< PropagationLossModel > m_propagationLoss
Single-frequency propagation loss model to be used with this channel.
double m_maxLossDb
Maximum loss [dB].
Class which implements a converter between SpectrumValue which are defined over different SpectrumMod...
Simulation virtual time values and global simulation resolution.
The Tx spectrum model information.
Ptr< const SpectrumModel > m_txSpectrumModel
Tx Spectrum model.
TxSpectrumModelInfo(Ptr< const SpectrumModel > txSpectrumModel)
Constructor.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
std::map< SpectrumModelUid_t, TxSpectrumModelInfo > TxSpectrumModelInfoMap_t
Container: SpectrumModelUid_t, TxSpectrumModelInfo.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
uint32_t SpectrumModelUid_t
Uid for SpectrumModels.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.