Loading...
Searching...
No Matches
satellite-input-fstream-time-long-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("SatInputFileStreamTimeLongDoubleContainer");
28
29namespace ns3
30{
31
32TypeId
34{
35 static TypeId tid = TypeId("ns3::SatInputFileStreamTimeLongDoubleContainer")
36 .SetParent<Object>()
37 .AddConstructor<SatInputFileStreamTimeLongDoubleContainer>();
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("SatInputFileStreamTimeLongDoubleContainer::"
75 "SatInputFileStreamTimeLongDoubleContainer - 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<long 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<long double>
133{
134 NS_LOG_FUNCTION(this);
135
136 long double tempValue;
137 std::vector<long 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("SatInputFileStreamTimeLongDoubleContainer::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("SatInputFileStreamTimeLongDoubleContainer::UpdateContainer - Invalid "
162 "input 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("SatInputFileStreamTimeLongDoubleContainer::UpdateContainer - "
174 "Invalid input file format (time sample error)");
175 }
176 tempValue1 = m_container[i].at(m_timeColumn);
177 }
178 }
179}
180
181std::vector<long 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! - "
199 "SatInputFileStreamTimeLongDoubleContainer::ProceedToNextClosestTimeSample for "
200 << m_fileName << " is out of samples @ time sample " << Now().GetSeconds()
201 << " (passes " << m_numOfPasses << ")" << std::endl;
202 std::cout << "The container will loop samples from the beginning." << std::endl;
203 }
204
206}
207
208std::vector<long double>
210{
211 NS_LOG_FUNCTION(this);
212
213 long double currentTime = Now().GetSeconds();
215
216 std::vector<long double> selectedPosition = m_container[m_lastValidPosition];
217 long double selectedTime = selectedPosition.at(m_timeColumn);
218
219 // Easy case: a time sample for the current time exist
220 if (selectedTime == currentTime)
221 {
222 return selectedPosition;
223 }
224
225 // Fetch the second position to perform linear interpolation
226 std::vector<long double> closestPosition;
227 if (selectedTime > currentTime)
228 {
229 if (m_lastValidPosition == 0)
230 {
231 // No previous position available, abort
232 return selectedPosition;
233 }
234 closestPosition = m_container[m_lastValidPosition - 1];
235 }
236 else
237 {
238 if (m_lastValidPosition == m_container.size() - 1)
239 {
240 // No next position available, abort
241 return selectedPosition;
242 }
243 closestPosition = m_container[m_lastValidPosition + 1];
244 }
245
246 long double linearCoefficient =
247 (currentTime - selectedTime) / (closestPosition.at(m_timeColumn) - selectedTime);
248 std::size_t rowSize = selectedPosition.size();
249 std::vector<long double> interpolatedPosition(rowSize);
250 for (std::size_t i = 0; i < rowSize; ++i)
251 {
252 interpolatedPosition[i] =
253 selectedPosition[i] + linearCoefficient * (closestPosition[i] - selectedPosition[i]);
254 }
255
256 return interpolatedPosition;
257}
258
259bool
261 long double timeShiftValue,
262 long double comparisonTimeValue)
263{
264 NS_LOG_FUNCTION(this);
265
266 NS_ASSERT(m_timeColumn < m_valuesInRow);
267 NS_ASSERT(m_container.size() > 0);
268 NS_ASSERT(lastValidPosition >= 0 && lastValidPosition < m_container.size());
269
270 NS_LOG_INFO("LastValidPosition " << lastValidPosition << " column " << m_timeColumn
271 << " timeShiftValue " << timeShiftValue
272 << " comparisonTimeValue " << comparisonTimeValue);
273
274 bool valueFound = false;
275
276 for (uint32_t i = lastValidPosition; i < m_container.size(); i++)
277 {
278 if (m_container[i].at(m_timeColumn) + timeShiftValue >= comparisonTimeValue)
279 {
280 long double difference1 = std::abs(m_container[lastValidPosition].at(m_timeColumn) +
281 timeShiftValue - comparisonTimeValue);
282 long double difference2 =
283 std::abs(m_container[i].at(m_timeColumn) + timeShiftValue - comparisonTimeValue);
284
285 if (difference1 < difference2)
286 {
287 m_lastValidPosition = lastValidPosition;
288 }
289 else
290 {
292 }
293 valueFound = true;
294 break;
295 }
296 lastValidPosition = i;
297 }
298
299 if (valueFound && m_numOfPasses > 0 && m_lastValidPosition == 0)
300 {
301 long double difference1 = std::abs(m_container[m_lastValidPosition].at(m_timeColumn) +
302 timeShiftValue - comparisonTimeValue);
303 long double difference2 =
304 std::abs(m_container[m_container.size() - 1].at(m_timeColumn) +
305 ((m_numOfPasses - 1) * m_container[m_container.size() - 1].at(m_timeColumn)) -
306 comparisonTimeValue);
307
308 if (difference1 > difference2)
309 {
310 m_lastValidPosition = m_container.size() - 1;
313 }
314 }
315
316 NS_LOG_INFO("Done: " << valueFound
317 << " value: " << m_container[m_lastValidPosition].at(m_timeColumn)
318 << " @ line: " << m_lastValidPosition + 1 << " comparison time value: "
319 << comparisonTimeValue << " passes: " << m_numOfPasses);
320
321 return valueFound;
322}
323
324void
326{
327 NS_LOG_FUNCTION(this);
328
329 ResetStream();
331}
332
333void
335{
336 NS_LOG_FUNCTION(this);
337
338 if (m_inputFileStreamWrapper != NULL)
339 {
342 }
344}
345
346void
348{
349 NS_LOG_FUNCTION(this);
350
351 if (!m_container.empty())
352 {
353 for (uint32_t i = 0; i < m_container.size(); i++)
354 {
355 if (!m_container[i].empty())
356 {
357 m_container[i].clear();
358 }
359 }
360 m_container.clear();
361 }
362
363 m_valuesInRow = 0;
365 m_numOfPasses = 0;
367}
368
369} // namespace ns3
std::vector< long double > ReadRow()
Function for reading a row from file.
uint32_t m_timeColumn
Index for column which contains time information.
bool FindNextClosest(uint32_t lastValidPosition, long double timeShiftValue, double long comparisonTimeValue)
Function for locating the next closest value index.
void UpdateContainer(std::string filename, std::ios::openmode filemode, uint32_t valuesInRow)
Function for updating the container.
std::vector< long 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.
std::vector< long double > InterpolateBetweenClosestTimeSamples()
Function for locating time samples enclosing the current time and a linear interpolation between thes...
std::vector< std::vector< long double > > m_container
Container for value rows.
SatInputFileStreamWrapper * m_inputFileStreamWrapper
Pointer to input file stream wrapper.
A class encapsulating an STL input stream.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.