A Discrete-Event Network Simulator
API
uniform-planar-array.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2020 University of Padova, Dep. of Information Engineering, SIGNET lab.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 
20 #include "uniform-planar-array.h"
21 #include <ns3/log.h>
22 #include <ns3/double.h>
23 #include <ns3/uinteger.h>
24 #include <ns3/boolean.h>
25 
26 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("UniformPlanarArray");
29 
30 NS_OBJECT_ENSURE_REGISTERED (UniformPlanarArray);
31 
32 
33 
35  : PhasedArrayModel ()
36 {}
37 
39 {}
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::UniformPlanarArray")
46  .AddConstructor<UniformPlanarArray> ()
47  .SetGroupName ("Antenna")
48  .AddAttribute ("AntennaHorizontalSpacing",
49  "Horizontal spacing between antenna elements, in multiples of wave length",
50  DoubleValue (0.5),
53  MakeDoubleChecker<double> (0.0))
54  .AddAttribute ("AntennaVerticalSpacing",
55  "Vertical spacing between antenna elements, in multiples of wave length",
56  DoubleValue (0.5),
59  MakeDoubleChecker<double> (0.0))
60  .AddAttribute ("NumColumns",
61  "Horizontal size of the array",
62  UintegerValue (4),
65  MakeUintegerChecker<uint32_t> (1))
66  .AddAttribute ("NumRows",
67  "Vertical size of the array",
68  UintegerValue (4),
71  MakeUintegerChecker<uint32_t> (1))
72  .AddAttribute ("BearingAngle",
73  "The bearing angle in radians",
74  DoubleValue (0.0),
76  MakeDoubleChecker<double> (-M_PI, M_PI))
77  .AddAttribute ("DowntiltAngle",
78  "The downtilt angle in radians",
79  DoubleValue (0.0),
81  MakeDoubleChecker<double> (-M_PI, M_PI))
82  .AddAttribute ("PolSlantAngle",
83  "The polarization slant angle in radians",
84  DoubleValue (0.0),
86  MakeDoubleChecker<double> (-M_PI, M_PI))
87  ;
88  return tid;
89 }
90 
91 
92 void
94 {
95  NS_LOG_FUNCTION (this << n);
96  if (n != m_numColumns)
97  {
98  m_isBfVectorValid = false;
99  }
100  m_numColumns = n;
101 }
102 
103 
104 uint32_t
106 {
107  return m_numColumns;
108 }
109 
110 
111 void
113 {
114  NS_LOG_FUNCTION (this << n);
115  if (n != m_numRows)
116  {
117  m_isBfVectorValid = false;
118  }
119  m_numRows = n;
120 }
121 
122 
123 uint32_t
125 {
126  return m_numRows;
127 }
128 
129 void
131 {
132  m_alpha = alpha;
133  m_cosAlpha = cos (m_alpha);
134  m_sinAlpha = sin (m_alpha);
135 }
136 
137 void
139 {
140  m_beta = beta;
141  m_cosBeta = cos (m_beta);
142  m_sinBeta = sin (m_beta);
143 }
144 
145 void
147 {
148  m_polSlant = polSlant;
149  m_cosPolSlant = cos (m_polSlant);
150  m_sinPolSlant = sin (m_polSlant);
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << s);
157  NS_ABORT_MSG_IF (s <= 0, "Trying to set an invalid spacing: " << s);
158 
159  if (s != m_disH)
160  {
161  m_isBfVectorValid = false;
162  }
163  m_disH = s;
164 }
165 
166 
167 double
169 {
170  return m_disH;
171 }
172 
173 
174 void
176 {
177  NS_LOG_FUNCTION (this << s);
178  NS_ABORT_MSG_IF (s <= 0, "Trying to set an invalid spacing: " << s);
179 
180  if (s != m_disV)
181  {
182  m_isBfVectorValid = false;
183  }
184  m_disV = s;
185 }
186 
187 
188 double
190 {
191  return m_disV;
192 }
193 
194 
195 std::pair<double, double>
197 {
198  NS_LOG_FUNCTION (this << a);
199 
200  // convert the theta and phi angles from GCS to LCS using eq. 7.1-7 and 7.1-8 in 3GPP TR 38.901
201  // NOTE we assume a fixed slant angle of 0 degrees
202  double cosIncl = cos (a.GetInclination ());
203  double sinIncl = sin (a.GetInclination ());
204  double cosAzim = cos (a.GetAzimuth () - m_alpha);
205  double sinAzim = sin (a.GetAzimuth () - m_alpha);
206  double thetaPrime = std::acos (m_cosBeta * cosIncl + m_sinBeta * cosAzim * sinIncl);
207  double phiPrime = std::arg (std::complex<double> (m_cosBeta * sinIncl * cosAzim - m_sinBeta * cosIncl, sinAzim * sinIncl));
208  Angles aPrime (phiPrime, thetaPrime);
209  NS_LOG_DEBUG (a << " -> " << aPrime);
210 
211  // compute the antenna element field patterns using eq. 7.3-4 and 7.3-5 in 3GPP TR 38.901,
212  // using the configured polarization slant angle (m_polSlant)
213  // NOTE: the slant angle (assumed to be 0) differs from the polarization slant angle
214  // (m_polSlant, given by the attribute), in 3GPP TR 38.901
215  double aPrimeDb = m_antennaElement->GetGainDb (aPrime);
216  double fieldThetaPrime = pow (10, aPrimeDb / 20) * m_cosPolSlant; // convert to linear magnitude
217  double fieldPhiPrime = pow (10, aPrimeDb / 20) * m_sinPolSlant; // convert to linear magnitude
218 
219  // compute psi using eq. 7.1-15 in 3GPP TR 38.901, assuming that the slant
220  // angle (gamma) is 0
221  double psi = std::arg (std::complex<double> (m_cosBeta * sinIncl - m_sinBeta * cosIncl * cosAzim, m_sinBeta * sinAzim));
222  NS_LOG_DEBUG ("psi " << psi);
223 
224  // convert the antenna element field pattern to GCS using eq. 7.1-11
225  // in 3GPP TR 38.901
226  double fieldTheta = cos (psi) * fieldThetaPrime - sin (psi) * fieldPhiPrime;
227  double fieldPhi = sin (psi) * fieldThetaPrime + cos (psi) * fieldPhiPrime;
228  NS_LOG_DEBUG (RadiansToDegrees (a.GetAzimuth ()) << " " << RadiansToDegrees (a.GetInclination ()) << " " << fieldTheta * fieldTheta + fieldPhi * fieldPhi);
229 
230  return std::make_pair (fieldPhi, fieldTheta);
231 }
232 
233 
234 Vector
236 {
237  NS_LOG_FUNCTION (this << index);
238 
239  // compute the element coordinates in the LCS
240  // assume the left bottom corner is (0,0,0), and the rectangular antenna array is on the y-z plane.
241  double xPrime = 0;
242  double yPrime = m_disH * (index % m_numColumns);
243  double zPrime = m_disV * floor (index / m_numColumns);
244 
245  // convert the coordinates to the GCS using the rotation matrix 7.1-4 in 3GPP
246  // TR 38.901
247  Vector loc;
248  loc.x = m_cosAlpha * m_cosBeta * xPrime - m_sinAlpha * yPrime + m_cosAlpha * m_sinBeta * zPrime;
249  loc.y = m_sinAlpha * m_cosBeta * xPrime + m_cosAlpha * yPrime + m_sinAlpha * m_sinBeta * zPrime;
250  loc.z = -m_sinBeta * xPrime + m_cosBeta * zPrime;
251  return loc;
252 }
253 
254 uint64_t
256 {
257  return m_numRows * m_numColumns;
258 }
259 
260 } /* namespace ns3 */
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:119
double GetInclination(void) const
Getter for inclination angle.
Definition: angles.cc:231
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:224
virtual double GetGainDb(Angles a)=0
this method is expected to be re-implemented by each antenna model
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Class implementing the phased array model virtual base class.
Ptr< AntennaModel > m_antennaElement
the model of the antenna element in use
bool m_isBfVectorValid
ensures the validity of the beamforming vector
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
double m_cosPolSlant
the cosine of polarization slant angle
double m_disV
antenna spacing in the vertical direction in multiples of wave length
double m_sinAlpha
the sine of alpha
void SetPolSlant(double polSlant)
Set the polarization slant angle This method sets the polarization slant angle and computes its cosin...
double m_disH
antenna spacing in the horizontal direction in multiples of wave length
void SetBeta(double beta)
Set the downtilt angle This method sets the downtilt angle and computes its cosine and sine.
double m_sinPolSlant
the sine polarization slant angle
void SetAlpha(double alpha)
Set the bearing angle This method sets the bearing angle and computes its cosine and sine.
std::pair< double, double > GetElementFieldPattern(Angles a) const override
Returns the horizontal and vertical components of the antenna element field pattern at the specified ...
double m_polSlant
the polarization slant angle in radians
static TypeId GetTypeId(void)
Get the type ID.
double m_cosBeta
the cosine of Beta
void SetAntennaVerticalSpacing(double s)
Set the vertical spacing for the antenna elements of the phased array This method resets the stored b...
void SetNumRows(uint32_t n)
Set the number of rows of the phased array This method resets the stored beamforming vector to a Comp...
uint32_t m_numRows
number of rows
Vector GetElementLocation(uint64_t index) const override
Returns the location of the antenna element with the specified index assuming the left bottom corner ...
uint32_t m_numColumns
number of columns
double m_alpha
the bearing angle in radians
double GetAntennaVerticalSpacing(void) const
Get the vertical spacing for the antenna elements of the phased array.
virtual ~UniformPlanarArray(void)
Destructor.
double GetAntennaHorizontalSpacing(void) const
Get the horizontal spacing for the antenna elements of the phased array.
void SetNumColumns(uint32_t n)
Set the number of columns of the phased array This method resets the stored beamforming vector to a C...
double m_sinBeta
the sine of Beta
uint32_t GetNumRows(void) const
Get the number of rows of the phased array.
void SetAntennaHorizontalSpacing(double s)
Set the horizontal spacing for the antenna elements of the phased array This method resets the stored...
double m_beta
the downtilt angle in radians
double m_cosAlpha
the cosine of alpha
uint32_t GetNumColumns(void) const
Get the number of columns of the phased array.
UniformPlanarArray(void)
Constructor.
uint64_t GetNumberOfElements(void) const override
Returns the number of antenna elements.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:42
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double RadiansToDegrees(double radians)
converts radians to degrees
Definition: angles.cc:47
float alpha
Plot alpha value (transparency)