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