satellite-look-up-table.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
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: Budiarto Herman <budiarto.herman@magister.fi>
19  *
20  */
21 
23 
24 #include "satellite-utils.h"
25 
26 #include <ns3/fatal-error.h>
27 #include <ns3/log.h>
28 
29 #include <cmath>
30 
31 NS_LOG_COMPONENT_DEFINE("SatLookUpTable");
32 
33 namespace ns3
34 {
35 
36 NS_OBJECT_ENSURE_REGISTERED(SatLookUpTable);
37 
38 SatLookUpTable::SatLookUpTable(std::string linkResultPath)
39 {
40  NS_LOG_FUNCTION(this << linkResultPath);
41  Load(linkResultPath);
42 }
43 
45 {
46  NS_LOG_FUNCTION(this);
47 }
48 
49 void
51 {
52  NS_LOG_FUNCTION(this);
53 
54  m_esNoDb.clear();
55  m_bler.clear();
56 
57  if (m_ifs != 0)
58  {
59  if (m_ifs->is_open())
60  {
61  m_ifs->close();
62  }
63 
64  delete m_ifs;
65  m_ifs = 0;
66  }
67 
68  Object::DoDispose();
69 }
70 
71 TypeId
73 {
74  static TypeId tid = TypeId("ns3::SatLookUpTable").SetParent<Object>();
75  return tid;
76 }
77 
78 double
79 SatLookUpTable::GetBler(double esNoDb) const
80 {
81  NS_LOG_FUNCTION(this << esNoDb);
82 
83  uint16_t n = m_esNoDb.size();
84 
85  NS_ASSERT(n > 0);
86  NS_ASSERT(m_bler.size() == n);
87 
88  if (esNoDb < m_esNoDb[0])
89  {
90  // edge case: very low SINR, return maximum BLER (100% error rate)
91  NS_LOG_INFO(this << " Very low SINR -> BLER = 1.0");
92  return 1.0;
93  }
94 
95  uint16_t i = 1;
96 
97  while ((i < n) && (esNoDb > m_esNoDb[i]))
98  {
99  i++;
100  }
101 
102  NS_LOG_DEBUG(this << " i=" << i << " esno[i]=" << m_esNoDb[i] << " bler[i]=" << m_bler[i]);
103 
104  if (i >= n)
105  {
106  // edge case: very high SINR, return minimum BLER (100% success rate)
107  if (n == 1)
108  {
109  NS_LOG_INFO(this << " Very high SINR -> BLER = " << m_bler[0]);
110  return m_bler[0];
111  }
112  else
113  {
114  NS_LOG_INFO(this << " Very high SINR -> BLER = 0.0");
115  return 0.0;
116  }
117  }
118  else // sinrDb <= m_esNoDb[i]
119  {
120  // normal case
121  NS_ASSERT(i > 0);
122  NS_ASSERT(i < n);
123 
124  double esno = esNoDb;
125  double esno0 = m_esNoDb[i - 1];
126  double esno1 = m_esNoDb[i];
127  double bler = SatUtils::Interpolate(esno, esno0, esno1, m_bler[i - 1], m_bler[i]);
128  NS_LOG_INFO(this << " Interpolate: " << esno << " to BLER = " << bler << "(sinr0: " << esno0
129  << ", sinr1: " << esno1 << ", bler0: " << m_bler[i - 1]
130  << ", bler1: " << m_bler[i] << ")");
131 
132  return bler;
133  }
134 
135 } // end of double SatLookUpTable::GetBler (double sinrDb) const
136 
137 double
138 SatLookUpTable::GetEsNoDb(double blerTarget) const
139 {
140  NS_LOG_FUNCTION(this << blerTarget);
141 
142  uint16_t n = m_bler.size();
143 
144  NS_ASSERT(n > 0);
145  NS_ASSERT(m_esNoDb.size() == n);
146 
147  // If the requested BLER is smaller than the smallest BLER entry
148  // in the look-up-table
149  if (blerTarget <= m_bler[n - 1])
150  {
151  return m_esNoDb[n - 1];
152  }
153 
154  // The requested BLER is higher than the highest BLER entry
155  // in the look-up-table
156  if (blerTarget > m_bler[0])
157  {
158  NS_FATAL_ERROR("The BLER target is set to be too high!");
159  }
160 
161  double sinr = 0.0;
162  // Go through the list from end to beginning
163  for (uint32_t i = 0; i < n; ++i)
164  {
165  if (blerTarget >= m_bler[i])
166  {
167  sinr = SatUtils::Interpolate(blerTarget,
168  m_bler[i - 1],
169  m_bler[i],
170  m_esNoDb[i - 1],
171  m_esNoDb[i]);
172  NS_LOG_INFO(this << " Interpolate: " << blerTarget << " to SINR = " << sinr
173  << "(bler0: " << m_bler[i - 1] << ", bler1: " << m_bler[i]
174  << ", sinr0: " << m_esNoDb[i - 1] << ", sinr1: " << m_esNoDb[i]
175  << ")");
176  return sinr;
177  }
178  }
179 
180  return sinr;
181 } // end of double SatLookUpTable::GetSinr (double bler) const
182 
183 void
184 SatLookUpTable::Load(std::string linkResultPath)
185 {
186  NS_LOG_FUNCTION(this << linkResultPath);
187 
188  // READ FROM THE SPECIFIED INPUT FILE
189 
190  m_ifs = new std::ifstream(linkResultPath.c_str(), std::ifstream::in);
191 
192  if (!m_ifs->is_open())
193  {
194  // script might be launched by test.py, try a different base path
195  delete m_ifs;
196  linkResultPath = "../../" + linkResultPath;
197  m_ifs = new std::ifstream(linkResultPath.c_str(), std::ifstream::in);
198 
199  if (!m_ifs->is_open())
200  {
201  NS_FATAL_ERROR("The file " << linkResultPath << " is not found.");
202  }
203  }
204 
205  double lastEsNoDb = -100.0; // very low value
206  double lastBler = 1.0; // maximum value
207 
208  double esNoDb, bler;
209  *m_ifs >> esNoDb >> bler;
210 
211  while (m_ifs->good())
212  {
213  NS_LOG_DEBUG(this << " sinrDb=" << esNoDb << ", bler=" << bler);
214 
215  // SANITY CHECK PART I
216  if ((esNoDb <= lastEsNoDb) || (bler > lastBler))
217  {
218  NS_FATAL_ERROR("The file " << linkResultPath << " is not properly sorted.");
219  }
220 
221  // record the values
222  m_esNoDb.push_back(esNoDb);
223  m_bler.push_back(bler);
224  lastEsNoDb = esNoDb;
225  lastBler = bler;
226 
227  // get next row
228  *m_ifs >> esNoDb >> bler;
229  }
230 
231  m_ifs->close();
232  delete m_ifs;
233  m_ifs = 0;
234 
235  // SANITY CHECK PART II
236 
237  // at least contains one row
238  if (m_esNoDb.empty())
239  {
240  NS_FATAL_ERROR("Error reading data from file " << linkResultPath << ".");
241  }
242 
243  // SINR and BLER have same size
244  NS_ASSERT(m_esNoDb.size() == m_bler.size());
245 
246 } // end of void Load (std::string linkResultPath)
247 
248 } // end of namespace ns3
virtual ~SatLookUpTable()
Destructor for SatLookUpTable.
double GetBler(double sinrDb) const
Get the BLER corresponding to a given SINR.
std::vector< double > m_bler
static TypeId GetTypeId()
Get the type ID.
double GetEsNoDb(double blerTarget) const
Get Es/No in dB for a given BLER target.
std::vector< double > m_esNoDb
void Load(std::string linkResultPath)
Load the link results.
SatLookUpTable(std::string linkResultPath)
Constructor with initialization parameters.
static double Interpolate(double x, double x0, double x1, double y0, double y1)
Simple linear interpolation.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.