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  m_numColumns {1},
37  m_numRows {1},
38  m_disV {0.5},
39  m_disH {0.5},
40  m_alpha {0},
41  m_beta {0}
42 {}
43 
45 {}
46 
47 TypeId
49 {
50  static TypeId tid = TypeId ("ns3::UniformPlanarArray")
52  .AddConstructor<UniformPlanarArray> ()
53  .SetGroupName ("Antenna")
54  .AddAttribute ("AntennaHorizontalSpacing",
55  "Horizontal spacing between antenna elements, in multiples of wave length",
56  DoubleValue (0.5),
59  MakeDoubleChecker<double> (0.0))
60  .AddAttribute ("AntennaVerticalSpacing",
61  "Vertical spacing between antenna elements, in multiples of wave length",
62  DoubleValue (0.5),
65  MakeDoubleChecker<double> (0.0))
66  .AddAttribute ("NumColumns",
67  "Horizontal size of the array",
68  UintegerValue (4),
71  MakeUintegerChecker<uint32_t> (1))
72  .AddAttribute ("NumRows",
73  "Vertical size of the array",
74  UintegerValue (4),
77  MakeUintegerChecker<uint32_t> (1))
78  .AddAttribute ("BearingAngle",
79  "The bearing angle in radians",
80  DoubleValue (0.0),
82  MakeDoubleChecker<double> (-M_PI, M_PI))
83  .AddAttribute ("DowntiltAngle",
84  "The downtilt angle in radians",
85  DoubleValue (0.0),
87  MakeDoubleChecker<double> (-M_PI, M_PI))
88  ;
89  return tid;
90 }
91 
92 
93 void
95 {
96  NS_LOG_FUNCTION (this << n);
97  if (n != m_numColumns)
98  {
99  m_isBfVectorValid = false;
100  }
101  m_numColumns = n;
102 }
103 
104 
105 uint32_t
107 {
108  return m_numColumns;
109 }
110 
111 
112 void
114 {
115  NS_LOG_FUNCTION (this << n);
116  if (n != m_numRows)
117  {
118  m_isBfVectorValid = false;
119  }
120  m_numRows = n;
121 }
122 
123 
124 uint32_t
126 {
127  return m_numRows;
128 }
129 
130 
131 void
133 {
134  NS_LOG_FUNCTION (this << s);
135  NS_ABORT_MSG_IF (s <= 0, "Trying to set an invalid spacing: " << s);
136 
137  if (s != m_disH)
138  {
139  m_isBfVectorValid = false;
140  }
141  m_disH = s;
142 }
143 
144 
145 double
147 {
148  return m_disH;
149 }
150 
151 
152 void
154 {
155  NS_LOG_FUNCTION (this << s);
156  NS_ABORT_MSG_IF (s <= 0, "Trying to set an invalid spacing: " << s);
157 
158  if (s != m_disV)
159  {
160  m_isBfVectorValid = false;
161  }
162  m_disV = s;
163 }
164 
165 
166 double
168 {
169  return m_disV;
170 }
171 
172 
173 std::pair<double, double>
175 {
176  NS_LOG_FUNCTION (this << a);
177 
178  // convert the theta and phi angles from GCS to LCS using eq. 7.1-7 and 7.1-8 in 3GPP TR 38.901
179  // NOTE we assume a fixed slant angle of 0 degrees
180  double thetaPrime = std::acos (cos (m_beta) * cos (a.GetInclination ()) + sin (m_beta) * cos (a.GetAzimuth () - m_alpha) * sin (a.GetInclination ()));
181  double phiPrime = std::arg (std::complex<double> (cos (m_beta) * sin (a.GetInclination ()) * cos (a.GetAzimuth () - m_alpha) - sin (m_beta) * cos (a.GetInclination ()), sin (a.GetAzimuth () - m_alpha) * sin (a.GetInclination ())));
182  Angles aPrime (phiPrime, thetaPrime);
183  NS_LOG_DEBUG (a << " -> " << aPrime);
184 
185  // compute the antenna element field pattern in the vertical polarization using
186  // eq. 7.3-4 in 3GPP TR 38.901
187  // NOTE we assume vertical polarization, hence the field pattern in the
188  // horizontal polarization is 0
189  double aPrimeDb = m_antennaElement->GetGainDb (aPrime);
190  double fieldThetaPrime = pow (10, aPrimeDb / 20); // convert to linear magnitude
191 
192  // compute psi using eq. 7.1-15 in 3GPP TR 38.901, assuming that the slant
193  // angle (gamma) is 0
194  double psi = std::arg (std::complex<double> (cos (m_beta) * sin (a.GetInclination ()) - sin (m_beta) * cos (a.GetInclination ()) * cos (a.GetAzimuth () - m_alpha), sin (m_beta) * sin (a.GetAzimuth () - m_alpha)));
195  NS_LOG_DEBUG ("psi " << psi);
196 
197  // convert the antenna element field pattern to GCS using eq. 7.1-11
198  // in 3GPP TR 38.901
199  double fieldTheta = cos (psi) * fieldThetaPrime;
200  double fieldPhi = sin (psi) * fieldThetaPrime;
201  NS_LOG_DEBUG (RadiansToDegrees (a.GetAzimuth ()) << " " << RadiansToDegrees (a.GetInclination ()) << " " << fieldTheta * fieldTheta + fieldPhi * fieldPhi);
202 
203  return std::make_pair (fieldPhi, fieldTheta);
204 }
205 
206 
207 Vector
209 {
210  NS_LOG_FUNCTION (this << index);
211 
212  // compute the element coordinates in the LCS
213  // assume the left bottom corner is (0,0,0), and the rectangular antenna array is on the y-z plane.
214  double xPrime = 0;
215  double yPrime = m_disH * (index % m_numColumns);
216  double zPrime = m_disV * floor (index / m_numColumns);
217 
218  // convert the coordinates to the GCS using the rotation matrix 7.1-4 in 3GPP
219  // TR 38.901
220  Vector loc;
221  loc.x = cos (m_alpha) * cos (m_beta) * xPrime - sin (m_alpha) * yPrime + cos (m_alpha) * sin (m_beta) * zPrime;
222  loc.y = sin (m_alpha) * cos (m_beta) * xPrime + cos (m_alpha) * yPrime + sin (m_alpha) * sin (m_beta) * zPrime;
223  loc.z = -sin (m_beta) * xPrime + cos (m_beta) * zPrime;
224  return loc;
225 }
226 
227 uint64_t
229 {
230  return m_numRows * m_numColumns;
231 }
232 
233 } /* namespace ns3 */
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetNumColumns(uint32_t n)
Set the number of columns of the phased array This method resets the stored beamforming vector to a C...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
bool m_isBfVectorValid
ensures the validity of the beamforming vector
double GetAntennaVerticalSpacing(void) const
Get the vertical spacing for the antenna elements of the phased array.
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Ptr< AntennaModel > m_antennaElement
the model of the antenna element in use
std::pair< double, double > GetElementFieldPattern(Angles a) const override
Returns the horizontal and vertical components of the antenna element field pattern at the specified ...
uint64_t GetNumberOfElements(void) const override
Returns the number of antenna elements.
double m_beta
the downtilt angle in radians
UniformPlanarArray(void)
Constructor.
uint32_t GetNumColumns(void) const
Get the number of columns of the phased array.
uint32_t m_numColumns
number of columns
Vector GetElementLocation(uint64_t index) const override
Returns the location of the antenna element with the specified index assuming the left bottom corner ...
void SetNumRows(uint32_t n)
Set the number of rows of the phased array This method resets the stored beamforming vector to a Comp...
static TypeId GetTypeId(void)
void SetAntennaHorizontalSpacing(double s)
Set the horizontal spacing for the antenna elements of the phased array This method resets the stored...
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:222
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual ~UniformPlanarArray(void)
Destructor.
uint32_t GetNumRows(void) const
Get the number of rows of the phased array.
double m_disH
antenna spacing in the horizontal direction in multiples of wave length
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_numRows
number of rows
Class implementing the phased array model virtual base class.
virtual double GetGainDb(Angles a)=0
this method is expected to be re-implemented by each antenna model
double GetAntennaHorizontalSpacing(void) const
Get the horizontal spacing for the antenna elements of the phased array.
double m_alpha
the bearing angle in radians
double RadiansToDegrees(double radians)
converts radians to degrees
Definition: angles.cc:45
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
#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_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
double m_disV
antenna spacing in the vertical direction in multiples of wave length
double GetInclination(void) const
Getter for inclination angle.
Definition: angles.cc:229
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
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
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void SetAntennaVerticalSpacing(double s)
Set the vertical spacing for the antenna elements of the phased array This method resets the stored b...