5#include "beamforming-vector.h"
8#include "ns3/uinteger.h"
13PhasedArrayModel::ComplexVector
16 auto antennaRows = antenna->GetNumRows();
17 auto antennaColumns = antenna->GetNumColumns();
18 auto numElemsPerPort = antenna->GetNumElemsPerPort();
20 double power = 1 / sqrt(numElemsPerPort);
21 size_t numPolarizations = antenna->IsDualPol() ? 2 : 1;
23 PhasedArrayModel::ComplexVector omni(antennaRows * antennaColumns * numPolarizations);
25 for (
size_t pol = 0; pol < numPolarizations; pol++)
27 for (uint32_t ind = 0; ind < antennaRows; ind++)
29 std::complex<double> c = 0.0;
30 if (antennaRows % 2 == 0)
32 c = exp(std::complex<double>(0, M_PI * ind * ind / antennaRows));
36 c = exp(std::complex<double>(0, M_PI * ind * (ind + 1) / antennaRows));
38 for (uint32_t ind2 = 0; ind2 < antennaColumns; ind2++)
40 std::complex<double> d = 0.0;
41 if (antennaColumns % 2 == 0)
43 d = exp(std::complex<double>(0, M_PI * ind2 * ind2 / antennaColumns));
47 d = exp(std::complex<double>(0, M_PI * ind2 * (ind2 + 1) / antennaColumns));
49 omni[bfIndex] = (c * d * power);
57PhasedArrayModel::ComplexVector
60 UintegerValue uintValueNumColumns;
61 antenna->GetAttribute(
"NumColumns", uintValueNumColumns);
63 double hAngle_radian =
64 M_PI * (sector /
static_cast<double>(uintValueNumColumns.Get())) - 0.5 * M_PI;
65 double vAngle_radian = elevation * M_PI / 180;
66 uint16_t size = antenna->GetNumElems();
67 PhasedArrayModel::ComplexVector tempVector(size);
68 auto numAnalogBeamElements = (antenna->GetVElemsPerPort() * antenna->GetHElemsPerPort());
69 auto power = 1.0 / sqrt(numAnalogBeamElements);
70 for (
auto ind = 0; ind < size; ind++)
72 Vector loc = antenna->GetElementLocation(ind);
75 (sin(vAngle_radian) * cos(hAngle_radian) * loc.x +
76 sin(vAngle_radian) * sin(hAngle_radian) * loc.y + cos(vAngle_radian) * loc.z);
77 tempVector[ind] = (exp(std::complex<double>(0, phase)) * power);
82PhasedArrayModel::ComplexVector
85 UintegerValue uintValueNumColumns;
86 antenna->GetAttribute(
"NumColumns", uintValueNumColumns);
88 double hAngle_radian = azimuth * M_PI / 180;
89 double vAngle_radian = zenith * M_PI / 180;
90 uint16_t size = antenna->GetNumElems();
91 double power = 1 / sqrt(size);
92 PhasedArrayModel::ComplexVector tempVector(size);
95 tempVector[0] = power;
99 for (
auto ind = 0; ind < size; ind++)
101 Vector loc = antenna->GetElementLocation(ind);
104 (sin(vAngle_radian) * cos(hAngle_radian) * loc.x +
105 sin(vAngle_radian) * sin(hAngle_radian) * loc.y + cos(vAngle_radian) * loc.z);
106 tempVector[ind] = exp(std::complex<double>(0, phase)) * power;
112PhasedArrayModel::ComplexVector
113CreateDirectPathBfv(
const Ptr<MobilityModel>& a,
114 const Ptr<MobilityModel>& b,
115 const Ptr<const UniformPlanarArray>& antenna)
118 Vector aPos = a->GetPosition();
119 Vector bPos = b->GetPosition();
122 Angles completeAngle(bPos, aPos);
124 double hAngleRadian = completeAngle.GetAzimuth();
126 double vAngleRadian = completeAngle.GetInclination();
129 int totNoArrayElements = antenna->GetNumElems();
130 auto numElemsPerPort = antenna->GetNumElemsPerPort();
133 double power = 1 / sqrt(numElemsPerPort);
135 PhasedArrayModel::ComplexVector antennaWeights(totNoArrayElements);
137 for (
int ind = 0; ind < totNoArrayElements; ind++)
139 Vector loc = antenna->GetElementLocation(ind);
140 double phase = -2 * M_PI *
141 (sin(vAngleRadian) * cos(hAngleRadian) * loc.x +
142 sin(vAngleRadian) * sin(hAngleRadian) * loc.y + cos(vAngleRadian) * loc.z);
143 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
146 return antennaWeights;
149PhasedArrayModel::ComplexVector
150CreateKroneckerBfv(
const Ptr<const UniformPlanarArray>& antenna,
double rowAngle,
double colAngle)
153 PhasedArrayModel::ComplexVector bfVector(antenna->GetNumElems());
155 -2.0 * M_PI * antenna->GetAntennaVerticalSpacing() * cos(rowAngle * M_PI / 180.0);
157 -2.0 * M_PI * antenna->GetAntennaHorizontalSpacing() * cos(colAngle * M_PI / 180.0);
159 auto numAnalogBeamElements = antenna->GetVElemsPerPort() * antenna->GetHElemsPerPort();
162 auto normalizer = 1.0 / sqrt(numAnalogBeamElements);
164 auto numCols = antenna->GetNumColumns();
165 auto numRows = antenna->GetNumRows();
168 for (
auto elIdx =
size_t{0}; elIdx < antenna->GetNumElems(); elIdx++)
170 auto colIdx = elIdx % numCols;
171 auto rowIdx = elIdx / numCols;
172 auto isSkippedCol = (colIdx >= antenna->GetHElemsPerPort());
173 auto isSkippedRow = (rowIdx >= antenna->GetVElemsPerPort());
174 if (isSkippedCol || isSkippedRow || (elIdx >= numRows * numCols))
176 bfVector[elIdx] = 0.0;
179 auto combPhase = rowIdx * vPhasePerEl + colIdx * hPhasePerEl;
180 bfVector[elIdx] = normalizer * std::complex<double>(cos(combPhase), sin(combPhase));
PhasedArrayModel::ComplexVector CreateDirectionalBfvAz(const Ptr< const UniformPlanarArray > &antenna, double azimuth, double zenith)
Creates a beamforming vector for a given azimuth and zenith.
PhasedArrayModel::ComplexVector CreateDirectionalBfv(const Ptr< const UniformPlanarArray > &antenna, double sector, double elevation)
Creates a beamforming vector for a given sector and elevation.
PhasedArrayModel::ComplexVector CreateQuasiOmniBfv(const Ptr< const UniformPlanarArray > &antenna)
Create a quasi omni beamforming vector.