5G-LENA nr-v3.1-14-g738b08bc
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
beam-manager.cc
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "beam-manager.h"
6
7#include <ns3/boolean.h>
8#include <ns3/log.h>
9#include <ns3/node.h>
10#include <ns3/simulator.h>
11#include <ns3/uinteger.h>
12
13namespace ns3
14{
15
16NS_LOG_COMPONENT_DEFINE("BeamManager");
17NS_OBJECT_ENSURE_REGISTERED(BeamManager);
18
20{
21 // TODO Auto-generated constructor stub
22}
23
24void
25BeamManager::Configure(const Ptr<UniformPlanarArray>& antennaArray)
26{
27 m_antennaArray = antennaArray;
29}
30
31PhasedArrayModel::ComplexVector
33{
34 return v.first;
35}
36
39{
40 return v.second;
41}
42
43Ptr<const UniformPlanarArray>
45{
46 return m_antennaArray;
47}
48
50{
51 // TODO Auto-generated destructor stub
52}
53
54TypeId
56{
57 static TypeId tid =
58 TypeId("ns3::BeamManager").SetParent<Object>().AddConstructor<BeamManager>();
59 return tid;
60}
61
62void
63BeamManager::SetPredefinedBeam(PhasedArrayModel::ComplexVector predefinedBeam)
64{
65 NS_LOG_FUNCTION(this);
66 NS_ABORT_MSG_IF(predefinedBeam.GetSize() == 0, "Cannot assign an empty predefined beam");
67 NS_ABORT_MSG_IF(predefinedBeam.GetSize() != m_antennaArray->GetNumElems(),
68 "Cannot assign a predefined beamforming vector whose dimension is not "
69 "compatible with antenna array");
70 m_predefinedDirTxRxW = std::make_pair(predefinedBeam, PREDEFINED_BEAM_ID);
71}
72
73void
74BeamManager::SetPredefinedBeam(uint16_t sector, double elevation)
75{
76 NS_LOG_FUNCTION(this);
77 m_predefinedDirTxRxW = std::make_pair(CreateDirectionalBfv(m_antennaArray, sector, elevation),
78 BeamId(sector, elevation));
79}
80
81void
82BeamManager::SaveBeamformingVector(const BeamformingVector& bfv, const Ptr<const NetDevice>& device)
83{
84 NS_LOG_INFO("Save beamforming vector toward device with node id:"
85 << device->GetNode()->GetId() << " with BeamId:" << bfv.second);
86
87 if (m_predefinedDirTxRxW.first.GetSize() != 0)
88 {
89 NS_LOG_WARN("Saving beamforming vector for device, while there is also a predefined "
90 "beamforming vector defined to be used for all transmissions.");
91 }
92
93 if (device != nullptr)
94 {
95 BeamformingStorage::iterator iter = m_beamformingVectorMap.find(device);
96 if (iter != m_beamformingVectorMap.end())
97 {
98 (*iter).second = bfv;
99 }
100 else
101 {
102 m_beamformingVectorMap.insert(std::make_pair(device, bfv));
103 }
104 }
105}
106
107void
108BeamManager::ChangeBeamformingVector(const Ptr<const NetDevice>& device)
109{
110 NS_LOG_FUNCTION(this);
111
112 BeamformingStorage::iterator it = m_beamformingVectorMap.find(device);
113 if (it == m_beamformingVectorMap.end())
114 {
115 NS_LOG_INFO("Could not find the beamforming vector for the provided device");
116
117 // if there is no beam defined for this specific device then use a
118 // predefined beam if specified and if not, then use quasi omni
119 if (m_predefinedDirTxRxW.first.GetSize() != 0)
120 {
121 m_antennaArray->SetBeamformingVector(m_predefinedDirTxRxW.first);
122 }
123 else
124 {
126 }
127 }
128 else
129 {
130 NS_LOG_INFO("Beamforming vector found");
131 m_antennaArray->SetBeamformingVector(it->second.first);
132 }
133}
134
135PhasedArrayModel::ComplexVector
137{
138 return m_antennaArray->GetBeamformingVector();
139}
140
141void
143{
144 NS_LOG_FUNCTION(this);
145
146 UintegerValue numRows;
147 UintegerValue numColumns;
148 m_antennaArray->GetAttribute("NumRows", numRows);
149 m_antennaArray->GetAttribute("NumColumns", numColumns);
150
158 if (numRows.Get() != m_numRows || numColumns.Get() != m_numColumns ||
159 m_isPolDual != m_antennaArray->IsDualPol())
160 {
161 m_isPolDual = m_antennaArray->IsDualPol();
162 m_numPortElems = m_antennaArray->GetNumElemsPerPort();
163 m_numRows = numRows.Get();
164 m_numColumns = numColumns.Get();
165 m_omniTxRxW = std::make_pair(CreateQuasiOmniBfv(m_antennaArray), OMNI_BEAM_ID);
166 }
167
168 m_antennaArray->SetBeamformingVector(m_omniTxRxW.first);
169}
170
171PhasedArrayModel::ComplexVector
172BeamManager::GetBeamformingVector(const Ptr<NetDevice>& device) const
173{
174 NS_LOG_FUNCTION(this);
175 PhasedArrayModel::ComplexVector beamformingVector;
176 BeamformingStorage::const_iterator it = m_beamformingVectorMap.find(device);
177 if (it != m_beamformingVectorMap.end())
178 {
179 beamformingVector = it->second.first;
180 }
181 else
182 {
183 // it there is no specific beam saved for this device, check
184 // whether we have a predefined beam set, if yes return its vector
185 if (m_predefinedDirTxRxW.first.GetSize() != 0)
186 {
187 beamformingVector = m_predefinedDirTxRxW.first;
188 }
189 else
190 {
191 beamformingVector = m_antennaArray->GetBeamformingVector();
192 }
193 }
194 return beamformingVector;
195}
196
197BeamId
198BeamManager::GetBeamId(const Ptr<NetDevice>& device) const
199{
200 BeamId beamId;
201 BeamformingStorage::const_iterator it = m_beamformingVectorMap.find(device);
202 if (it != m_beamformingVectorMap.end())
203 {
204 beamId = it->second.second;
205 }
206 else
207 {
208 // it there is no specific beam saved for this device, check
209 // whether we have a predefined beam set, if yes return its ID
210 if (m_predefinedDirTxRxW.first.GetSize() != 0)
211 {
212 beamId = m_predefinedDirTxRxW.second;
213 }
214 else
215 {
216 beamId = OMNI_BEAM_ID;
217 }
218 }
219 return beamId;
220}
221
222void
223BeamManager::SetSector(uint16_t sector, double elevation) const
224{
225 NS_LOG_INFO("Set sector to : " << (unsigned)sector << ", and elevation to: " << elevation);
226 m_antennaArray->SetBeamformingVector(CreateDirectionalBfv(m_antennaArray, sector, elevation));
227}
228
229void
230BeamManager::SetSectorAz(double azimuth, double zenith) const
231{
232 NS_LOG_INFO("Set azimuth to : " << (unsigned)azimuth << ", and zenith to:" << zenith);
233 m_antennaArray->SetBeamformingVector(CreateDirectionalBfvAz(m_antennaArray, azimuth, zenith));
234}
235
236} /* namespace ns3 */
Representation of a beam id.
Definition beam-id.h:26
static TypeId GetTypeId()
GetTypeId.
BeamManager()
BeamManager constructor.
void SetSectorAz(double azimuth, double zenith) const
Set the Sector.
PhasedArrayModel::ComplexVector GetVector(const BeamformingVector &v) const
Get weight vector from a BeamformingVector.
virtual PhasedArrayModel::ComplexVector GetBeamformingVector(const Ptr< NetDevice > &device) const
Function that returns the beamforming vector weights that is used to communicated with a specified de...
virtual PhasedArrayModel::ComplexVector GetCurrentBeamformingVector()
Function that returns the beamforming vector that is currently being used by the antenna.
BeamId GetBeamId(const BeamformingVector &v) const
Extract the beam id from the beamforming vector specified.
virtual void ChangeToQuasiOmniBeamformingVector()
Change current beamforming vector to quasi-omni beamforming vector.
void Configure(const Ptr< UniformPlanarArray > &antennaArray)
Configures quasi-omni beamforming vector.
void SetSector(uint16_t sector, double elevation) const
Set the Sector.
Ptr< const UniformPlanarArray > GetAntenna() const
Get a pointer to the current antenna.
~BeamManager() override
~BeamManager
virtual void ChangeBeamformingVector(const Ptr< const NetDevice > &device)
Change the beamforming vector for tx/rx to/from specified device.
virtual void SaveBeamformingVector(const BeamformingVector &bfv, const Ptr< const NetDevice > &device)
Function that saves the beamforming weights of the antenna for transmission or reception to/from a sp...
const BeamId PREDEFINED_BEAM_ID
Reserved ID for the predefined directional beam if it cannot be expressed through sector and elevatio...
Definition beam-id.cc:10
std::pair< PhasedArrayModel::ComplexVector, BeamId > BeamformingVector
Physical representation of a beam.
PhasedArrayModel::ComplexVector CreateDirectionalBfvAz(const Ptr< const UniformPlanarArray > &antenna, double azimuth, double zenith)
Creates a beamforming vector for a given azimuth and zenith.
const BeamId OMNI_BEAM_ID
Name of the OMNI beam.
Definition beam-id.cc:9
PhasedArrayModel::ComplexVector CreateQuasiOmniBfv(const Ptr< const UniformPlanarArray > &antenna)
Create a quasi omni beamforming vector.
PhasedArrayModel::ComplexVector CreateDirectionalBfv(const Ptr< const UniformPlanarArray > &antenna, uint16_t sector, double elevation)
Creates a beamforming vector for a given sector and elevation.