diff --git a/src/spectrum/CMakeLists.txt b/src/spectrum/CMakeLists.txt index b109e613d..cc2af34d9 100644 --- a/src/spectrum/CMakeLists.txt +++ b/src/spectrum/CMakeLists.txt @@ -13,9 +13,9 @@ set(source_files model/ism-spectrum-value-helper.cc model/matrix-based-channel-model.cc model/microwave-oven-spectrum-value-helper.cc - model/two-ray-spectrum-propagation-loss-model.cc model/multi-model-spectrum-channel.cc model/non-communicating-net-device.cc + model/phased-array-spectrum-propagation-loss-model.cc model/single-model-spectrum-channel.cc model/spectrum-analyzer.cc model/spectrum-channel.cc @@ -27,15 +27,16 @@ set(source_files model/spectrum-model.cc model/spectrum-phy.cc model/spectrum-propagation-loss-model.cc - model/spectrum-transmit-filter.cc - model/phased-array-spectrum-propagation-loss-model.cc model/spectrum-signal-parameters.cc + model/spectrum-transmit-filter.cc model/spectrum-value.cc model/three-gpp-channel-model.cc model/three-gpp-spectrum-propagation-loss-model.cc model/trace-fading-loss-model.cc model/tv-spectrum-transmitter.cc + model/two-ray-spectrum-propagation-loss-model.cc model/waveform-generator.cc + model/wraparound-model.cc ) set(header_files @@ -53,9 +54,9 @@ set(header_files model/ism-spectrum-value-helper.h model/matrix-based-channel-model.h model/microwave-oven-spectrum-value-helper.h - model/two-ray-spectrum-propagation-loss-model.h model/multi-model-spectrum-channel.h model/non-communicating-net-device.h + model/phased-array-spectrum-propagation-loss-model.h model/single-model-spectrum-channel.h model/spectrum-analyzer.h model/spectrum-channel.h @@ -67,15 +68,16 @@ set(header_files model/spectrum-model.h model/spectrum-phy.h model/spectrum-propagation-loss-model.h - model/spectrum-transmit-filter.h - model/phased-array-spectrum-propagation-loss-model.h model/spectrum-signal-parameters.h + model/spectrum-transmit-filter.h model/spectrum-value.h model/three-gpp-channel-model.h model/three-gpp-spectrum-propagation-loss-model.h model/trace-fading-loss-model.h model/tv-spectrum-transmitter.h + model/two-ray-spectrum-propagation-loss-model.h model/waveform-generator.h + model/wraparound-model.h utils/spectrum-test.h ) @@ -83,10 +85,11 @@ build_lib( LIBNAME spectrum SOURCE_FILES ${source_files} HEADER_FILES ${header_files} - LIBRARIES_TO_LINK ${libpropagation} - ${libantenna} + LIBRARIES_TO_LINK + ${libpropagation} + ${libantenna} + ${libbuildings} TEST_SOURCES - test/two-ray-splm-test-suite.cc test/spectrum-ideal-phy-test.cc test/spectrum-interference-test.cc test/spectrum-value-test.cc @@ -94,4 +97,5 @@ build_lib( test/three-gpp-channel-test-suite.cc test/tv-helper-distribution-test.cc test/tv-spectrum-transmitter-test.cc + test/two-ray-splm-test-suite.cc ) diff --git a/src/spectrum/model/multi-model-spectrum-channel.cc b/src/spectrum/model/multi-model-spectrum-channel.cc index 1406d8432..ffded7cbe 100644 --- a/src/spectrum/model/multi-model-spectrum-channel.cc +++ b/src/spectrum/model/multi-model-spectrum-channel.cc @@ -12,6 +12,7 @@ #include "spectrum-phy.h" #include "spectrum-propagation-loss-model.h" #include "spectrum-transmit-filter.h" +#include "wraparound-model.h" #include "ns3/angles.h" #include "ns3/antenna-model.h" @@ -225,7 +226,9 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) // potential underlying DynamicCasts) m_txSigParamsTrace(txParamsTrace); - auto txMobility = txParams->txPhy->GetMobility(); + auto wraparound = GetObject(); + auto refTxMobility = txParams->txPhy->GetMobility(); + auto txMobility = refTxMobility; const auto txSpectrumModelUid = txParams->psd->GetSpectrumModelUid(); NS_LOG_LOGIC("txSpectrumModelUid " << txSpectrumModelUid); @@ -321,6 +324,14 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) if (txMobility && receiverMobility) { + if (wraparound) + { + // Use virtual mobility model instead + txMobility = + wraparound->GetVirtualMobilityModel(refTxMobility, receiverMobility); + } + rxParams->txMobility = txMobility; + if (rxParams->txAntenna) { Angles txAngles(receiverMobility->GetPosition(), txMobility->GetPosition()); @@ -413,7 +424,7 @@ MultiModelSpectrumChannel::StartRx( } } - auto txMobility = params->txPhy->GetMobility(); + auto txMobility = params->txMobility; auto rxMobility = receiver->GetMobility(); if (txMobility && rxMobility) { diff --git a/src/spectrum/model/single-model-spectrum-channel.cc b/src/spectrum/model/single-model-spectrum-channel.cc index 7d4be70f0..4ae011632 100644 --- a/src/spectrum/model/single-model-spectrum-channel.cc +++ b/src/spectrum/model/single-model-spectrum-channel.cc @@ -11,6 +11,7 @@ #include "spectrum-phy.h" #include "spectrum-propagation-loss-model.h" #include "spectrum-transmit-filter.h" +#include "wraparound-model.h" #include "ns3/angles.h" #include "ns3/antenna-model.h" @@ -111,7 +112,9 @@ SingleModelSpectrumChannel::StartTx(Ptr txParams) NS_ASSERT(*(txParams->psd->GetSpectrumModel()) == *m_spectrumModel); } - Ptr senderMobility = txParams->txPhy->GetMobility(); + auto wraparound = GetObject(); + Ptr refSenderMobility = txParams->txPhy->GetMobility(); + Ptr senderMobility = refSenderMobility; for (auto rxPhyIterator = m_phyList.begin(); rxPhyIterator != m_phyList.end(); ++rxPhyIterator) { @@ -144,6 +147,14 @@ SingleModelSpectrumChannel::StartTx(Ptr txParams) if (senderMobility && receiverMobility) { + if (wraparound) + { + // Use virtual mobility model instead + senderMobility = + wraparound->GetVirtualMobilityModel(refSenderMobility, receiverMobility); + } + rxParams->txMobility = senderMobility; + double txAntennaGain = 0; double rxAntennaGain = 0; double propagationGainDb = 0; @@ -228,7 +239,7 @@ SingleModelSpectrumChannel::StartRx(Ptr params, Ptrpsd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity(params, - params->txPhy->GetMobility(), + params->txMobility, receiver->GetMobility()); } receiver->StartRx(params); diff --git a/src/spectrum/model/wraparound-model.cc b/src/spectrum/model/wraparound-model.cc new file mode 100644 index 000000000..223de2968 --- /dev/null +++ b/src/spectrum/model/wraparound-model.cc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 CTTC + * + * SPDX-License-Identifier: GPL-2.0-only + * + * Author: Gabriel Ferreira + */ + +#include "wraparound-model.h" + +#include "ns3/log.h" +#include "ns3/mobility-building-info.h" +#include "ns3/node.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE("WraparoundModel"); +NS_OBJECT_ENSURE_REGISTERED(WraparoundModel); + +TypeId +WraparoundModel::GetTypeId() +{ + static TypeId tid = TypeId("ns3::WraparoundModel") + .SetParent() + .SetGroupName("Spectrum") + .AddConstructor(); + return tid; +} + +Ptr +WraparoundModel::GetVirtualMobilityModel(Ptr tx, + Ptr rx) const +{ + NS_LOG_DEBUG("Transmitter using virtual mobility model. Real position " + << tx->GetPosition() << ", receiver position " << rx->GetPosition() + << ", wrapped position " + << GetVirtualPosition(tx->GetPosition(), rx->GetPosition()) << "."); + auto virtualMm = tx->Copy(); + // Set the transmitter to its virtual position respective to receiver + virtualMm->SetPosition(GetVirtualPosition(tx->GetPosition(), rx->GetPosition())); + + // Unidirectionally aggregate NodeId to it, so it can be fetched later by + // propagation models + auto node = tx->GetObject(); + if (node) + { + virtualMm->UnidirectionalAggregateObject(node); + } + + // Some mobility models access building info related to mobility model + auto mbi = tx->GetObject(); + if (mbi) + { + virtualMm->UnidirectionalAggregateObject(mbi); + } + return virtualMm; +} + +Vector3D +WraparoundModel::GetVirtualPosition(const Vector3D tx, const Vector3D rx) const +{ + return tx; // Placeholder, you are supposed to implement whatever wraparound model you want +} diff --git a/src/spectrum/model/wraparound-model.h b/src/spectrum/model/wraparound-model.h new file mode 100644 index 000000000..5a4735977 --- /dev/null +++ b/src/spectrum/model/wraparound-model.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 CTTC + * + * SPDX-License-Identifier: GPL-2.0-only + * + * Author: Gabriel Ferreira + */ + +#ifndef WRAPAROUNDMODEL_H +#define WRAPAROUNDMODEL_H + +#include "ns3/mobility-model.h" + +namespace ns3 +{ +class WraparoundModel : public Object +{ + public: + /** + * @brief Default constructor + */ + WraparoundModel() = default; + + /** + * Register this type with the TypeId system. + * @return the object TypeId + */ + static TypeId GetTypeId(); + + /** + * @brief Creates a disposable virtual mobility model for tx based on rx distance and + * a wraparound model + * @param tx Transmitter mobility model + * @param rx Receiver Mobility model + * @return virtual mobility model for transmitter + */ + Ptr GetVirtualMobilityModel(Ptr tx, + Ptr rx) const; + /** + * @brief Get virtual position of txPos with respect to rxPos. Each wraparound model + * should override this function with their own implementation + * @param tx Transmitter position + * @param rx Receiver position + * @return virtual position of transmitter in respect to receiver position + */ + virtual Vector3D GetVirtualPosition(const Vector3D tx, const Vector3D rx) const; +}; +} // namespace ns3 + +#endif // WRAPAROUNDMODEL_H