A Discrete-Event Network Simulator
API
three-gpp-channel-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17 
18 #include "ns3/abort.h"
19 #include "ns3/angles.h"
20 #include "ns3/channel-condition-model.h"
21 #include "ns3/config.h"
22 #include "ns3/constant-position-mobility-model.h"
23 #include "ns3/double.h"
24 #include "ns3/ism-spectrum-value-helper.h"
25 #include "ns3/isotropic-antenna-model.h"
26 #include "ns3/log.h"
27 #include "ns3/node-container.h"
28 #include "ns3/pointer.h"
29 #include "ns3/rng-seed-manager.h"
30 #include "ns3/simple-net-device.h"
31 #include "ns3/simulator.h"
32 #include "ns3/spectrum-signal-parameters.h"
33 #include "ns3/string.h"
34 #include "ns3/test.h"
35 #include "ns3/three-gpp-antenna-model.h"
36 #include "ns3/three-gpp-channel-model.h"
37 #include "ns3/three-gpp-spectrum-propagation-loss-model.h"
38 #include "ns3/uinteger.h"
39 #include "ns3/uniform-planar-array.h"
40 
41 #include <valarray>
42 
43 using namespace ns3;
44 
45 NS_LOG_COMPONENT_DEFINE("ThreeGppChannelTestSuite");
46 
55 {
56  public:
67  ThreeGppChannelMatrixComputationTest(uint32_t txAntennaElements = 2,
68  uint32_t rxAntennaElements = 2,
69  uint32_t txPorts = 1,
70  uint32_t rxPorts = 1);
71 
76 
77  private:
81  void DoRun() override;
82 
91  void DoComputeNorm(Ptr<ThreeGppChannelModel> channelModel,
92  Ptr<MobilityModel> txMob,
93  Ptr<MobilityModel> rxMob,
94  Ptr<PhasedArrayModel> txAntenna,
95  Ptr<PhasedArrayModel> rxAntenna);
96 
97  std::vector<double> m_normVector;
98  uint32_t m_txAntennaElements{4};
99  uint32_t m_rxAntennaElements{4};
100  uint32_t m_txPorts{1};
101  uint32_t m_rxPorts{1};
102 };
103 
105  uint32_t txAntennaElements,
106  uint32_t rxAntennaElements,
107  uint32_t txPorts,
108  uint32_t rxPorts)
109  : TestCase("Check the dimensions and the norm of the channel matrix")
110 {
111  m_txAntennaElements = txAntennaElements;
112  m_rxAntennaElements = rxAntennaElements;
113  m_txPorts = txPorts;
114  m_rxPorts = rxPorts;
115 }
116 
118 {
119 }
120 
121 void
123  Ptr<MobilityModel> txMob,
124  Ptr<MobilityModel> rxMob,
125  Ptr<PhasedArrayModel> txAntenna,
126  Ptr<PhasedArrayModel> rxAntenna)
127 {
128  uint64_t txAntennaElements = txAntenna->GetNumElems();
129  uint64_t rxAntennaElements = rxAntenna->GetNumElems();
130 
132  channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
133 
134  double channelNorm = 0;
135  uint16_t numTotalClusters = channelMatrix->m_channel.GetNumPages();
136  for (uint16_t cIndex = 0; cIndex < numTotalClusters; cIndex++)
137  {
138  double clusterNorm = 0;
139  for (uint64_t sIndex = 0; sIndex < txAntennaElements; sIndex++)
140  {
141  for (uint64_t uIndex = 0; uIndex < rxAntennaElements; uIndex++)
142  {
143  clusterNorm +=
144  std::pow(std::abs(channelMatrix->m_channel(uIndex, sIndex, cIndex)), 2);
145  }
146  }
147  channelNorm += clusterNorm;
148  }
149  m_normVector.push_back(channelNorm);
150 }
151 
152 void
154 {
155  RngSeedManager::SetSeed(1);
156  RngSeedManager::SetRun(1);
157  // Build the scenario for the test
158  uint32_t updatePeriodMs = 100; // update period in ms
159 
160  // create the channel condition model
161  Ptr<ChannelConditionModel> channelConditionModel =
162  CreateObject<NeverLosChannelConditionModel>();
163 
164  // create the ThreeGppChannelModel object used to generate the channel matrix
165  Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
166  channelModel->SetAttribute("Frequency", DoubleValue(60.0e9));
167  channelModel->SetAttribute("Scenario", StringValue("RMa"));
168  channelModel->SetAttribute("ChannelConditionModel", PointerValue(channelConditionModel));
169  channelModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(updatePeriodMs - 1)));
170  channelModel->AssignStreams(1);
171 
172  // create the tx and rx nodes
174  nodes.Create(2);
175 
176  // create the tx and rx devices
177  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
178  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
179 
180  // associate the nodes and the devices
181  nodes.Get(0)->AddDevice(txDev);
182  txDev->SetNode(nodes.Get(0));
183  nodes.Get(1)->AddDevice(rxDev);
184  rxDev->SetNode(nodes.Get(1));
185 
186  // create the tx and rx mobility models and set their positions
187  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
188  txMob->SetPosition(Vector(0.0, 0.0, 10.0));
189  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
190  rxMob->SetPosition(Vector(100.0, 0.0, 10.0));
191 
192  // associate the nodes and the mobility models
193  nodes.Get(0)->AggregateObject(txMob);
194  nodes.Get(1)->AggregateObject(rxMob);
195 
196  // create the tx and rx antennas and set the their dimensions
197  Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
198  "NumColumns",
200  "NumRows",
202  "AntennaElement",
203  PointerValue(CreateObject<IsotropicAntennaModel>()),
204  "NumVerticalPorts",
206  "NumHorizontalPorts",
208 
209  Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
210  "NumColumns",
212  "NumRows",
214  "AntennaElement",
215  PointerValue(CreateObject<IsotropicAntennaModel>()),
216  "NumVerticalPorts",
218  "NumHorizontalPorts",
220  // generate the channel matrix
222  channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
223 
224  // check the channel matrix dimensions, expected H[cluster][rx][tx]
226  channelMatrix->m_channel.GetNumCols(),
228  "The third dimension of H should be equal to the number of tx antenna elements");
230  channelMatrix->m_channel.GetNumRows(),
232  "The second dimension of H should be equal to the number of rx antenna elements");
233 
234  // test if the channel matrix is correctly generated
235  uint16_t numIt = 1000;
236  for (uint16_t i = 0; i < numIt; i++)
237  {
238  Simulator::Schedule(MilliSeconds(updatePeriodMs * i),
240  this,
241  channelModel,
242  txMob,
243  rxMob,
244  txAntenna,
245  rxAntenna);
246  }
247 
248  Simulator::Run();
249 
250  // compute the sample mean
251  double sampleMean = 0;
252  for (auto i : m_normVector)
253  {
254  sampleMean += i;
255  }
256  sampleMean /= numIt;
257 
258  // compute the sample standard deviation
259  double sampleStd = 0;
260  for (auto i : m_normVector)
261  {
262  sampleStd += ((i - sampleMean) * (i - sampleMean));
263  }
264  sampleStd = std::sqrt(sampleStd / (numIt - 1));
265 
266  // perform the one sample t-test with a significance level of 0.05 to test
267  // the hypothesis "E [|H|^2] = M*N, where |H| indicates the Frobenius norm of
268  // H, M is the number of transmit antenna elements, and N is the number of
269  // the receive antenna elements"
270  double t = (sampleMean - m_txAntennaElements * m_txAntennaElements * m_rxAntennaElements *
272  (sampleStd / std::sqrt(numIt));
273 
274  // Using a significance level of 0.05, we reject the null hypothesis if |t| is
275  // greater than the critical value from a t-distribution with df = numIt-1
277  std::abs(t),
278  0,
279  1.65,
280  "We reject the hypothesis E[|H|^2] = M*N with a significance level of 0.05");
281 
282  Simulator::Destroy();
283 }
284 
293 {
294  public:
305  ThreeGppChannelMatrixUpdateTest(uint32_t txAntennaElements = 2,
306  uint32_t rxAntennaElements = 4,
307  uint32_t txPorts = 1,
308  uint32_t rxPorts = 1);
309 
314 
315  private:
319  void DoRun() override;
320 
331  void DoGetChannel(Ptr<ThreeGppChannelModel> channelModel,
332  Ptr<MobilityModel> txMob,
333  Ptr<MobilityModel> rxMob,
334  Ptr<PhasedArrayModel> txAntenna,
335  Ptr<PhasedArrayModel> rxAntenna,
336  bool update);
337 
340  uint32_t m_txAntennaElements{4};
341  uint32_t m_rxAntennaElements{4};
342  uint32_t m_txPorts{1};
343  uint32_t m_rxPorts{1};
344 };
345 
347  uint32_t rxAntennaElements,
348  uint32_t txPorts,
349  uint32_t rxPorts)
350  : TestCase("Check if the channel realizations are correctly updated during the simulation")
351 {
352  m_txAntennaElements = txAntennaElements;
353  m_rxAntennaElements = rxAntennaElements;
354  m_txPorts = txPorts;
355  m_rxPorts = rxPorts;
356 }
357 
359 {
360 }
361 
362 void
364  Ptr<MobilityModel> txMob,
365  Ptr<MobilityModel> rxMob,
366  Ptr<PhasedArrayModel> txAntenna,
367  Ptr<PhasedArrayModel> rxAntenna,
368  bool update)
369 {
370  // retrieve the channel matrix
372  channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
373 
374  if (!m_currentChannel)
375  {
376  // this is the first time we compute the channel matrix, we initialize
377  // m_currentChannel
378  m_currentChannel = channelMatrix;
379  }
380  else
381  {
382  // compare the old and the new channel matrices
384  update,
386  << " The channel matrix is not correctly updated");
387  }
388 }
389 
390 void
392 {
393  // Build the scenario for the test
394  uint32_t updatePeriodMs = 100; // update period in ms
395 
396  // create the channel condition model
397  Ptr<ChannelConditionModel> channelConditionModel =
398  CreateObject<AlwaysLosChannelConditionModel>();
399 
400  // create the ThreeGppChannelModel object used to generate the channel matrix
401  Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
402  channelModel->SetAttribute("Frequency", DoubleValue(60.0e9));
403  channelModel->SetAttribute("Scenario", StringValue("UMa"));
404  channelModel->SetAttribute("ChannelConditionModel", PointerValue(channelConditionModel));
405  channelModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(updatePeriodMs)));
406 
407  // create the tx and rx nodes
409  nodes.Create(2);
410 
411  // create the tx and rx devices
412  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
413  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
414 
415  // associate the nodes and the devices
416  nodes.Get(0)->AddDevice(txDev);
417  txDev->SetNode(nodes.Get(0));
418  nodes.Get(1)->AddDevice(rxDev);
419  rxDev->SetNode(nodes.Get(1));
420 
421  // create the tx and rx mobility models and set their positions
422  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
423  txMob->SetPosition(Vector(0.0, 0.0, 10.0));
424  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
425  rxMob->SetPosition(Vector(100.0, 0.0, 1.6));
426 
427  // associate the nodes and the mobility models
428  nodes.Get(0)->AggregateObject(txMob);
429  nodes.Get(1)->AggregateObject(rxMob);
430 
431  // create the tx and rx antennas and set the their dimensions
432  Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
433  "NumColumns",
435  "NumRows",
437  "AntennaElement",
438  PointerValue(CreateObject<IsotropicAntennaModel>()),
439  "NumVerticalPorts",
441  "NumHorizontalPorts",
443 
444  Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
445  "NumColumns",
447  "NumRows",
449  "AntennaElement",
450  PointerValue(CreateObject<IsotropicAntennaModel>()),
451  "NumVerticalPorts",
453  "NumHorizontalPorts",
455 
456  // check if the channel matrix is correctly updated
457 
458  // compute the channel matrix for the first time
459  uint32_t firstTimeMs =
460  1; // time instant at which the channel matrix is generated for the first time
461  Simulator::Schedule(MilliSeconds(firstTimeMs),
463  this,
464  channelModel,
465  txMob,
466  rxMob,
467  txAntenna,
468  rxAntenna,
469  true);
470 
471  // call GetChannel before the update period is exceeded, the channel matrix
472  // should not be updated
473  Simulator::Schedule(MilliSeconds(firstTimeMs + updatePeriodMs / 2),
475  this,
476  channelModel,
477  txMob,
478  rxMob,
479  txAntenna,
480  rxAntenna,
481  false);
482 
483  // call GetChannel when the update period is exceeded, the channel matrix
484  // should be recomputed
485  Simulator::Schedule(MilliSeconds(firstTimeMs + updatePeriodMs + 1),
487  this,
488  channelModel,
489  txMob,
490  rxMob,
491  txAntenna,
492  rxAntenna,
493  true);
494 
495  Simulator::Run();
496  Simulator::Destroy();
497 }
498 
506 {
515 };
516 
528 {
529  public:
541  ThreeGppSpectrumPropagationLossModelTest(uint32_t txAntennaElements = 4,
542  uint32_t rxAntennaElements = 4,
543  uint32_t txPorts = 1,
544  uint32_t rxPorts = 1);
549 
550  private:
554  void DoRun() override;
555 
563  void DoBeamforming(Ptr<NetDevice> thisDevice,
564  Ptr<PhasedArrayModel> thisAntenna,
565  Ptr<NetDevice> otherDevice,
566  Ptr<PhasedArrayModel> otherAntenna);
567 
575 
576  uint32_t m_txAntennaElements{4};
577  uint32_t m_rxAntennaElements{4};
578  uint32_t m_txPorts{1};
579  uint32_t m_rxPorts{1};
580 };
581 
583  uint32_t txAntennaElements,
584  uint32_t rxAntennaElements,
585  uint32_t txPorts,
586  uint32_t rxPorts)
587  : TestCase("Test case for the ThreeGppSpectrumPropagationLossModel class")
588 {
589  m_txAntennaElements = txAntennaElements;
590  m_rxAntennaElements = rxAntennaElements;
591  m_txPorts = txPorts;
592  m_rxPorts = rxPorts;
593 }
594 
596 {
597 }
598 
599 void
601  Ptr<PhasedArrayModel> thisAntenna,
602  Ptr<NetDevice> otherDevice,
603  Ptr<PhasedArrayModel> otherAntenna)
604 {
605  Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
606  Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
607 
608  // compute the azimuth and the elevation angles
609  Angles completeAngle(bPos, aPos);
610 
611  PhasedArrayModel::ComplexVector antennaWeights =
612  thisAntenna->GetBeamformingVector(completeAngle);
613  thisAntenna->SetBeamformingVector(antennaWeights);
614 }
615 
616 void
619 {
620  auto rxPsdNewParams = params.lossModel->DoCalcRxPowerSpectralDensity(params.txParams,
621  params.txMob,
622  params.rxMob,
623  params.txAntenna,
624  params.rxAntenna);
625  NS_TEST_ASSERT_MSG_EQ((*params.rxPsdOld == *rxPsdNewParams->psd),
626  false,
627  "The long term is not updated when the channel matrix is recomputed");
628 }
629 
630 void
632 {
633  // Build the scenario for the test
634  Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(100)));
635 
636  // create the ChannelConditionModel object to be used to retrieve the
637  // channel condition
638  Ptr<ChannelConditionModel> condModel = CreateObject<AlwaysLosChannelConditionModel>();
639 
640  // create the ThreeGppSpectrumPropagationLossModel object, set frequency,
641  // scenario and channel condition model to be used
643  CreateObject<ThreeGppSpectrumPropagationLossModel>();
644  lossModel->SetChannelModelAttribute("Frequency", DoubleValue(2.4e9));
645  lossModel->SetChannelModelAttribute("Scenario", StringValue("UMa"));
646  lossModel->SetChannelModelAttribute(
647  "ChannelConditionModel",
648  PointerValue(condModel)); // create the ThreeGppChannelModel object used to generate the
649  // channel matrix
650 
651  // create the tx and rx nodes
653  nodes.Create(2);
654 
655  // create the tx and rx devices
656  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
657  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
658 
659  // associate the nodes and the devices
660  nodes.Get(0)->AddDevice(txDev);
661  txDev->SetNode(nodes.Get(0));
662  nodes.Get(1)->AddDevice(rxDev);
663  rxDev->SetNode(nodes.Get(1));
664 
665  // create the tx and rx mobility models and set their positions
666  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
667  txMob->SetPosition(Vector(0.0, 0.0, 10.0));
668  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
669  rxMob->SetPosition(
670  Vector(15.0, 0.0, 10.0)); // in this position the channel condition is always LOS
671 
672  // associate the nodes and the mobility models
673  nodes.Get(0)->AggregateObject(txMob);
674  nodes.Get(1)->AggregateObject(rxMob);
675 
676  // create the tx and rx antennas and set the their dimensions
677  Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
678  "NumColumns",
680  "NumRows",
682  "AntennaElement",
683  PointerValue(CreateObject<IsotropicAntennaModel>()),
684  "NumVerticalPorts",
686  "NumHorizontalPorts",
688 
689  Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
690  "NumColumns",
692  "NumRows",
694  "AntennaElement",
695  PointerValue(CreateObject<IsotropicAntennaModel>()),
696  "NumVerticalPorts",
698  "NumHorizontalPorts",
700 
701  // set the beamforming vectors
702  DoBeamforming(txDev, txAntenna, rxDev, rxAntenna);
703  DoBeamforming(rxDev, rxAntenna, txDev, txAntenna);
704 
705  // create the tx psd
707  double txPower = 0.1; // Watts
708  uint32_t channelNumber = 1;
709  Ptr<SpectrumValue> txPsd = sf.CreateTxPowerSpectralDensity(txPower, channelNumber);
710  Ptr<SpectrumSignalParameters> txParams = Create<SpectrumSignalParameters>();
711  txParams->psd = txPsd->Copy();
712 
713  // compute the rx psd
714  auto rxParamsOld =
715  lossModel->DoCalcRxPowerSpectralDensity(txParams, txMob, rxMob, txAntenna, rxAntenna);
716 
717  // 1) check that the rx PSD is equal for both the direct and the reverse channel
718  auto rxParamsNew =
719  lossModel->DoCalcRxPowerSpectralDensity(txParams, rxMob, txMob, rxAntenna, txAntenna);
720  NS_TEST_ASSERT_MSG_EQ((*rxParamsOld->psd == *rxParamsNew->psd),
721  true,
722  "The long term for the direct and the reverse channel are different");
723 
724  // 2) check if the long term is updated when changing the BF vector
725  // change the position of the rx device and recompute the beamforming vectors
726  rxMob->SetPosition(Vector(10.0, 5.0, 10.0));
727  PhasedArrayModel::ComplexVector txBfVector = txAntenna->GetBeamformingVector();
728  txBfVector[0] = std::complex<double>(0.0, 0.0);
729  txAntenna->SetBeamformingVector(txBfVector);
730 
731  rxParamsNew =
732  lossModel->DoCalcRxPowerSpectralDensity(txParams, rxMob, txMob, rxAntenna, txAntenna);
733  NS_TEST_ASSERT_MSG_EQ((*rxParamsOld->psd == *rxParamsNew->psd),
734  false,
735  "Changing the BF vectors the rx PSD does not change");
736 
738  (*rxParamsOld->spectrumChannelMatrix == *rxParamsNew->spectrumChannelMatrix),
739  false,
740  "Changing the BF should change de frequency domain channel matrix");
741 
742  // update rxPsdOld
743  rxParamsOld = rxParamsNew;
744 
745  // 3) check if the long term is updated when the channel matrix is recomputed
747  params{lossModel, txParams, txMob, rxMob, rxParamsOld->psd, txAntenna, rxAntenna};
748  Simulator::Schedule(MilliSeconds(101),
750  this,
751  params);
752 
753  Simulator::Run();
754  Simulator::Destroy();
755 }
756 
784 {
785  public:
790 
795 
796  private:
800  void DoRun() override;
801 };
802 
804  : TestCase("Check long term channel matrix generation when multiple ports at TX and RX are "
805  "being used.")
806 {
807 }
808 
810 {
811 }
812 
813 void
815 {
816  // create the channel condition model
817  Ptr<ChannelConditionModel> channelConditionModel =
818  CreateObject<AlwaysLosChannelConditionModel>();
819 
820  // create the ThreeGppChannelModel object used to generate the channel matrix
821  Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
822  channelModel->SetAttribute("Frequency", DoubleValue(2.0e9));
823  channelModel->SetAttribute("Scenario", StringValue("RMa"));
824  channelModel->SetAttribute("ChannelConditionModel", PointerValue(channelConditionModel));
825 
826  // create the tx and rx nodes
828  nodes.Create(2);
829 
830  // create the tx and rx devices
831  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
832  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
833 
834  // associate the nodes and the devices
835  nodes.Get(0)->AddDevice(txDev);
836  txDev->SetNode(nodes.Get(0));
837  nodes.Get(1)->AddDevice(rxDev);
838  rxDev->SetNode(nodes.Get(1));
839 
840  // create the tx and rx mobility models and set their positions
841  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
842  txMob->SetPosition(Vector(0.0, 0.0, 10.0));
843  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
844  rxMob->SetPosition(Vector(10.0, 0.0, 10.0));
845 
846  // associate the nodes and the mobility models
847  nodes.Get(0)->AggregateObject(txMob);
848  nodes.Get(1)->AggregateObject(rxMob);
849 
850  // create the tx and rx antennas and set the their dimensions
851  Ptr<PhasedArrayModel> txAntenna1 = CreateObjectWithAttributes<UniformPlanarArray>(
852  "NumColumns",
853  UintegerValue(8),
854  "NumRows",
855  UintegerValue(4),
856  "AntennaElement",
857  PointerValue(CreateObject<IsotropicAntennaModel>()),
858  "NumVerticalPorts",
859  UintegerValue(1),
860  "NumHorizontalPorts",
861  UintegerValue(4));
862 
863  Ptr<PhasedArrayModel> rxAntenna1 = CreateObjectWithAttributes<UniformPlanarArray>(
864  "NumColumns",
865  UintegerValue(4),
866  "NumRows",
867  UintegerValue(4),
868  "AntennaElement",
869  PointerValue(CreateObject<IsotropicAntennaModel>()),
870  "NumVerticalPorts",
871  UintegerValue(1),
872  "NumHorizontalPorts",
873  UintegerValue(2));
874 
875  // compute the azimuth and the elevation angles
876  Angles completeAngleTxRx(rxMob->GetPosition(), txMob->GetPosition());
877  Angles completeAngleRxTx(txMob->GetPosition(), rxMob->GetPosition());
878 
879  txAntenna1->SetBeamformingVector(txAntenna1->GetBeamformingVector(completeAngleTxRx));
880  rxAntenna1->SetBeamformingVector(rxAntenna1->GetBeamformingVector(completeAngleRxTx));
881 
882  // generate the channel matrix
884  channelModel->GetChannel(txMob, rxMob, txAntenna1, rxAntenna1);
885 
886  // create ThreeGppSpectrumPropagationLossModel instance so that we
887  // can call CalcLongTerm
889  CreateObject<ThreeGppSpectrumPropagationLossModel>();
890 
892  threeGppSplm->CalcLongTerm(channelMatrixM0, txAntenna1, rxAntenna1);
893 
894  // create the tx and rx antennas and set the their dimensions
895  Ptr<PhasedArrayModel> txAntenna2 = CreateObjectWithAttributes<UniformPlanarArray>(
896  "NumColumns",
897  UintegerValue(8),
898  "NumRows",
899  UintegerValue(4),
900  "AntennaElement",
901  PointerValue(CreateObject<IsotropicAntennaModel>()),
902  "NumVerticalPorts",
903  UintegerValue(1),
904  "NumHorizontalPorts",
905  UintegerValue(1));
906 
907  Ptr<PhasedArrayModel> rxAntenna2 = CreateObjectWithAttributes<UniformPlanarArray>(
908  "NumColumns",
909  UintegerValue(4),
910  "NumRows",
911  UintegerValue(4),
912  "AntennaElement",
913  PointerValue(CreateObject<IsotropicAntennaModel>()),
914  "NumVerticalPorts",
915  UintegerValue(1),
916  "NumHorizontalPorts",
917  UintegerValue(1));
918 
919  txAntenna2->SetBeamformingVector(txAntenna2->GetBeamformingVector(completeAngleTxRx));
920  rxAntenna2->SetBeamformingVector(rxAntenna2->GetBeamformingVector(completeAngleRxTx));
921 
923  threeGppSplm->CalcLongTerm(channelMatrixM0, txAntenna2, rxAntenna2);
924 
925  // create the tx and rx antennas and set the their dimensions
926  Ptr<PhasedArrayModel> txAntenna3 = CreateObjectWithAttributes<UniformPlanarArray>(
927  "NumColumns",
928  UintegerValue(4),
929  "NumRows",
930  UintegerValue(1),
931  "AntennaElement",
932  PointerValue(CreateObject<IsotropicAntennaModel>()),
933  "NumVerticalPorts",
934  UintegerValue(1),
935  "NumHorizontalPorts",
936  UintegerValue(1),
937  "AntennaHorizontalSpacing",
938  DoubleValue(1));
939 
940  Ptr<PhasedArrayModel> rxAntenna3 = CreateObjectWithAttributes<UniformPlanarArray>(
941  "NumColumns",
942  UintegerValue(2),
943  "NumRows",
944  UintegerValue(1),
945  "AntennaElement",
946  PointerValue(CreateObject<IsotropicAntennaModel>()),
947  "NumVerticalPorts",
948  UintegerValue(1),
949  "NumHorizontalPorts",
950  UintegerValue(1),
951  "AntennaHorizontalSpacing",
952  DoubleValue(1));
953 
955  Create<ThreeGppChannelModel::ChannelMatrix>();
956  channelMatrixMA->m_channel = *matrixA;
957 
958  txAntenna3->SetBeamformingVector(txAntenna3->GetBeamformingVector(completeAngleTxRx));
959  rxAntenna3->SetBeamformingVector(rxAntenna3->GetBeamformingVector(completeAngleRxTx));
960 
962  threeGppSplm->CalcLongTerm(channelMatrixMA, txAntenna3, rxAntenna3);
963 
964  NS_TEST_ASSERT_MSG_EQ(matrixB->IsAlmostEqual(*matrixC, 1e-6),
965  true,
966  "Matrix B and Matrix C should be equal.");
967 
968  Simulator::Run();
969  Simulator::Destroy();
970 }
971 
977 {
978  uint32_t m_rows = 1;
979  uint32_t m_cols = 2;
980  uint32_t m_vPorts = 1;
981  uint32_t m_hPorts = 2;
982  bool m_isotropic = false;
983  double m_polSlantAngle = 0;
984  double m_bearingAngle = 0;
985 
993  MimoPolarizationAntennaParams(bool isotropic, double polSlantAngle = 0, double bearingAngle = 0)
994  : m_isotropic(isotropic),
995  m_polSlantAngle(polSlantAngle),
996  m_bearingAngle(bearingAngle)
997  {
998  }
999 };
1000 
1030 {
1031  public:
1043  ThreeGppMimoPolarizationTest(std::string testCaseName,
1044  Vector txLoc,
1045  const MimoPolarizationAntennaParams& txAntennaParams,
1046  Vector rxLoc,
1047  const MimoPolarizationAntennaParams& rxAntennaParams,
1048  std::valarray<std::complex<double>> testChannel,
1049  double tolerance);
1050 
1054  ~ThreeGppMimoPolarizationTest() override;
1055 
1056  private:
1060  void DoRun() override;
1061 
1070 
1071  Vector m_txLoc;
1073  Vector m_rxLoc;
1075  std::valarray<std::complex<double>>
1077  double m_tolerance;
1079 };
1080 
1082  std::string testCaseName,
1083  Vector txLoc,
1084  const MimoPolarizationAntennaParams& txParams,
1085  Vector rxLoc,
1086  const MimoPolarizationAntennaParams& rxParams,
1087  std::valarray<std::complex<double>> testChannel,
1088  double tolerance)
1089  : TestCase("Test MIMO using dual polarization." + testCaseName),
1090  m_txLoc(txLoc),
1091  m_txParams(txParams),
1092  m_rxLoc(rxLoc),
1093  m_rxParams(rxParams),
1094  m_testChannel(testChannel),
1095  m_tolerance(tolerance)
1096 {
1097 }
1098 
1100 {
1101 }
1102 
1105 {
1106  NS_LOG_FUNCTION(this);
1107  Ptr<AntennaModel> antenna;
1108  if (params.m_isotropic)
1109  {
1110  antenna = CreateObject<IsotropicAntennaModel>();
1111  }
1112  else
1113  {
1114  antenna = CreateObject<ThreeGppAntennaModel>();
1115  }
1116  // create the tx and rx antennas and set the their dimensions
1117  return CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
1118  UintegerValue(params.m_cols),
1119  "NumRows",
1120  UintegerValue(params.m_rows),
1121  "AntennaElement",
1122  PointerValue(antenna),
1123  "NumVerticalPorts",
1124  UintegerValue(params.m_vPorts),
1125  "NumHorizontalPorts",
1126  UintegerValue(params.m_hPorts),
1127  "BearingAngle",
1128  DoubleValue(params.m_bearingAngle),
1129  "PolSlantAngle",
1130  DoubleValue(params.m_polSlantAngle),
1131  "IsDualPolarized",
1132  BooleanValue(true));
1133 }
1134 
1135 void
1137 {
1138  RngSeedManager::SetSeed(1);
1139  RngSeedManager::SetRun(1);
1140  // create the ThreeGppChannelModel object used to generate the channel matrix
1141  Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
1142  channelModel->SetAttribute("Frequency", DoubleValue(60e9));
1143  channelModel->SetAttribute("Scenario", StringValue("RMa"));
1144  channelModel->SetAttribute("ChannelConditionModel",
1145  PointerValue(CreateObject<AlwaysLosChannelConditionModel>()));
1146 
1147  int64_t randomStream = 1;
1148  randomStream += channelModel->AssignStreams(randomStream);
1149 
1150  // create the tx and rx nodes
1152  nodes.Create(2);
1153 
1154  // create the tx and rx devices
1155  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
1156  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
1157 
1158  // associate the nodes and the devices
1159  nodes.Get(0)->AddDevice(txDev);
1160  txDev->SetNode(nodes.Get(0));
1161  nodes.Get(1)->AddDevice(rxDev);
1162  rxDev->SetNode(nodes.Get(1));
1163 
1164  // create the tx and rx mobility models and set their positions
1165  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
1166  txMob->SetPosition(m_txLoc);
1167  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
1168  rxMob->SetPosition(m_rxLoc);
1169 
1170  // associate the nodes and the mobility models
1171  nodes.Get(0)->AggregateObject(txMob);
1172  nodes.Get(1)->AggregateObject(rxMob);
1173 
1174  // create the tx and rx antennas and set the their dimensions
1177 
1178  // configure direct beamforming vectors to point to each other
1179  txAntenna->SetBeamformingVector(
1180  txAntenna->GetBeamformingVector(Angles(rxMob->GetPosition(), txMob->GetPosition())));
1181  rxAntenna->SetBeamformingVector(
1182  rxAntenna->GetBeamformingVector(Angles(txMob->GetPosition(), rxMob->GetPosition())));
1183 
1184  // generate the time domain channel matrix
1186  channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
1187 
1188  // test whether the channel matrix for the first cluster experiences strong
1189  // symmetry that is caused by existence of dual polarized ports at the
1190  // transmitter and the receiver
1191  const std::complex<double>* strongestClusterPtr = channelMatrix->m_channel.GetPagePtr(0);
1192  size_t matrixSize =
1193  channelMatrix->m_channel.GetNumRows() * channelMatrix->m_channel.GetNumCols();
1194 
1196  channelMatrix->m_channel.GetNumRows(),
1197  channelMatrix->m_channel.GetNumCols(),
1198  std::valarray<std::complex<double>>(strongestClusterPtr, matrixSize));
1199 
1200  MatrixBasedChannelModel::Complex2DVector testChannel(channelMatrix->m_channel.GetNumRows(),
1201  channelMatrix->m_channel.GetNumCols(),
1202  m_testChannel);
1203 
1204  NS_LOG_INFO("Channel matrix:" << strongestCluster);
1205  NS_LOG_INFO("Test channel matrix: " << testChannel);
1206 
1208  strongestCluster.IsAlmostEqual(testChannel, m_tolerance),
1209  true,
1210  "The strongest cluster and the test channel matrix should be almost equal");
1211 
1212  Simulator::Run();
1213  Simulator::Destroy();
1214 }
1215 
1222 {
1223  public:
1228 };
1229 
1231  : TestSuite("three-gpp-channel", UNIT)
1232 {
1233  AddTestCase(new ThreeGppChannelMatrixComputationTest(2, 2, 1, 1), TestCase::QUICK);
1234  AddTestCase(new ThreeGppChannelMatrixComputationTest(4, 2, 1, 1), TestCase::QUICK);
1235  AddTestCase(new ThreeGppChannelMatrixComputationTest(2, 2, 2, 2), TestCase::QUICK);
1236  AddTestCase(new ThreeGppChannelMatrixComputationTest(4, 4, 2, 2), TestCase::QUICK);
1237  AddTestCase(new ThreeGppChannelMatrixComputationTest(4, 2, 2, 1), TestCase::QUICK);
1238  AddTestCase(new ThreeGppChannelMatrixUpdateTest(2, 4, 1, 1), TestCase::QUICK);
1239  AddTestCase(new ThreeGppChannelMatrixUpdateTest(2, 2, 1, 1), TestCase::QUICK);
1240  AddTestCase(new ThreeGppChannelMatrixUpdateTest(2, 4, 2, 2), TestCase::QUICK);
1241  AddTestCase(new ThreeGppChannelMatrixUpdateTest(2, 2, 2, 2), TestCase::QUICK);
1242  AddTestCase(new ThreeGppSpectrumPropagationLossModelTest(4, 4, 1, 1), TestCase::QUICK);
1243  AddTestCase(new ThreeGppSpectrumPropagationLossModelTest(4, 4, 2, 2), TestCase::QUICK);
1244  AddTestCase(new ThreeGppSpectrumPropagationLossModelTest(4, 2, 2, 2), TestCase::QUICK);
1245  AddTestCase(new ThreeGppSpectrumPropagationLossModelTest(4, 2, 2, 1), TestCase::QUICK);
1246  AddTestCase(new ThreeGppCalcLongTermMultiPortTest(), TestCase::QUICK);
1247 
1257  std::valarray<std::complex<double>> testChannel1 =
1258  {5.9, 5.9, 0, 0, 5.9, 5.9, 0, 0, 0, 0, -5.8, -5.8, 0, 0, -5.8, -5.8};
1259  AddTestCase(new ThreeGppMimoPolarizationTest("Face-to-face. 0 and 0 pol. slant angles.",
1260  Vector{0, 0, 3},
1261  MimoPolarizationAntennaParams(false, 0, 0),
1262  Vector{9, 0, 3},
1263  MimoPolarizationAntennaParams(false, 0, M_PI),
1264  testChannel1,
1265  0.9),
1266  TestCase::QUICK);
1267 
1277  AddTestCase(
1278  new ThreeGppMimoPolarizationTest("Face-to-face. 30 and 0 pol. slant angles.",
1279  Vector{0, 0, 3},
1280  MimoPolarizationAntennaParams(false, M_PI / 6, 0),
1281  Vector{6, 0, 3},
1282  MimoPolarizationAntennaParams(false, 0, M_PI),
1283  {5, 5, 3, 3, 5, 5, 3, 3, 3, 3, -5, -5, 3, 3, -5, -5},
1284  0.8),
1285  TestCase::QUICK);
1286 
1296  AddTestCase(
1297  new ThreeGppMimoPolarizationTest("Face-to-face. 45 and 0 pol. slant angles.",
1298  Vector{0, 0, 3},
1299  MimoPolarizationAntennaParams(false, M_PI / 4, 0),
1300  Vector{6, 0, 3},
1301  MimoPolarizationAntennaParams(false, 0, M_PI),
1302  {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -4, -4, 4, 4, -4, -4},
1303  0.7),
1304  TestCase::QUICK);
1305 
1316  "Face-to-face. 90 and 0 pol. slant angles.",
1317  Vector{0, 0, 3},
1318  MimoPolarizationAntennaParams(false, M_PI / 2, 0),
1319  Vector{6, 0, 3},
1320  MimoPolarizationAntennaParams(false, 0, M_PI),
1321  {0, 0, 5.8, 5.8, 0, 0, 5.8, 5.8, 5.9, 5.9, 0, 0, 5.9, 5.9, 0, 0},
1322  0.9),
1323  TestCase::QUICK);
1324 
1338  AddTestCase(
1339  new ThreeGppMimoPolarizationTest("Face-to-face. Different positions. Different bearing "
1340  "angles. 0 and 0 pol. slant angles.",
1341  Vector{0, 0, 3},
1342  MimoPolarizationAntennaParams(false, 0, M_PI / 4),
1343  Vector{6.363961031, 6.363961031, 3},
1344  MimoPolarizationAntennaParams(false, 0, -(M_PI / 4) * 3),
1345  testChannel1,
1346  0.9),
1347  TestCase::QUICK);
1348 
1360  "Not face-to-face. Different heights. 0 and 0 pol. slant angles.",
1361  Vector{0, 0, 10},
1362  MimoPolarizationAntennaParams(false, 0, 0),
1363  Vector{30, 0, 3},
1364  MimoPolarizationAntennaParams(false, 0, M_PI),
1365  {{2.5, -4.7},
1366  {2.5, -4.7},
1367  0,
1368  0,
1369  {2.5, -4.7},
1370  {2.5, -4.7},
1371  0,
1372  0,
1373  0,
1374  0,
1375  {-2.4, 4},
1376  {-2.4, 4},
1377  0,
1378  0,
1379  {-2.4, 4},
1380  {-2.4, 4}},
1381  0.5),
1382  TestCase::QUICK);
1383 }
1384 
Test case that test the correct use of the multi-port antennas in spectrum.
void DoRun() override
Build the test scenario.
Test case for the ThreeGppChannelModel class.
ThreeGppChannelMatrixComputationTest(uint32_t txAntennaElements=2, uint32_t rxAntennaElements=2, uint32_t txPorts=1, uint32_t rxPorts=1)
Constructor.
void DoRun() override
Build the test scenario.
uint32_t m_rxPorts
number of horizontal and vertical ports of rx antenna array
std::vector< double > m_normVector
each element is the norm of a channel realization
void DoComputeNorm(Ptr< ThreeGppChannelModel > channelModel, Ptr< MobilityModel > txMob, Ptr< MobilityModel > rxMob, Ptr< PhasedArrayModel > txAntenna, Ptr< PhasedArrayModel > rxAntenna)
Compute the Frobenius norm of the channel matrix and stores it in m_normVector.
uint32_t m_rxAntennaElements
number of rows and columns of rx antenna array
uint32_t m_txAntennaElements
number of rows and columns of tx antenna array
uint32_t m_txPorts
number of horizontal and vertical ports of tx antenna array
Test case for the ThreeGppChannelModel class.
void DoGetChannel(Ptr< ThreeGppChannelModel > channelModel, Ptr< MobilityModel > txMob, Ptr< MobilityModel > rxMob, Ptr< PhasedArrayModel > txAntenna, Ptr< PhasedArrayModel > rxAntenna, bool update)
This method is used to schedule the channel matrix computation at different time instants and to chec...
ThreeGppChannelMatrixUpdateTest(uint32_t txAntennaElements=2, uint32_t rxAntennaElements=4, uint32_t txPorts=1, uint32_t rxPorts=1)
Constructor.
uint32_t m_txAntennaElements
number of rows and columns of tx antenna array
void DoRun() override
Build the test scenario.
uint32_t m_rxPorts
number of horizontal and vertical ports of rx antenna array
Ptr< const ThreeGppChannelModel::ChannelMatrix > m_currentChannel
used by DoGetChannel to store the current channel matrix
uint32_t m_txPorts
number of horizontal and vertical ports of tx antenna array
uint32_t m_rxAntennaElements
number of rows and columns of rx antenna array
Test suite for the ThreeGppChannelModel class.
This test tests that the channel matrix is correctly generated when dual-polarized antennas are being...
void DoRun() override
Build the test scenario.
ThreeGppMimoPolarizationTest(std::string testCaseName, Vector txLoc, const MimoPolarizationAntennaParams &txAntennaParams, Vector rxLoc, const MimoPolarizationAntennaParams &rxAntennaParams, std::valarray< std::complex< double >> testChannel, double tolerance)
Constructor that receives MIMO polarization parameters of TX and RX devices.
Vector m_txLoc
Position of the TX device.
Vector m_rxLoc
Position of the RX device.
Ptr< PhasedArrayModel > CreateAndConfigureAntenna(const MimoPolarizationAntennaParams &params)
Function that can be used to configure the antenna using the set of parameters.
MimoPolarizationAntennaParams m_txParams
Parameters used to configure the TX antenna array.
double m_tolerance
The tolerance to be used when comparing the channel matrix with the test matrix.
std::valarray< std::complex< double > > m_testChannel
The test value for the matrix representing the strongest cluster.
MimoPolarizationAntennaParams m_rxParams
Parameters used to configure the RX antenna array.
Test case for the ThreeGppSpectrumPropagationLossModelTest class.
ThreeGppSpectrumPropagationLossModelTest(uint32_t txAntennaElements=4, uint32_t rxAntennaElements=4, uint32_t txPorts=1, uint32_t rxPorts=1)
Constructor.
void DoRun() override
Build the test scenario.
uint32_t m_txPorts
number of horizontal and vertical ports of tx antenna array
uint32_t m_rxAntennaElements
number of rows and columns of rx antenna array
uint32_t m_rxPorts
number of horizontal and vertical ports of rx antenna array
void CheckLongTermUpdate(const CheckLongTermUpdateParams &params)
Test of the long term component is correctly updated when the channel matrix is recomputed.
void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< PhasedArrayModel > thisAntenna, Ptr< NetDevice > otherDevice, Ptr< PhasedArrayModel > otherAntenna)
Points the beam of thisDevice towards otherDevice.
uint32_t m_txAntennaElements
number of rows and columns of tx antenna array
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
MatrixArray class inherits ValArray class and provides additional interfaces to ValArray which enable...
Definition: matrix-array.h:83
Keep track of the current position and velocity of an object.
Vector GetPosition() const
void SetPosition(const Vector &position)
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
ComplexVector GetBeamformingVector() const
Returns the beamforming vector that is currently being used.
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
virtual size_t GetNumElems() const =0
Returns the number of antenna elements.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Implements Wifi SpectrumValue for the 2.4 GHz ISM band only, with a 5 MHz spectrum resolution.
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double txPower, uint8_t channel)
Creates a SpectrumValue instance that represents the TX Power Spectral Density of a wifi device corre...
Ptr< SpectrumValue > Copy() const
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Ptr< SpectrumSignalParameters > DoCalcRxPowerSpectralDensity(Ptr< const SpectrumSignalParameters > spectrumSignalParams, Ptr< const MobilityModel > a, Ptr< const MobilityModel > b, Ptr< const PhasedArrayModel > aPhasedArrayModel, Ptr< const PhasedArrayModel > bPhasedArrayModel) const override
Computes the received PSD.
void SetChannelModelAttribute(const std::string &name, const AttributeValue &value)
Sets the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:408
Hold an unsigned integer type.
Definition: uinteger.h:45
T * GetPagePtr(size_t pageIndex)
Get a data pointer to a specific 2D array for use in linear algebra libraries.
Definition: val-array.h:522
bool IsAlmostEqual(const ValArray< T > &rhs, T tol) const
Compare Valarray up to a given absolute tolerance.
Definition: val-array.h:684
size_t GetNumPages() const
Definition: val-array.h:393
size_t GetNumRows() const
Definition: val-array.h:379
size_t GetNumCols() const
Definition: val-array.h:386
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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 function CheckLongTermUpdate.
Ptr< ThreeGppSpectrumPropagationLossModel > lossModel
the ThreeGppSpectrumPropagationLossModel object used to compute the rx PSD
Ptr< MobilityModel > txMob
the mobility model of the tx device
Ptr< SpectrumValue > rxPsdOld
the previously received PSD
Ptr< SpectrumSignalParameters > txParams
the params of the tx signal
Ptr< PhasedArrayModel > rxAntenna
the antenna array of the rx device
Ptr< MobilityModel > rxMob
the mobility model of the rx device
Ptr< PhasedArrayModel > txAntenna
the antenna array of the tx device
Structure that contains some of the main configuration parameters of the antenna array that are used ...
uint32_t m_rows
the number of rows of antenna array
double m_bearingAngle
bearing angle of the antenna array
MimoPolarizationAntennaParams(bool isotropic, double polSlantAngle=0, double bearingAngle=0)
Constructor Currently only configurable through constructor are polSlantAngle and bearingAngle.
bool m_isotropic
defines whether the antenna elements are isotropic
uint32_t m_hPorts
the number of horizontal ports of antenna array
double m_polSlantAngle
polarization angle of the antenna array
uint32_t m_cols
the number of columns of antenna array
uint32_t m_vPorts
the number of vertical ports of antenna array
Complex3DVector m_channel
Channel matrix H[u][s][n].
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
static ThreeGppChannelTestSuite myTestSuite
Static variable for test initialization.