satellite-antenna-gain-pattern-container.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: Jani Puttonen <jani.puttonen@magister.fi>
19  */
20 
22 
24 
25 #include "ns3/log.h"
26 #include "ns3/satellite-env-variables.h"
27 #include "ns3/singleton.h"
28 #include "ns3/string.h"
29 
30 #include <cmath>
31 #include <cstddef>
32 #include <dirent.h>
33 #include <errno.h>
34 #include <fstream>
35 #include <limits>
36 #include <map>
37 #include <sstream>
38 #include <string.h>
39 #include <string>
40 #include <utility>
41 
42 NS_LOG_COMPONENT_DEFINE("SatAntennaGainPatternContainer");
43 
44 const std::string numbers{"0123456789"};
45 
46 namespace ns3
47 {
48 
49 NS_OBJECT_ENSURE_REGISTERED(SatAntennaGainPatternContainer);
50 
51 TypeId
53 {
54  static TypeId tid = TypeId("ns3::SatAntennaGainPatternContainer")
55  .SetParent<Object>()
56  .AddConstructor<SatAntennaGainPatternContainer>();
57  return tid;
58 }
59 
60 TypeId
62 {
63  NS_LOG_FUNCTION(this);
64  return GetTypeId();
65 }
66 
68 {
69  NS_LOG_FUNCTION(this);
70 
71  NS_FATAL_ERROR("Constructor not in use");
72 }
73 
75  std::string patternsFolder)
76 {
77  NS_LOG_FUNCTION(this << nbSats << patternsFolder);
78 
79  m_patternsFolder = patternsFolder;
80 
82 
83  NS_LOG_INFO(this << " directory for antenna patterns set to " << m_patternsFolder);
84 
85  if (!Singleton<SatEnvVariables>::Get()->IsValidDirectory(m_patternsFolder))
86  {
87  NS_FATAL_ERROR("SatAntennaGainPatternContainer::SatAntennaGainPatternContainer directory "
88  << m_patternsFolder << " not found in antennapatterns folder");
89  }
90 
91  DIR* dir;
92  struct dirent* ent;
93  std::string prefix;
94  if ((dir = opendir(m_patternsFolder.c_str())) != nullptr)
95  {
96  /* process all the files and directories within m_patternsFolder */
97  while ((ent = readdir(dir)) != nullptr)
98  {
99  std::string filename{ent->d_name};
100  std::size_t pathLength = filename.length();
101  if (pathLength > 4)
102  {
103  pathLength -= 4; // Size of .txt extention
104  if (filename.substr(pathLength) == ".txt")
105  {
106  std::string num, stem = filename.substr(0, pathLength);
107  std::size_t found = stem.find_last_not_of(numbers);
108  if (found == std::string::npos)
109  {
110  num = stem;
111  stem.erase(0);
112  }
113  else
114  {
115  num = stem.substr(found + 1);
116  stem.erase(found + 1);
117  }
118 
119  if (prefix.empty())
120  {
121  prefix = stem;
122  }
123 
124  if (prefix != stem)
125  {
126  NS_FATAL_ERROR(
127  "SatAntennaGainPatternContainer::SatAntennaGainPatternContainer mixing "
128  "different prefix for antenna pattern names: "
129  << prefix << " and " << stem);
130  }
131 
132  std::string filePath = m_patternsFolder + "/" + filename;
133  std::istringstream ss{num};
134  uint32_t beamId;
135  ss >> beamId;
136  if (ss.bad())
137  {
138  NS_FATAL_ERROR(
139  "SatAntennaGainPatternContainer::SatAntennaGainPatternContainer unable "
140  "to find beam number in "
141  << filePath << " file name");
142  }
143 
144  Ptr<SatAntennaGainPattern> gainPattern =
145  CreateObject<SatAntennaGainPattern>(filePath, geoPos);
146  std::pair<std::map<uint32_t, Ptr<SatAntennaGainPattern>>::iterator, bool> ret;
147  ret = m_antennaPatternMap.insert(std::make_pair(beamId, gainPattern));
148 
149  if (ret.second == false)
150  {
151  NS_FATAL_ERROR("SatAntennaGainPatternContainer::"
152  "SatAntennaGainPatternContainer an antenna pattern for beam "
153  << beamId << " already exists!");
154  }
155  }
156  }
157  }
158  closedir(dir);
159  }
160  else
161  {
162  /* could not open directory */
163  const char* error = strerror(errno);
164  NS_FATAL_ERROR("SatAntennaGainPatternContainer::SatAntennaGainPatternContainer unable to "
165  "open directory "
166  << m_patternsFolder << ": " << error);
167  }
168 }
169 
171 {
172  NS_LOG_FUNCTION(this);
173 }
174 
177 {
178  NS_LOG_FUNCTION(this);
179 
180  std::string geoPosFilename = m_patternsFolder + "/GeoPos.in";
181 
182  // READ FROM THE SPECIFIED INPUT FILE
183  std::ifstream* ifs = new std::ifstream(geoPosFilename, std::ifstream::in);
184 
185  if (!ifs->is_open())
186  {
187  NS_FATAL_ERROR("The file " << geoPosFilename << " is not found.");
188  }
189 
190  double lat, lon, alt;
191  *ifs >> lat >> lon >> alt;
192 
193  // Store the values
194  GeoCoordinate coord(lat, lon, alt);
195 
196  ifs->close();
197  delete ifs;
198 
199  return coord;
200 }
201 
202 Ptr<SatAntennaGainPattern>
204 {
205  NS_LOG_FUNCTION(this << beamId);
206 
207  std::map<uint32_t, Ptr<SatAntennaGainPattern>>::const_iterator agp =
208  m_antennaPatternMap.find(beamId);
209  if (agp == m_antennaPatternMap.end())
210  {
211  NS_FATAL_ERROR(
212  "SatAntennaGainPatternContainer::GetAntennaGainPattern - unvalid beam id: " << beamId);
213  }
214 
215  return agp->second;
216 }
217 
218 Ptr<SatMobilityModel>
220 {
221  NS_LOG_FUNCTION(this << satelliteId);
222 
223  std::map<uint32_t, Ptr<SatMobilityModel>>::const_iterator mm =
224  m_mobilityModelMap.find(satelliteId);
225  if (mm == m_mobilityModelMap.end())
226  {
227  NS_FATAL_ERROR(
228  "SatAntennaGainPatternContainer::GetAntennaGainPattern - unvalid satellite id: "
229  << satelliteId);
230  }
231 
232  return mm->second;
233 }
234 
235 uint32_t
237  GeoCoordinate coord,
238  bool ignoreNan)
239 {
240  NS_LOG_FUNCTION(this << satelliteId << coord.GetLatitude() << coord.GetLongitude()
241  << ignoreNan);
242 
243  double bestGain(-100.0);
244  uint32_t bestId(0);
245 
246  Ptr<SatMobilityModel> mobility = m_mobilityModelMap[satelliteId];
247 
248  for (const auto& entry : m_antennaPatternMap)
249  {
250  uint32_t i = entry.first;
251  double gain = entry.second->GetAntennaGain_lin(coord, mobility);
252 
253  // The antenna pattern has returned a NAN gain. This means
254  // that this position is not valid. Return 0, which is not a valid beam id.
255  if (std::isnan(gain))
256  {
257  if (ignoreNan)
258  {
259  NS_LOG_WARN("SatAntennaGainPatternContainer::GetBestBeamId - Beam "
260  << i << " returned a NAN antenna gain value!");
261  }
262  else
263  {
264  NS_FATAL_ERROR("SatAntennaGainPatternContainer::GetBestBeamId - Beam "
265  << i << " returned a NAN antenna gain value!");
266  }
267  }
268  else if (gain > bestGain)
269  {
270  bestGain = gain;
271  bestId = i;
272  }
273  }
274 
275  if (bestId == 0 && ignoreNan)
276  {
277  NS_LOG_WARN(
278  "SatAntennaGainPatternContainer::GetBestBeamId - did not find any good beam! The "
279  "ground station is probably too far from the satellite. Return 0 by default.");
280  }
281 
282  return bestId;
283 }
284 
285 double
287  uint32_t beamId,
288  GeoCoordinate coord)
289 {
290  NS_LOG_FUNCTION(this << satelliteId << beamId << coord.GetLatitude() << coord.GetLongitude());
291 
292  Ptr<SatMobilityModel> mobility = m_mobilityModelMap[satelliteId];
293 
294  if (m_antennaPatternMap.find(beamId) == m_antennaPatternMap.end())
295  {
296  return std::numeric_limits<double>::quiet_NaN();
297  }
298  Ptr<SatAntennaGainPattern> pattern = m_antennaPatternMap.at(beamId);
299 
300  return pattern->GetAntennaGain_lin(coord, mobility);
301 }
302 
303 uint32_t
305 {
306  NS_LOG_FUNCTION(this);
307 
308  // Note, that now we assume that all the antenna patterns are created
309  // regardless of how many beams are actually simulated.
310  return m_antennaPatternMap.size();
311 }
312 
313 void
315  Ptr<SatMobilityModel> mobility)
316 {
317  NS_LOG_FUNCTION(this << satelliteId << mobility);
318 
319  m_mobilityModelMap[satelliteId] = mobility;
320 }
321 
322 void
324 {
325  std::map<uint32_t, Ptr<SatAntennaGainPattern>>::iterator it = m_antennaPatternMap.begin();
326  while (it != m_antennaPatternMap.end())
327  {
328  uint32_t beamIdIterator = it->first;
329  BeamUserInfoMap_t::iterator infoIterator;
330  bool found = false;
331  for (infoIterator = info.begin(); infoIterator != info.end(); infoIterator++)
332  {
333  uint32_t beamId = infoIterator->first.second;
334  if (beamId == beamIdIterator)
335  {
336  found = true;
337  }
338  }
339  if (!found)
340  {
341  it = m_antennaPatternMap.erase(it);
342  }
343  else
344  {
345  it++;
346  }
347  }
348 }
349 
350 } // namespace ns3
GeoCoordinate class is used to store and operate with geodetic coordinates.
double GetLatitude() const
Gets latitude value of coordinate.
double GetLongitude() const
Gets longitude value of coordinate.
double GetBeamGain(uint32_t satelliteId, uint32_t beamId, GeoCoordinate coord)
Get beam gain for given coordinates.
Ptr< SatAntennaGainPattern > GetAntennaGainPattern(uint32_t beamId) const
Get the antenna pattern of a specified beam id.
GeoCoordinate GetDefaultGeoPosition()
Load the default satellite position associated to these traces.
uint32_t GetBestBeamId(uint32_t satelliteId, GeoCoordinate coord, bool ignoreNan)
Get the best beam id based on the antenna patterns in a specified geo coordinate.
std::map< uint32_t, Ptr< SatAntennaGainPattern > > m_antennaPatternMap
Container of antenna patterns.
uint32_t GetNAntennaGainPatterns() const
Get the number of stored antenna pattern.
std::map< std::pair< uint32_t, uint32_t >, SatBeamUserInfo > BeamUserInfoMap_t
definition for beam map key is pair sat ID / beam ID and value is UT/user info.
void ConfigureBeamsMobility(uint32_t satelliteId, Ptr< SatMobilityModel > mobility)
Ptr< SatMobilityModel > GetAntennaMobility(uint32_t satelliteId) const
Get the mobility model of a specified satellite id.
std::map< uint32_t, Ptr< SatMobilityModel > > m_mobilityModelMap
Container of mobility models.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
const std::string numbers