22#include <ns3/angles.h>
23#include <ns3/antenna-model.h>
24#include <ns3/double.h>
26#include <ns3/mobility-model.h>
27#include <ns3/net-device.h>
29#include <ns3/object.h>
30#include <ns3/packet-burst.h>
31#include <ns3/packet.h>
32#include <ns3/propagation-delay-model.h>
33#include <ns3/propagation-loss-model.h>
34#include <ns3/simulator.h>
35#include <ns3/spectrum-converter.h>
36#include <ns3/spectrum-phy.h>
37#include <ns3/spectrum-propagation-loss-model.h>
38#include <ns3/spectrum-transmit-filter.h>
60 for (TxSpectrumModelInfoMap_t::iterator it = rhs.begin(); it != rhs.end(); ++it)
62 SpectrumConverterMap_t::iterator jt;
63 for (jt = it->second.m_spectrumConverterMap.begin();
64 jt != it->second.m_spectrumConverterMap.end();
67 lhs <<
"(" << it->first <<
"," << jt->first <<
") ";
74 : m_txSpectrumModel(txSpectrumModel)
79 : m_rxSpectrumModel(rxSpectrumModel)
101 static TypeId tid =
TypeId(
"ns3::MultiModelSpectrumChannel")
103 .SetGroupName(
"Spectrum")
123 auto phyIt = std::find(rxInfoIterator->second.m_rxPhys.begin(),
124 rxInfoIterator->second.m_rxPhys.end(),
126 if (phyIt != rxInfoIterator->second.m_rxPhys.end())
128 rxInfoIterator->second.m_rxPhys.erase(phyIt);
143 "phy->GetRxSpectrumModel () returned 0. Please check that the RxSpectrumModel is "
144 "already set for the phy before calling MultiModelSpectrumChannel::AddRx (phy)");
152 auto [rxInfoIterator, inserted] =
157 rxInfoIterator->second.m_rxPhys.push_back(phy);
169 if (rxSpectrumModelUid != txSpectrumModelUid &&
170 !txSpectrumModel->IsOrthogonal(*rxSpectrumModel))
172 NS_LOG_LOGIC(
"Creating converter between SpectrumModelUid "
173 << txSpectrumModel->GetUid() <<
" and " << rxSpectrumModelUid);
175 std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
176 ret2 = txInfoIterator->second.m_spectrumConverterMap.insert(
177 std::make_pair(rxSpectrumModelUid, converter));
184TxSpectrumModelInfoMap_t::const_iterator
190 TxSpectrumModelInfoMap_t::iterator txInfoIterator =
197 std::pair<TxSpectrumModelInfoMap_t::iterator, bool> ret;
201 txInfoIterator = ret.first;
204 for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator =
212 if (rxSpectrumModelUid != txSpectrumModelUid &&
213 !txSpectrumModel->IsOrthogonal(*rxSpectrumModel))
215 NS_LOG_LOGIC(
"Creating converter between SpectrumModelUid "
216 << txSpectrumModelUid <<
" and " << rxSpectrumModelUid);
219 std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
220 ret2 = txInfoIterator->second.m_spectrumConverterMap.insert(
221 std::make_pair(rxSpectrumModelUid, converter));
228 NS_LOG_LOGIC(
"SpectrumModelUid " << txSpectrumModelUid <<
" already present");
230 return txInfoIterator;
247 NS_LOG_LOGIC(
"txSpectrumModelUid " << txSpectrumModelUid);
250 TxSpectrumModelInfoMap_t::const_iterator txInfoIteratorerator =
254 NS_LOG_LOGIC(
"converter map for TX SpectrumModel with Uid " << txInfoIteratorerator->first);
256 "converter map size: " << txInfoIteratorerator->second.m_spectrumConverterMap.size());
258 << txInfoIteratorerator->second.m_spectrumConverterMap.begin()->first);
264 SpectrumModelUid_t rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid();
265 NS_LOG_LOGIC(
"rxSpectrumModelUids " << rxSpectrumModelUid);
268 if (txSpectrumModelUid == rxSpectrumModelUid)
271 convertedTxPowerSpectrum = txParams->psd;
275 NS_LOG_LOGIC(
"converting txPowerSpectrum SpectrumModelUids "
276 << txSpectrumModelUid <<
" --> " << rxSpectrumModelUid);
277 SpectrumConverterMap_t::const_iterator rxConverterIterator =
278 txInfoIteratorerator->second.m_spectrumConverterMap.find(rxSpectrumModelUid);
279 if (rxConverterIterator == txInfoIteratorerator->second.m_spectrumConverterMap.end())
284 convertedTxPowerSpectrum = rxConverterIterator->second.Convert(txParams->psd);
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 if ((*rxPhyIterator) != txParams->txPhy)
300 if (rxNetDevice && txNetDevice)
303 if (rxNetDevice->GetNode()->GetId() == txNetDevice->GetNode()->GetId())
306 "Skipping the pathloss calculation among different antennas of the "
307 "same node, not supported yet by any pathloss model in ns-3.");
319 rxParams->psd = Copy<SpectrumValue>(convertedTxPowerSpectrum);
324 if (txMobility && receiverMobility)
326 double txAntennaGain = 0;
327 double rxAntennaGain = 0;
328 double propagationGainDb = 0;
329 double pathLossDb = 0;
330 if (rxParams->txAntenna)
332 Angles txAngles(receiverMobility->GetPosition(), txMobility->GetPosition());
333 txAntennaGain = rxParams->txAntenna->GetGainDb(txAngles);
334 NS_LOG_LOGIC(
"txAntennaGain = " << txAntennaGain <<
" dB");
335 pathLossDb -= txAntennaGain;
338 DynamicCast<AntennaModel>((*rxPhyIterator)->GetAntenna());
341 Angles rxAngles(txMobility->GetPosition(), receiverMobility->GetPosition());
342 rxAntennaGain = rxAntenna->GetGainDb(rxAngles);
343 NS_LOG_LOGIC(
"rxAntennaGain = " << rxAntennaGain <<
" dB");
344 pathLossDb -= rxAntennaGain;
350 NS_LOG_LOGIC(
"propagationGainDb = " << propagationGainDb <<
" dB");
351 pathLossDb -= propagationGainDb;
353 NS_LOG_LOGIC(
"total pathLoss = " << pathLossDb <<
" dB");
368 double pathGainLinear = std::pow(10.0, (-pathLossDb) / 10.0);
369 *(rxParams->psd) *= pathGainLinear;
380 uint32_t dstNode = rxNetDevice->GetNode()->GetId();
411 params->txPhy->GetMobility(),
412 receiver->GetMobility());
417 DynamicCast<PhasedArrayModel>(params->txPhy->GetAntenna());
419 DynamicCast<PhasedArrayModel>(receiver->GetAntenna());
422 "PhasedArrayModel instances should be installed at both TX and RX "
423 "SpectrumPhy in order to use PhasedArraySpectrumPropagationLoss.");
427 params->txPhy->GetMobility(),
428 receiver->GetMobility(),
432 receiver->StartRx(params);
458 for (
const auto& phyIt : rxInfoIterator->second.m_rxPhys)
462 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.
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.
virtual void StartRx(Ptr< SpectrumSignalParameters > params, Ptr< SpectrumPhy > receiver)
Used internally to reschedule transmission after the propagation delay.
MultiModelSpectrumChannel()
RxSpectrumModelInfoMap_t m_rxSpectrumModelInfoMap
Data structure holding, for each RX spectrum model, all the corresponding SpectrumPhy instances.
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
Smart pointer class similar to boost::intrusive_ptr.
The Rx spectrum model information.
RxSpectrumModelInfo(Ptr< const SpectrumModel > rxSpectrumModel)
Constructor.
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.
Defines the interface for spectrum-aware channel implementations.
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.
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.
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.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)