satellite-position-allocator.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd
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  * Author: Sami Rantanen <sami.rantanen@magister.fi>
19  * Author: Bastien Tauran <bastien.tauran@viveris.fr>
20  */
21 
23 
27 #include "satellite-utils.h"
28 
29 #include <ns3/boolean.h>
30 #include <ns3/double.h>
31 #include <ns3/enum.h>
32 #include <ns3/log.h>
33 #include <ns3/pointer.h>
34 #include <ns3/string.h>
35 #include <ns3/uinteger.h>
36 
37 #include <cmath>
38 #include <limits>
39 
40 NS_LOG_COMPONENT_DEFINE("SatPositionAllocator");
41 
42 namespace ns3
43 {
44 
45 NS_OBJECT_ENSURE_REGISTERED(SatPositionAllocator);
46 
47 TypeId
49 {
50  static TypeId tid =
51  TypeId("ns3::SatPositionAllocator")
52  .SetParent<PositionAllocator>()
53  .AddAttribute("AsGeoCoordinates",
54  "GetNext method returns geodetic coordinates in returned Vector, "
55  "x=longitude, y=latitude, z=altitude",
56  BooleanValue(true),
57  MakeBooleanAccessor(&SatPositionAllocator::m_GetAsGeoCoordinates),
58  MakeBooleanChecker());
59  return tid;
60 }
61 
63  : m_GetAsGeoCoordinates(true)
64 {
65 }
66 
68 {
69 }
70 
71 Vector
73 {
74  NS_LOG_INFO(this);
75 
77 
79  {
80  return Vector(pos.GetLatitude(), pos.GetLongitude(), pos.GetAltitude());
81  }
82  else
83  {
84  return pos.ToVector();
85  }
86 }
87 
88 int64_t
90 {
91  return 0;
92 }
93 
94 NS_OBJECT_ENSURE_REGISTERED(SatListPositionAllocator);
95 
96 TypeId
98 {
99  static TypeId tid = TypeId("ns3::SatListPositionAllocator")
100  .SetParent<SatPositionAllocator>()
101  .AddConstructor<SatListPositionAllocator>();
102  return tid;
103 }
104 
106 {
107 }
108 
109 void
111 {
112  NS_LOG_INFO(this << coordinate.GetLatitude() << coordinate.GetLongitude()
113  << coordinate.GetAltitude());
114 
115  m_positions.push_back(coordinate);
116  m_current = m_positions.begin();
117 }
118 
121 {
122  NS_LOG_INFO(this);
123 
124  GeoCoordinate coordinate = *m_current;
125  m_current++;
126 
127  if (m_current == m_positions.end())
128  {
129  m_current = m_positions.begin();
130  }
131  return coordinate;
132 }
133 
134 NS_OBJECT_ENSURE_REGISTERED(SatRandomBoxPositionAllocator);
135 
136 TypeId
138 {
139  static TypeId tid =
140  TypeId("ns3::SatRandomBoxPositionAllocator")
141  .SetParent<SatPositionAllocator>()
142  .SetGroupName("Mobility")
143  .AddConstructor<SatRandomBoxPositionAllocator>()
144  .AddAttribute("Longitude",
145  "A random variable which represents the longitude coordinate of a "
146  "position in a random rectangle.",
147  StringValue("ns3::UniformRandomVariable[Min=-180.0|Max=180.0]"),
148  MakePointerAccessor(&SatRandomBoxPositionAllocator::m_longitude),
149  MakePointerChecker<RandomVariableStream>())
150  .AddAttribute("Latitude",
151  "A random variable which represents the latitude coordinate of a "
152  "position in a random rectangle.",
153  StringValue("ns3::UniformRandomVariable[Min=-90.0|Max=90.0]"),
154  MakePointerAccessor(&SatRandomBoxPositionAllocator::m_latitude),
155  MakePointerChecker<RandomVariableStream>())
156  .AddAttribute("Altitude",
157  "A random variable which represents the altitude coordinate of a "
158  "position in a random box.",
159  StringValue("ns3::UniformRandomVariable[Min=0.0]"),
160  MakePointerAccessor(&SatRandomBoxPositionAllocator::m_altitude),
161  MakePointerChecker<RandomVariableStream>());
162  return tid;
163 }
164 
166 {
167 }
168 
170 {
171 }
172 
173 void
174 SatRandomBoxPositionAllocator::SetLongitude(Ptr<RandomVariableStream> longitude)
175 {
176  NS_LOG_INFO(this);
177 
178  m_longitude = longitude;
179 }
180 
181 void
182 SatRandomBoxPositionAllocator::SetLatitude(Ptr<RandomVariableStream> latitude)
183 {
184  NS_LOG_INFO(this);
185 
186  m_latitude = latitude;
187 }
188 
189 void
190 SatRandomBoxPositionAllocator::SetAltitude(Ptr<RandomVariableStream> altitude)
191 {
192  NS_LOG_INFO(this);
193 
194  m_altitude = altitude;
195 }
196 
199 {
200  NS_LOG_INFO(this);
201  double longitude = m_longitude->GetValue();
202  double latitude = m_latitude->GetValue();
203  double altitude = m_altitude->GetValue();
204 
205  return GeoCoordinate(latitude, longitude, altitude);
206 }
207 
208 int64_t
210 {
211  m_longitude->SetStream(stream);
212  m_latitude->SetStream(stream + 1);
213  m_altitude->SetStream(stream + 2);
214  return 3;
215 }
216 
217 NS_OBJECT_ENSURE_REGISTERED(SatRandomCirclePositionAllocator);
218 
219 TypeId
221 {
222  static TypeId tid = TypeId("ns3::SatRandomCirclePositionAllocator")
223  .SetParent<SatPositionAllocator>()
224  .SetGroupName("Mobility")
225  .AddConstructor<SatRandomCirclePositionAllocator>();
226  return tid;
227 }
228 
230 {
231  m_rand = CreateObject<UniformRandomVariable>();
232 }
233 
235  uint32_t radius)
236  : m_center(center),
237  m_radius(radius)
238 {
239  m_rand = CreateObject<UniformRandomVariable>();
240 }
241 
243 {
244 }
245 
246 void
248 {
249  NS_LOG_INFO(this);
250 
251  m_center = center;
252 }
253 
254 void
256 {
257  NS_LOG_INFO(this);
258 
259  m_radius = radius;
260 }
261 
264 {
265  NS_LOG_INFO(this);
266 
267  double radius = m_radius * sqrt(m_rand->GetValue());
268  double theta = m_rand->GetValue() * 2 * M_PI;
269 
270  double latitude = m_center.GetLatitude() * M_PI / 180;
271  double longitude = m_center.GetLongitude() * M_PI / 180;
272  double altitude = m_center.GetAltitude();
273 
274  double radiusNormalized = radius / GeoCoordinate::polarRadius_sphere;
275 
276  double lat2 = asin(sin(latitude) * cos(radiusNormalized) +
277  cos(latitude) * sin(radiusNormalized) * cos(theta));
278  double lon2 = longitude + atan2(sin(theta) * sin(radiusNormalized) * cos(latitude),
279  cos(radiusNormalized) - sin(latitude) * sin(lat2));
280 
281  GeoCoordinate position = GeoCoordinate((180 / M_PI) * lat2, (180 / M_PI) * lon2, altitude);
282 
283  return position;
284 }
285 
286 int64_t
288 {
289  m_rand->SetStream(stream);
290  return 1;
291 }
292 
293 NS_OBJECT_ENSURE_REGISTERED(SatSpotBeamPositionAllocator);
294 
295 TypeId
297 {
298  static TypeId tid =
299  TypeId("ns3::SatSpotBeamPositionAllocator")
300  .SetParent<SatPositionAllocator>()
301  .SetGroupName("Mobility")
302  .AddConstructor<SatSpotBeamPositionAllocator>()
303  .AddAttribute("Altitude",
304  "A random variable which represents the altitude coordinate of a "
305  "position in a random box.",
306  StringValue("ns3::UniformRandomVariable[Min=0.0]"),
307  MakePointerAccessor(&SatSpotBeamPositionAllocator::m_altitude),
308  MakePointerChecker<RandomVariableStream>())
309  .AddAttribute(
310  "MinElevationAngleInDegForUT",
311  "Minimum accepted elevation angle in degrees for UTs",
312  DoubleValue(5.00),
314  MakeDoubleChecker<double>());
315  return tid;
316 }
317 
319  : m_targetBeamId(0),
320  m_minElevationAngleInDeg(1)
321 {
322 }
323 
325  uint32_t beamId,
326  Ptr<SatAntennaGainPatternContainer> patterns,
327  GeoCoordinate geoPos)
328  : m_targetBeamId(beamId),
329  m_minElevationAngleInDeg(1),
330  m_antennaGainPatterns(patterns),
331  m_geoPos(geoPos)
332 {
333 }
334 
336 {
337 }
338 
339 void
340 SatSpotBeamPositionAllocator::SetAltitude(Ptr<RandomVariableStream> altitude)
341 {
342  NS_LOG_FUNCTION(this);
343 
344  m_altitude = altitude;
345 }
346 
349 {
350  NS_LOG_FUNCTION(this);
351 
352  uint32_t bestBeamId(std::numeric_limits<uint32_t>::max());
353  Ptr<SatAntennaGainPattern> agp = m_antennaGainPatterns->GetAntennaGainPattern(m_targetBeamId);
354  Ptr<SatMobilityModel> mobility = m_antennaGainPatterns->GetAntennaMobility(satId);
355  uint32_t tries(0);
356  GeoCoordinate pos;
357 
358  Ptr<SatConstantPositionMobilityModel> utMob = CreateObject<SatConstantPositionMobilityModel>();
359  Ptr<SatConstantPositionMobilityModel> geoMob = CreateObject<SatConstantPositionMobilityModel>();
360  utMob->SetGeoPosition(GeoCoordinate(0.00, 0.00, 0.00));
361  geoMob->SetGeoPosition(m_geoPos);
362  Ptr<SatMobilityObserver> utObserver = CreateObject<SatMobilityObserver>(utMob, geoMob);
363 
364  double elevation(std::numeric_limits<double>::max());
365 
366  // Try until
367  // - we have a valid position
368  // - the MAX_TRIES have been exceeded
369  // - elevation is NOT NaN
370  // - elevation is not higher than threshold
371  while ((bestBeamId == 0 || bestBeamId != m_targetBeamId || std::isnan(elevation) ||
372  elevation < m_minElevationAngleInDeg) &&
373  tries < MAX_TRIES)
374  {
375  pos = agp->GetValidRandomPosition(mobility);
376  bestBeamId = m_antennaGainPatterns->GetBestBeamId(satId, pos, true);
377 
378  // Set the new position to the UT mobility
379  utMob->SetGeoPosition(pos);
380 
381  // Calculate the elevation angle
382  elevation = utObserver->GetElevationAngle();
383 
384  ++tries;
385  }
386 
387  // If the positioning fails
388  if (tries >= MAX_TRIES)
389  {
390  NS_FATAL_ERROR(this << " max number of tries for spot-beam allocation exceeded!");
391  }
392 
393  // Set a random altitude
394  pos.SetAltitude(m_altitude->GetValue());
395 
396  if (pos.GetLatitude() < -90.0 || pos.GetLatitude() > 90.0 || pos.GetLongitude() < -180.0 ||
397  pos.GetLongitude() > 180.0 || elevation < m_minElevationAngleInDeg || elevation > 90.0)
398  {
399  NS_FATAL_ERROR(
400  "SatSpotBeamPositionAllocator::GetNextGeoPosition - unvalid selected position!");
401  }
402 
403  return pos;
404 }
405 
406 int64_t
408 {
409  NS_LOG_FUNCTION(this);
410 
411  m_altitude->SetStream(stream + 2);
412  return 3;
413 }
414 
415 } // namespace ns3
GeoCoordinate class is used to store and operate with geodetic coordinates.
void SetAltitude(double altitude)
Sets altitude value of coordinate.
double GetAltitude() const
Gets altitude value of coordinate.
double GetLatitude() const
Gets latitude value of coordinate.
double GetLongitude() const
Gets longitude value of coordinate.
Vector ToVector() const
Converts Geodetic coordinates to Cartesian coordinates.
static constexpr double polarRadius_sphere
Allocate positions from a deterministic list specified by the user.
void Add(GeoCoordinate coordinate)
std::vector< GeoCoordinate > m_positions
static TypeId GetTypeId(void)
Get the type ID.
virtual GeoCoordinate GetNextGeoPosition(uint32_t satId=0) const
Get next position.
std::vector< GeoCoordinate >::const_iterator m_current
Allocate a set of satellite positions.
virtual Vector GetNext(void) const
SatPositionAllocator()
Default constructor.
static TypeId GetTypeId(void)
Get the type ID.
virtual ~SatPositionAllocator()
Destructor for SatPositionAllocator.
virtual GeoCoordinate GetNextGeoPosition(uint32_t satId=0) const =0
Get next position.
virtual int64_t AssignStreams(int64_t stream)
Allocate random positions within a 3D box according to a set of three random variables (longitude,...
virtual ~SatRandomBoxPositionAllocator()
Destructor for SatRandomBoxPositionAllocator.
virtual int64_t AssignStreams(int64_t stream)
void SetLongitude(Ptr< RandomVariableStream > longitude)
virtual GeoCoordinate GetNextGeoPosition(uint32_t satId=0) const
Get next position.
void SetAltitude(Ptr< RandomVariableStream > altitude)
static TypeId GetTypeId(void)
Get the type ID.
void SetLatitude(Ptr< RandomVariableStream > latitude)
Allocate random positions within a circle (center and radius), uniformly distributed.
virtual ~SatRandomCirclePositionAllocator()
Destructor for SatRandomCirclePositionAllocator.
virtual GeoCoordinate GetNextGeoPosition(uint32_t satId=0) const
Get next position.
static TypeId GetTypeId(void)
Get the type ID.
Allocate random positions within the area of a certain spot-beam.
GeoCoordinate m_geoPos
Position of the GEO satellite.
Ptr< RandomVariableStream > m_altitude
A random variable stream for altitude.
virtual int64_t AssignStreams(int64_t stream)
static constexpr uint32_t MAX_TRIES
Max number of tries to pick a random position for a UT.
void SetAltitude(Ptr< RandomVariableStream > altitude)
virtual ~SatSpotBeamPositionAllocator()
Destructor for SatSpotBeamPositionAllocator.
Ptr< SatAntennaGainPatternContainer > m_antennaGainPatterns
Antenna pattern used to check that the give position is valid based on antenna gains.
virtual GeoCoordinate GetNextGeoPosition(uint32_t satId) const
Get next position.
uint32_t m_targetBeamId
Target beam id to which the UT is tried to be placed.
double m_minElevationAngleInDeg
Minimum accepted elevation angle in degrees for UTs.
static TypeId GetTypeId(void)
Get the type ID.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.