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 <dirent.h>
31 #include <errno.h>
32 #include <fstream>
33 #include <sstream>
34 #include <string.h>
35 
36 NS_LOG_COMPONENT_DEFINE("SatAntennaGainPatternContainer");
37 
38 const std::string numbers{"0123456789"};
39 
40 namespace ns3
41 {
42 
43 NS_OBJECT_ENSURE_REGISTERED(SatAntennaGainPatternContainer);
44 
45 TypeId
47 {
48  static TypeId tid =
49  TypeId("ns3::SatAntennaGainPatternContainer")
50  .SetParent<Object>()
51  .AddConstructor<SatAntennaGainPatternContainer>()
52  .AddAttribute(
53  "PatternsFolder",
54  "Sub-folder in 'antennapatterns' containing the gains definition for each beam",
55  StringValue("SatAntennaGain72Beams"),
57  MakeStringChecker());
58  return tid;
59 }
60 
61 TypeId
63 {
64  NS_LOG_FUNCTION(this);
65  return GetTypeId();
66 }
67 
69 {
70  NS_LOG_FUNCTION(this);
71 
72  ObjectBase::ConstructSelf(AttributeConstructionList());
73 
74  std::string dataPath{Singleton<SatEnvVariables>::Get()->LocateDataDirectory()};
75  std::string patternsFolder = dataPath + "/antennapatterns/" + m_patternsFolder;
76 
78 
79  NS_LOG_INFO(this << " directory for antenna patterns set to " << patternsFolder);
80 
81  if (!Singleton<SatEnvVariables>::Get()->IsValidDirectory(patternsFolder))
82  {
83  NS_FATAL_ERROR("SatAntennaGainPatternContainer::SatAntennaGainPatternContainer directory "
84  << m_patternsFolder << " not found in antennapatterns folder");
85  }
86 
87  DIR* dir;
88  struct dirent* ent;
89  std::string prefix;
90  if ((dir = opendir(patternsFolder.c_str())) != nullptr)
91  {
92  /* process all the files and directories within patternsFolder */
93  while ((ent = readdir(dir)) != nullptr)
94  {
95  std::string filename{ent->d_name};
96  std::size_t pathLength = filename.length();
97  if (pathLength > 4)
98  {
99  pathLength -= 4; // Size of .txt extention
100  if (filename.substr(pathLength) == ".txt")
101  {
102  std::string num, stem = filename.substr(0, pathLength);
103  std::size_t found = stem.find_last_not_of(numbers);
104  if (found == std::string::npos)
105  {
106  num = stem;
107  stem.erase(0);
108  }
109  else
110  {
111  num = stem.substr(found + 1);
112  stem.erase(found + 1);
113  }
114 
115  if (prefix.empty())
116  {
117  prefix = stem;
118  }
119 
120  if (prefix != stem)
121  {
122  NS_FATAL_ERROR(
123  "SatAntennaGainPatternContainer::SatAntennaGainPatternContainer mixing "
124  "different prefix for antenna pattern names: "
125  << prefix << " and " << stem);
126  }
127 
128  std::string filePath = patternsFolder + "/" + filename;
129  std::istringstream ss{num};
130  uint32_t beamId;
131  ss >> beamId;
132  if (ss.bad())
133  {
134  NS_FATAL_ERROR(
135  "SatAntennaGainPatternContainer::SatAntennaGainPatternContainer unable "
136  "to find beam number in "
137  << filePath << " file name");
138  }
139 
140  Ptr<SatAntennaGainPattern> gainPattern =
141  CreateObject<SatAntennaGainPattern>(filePath, geoPos);
142  std::pair<std::map<uint32_t, Ptr<SatAntennaGainPattern>>::iterator, bool> ret;
143  ret = m_antennaPatternMap.insert(std::make_pair(beamId, gainPattern));
144  if (ret.second == false)
145  {
146  NS_FATAL_ERROR("SatAntennaGainPatternContainer::"
147  "SatAntennaGainPatternContainer an antenna pattern for beam "
148  << beamId << " already exists!");
149  }
150  }
151  }
152  }
153  closedir(dir);
154  }
155  else
156  {
157  /* could not open directory */
158  const char* error = strerror(errno);
159  NS_FATAL_ERROR("SatAntennaGainPatternContainer::SatAntennaGainPatternContainer unable to "
160  "open directory "
161  << m_patternsFolder << ": " << error);
162  }
163 }
164 
166 {
167  NS_LOG_FUNCTION(this);
168 }
169 
172 {
173  NS_LOG_FUNCTION(this);
174 
175  std::string dataPath{Singleton<SatEnvVariables>::Get()->LocateDataDirectory()};
176  std::string geoPosFilename = dataPath + "/antennapatterns/" + m_patternsFolder + "/GeoPos.in";
177 
178  // READ FROM THE SPECIFIED INPUT FILE
179  std::ifstream* ifs = new std::ifstream(geoPosFilename, std::ifstream::in);
180 
181  if (!ifs->is_open())
182  {
183  NS_FATAL_ERROR("The file " << geoPosFilename << " is not found.");
184  }
185 
186  double lat, lon, alt;
187  *ifs >> lat >> lon >> alt;
188 
189  // Store the values
190  GeoCoordinate coord(lat, lon, alt);
191 
192  ifs->close();
193  delete ifs;
194 
195  return coord;
196 }
197 
198 Ptr<SatAntennaGainPattern>
200 {
201  NS_LOG_FUNCTION(this << beamId);
202 
203  std::map<uint32_t, Ptr<SatAntennaGainPattern>>::const_iterator agp =
204  m_antennaPatternMap.find(beamId);
205  if (agp == m_antennaPatternMap.end())
206  {
207  NS_FATAL_ERROR(
208  "SatAntennaGainPatternContainer::GetAntennaGainPattern - unvalid beam id: " << beamId);
209  }
210 
211  return agp->second;
212 }
213 
214 Ptr<SatMobilityModel>
216 {
217  NS_LOG_FUNCTION(this << satelliteId);
218 
219  std::map<uint32_t, Ptr<SatMobilityModel>>::const_iterator mm =
220  m_mobilityModelMap.find(satelliteId);
221  if (mm == m_mobilityModelMap.end())
222  {
223  NS_FATAL_ERROR(
224  "SatAntennaGainPatternContainer::GetAntennaGainPattern - unvalid satellite id: "
225  << satelliteId);
226  }
227 
228  return mm->second;
229 }
230 
231 uint32_t
233  GeoCoordinate coord,
234  bool ignoreNan)
235 {
236  NS_LOG_FUNCTION(this << satelliteId << coord.GetLatitude() << coord.GetLongitude());
237 
238  double bestGain(-100.0);
239  uint32_t bestId(0);
240 
241  Ptr<SatMobilityModel> mobility = m_mobilityModelMap[satelliteId];
242 
243  for (const auto& entry : m_antennaPatternMap)
244  {
245  uint32_t i = entry.first;
246  double gain = entry.second->GetAntennaGain_lin(coord, mobility);
247 
248  // The antenna pattern has returned a NAN gain. This means
249  // that this position is not valid. Return 0, which is not a valid beam id.
250  if (std::isnan(gain))
251  {
252  if (ignoreNan)
253  {
254  NS_LOG_WARN("SatAntennaGainPatternContainer::GetBestBeamId - Beam "
255  << i << " returned a NAN antenna gain value!");
256  }
257  else
258  {
259  NS_FATAL_ERROR("SatAntennaGainPatternContainer::GetBestBeamId - Beam "
260  << i << " returned a NAN antenna gain value!");
261  }
262  }
263  else if (gain > bestGain)
264  {
265  bestGain = gain;
266  bestId = i;
267  }
268  }
269 
270  if (bestId == 0 && ignoreNan)
271  {
272  NS_LOG_WARN(
273  "SatAntennaGainPatternContainer::GetBestBeamId - did not find any good beam! The "
274  "ground station is probably too far from the satellite. Return 1 by default.");
275  bestId = 1;
276  }
277 
278  return bestId;
279 }
280 
281 uint32_t
283 {
284  NS_LOG_FUNCTION(this);
285 
286  // Note, that now we assume that all the antenna patterns are created
287  // regardless of how many beams are actually simulated.
288  return m_antennaPatternMap.size();
289 }
290 
291 void
293  Ptr<SatMobilityModel> mobility)
294 {
295  NS_LOG_FUNCTION(this << satelliteId << mobility);
296 
297  m_mobilityModelMap[satelliteId] = mobility;
298 }
299 
300 void
302 {
303  std::map<uint32_t, Ptr<SatAntennaGainPattern>>::iterator it = m_antennaPatternMap.begin();
304  while (it != m_antennaPatternMap.end())
305  {
306  uint32_t beamIdIterator = it->first;
307  BeamUserInfoMap_t::iterator infoIterator;
308  bool found = false;
309  for (infoIterator = info.begin(); infoIterator != info.end(); infoIterator++)
310  {
311  uint32_t beamId = infoIterator->first.second;
312  if (beamId == beamIdIterator)
313  {
314  found = true;
315  }
316  }
317  if (!found)
318  {
319  it = m_antennaPatternMap.erase(it);
320  }
321  else
322  {
323  it++;
324  }
325  }
326 }
327 
328 } // 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.
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 beam id.
SatAntennaGainPatternContainer(uint32_t nbSats=1)
Default constructor.
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