Loading...
Searching...
No Matches
satellite-input-fstream-time-double-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: Frans Laakso <frans.laakso@magister.fi>
19 */
20
22
23#include "ns3/abort.h"
24#include "ns3/log.h"
25#include "ns3/simulator.h"
26
27NS_LOG_COMPONENT_DEFINE("SatInputFileStreamTimeDoubleContainer");
28
29namespace ns3
30{
31
32TypeId
34{
35 static TypeId tid = TypeId("ns3::SatInputFileStreamTimeDoubleContainer")
36 .SetParent<Object>()
37 .AddConstructor<SatInputFileStreamTimeDoubleContainer>();
38 return tid;
39}
40
42 std::string filename,
43 std::ios::openmode filemode,
44 uint32_t valuesInRow)
48 m_fileName(filename),
49 m_fileMode(filemode),
50 m_valuesInRow(valuesInRow),
55{
56 NS_LOG_FUNCTION(this << m_fileName << m_fileMode);
57
59}
60
65 m_fileName(),
66 m_fileMode(),
72{
73 NS_LOG_FUNCTION(this);
74 NS_FATAL_ERROR("SatInputFileStreamTimeDoubleContainer::SatInputFileStreamTimeDoubleContainer - "
75 "Constructor not in use");
76}
77
84
85void
87{
88 NS_LOG_FUNCTION(this);
89
90 Reset();
91 Object::DoDispose();
92}
93
94void
96 std::ios::openmode filemode,
97 uint32_t valuesInRow)
98{
99 NS_LOG_FUNCTION(this);
100
102
103 m_fileName = filename;
104 m_fileMode = filemode;
105 m_valuesInRow = valuesInRow;
106
107 m_inputFileStreamWrapper = new SatInputFileStreamWrapper(filename, filemode);
109
110 if (m_inputFileStream->is_open())
111 {
112 std::vector<double> tempVector = ReadRow();
113
114 while (!m_inputFileStream->eof())
115 {
116 m_container.push_back(tempVector);
117 tempVector = ReadRow();
118 }
119 m_inputFileStream->close();
120 }
121 else
122 {
123 NS_ABORT_MSG("Input stream is not valid for reading.");
124 }
125
127
128 ResetStream();
129}
130
131std::vector<double>
133{
134 NS_LOG_FUNCTION(this);
135
136 double tempValue;
137 std::vector<double> tempVector;
138
139 for (uint32_t i = 0; i < m_valuesInRow; i++)
140 {
141 *m_inputFileStream >> tempValue;
142 tempVector.push_back(tempValue);
143 }
144 return tempVector;
145}
146
147void
149{
150 NS_LOG_FUNCTION(this);
151
153 if (m_container.size() < 1)
154 {
155 NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Empty file");
156 }
157 else if (m_container.size() == 1)
158 {
159 if (m_container[m_container.size() - 1].at(m_timeColumn) == 0)
160 {
161 NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Invalid input "
162 "file format (time sample error)");
163 }
164 }
165 else
166 {
167 double tempValue1 = m_container[0].at(m_timeColumn);
168
169 for (uint32_t i = 1; i < m_container.size(); i++)
170 {
171 if (tempValue1 > m_container[i].at(m_timeColumn))
172 {
173 NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Invalid input "
174 "file format (time sample error)");
175 }
176 tempValue1 = m_container[i].at(m_timeColumn);
177 }
178 }
179}
180
181std::vector<double>
183{
184 NS_LOG_FUNCTION(this);
185
186 while (!FindNextClosest(m_lastValidPosition, m_timeShiftValue, Now().GetSeconds()))
187 {
191
192 NS_LOG_INFO("Looping samples again with shift value: " << m_timeShiftValue);
193 }
194
195 if (m_numOfPasses > 0)
196 {
197 std::cout
198 << "WARNING! - SatInputFileStreamDoubleContainer::ProceedToNextClosestTimeSample for "
199 << m_fileName << " is out of samples @ time sample " << Now().GetSeconds()
200 << " (passes " << m_numOfPasses << ")" << std::endl;
201 std::cout << "The container will loop samples from the beginning." << std::endl;
202 }
203
205}
206
207std::vector<double>
209{
210 NS_LOG_FUNCTION(this);
211
212 double currentTime = Now().GetSeconds();
214
215 std::vector<double> selectedPosition = m_container[m_lastValidPosition];
216 double selectedTime = selectedPosition.at(m_timeColumn);
217
218 // Easy case: a time sample for the current time exist
219 if (selectedTime == currentTime)
220 {
221 return selectedPosition;
222 }
223
224 // Fetch the second position to perform linear interpolation
225 std::vector<double> closestPosition;
226 if (selectedTime > currentTime)
227 {
228 if (m_lastValidPosition == 0)
229 {
230 // No previous position available, abort
231 return selectedPosition;
232 }
233 closestPosition = m_container[m_lastValidPosition - 1];
234 }
235 else
236 {
237 if (m_lastValidPosition == m_container.size() - 1)
238 {
239 // No next position available, abort
240 return selectedPosition;
241 }
242 closestPosition = m_container[m_lastValidPosition + 1];
243 }
244
245 double linearCoefficient =
246 (currentTime - selectedTime) / (closestPosition.at(m_timeColumn) - selectedTime);
247 std::size_t rowSize = selectedPosition.size();
248 std::vector<double> interpolatedPosition(rowSize);
249 for (std::size_t i = 0; i < rowSize; ++i)
250 {
251 interpolatedPosition[i] =
252 selectedPosition[i] + linearCoefficient * (closestPosition[i] - selectedPosition[i]);
253 }
254
255 return interpolatedPosition;
256}
257
258bool
260 double timeShiftValue,
261 double comparisonTimeValue)
262{
263 NS_LOG_FUNCTION(this);
264
265 NS_ASSERT(m_timeColumn < m_valuesInRow);
266 NS_ASSERT(m_container.size() > 0);
267 NS_ASSERT(lastValidPosition >= 0 && lastValidPosition < m_container.size());
268
269 NS_LOG_INFO("LastValidPosition " << lastValidPosition << " column " << m_timeColumn
270 << " timeShiftValue " << timeShiftValue
271 << " comparisonTimeValue " << comparisonTimeValue);
272
273 bool valueFound = false;
274
275 for (uint32_t i = lastValidPosition; i < m_container.size(); i++)
276 {
277 if (m_container[i].at(m_timeColumn) + timeShiftValue >= comparisonTimeValue)
278 {
279 double difference1 = std::abs(m_container[lastValidPosition].at(m_timeColumn) +
280 timeShiftValue - comparisonTimeValue);
281 double difference2 =
282 std::abs(m_container[i].at(m_timeColumn) + timeShiftValue - comparisonTimeValue);
283
284 if (difference1 < difference2)
285 {
286 m_lastValidPosition = lastValidPosition;
287 }
288 else
289 {
291 }
292 valueFound = true;
293 break;
294 }
295 lastValidPosition = i;
296 }
297
298 if (valueFound && m_numOfPasses > 0 && m_lastValidPosition == 0)
299 {
300 double difference1 = std::abs(m_container[m_lastValidPosition].at(m_timeColumn) +
301 timeShiftValue - comparisonTimeValue);
302 double difference2 =
303 std::abs(m_container[m_container.size() - 1].at(m_timeColumn) +
304 ((m_numOfPasses - 1) * m_container[m_container.size() - 1].at(m_timeColumn)) -
305 comparisonTimeValue);
306
307 if (difference1 > difference2)
308 {
309 m_lastValidPosition = m_container.size() - 1;
312 }
313 }
314
315 NS_LOG_INFO("Done: " << valueFound
316 << " value: " << m_container[m_lastValidPosition].at(m_timeColumn)
317 << " @ line: " << m_lastValidPosition + 1 << " comparison time value: "
318 << comparisonTimeValue << " passes: " << m_numOfPasses);
319
320 return valueFound;
321}
322
323void
325{
326 NS_LOG_FUNCTION(this);
327
328 ResetStream();
330}
331
332void
334{
335 NS_LOG_FUNCTION(this);
336
337 if (m_inputFileStreamWrapper != NULL)
338 {
341 }
343}
344
345void
347{
348 NS_LOG_FUNCTION(this);
349
350 if (!m_container.empty())
351 {
352 for (uint32_t i = 0; i < m_container.size(); i++)
353 {
354 if (!m_container[i].empty())
355 {
356 m_container[i].clear();
357 }
358 }
359 m_container.clear();
360 }
361
362 m_valuesInRow = 0;
364 m_numOfPasses = 0;
366}
367
368} // namespace ns3
bool FindNextClosest(uint32_t lastValidPosition, double timeShiftValue, double comparisonTimeValue)
Function for locating the next closest value index.
std::vector< std::vector< double > > m_container
Container for value rows.
uint32_t m_timeColumn
Index for column which contains time information.
std::vector< double > ReadRow()
Function for reading a row from file.
SatInputFileStreamWrapper * m_inputFileStreamWrapper
Pointer to input file stream wrapper.
std::vector< double > ProceedToNextClosestTimeSample()
Function for locating the next closest time sample and returning the values related to it.
uint32_t m_numOfPasses
Number for how many times the available samples have been looped over.
void UpdateContainer(std::string filename, std::ios::openmode filemode, uint32_t valuesInRow)
Function for updating the container.
std::vector< double > InterpolateBetweenClosestTimeSamples()
Function for locating time samples enclosing the current time and a linear interpolation between thes...
A class encapsulating an STL input stream.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.