SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SENSSimulator.cpp
Go to the documentation of this file.
1 #include "SENSSimulator.h"
2 
4 {
5 }
6 
7 bool SENSSimulator::getSimulatorErrors(std::vector<std::string>& errorMsgs)
8 {
9  for (int i = 0; i < _activeSensors.size(); ++i)
10  {
11  SENSSimulatedBase* sensor = _activeSensors[i].get();
12  std::string msg;
13  if (sensor->getErrorMsg(msg))
14  errorMsgs.emplace_back(msg);
15  }
16 
17  return errorMsgs.size() != 0;
18 }
19 
21 {
22  if (_clock)
23  _clock->pause();
24 }
25 
27 {
28  if (_clock)
29  return _clock->isPaused();
30  else
31  return false;
32 }
33 
35 {
36  if (_clock)
37  _clock->resume();
38 }
39 
41 {
43  if (_clock)
44  passedTime = _clock->passedTime();
45  return passedTime;
46 }
47 
49 {
50  SENSTimePt simNow;
51  if (_clock)
52  simNow = _clock->now();
53  return simNow;
54 }
55 
56 void findSimStartTimePt(SENSTimePt& simStartTimePt, bool& initialized, SENSTimePt tp)
57 {
58  if (!initialized)
59  {
60  initialized = true;
61  simStartTimePt = tp;
62  }
63  else if (tp < simStartTimePt)
64  simStartTimePt = tp;
65 }
66 
67 SENSSimulator::SENSSimulator(const std::string& simDirName)
68 {
69  try
70  {
71  //check directory content and enable simulated sensors depending on this
72  std::string dirName = Utils::unifySlashes(simDirName);
73 
74  if (Utils::dirExists(dirName))
75  {
76  std::vector<std::pair<SENSTimePt, SENSGps::Location>> gpsData;
77  loadGpsData(dirName, gpsData);
78  std::vector<std::pair<SENSTimePt, SENSOrientation::Quat>> orientationData;
79  loadOrientationData(dirName, orientationData);
80  std::vector<std::pair<SENSTimePt, int>> cameraData;
81  std::string videoFileName;
82  SENSCameraConfig cameraConfig;
83  loadCameraData(dirName, cameraData, videoFileName, cameraConfig);
84 
85  //search for common sim time start point
86  //start time point of simulation in the past
87  SENSTimePt simStartTimePt;
88 
89  bool initialized = false;
90 
91  if (gpsData.size())
92  findSimStartTimePt(simStartTimePt, initialized, gpsData.front().first);
93  if (orientationData.size())
94  findSimStartTimePt(simStartTimePt, initialized, orientationData.front().first);
95  if (cameraData.size())
96  findSimStartTimePt(simStartTimePt, initialized, cameraData.front().first);
97 
98  if (initialized)
99  {
100  //instantiate simulator clock
101  _clock = std::make_unique<SENSSimClock>(SENSClock::now(), simStartTimePt);
102 
103  if (gpsData.size())
104  {
105  //make_unique has problems with fiendship and private constructor so we use unique_ptr
106  _activeSensors.push_back(std::unique_ptr<SENSSimulatedGps>(
107  new SENSSimulatedGps(std::bind(&SENSSimulator::onStart, this),
108  std::bind(&SENSSimulator::onSensorSimStopped, this),
109  std::move(gpsData),
110  *_clock)));
111  }
112 
113  if (orientationData.size())
114  {
115  //make_unique has problems with fiendship and private constructor so we use unique_ptr
116  _activeSensors.push_back(std::unique_ptr<SENSSimulatedOrientation>(
117  new SENSSimulatedOrientation(std::bind(&SENSSimulator::onStart, this),
118  std::bind(&SENSSimulator::onSensorSimStopped, this),
119  std::move(orientationData),
120  *_clock)));
121  }
122 
123  if (cameraData.size())
124  {
125  //make_unique has problems with fiendship and private constructor so we use unique_ptr
126  _activeSensors.push_back(std::unique_ptr<SENSSimulatedCamera>(
127  new SENSSimulatedCamera(std::bind(&SENSSimulator::onStart, this),
128  std::bind(&SENSSimulator::onSensorSimStopped, this),
129  std::move(cameraData),
130  videoFileName,
131  cameraConfig,
132  *_clock)));
133  }
134  }
135  }
136  else
137  Utils::log("SENS", "SENSSimulator: Directory does not exist: %s", simDirName.c_str());
138  }
139  catch (...)
140  {
141  Utils::log("SENS", "SENSSimulator: Exception while parsing sensor files");
142  }
143 }
144 
146 {
147  if (!_running)
148  {
149  if (_clock)
150  _clock->reset();
151  _running = true;
152  }
153 }
154 
156 {
157  //if no sensor is running anymore, we stop the simulation
158  bool aSensorIsRunning = false;
159  for (int i = 0; i < _activeSensors.size(); ++i)
160  {
161  if (_activeSensors[i]->isThreadRunning())
162  {
163  aSensorIsRunning = true;
164  break;
165  }
166  }
167 
168  if (!aSensorIsRunning)
169  _running = false;
170 
171  //THIS DOES NOT WORK BECAUSE WE WOULD JOIN A THREAD FROM THE CURRENT THREAD
172  //assuming sensor implementations (e.g. SENSGps) are still in running we can restart the backend threads
173  /*
174  if (!_running && _repeat)
175  {
176  _clock.reset();
177  for (int i = 0; i < _activeSensors.size(); ++i)
178  {
179  _activeSensors[i]->startSim();
180  }
181  }
182  */
183 }
184 
185 void SENSSimulator::loadGpsData(const std::string& dirName, std::vector<std::pair<SENSTimePt, SENSGps::Location>>& data)
186 {
187  std::string gpsFileName = dirName + "gps.txt";
188  //check if directory contains gps.txt
189  if (Utils::fileExists(gpsFileName))
190  {
191  std::string line;
192  ifstream file(gpsFileName);
193  if (file.is_open())
194  {
195  while (std::getline(file, line))
196  {
197  //cout << line << '\n';
198  long long readTimePt;
199  SENSGps::Location loc;
200  std::vector<std::string> values;
201  Utils::splitString(line, ' ', values);
202  if (values.size() == 5)
203  {
204  readTimePt = std::stoll(values[0]);
205  loc.latitudeDEG = std::stof(values[1]);
206  loc.longitudeDEG = std::stof(values[2]);
207  loc.altitudeM = std::stof(values[3]);
208  loc.accuracyM = std::stof(values[4]);
209 
210  SENSMicroseconds readTimePtUs(readTimePt);
211  SENSTimePt tPt(readTimePtUs);
212  data.push_back(std::make_pair(tPt, loc));
213  }
214  }
215  file.close();
216  }
217  else
218  Utils::log("SENS", "SENSSimulator: Unable to open file: %s", gpsFileName.c_str());
219  }
220 }
221 
222 void SENSSimulator::loadOrientationData(const std::string& dirName, std::vector<std::pair<SENSTimePt, SENSOrientation::Quat>>& data)
223 {
224  std::string orientationFileName = dirName + "orientation.txt";
225  //check if directory contains orientation.txt
226  if (Utils::fileExists(orientationFileName))
227  {
228  std::string line;
229  ifstream file(orientationFileName);
230  if (file.is_open())
231  {
232  while (std::getline(file, line))
233  {
234  //cout << line << '\n';
235  long long readTimePt;
237  std::vector<std::string> values;
238  Utils::splitString(line, ' ', values);
239  if (values.size() == 5)
240  {
241  readTimePt = std::stoll(values[0]);
242  quat.quatX = std::stof(values[1]);
243  quat.quatY = std::stof(values[2]);
244  quat.quatZ = std::stof(values[3]);
245  quat.quatW = std::stof(values[4]);
246 
247  SENSMicroseconds readTimePtUs(readTimePt);
248  SENSTimePt tPt(readTimePtUs);
249  data.push_back(std::make_pair(tPt, quat));
250  }
251  }
252  file.close();
253  }
254  else
255  Utils::log("SENS", "SENSSimulator: Unable to open file: %s", orientationFileName.c_str());
256  }
257 }
258 
259 void SENSSimulator::loadCameraData(const std::string& dirName,
260  std::vector<std::pair<SENSTimePt, int>>& data,
261  std::string& videoFileName,
262  SENSCameraConfig& cameraConfig)
263 {
264  std::string textFileName = dirName + "camera.txt";
265  videoFileName = dirName + "video.avi";
266  std::string configFileName = dirName + "cameraConfig.json";
267 
268  //check if directory contains gps.txt
269  if (Utils::fileExists(textFileName) && Utils::fileExists(videoFileName) && Utils::fileExists(configFileName))
270  {
271  //load config file
272  {
273  cv::FileStorage fs;
274  fs.open(configFileName, cv::FileStorage::READ);
275  if (fs.isOpened())
276  {
277  fs["deviceId"] >> cameraConfig.deviceId;
278  fs["widthPix"] >> cameraConfig.streamConfig.widthPix;
279  fs["heightPix"] >> cameraConfig.streamConfig.heightPix;
280  fs["focalLengthPix"] >> cameraConfig.streamConfig.focalLengthPix;
281  int focusMode;
282  fs["focusMode"] >> focusMode;
283  cameraConfig.focusMode = (SENSCameraFocusMode)focusMode;
284  int facing;
285  fs["facing"] >> facing;
286  cameraConfig.facing = (SENSCameraFacing)facing;
287  }
288  else
289  Utils::log("SENS", "SENSSimulator: Unable to open file: %s ", configFileName.c_str());
290  }
291 
292  //load frame info
293  {
294  std::string line;
295  ifstream file(textFileName);
296  if (file.is_open())
297  {
298  while (std::getline(file, line))
299  {
300  //cout << line << '\n';
301  long long readTimePt;
302  int frameIndex;
303  std::vector<std::string> values;
304  Utils::splitString(line, ' ', values);
305  if (values.size() == 2)
306  {
307  readTimePt = std::stoll(values[0]);
308  frameIndex = std::stoi(values[1]);
309 
310  SENSMicroseconds readTimePtUs(readTimePt);
311  SENSTimePt tPt(readTimePtUs);
312  data.push_back(std::make_pair(tPt, frameIndex));
313  }
314  }
315  file.close();
316  }
317  else
318  Utils::log("SENS", "SENSSimulator: Unable to open file: %s ", textFileName.c_str());
319  }
320  }
321 }
std::chrono::microseconds SENSMicroseconds
Definition: SENS.h:58
std::chrono::high_resolution_clock::time_point SENSTimePt
Definition: SENS.h:57
SENSCameraFocusMode
Definition of autofocus mode.
Definition: SENSCamera.h:49
SENSCameraFacing
Definition of camera facing.
Definition: SENSCamera.h:28
void findSimStartTimePt(SENSTimePt &simStartTimePt, bool &initialized, SENSTimePt tp)
virtual bool getErrorMsg(std::string &msg)=0
std::atomic_bool _running
flags if simulator is currently running
Definition: SENSSimulator.h:82
void loadOrientationData(const std::string &dirName, std::vector< std::pair< SENSTimePt, SENSOrientation::Quat >> &data)
load data from file and instantiate sensor if valid
bool getSimulatorErrors(std::vector< std::string > &errorMsgs)
std::unique_ptr< SENSSimClock > _clock
Definition: SENSSimulator.h:80
SENSMicroseconds passedTime()
get passed simulation time
std::vector< std::unique_ptr< SENSSimulatedBase > > _activeSensors
list of currently activated sensors. Which sensors are activated depends on the content of simulation...
Definition: SENSSimulator.h:78
void loadGpsData(const std::string &dirName, std::vector< std::pair< SENSTimePt, SENSGps::Location >> &data)
load data from file and instantiate sensor if valid
void pause()
pause simulation time
SENSSimulator(const std::string &simDirName)
ctor, transfer directory containing sensor data that was recorded with SENSRecorder
void resume()
resume simulation time
void onStart()
callback called from SENSSimulated when the simulated sensor was started
void loadCameraData(const std::string &dirName, std::vector< std::pair< SENSTimePt, int >> &data, std::string &videoFileName, SENSCameraConfig &cameraConfig)
load data from file and instantiate sensor if valid
void onSensorSimStopped()
callback called from SENSSimulated when the simulated sensor was stopped
SENSTimePt now()
reset simulation time
string unifySlashes(const string &inputDir, bool withTrailingSlash)
Returns the inputDir string with unified forward slashes, e.g.: "dirA/dirB/".
Definition: Utils.cpp:367
bool fileExists(const string &pathfilename)
Returns true if a file exists.
Definition: Utils.cpp:894
bool dirExists(const string &path)
Returns true if a directory exists.
Definition: Utils.cpp:789
void splitString(const string &s, char delimiter, vector< string > &splits)
Splits an input string at a delimiter character into a string vector.
Definition: Utils.cpp:152
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1100
SENSCameraFacing facing
camera facing
Definition: SENSCamera.h:133
SENSCameraStreamConfig streamConfig
currently selected stream config index (use it to look up original capture size)
Definition: SENSCamera.h:131
std::string deviceId
Definition: SENSCamera.h:130
SENSCameraFocusMode focusMode
autofocus mode
Definition: SENSCamera.h:132
float accuracyM
Definition: SENSGps.h:22
double latitudeDEG
Definition: SENSGps.h:19
double longitudeDEG
Definition: SENSGps.h:20
double altitudeM
Definition: SENSGps.h:21