25#include "ns3/channel-condition-model.h"
26#include "ns3/constant-position-mobility-model.h"
27#include "ns3/constant-velocity-mobility-model.h"
28#include "ns3/core-module.h"
29#include "ns3/lte-spectrum-value-helper.h"
30#include "ns3/mobility-model.h"
31#include "ns3/node-container.h"
33#include "ns3/spectrum-signal-parameters.h"
34#include "ns3/three-gpp-channel-model.h"
35#include "ns3/three-gpp-propagation-loss-model.h"
36#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
37#include "ns3/uniform-planar-array.h"
121 Vector aPos = txMob->GetPosition();
122 Vector bPos = rxMob->GetPosition();
125 Angles completeAngle(bPos, aPos);
126 double hAngleRadian = completeAngle.
GetAzimuth();
131 uint64_t totNoArrayElements = thisAntenna->GetNumElems();
135 double power = 1.0 / sqrt(totNoArrayElements);
138 const double sinVAngleRadian = sin(vAngleRadian);
139 const double cosVAngleRadian = cos(vAngleRadian);
140 const double sinHAngleRadian = sin(hAngleRadian);
141 const double cosHAngleRadian = cos(hAngleRadian);
143 for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
145 Vector loc = thisAntenna->GetElementLocation(ind);
146 double phase = sign * 2 * M_PI *
147 (sinVAngleRadian * cosHAngleRadian * loc.x +
148 sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
149 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
153 thisAntenna->SetBeamformingVector(antennaWeights);
184 using C = std::complex<double>;
186 const uint64_t nTx = txAntenna->GetNumElems();
187 const uint64_t nRx = rxAntenna->GetNumElems();
188 const size_t numClusters = params->m_channel.GetNumPages();
191 NS_ASSERT_MSG(params->m_channel.GetNumRows() == nRx,
"Channel rows != #RX elements");
192 NS_ASSERT_MSG(params->m_channel.GetNumCols() == nTx,
"Channel cols != #TX elements");
197 for (
size_t c = 0; c < numClusters; ++c)
199 for (uint64_t
u = 0;
u < nRx; ++
u)
202 for (uint64_t s = 0; s < nTx; ++s)
204 acc += params->m_channel(
u, s, c) * wTx[s];
211 for (uint64_t
u = 0;
u < nRx; ++
u)
213 norm2 += std::norm(g[
u]);
217 const double invNorm = 1.0 / std::sqrt(norm2);
218 for (uint64_t
u = 0;
u < nRx; ++
u)
237 std::vector<int> activeRbs0(100);
238 for (
int i = 0; i < 100; i++)
245 txParams->psd = txPsd->Copy();
246 NS_LOG_DEBUG(
"Average tx power " << 10 * log10(
Sum(*txPsd) * 180e3) <<
" dB");
251 NS_LOG_DEBUG(
"Average noise power " << 10 * log10(
Sum(*noisePsd) * 180e3) <<
" dB");
255 NS_LOG_DEBUG(
"Pathloss " << -propagationGainDb <<
" dB");
256 double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
257 *(txParams->psd) *= propagationGainLinear;
259 NS_ASSERT_MSG(params.txAntenna,
"params.txAntenna is nullptr!");
260 NS_ASSERT_MSG(params.rxAntenna,
"params.rxAntenna is nullptr!");
264 DoBeamforming(params.txMob, params.txAntenna, params.rxMob, sign);
266 DoBeamforming(params.rxMob, params.rxAntenna, params.txMob, sign);
273 auto rxPsdSteering = rxParams->psd;
274 NS_LOG_DEBUG(
"Average rx power " << 10 * log10(
Sum(*rxPsdSteering) * 180e3) <<
" dB");
275 NS_LOG_DEBUG(
"Average SNR " << 10 * log10(
Sum(*rxPsdSteering) /
Sum(*noisePsd)) <<
" dB");
280 channelModel->GetChannel(params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
282 const auto& wTx = params.txAntenna->GetBeamformingVectorRef();
285 params.rxAntenna->SetBeamformingVector(wRx);
287 auto rxParamsMatchedFilterComb =
294 auto rxPsdMatchedFilterComb = rxParamsMatchedFilterComb->psd;
295 NS_LOG_DEBUG(
"Average rx power when using matched filter combining "
296 << 10 * log10(
Sum(*rxPsdMatchedFilterComb) * 180e3) <<
" dB");
297 NS_LOG_DEBUG(
"Average SNR when using matched filter combining "
298 << 10 * log10(
Sum(*rxPsdMatchedFilterComb) /
Sum(*noisePsd)) <<
" dB");
302 f.open(
"snr-trace.txt", std::ios::out | std::ios::app);
304 <<
" " << 10 * log10(
Sum(*rxPsdMatchedFilterComb) /
Sum(*noisePsd)) <<
" "
305 << propagationGainDb << std::endl;
310main(
int argc,
char* argv[])
312 double frequency = 2125.0e6;
314 double noiseFigure = 9.0;
315 double distance = 10.0;
318 std::string scenario =
"UMa";
321 cmd.AddValue(
"frequency",
"Operating frequency in Hz", frequency);
322 cmd.AddValue(
"txPow",
"TX power in dBm", txPow);
323 cmd.AddValue(
"noiseFigure",
"Noise figure in dB", noiseFigure);
324 cmd.AddValue(
"distance",
"Distance between TX and RX nodes in meters", distance);
325 cmd.AddValue(
"simTime",
"Simulation time in milliseconds", simTime);
326 cmd.AddValue(
"timeRes",
"Time resolution in milliseconds", timeRes);
327 cmd.AddValue(
"scenario",
"3GPP propagation scenario", scenario);
328 cmd.Parse(argc, argv);
341 if (scenario ==
"RMa")
346 else if (scenario ==
"UMa")
351 else if (scenario ==
"UMi-StreetCanyon")
358 else if (scenario ==
"InH-OfficeOpen")
365 else if (scenario ==
"InH-OfficeMixed")
400 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
402 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
403 rxMob->SetVelocity(Vector(0.5, 0, 0));
406 nodes.Get(0)->AggregateObject(txMob);
407 nodes.Get(1)->AggregateObject(rxMob);
421 for (
int i = 0; i < floor(simTime / timeRes); i++)
Class holding the azimuth and inclination angles of spherical coordinates.
double GetInclination() const
Getter for inclination angle.
double GetAzimuth() const
Getter for azimuth angle.
AttributeValue implementation for Boolean.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted.
keep track of a set of node pointers.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
ComplexMatrixArray ComplexVector
the underlying Valarray
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
Hold variables of type string.
Base class for the 3GPP channel condition models.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
Base class for the 3GPP propagation models.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
Hold an unsigned integer type.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
void SetDefault(std::string name, const AttributeValue &value)
#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.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
double Sum(const SpectrumValue &x)
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
A structure that holds the parameters for the ComputeSnr function.
Ptr< PhasedArrayModel > txAntenna
the tx antenna array
Ptr< MobilityModel > rxMob
the rx mobility model
double noiseFigure
the noise figure in dB
double txPow
the tx power in dBm
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
static void DoBeamforming(Ptr< MobilityModel > txMob, Ptr< PhasedArrayModel > thisAntenna, Ptr< MobilityModel > rxMob, double sign)
Perform a simple (DFT/steering) beamforming toward the other node.
static void ComputeSnr(const ComputeSnrParams ¶ms)
Compute the average SNR.
static ns3::PhasedArrayModel::ComplexVector BuildRxMatchedFilterOverAllClusters(ns3::Ptr< const ns3::MatrixBasedChannelModel::ChannelMatrix > params, ns3::Ptr< const ns3::PhasedArrayModel > txAntenna, ns3::Ptr< const ns3::PhasedArrayModel > rxAntenna, const ns3::PhasedArrayModel::ComplexVector &wTx)
Build the RX matched-filter (maximum-ratio) combining vector by aggregating the contributions of all ...
static Ptr< ThreeGppPropagationLossModel > m_propagationLossModel
the log component
static void ComputeSnr(const ComputeSnrParams ¶ms)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object