Helios++
Helios software for LiDAR simulations
AssetLoadingTest.h
1 #pragma once
2 
3 #include <BaseTest.h>
4 #include <assetloading/XmlUtils.h>
5 #include <assetloading/XmlSceneLoader.h>
6 #include <assetloading/XmlAssetsLoader.h>
7 #include <assetloading/XmlSurveyLoader.h>
8 #include <scanner/beamDeflector/OscillatingMirrorBeamDeflector.h>
9 #include <scanner/beamDeflector/ConicBeamDeflector.h>
10 #include <scanner/beamDeflector/PolygonMirrorBeamDeflector.h>
11 #include <scanner/beamDeflector/RisleyBeamDeflector.h>
12 #include <scanner/SingleScanner.h>
13 #include <scanner/MultiScanner.h>
14 #include <platform/Platform.h>
15 #include <platform/HelicopterPlatform.h>
16 #include <platform/LinearPathPlatform.h>
17 #include <platform/GroundVehiclePlatform.h>
18 #include <noise/NoiseSource.h>
19 #include <noise/NormalNoiseSource.h>
20 #include <noise/UniformNoiseSource.h>
21 
22 
23 namespace HeliosTests{
24 
30 class AssetLoadingTest : public BaseTest{
31 public:
32  // *** ATTRIBUTE *** //
33  // ******************* //
37  double const eps = 0.00001;
38 
39  // *** CONSTRUCTOR *** //
40  // ********************* //
44  AssetLoadingTest() : BaseTest("Asset loading test"){}
45 
46  // *** R U N *** //
47  // *************** //
51  bool run() override;
52 
53  // *** SUB-TESTS *** //
54  // ******************* //
59  bool testScannerLoading();
64  bool testPlatformLoading();
69  bool testObjLoading();
74  bool testVoxelLoading();
84  bool testTiffLoading();
89  bool testSceneLoading();
94  bool testSurveyLoading();
95 };
96 
97 
98 // *** R U N *** //
99 // *************** //
101  // Run tests
102  try{
103  if(!testScannerLoading()) return false;
104  if(!testPlatformLoading()) return false;
105  if(!testObjLoading()) return false;
106  if(!testVoxelLoading()) return false;
107  if(!testDetailedVoxelLoading()) return false;
108  if(!testTiffLoading()) return false;
109  if(!testSceneLoading()) return false;
110  if(!testSurveyLoading()) return false;
111  }
112  catch(std::exception &ex){
113  return false;
114  }
115  return true;
116 }
117 
118 
119 // *** SUB-TESTS *** //
120 // ******************* //
122  // Prepare scanner loading
123  std::string testScannersPath = "data/test/test_scanners.xml";
124  std::string assetsPath = "assets/";
125  XmlAssetsLoader loader(testScannersPath, assetsPath);
126  // Load and validate Leica ALS50
127  std::shared_ptr<Scanner> scanner = std::static_pointer_cast<Scanner>(
128  loader.getAssetById("scanner", "leica_als50", nullptr)
129  );
130  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
131  return false;
132  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
133  return false;
134  if(scanner->getScannerId() != "leica_als50") return false;
135  if(scanner->getDetector()->cfg_device_accuracy_m != 0.05) return false;
136  if(scanner->getBeamDivergence() != 0.00033) return false;
137  if(scanner->name != "Leica ALS50") return false;
138  if(
139  std::dynamic_pointer_cast<OscillatingMirrorBeamDeflector>(
140  scanner->getBeamDeflector()
141  ) == nullptr
142  ) return false;
143  std::list<int> &pfs = scanner->getSupportedPulseFreqs_Hz();
144  if(pfs.size() != 1) return false;
145  if(pfs.front() != 83000) return false;
146  if(scanner->getPulseFreq_Hz() != 83000) return false;
147  if(scanner->getPulseLength_ns() != 10) return false;
148  if(scanner->getDetector()->cfg_device_rangeMin_m != 200) return false;
149  if( std::fabs(
150  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.6544985
151  ) > eps
152  ) return false;
153  if(scanner->getBeamDeflector()->cfg_device_scanFreqMin_Hz != 25)
154  return false;
155  if(scanner->getBeamDeflector()->cfg_device_scanFreqMax_Hz != 70)
156  return false;
157  // Load and validate Leica ALST50-II
158  scanner = std::static_pointer_cast<Scanner>(
159  loader.getAssetById("scanner", "leica_als50-ii", nullptr)
160  );
161  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
162  return false;
163  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
164  return false;
165  if(scanner->getScannerId() != "leica_als50-ii") return false;
166  if(scanner->getDetector()->cfg_device_accuracy_m != 0.05) return false;
167  if(scanner->getBeamDivergence() != 0.00022) return false;
168  if(scanner->name != "Leica ALS50-II") return false;
169  if(
170  std::dynamic_pointer_cast<OscillatingMirrorBeamDeflector>(
171  scanner->getBeamDeflector()
172  ) == nullptr
173  ) return false;
174  pfs = scanner->getSupportedPulseFreqs_Hz();
175  if(pfs.size() != 3) return false;
176  std::list<int>::iterator pfsit = pfs.begin();
177  if(*pfsit != 20000) return false;
178  ++pfsit;
179  if(*pfsit != 60000) return false;
180  ++pfsit;
181  if(*pfsit != 150000) return false;
182  if(scanner->getPulseFreq_Hz() != 20000) return false;
183  if(scanner->getPulseLength_ns() != 10) return false;
184  if(scanner->getDetector()->cfg_device_rangeMin_m != 200) return false;
185  if( std::fabs(
186  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.6544985
187  ) > eps
188  ) return false;
189  if(scanner->getBeamDeflector()->cfg_device_scanFreqMin_Hz != 0)
190  return false;
191  if(scanner->getBeamDeflector()->cfg_device_scanFreqMax_Hz != 90)
192  return false;
193  if(scanner->getMaxNOR() != 4) return false;
194  // Load and validate Optech 2033
195  scanner = std::static_pointer_cast<Scanner>(
196  loader.getAssetById("scanner", "optech_2033", nullptr)
197  );
198  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
199  return false;
200  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
201  return false;
202  if(scanner->getScannerId() != "optech_2033") return false;
203  if(scanner->getDetector()->cfg_device_accuracy_m != 0.01) return false;
204  if(scanner->getBeamDivergence() != 0.000424) return false;
205  if(scanner->name != "Optech ALTM 2033") return false;
206  if(
207  std::dynamic_pointer_cast<OscillatingMirrorBeamDeflector>(
208  scanner->getBeamDeflector()
209  ) == nullptr
210  ) return false;
211  pfs = scanner->getSupportedPulseFreqs_Hz();
212  if(pfs.size() != 1) return false;
213  if(pfs.front() != 33000) return false;
214  if(scanner->getPulseLength_ns() != 8) return false;
215  if(scanner->getDetector()->cfg_device_rangeMin_m != 1) return false;
216  if( std::fabs(
217  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.3490659
218  ) > eps
219  ) return false;
220  if(scanner->getBeamDeflector()->cfg_device_scanFreqMin_Hz!=0) return false;
221  if(scanner->getBeamDeflector()->cfg_device_scanFreqMax_Hz!=30)
222  return false;
223  if(
224  std::dynamic_pointer_cast<OscillatingMirrorBeamDeflector>(
225  scanner->getBeamDeflector()
226  )->cfg_device_scanProduct != 590
227  ) return false;
228  if(scanner->getWavelength() != 1047e-9) return false;
229  glm::dvec3 epdiff = scanner->getHeadRelativeEmitterPosition()
230  - glm::dvec3(0, 0.085, 0.06);
231  if(
232  std::fabs(epdiff[0]) > eps ||
233  std::fabs(epdiff[1]) > eps ||
234  std::fabs(epdiff[2]) > eps
235  ) return false;
236  Rotation eatt = scanner->getHeadRelativeEmitterAttitude();
237  if(
238  eatt.getQ0()!=1 || eatt.getQ1()!=0 ||
239  eatt.getQ2()!=0 || eatt.getQ3()!=0
240  ) return false;
241  glm::dvec3 eraxis = scanner->getScannerHead()->cfg_device_rotateAxis;
242  if(eraxis[0] != 0 || eraxis[1] != 0 || eraxis[2] != 1) return false;
243  // Load and validate Riegl LMS-Q560
244  scanner = std::static_pointer_cast<Scanner>(
245  loader.getAssetById("scanner", "riegl_lms-q560")
246  );
247  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
248  return false;
249  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
250  return false;
251  if(scanner->getScannerId() != "riegl_lms-q560") return false;
252  if(scanner->getDetector()->cfg_device_accuracy_m != 0.02) return false;
253  if(scanner->getBeamDivergence() != 0.0005) return false;
254  if(scanner->name != "RIEGL LMS-Q560") return false;
255  if(
256  std::dynamic_pointer_cast<PolygonMirrorBeamDeflector>(
257  scanner->getBeamDeflector()
258  ) == nullptr
259  ) return false;
260  pfs = scanner->getSupportedPulseFreqs_Hz();
261  if(pfs.size() != 5) return false;
262  pfsit = pfs.begin();
263  if(*pfsit != 50000){return false;} ++pfsit;
264  if(*pfsit != 100000){return false;} ++pfsit;
265  if(*pfsit != 180000){return false;} ++pfsit;
266  if(*pfsit != 200000){return false;} ++pfsit;
267  if(*pfsit != 240000){return false;} ++pfsit;
268  if(scanner->getPulseLength_ns() != 4) return false;
269  if( std::fabs(
270  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.7853982
271  ) > eps
272  ) return false;
273  if( std::fabs(
274  std::dynamic_pointer_cast<PolygonMirrorBeamDeflector>(
275  scanner->getBeamDeflector()
276  )->getScanAngleEffectiveMax_rad() - 0.3926991
277  ) > eps
278  ) return false;
279  if(scanner->getBeamDeflector()->cfg_device_scanFreqMin_Hz != 10)
280  return false;
281  if(scanner->getBeamDeflector()->cfg_device_scanFreqMax_Hz != 160)
282  return false;
283  // Load and validate RIEGLS VQ-880-G
284  scanner = std::static_pointer_cast<Scanner>(
285  loader.getAssetById("scanner", "riegl_vq-880g", nullptr)
286  );
287  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
288  return false;
289  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
290  return false;
291  if(scanner->getScannerId() != "riegl_vq-880g") return false;
292  if(scanner->getDetector()->cfg_device_accuracy_m != 0.025) return false;
293  if(scanner->getBeamDivergence() != 0.0003) return false;
294  if(scanner->name != "RIEGL VQ-880-G") return false;
295  if(
296  std::dynamic_pointer_cast<ConicBeamDeflector>(
297  scanner->getBeamDeflector()
298  ) == nullptr
299  ) return false;
300  pfs = scanner->getSupportedPulseFreqs_Hz();
301  if(pfs.size()!=4) return false;
302  pfsit = pfs.begin();
303  if(*pfsit != 150000){return false;} ++pfsit;
304  if(*pfsit != 300000){return false;} ++pfsit;
305  if(*pfsit != 600000){return false;} ++pfsit;
306  if(*pfsit != 900000){return false;} ++pfsit;
307  if(scanner->getPulseLength_ns() != 2) return false;
308  if( std::fabs(
309  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.3490659
310  ) > eps
311  ) return false;
312  if(scanner->getBeamDeflector()->cfg_device_scanFreqMin_Hz != 28)
313  return false;
314  if(scanner->getBeamDeflector()->cfg_device_scanFreqMax_Hz != 200)
315  return false;
316  if(std::fabs(scanner->getWavelength()-1064e-9) > eps) return false;
317  epdiff = scanner->getHeadRelativeEmitterPosition()
318  - glm::dvec3(0, 0.085, 0.06);
319  if(
320  std::fabs(epdiff[0]) > eps ||
321  std::fabs(epdiff[1]) > eps ||
322  std::fabs(epdiff[2]) > eps
323  ) return false;
324  eatt = scanner->getHeadRelativeEmitterAttitude();
325  if(
326  eatt.getQ0()!=1 || eatt.getQ1()!=0 ||
327  eatt.getQ2()!=0 || eatt.getQ3()!=0
328  ) return false;
329  eraxis = scanner->getScannerHead()->cfg_device_rotateAxis;
330  if(eraxis[0] != 0 || eraxis[1] != 0 || eraxis[2] != 1) return false;
331  // Load and validate LIVOX Mid-70
332  scanner = std::static_pointer_cast<Scanner>(
333  loader.getAssetById("scanner", "livox_mid-70", nullptr)
334  );
335  if(std::dynamic_pointer_cast<SingleScanner>(scanner)==nullptr)
336  return false;
337  if(std::dynamic_pointer_cast<MultiScanner>(scanner)!=nullptr)
338  return false;
339  if(scanner->getScannerId() != "livox_mid-70") return false;
340  if(scanner->getDetector()->cfg_device_accuracy_m != 0.02) return false;
341  if(scanner->getBeamDivergence() != 0.004887) return false;
342  if(scanner->name != "Livox Mid-70") return false;
343  if(
344  std::dynamic_pointer_cast<RisleyBeamDeflector>(
345  scanner->getBeamDeflector()
346  ) == nullptr
347  ) return false;
348  pfs = scanner->getSupportedPulseFreqs_Hz();
349  if(pfs.size() != 1) return false;
350  if(pfs.front() != 100000) return false;
351  if(scanner->getPulseLength_ns() != 4) return false;
352  if(scanner->getDetector()->cfg_device_rangeMin_m != 2) return false;
353  if( std::fabs(
354  scanner->getBeamDeflector()->cfg_device_scanAngleMax_rad-0.6108652
355  ) > eps
356  ) return false;
357  if( std::fabs(
358  std::dynamic_pointer_cast<RisleyBeamDeflector>(
359  scanner->getBeamDeflector()
360  )->rotorSpeed_rad_1 - 1160.876155 // Hz / (2 pi)
361  ) > eps
362  ) return false;
363  if( std::fabs(
364  std::dynamic_pointer_cast<RisleyBeamDeflector>(
365  scanner->getBeamDeflector()
366  )->rotorSpeed_rad_2 + 742.298655 // Hz / (2 pi)
367  ) > eps
368  ) return false;
369  if(std::fabs(scanner->getWavelength()-905e-9) > eps) return false;
370  if(scanner->getMaxNOR() != 1) return false;
371  if(scanner->getFWFSettings().beamSampleQuality != 3) return false;
372  epdiff = scanner->getHeadRelativeEmitterPosition();
373  if(
374  std::fabs(epdiff[0]) > eps ||
375  std::fabs(epdiff[1]) > eps ||
376  std::fabs(epdiff[2]) > eps
377  ) return false;
378  eatt = scanner->getHeadRelativeEmitterAttitude();
379  if(
380  std::fabs(eatt.getQ0()-0.5)>eps || std::fabs(eatt.getQ1()+0.5)>eps ||
381  std::fabs(eatt.getQ2()+0.5)>eps || std::fabs(eatt.getQ3()+0.5)>eps
382  ) return false;
383  eraxis = scanner->getScannerHead()->cfg_device_rotateAxis;
384  if(eraxis[0] != 1 || eraxis[1] != 0 || eraxis[2] != 0) return false;
385  // Load and validate LIVOX Mid-100 with triple channel scanner
386  scanner = std::static_pointer_cast<Scanner>(
387  loader.getAssetById("scanner", "livox-mid-100", nullptr)
388  );
389  if(std::dynamic_pointer_cast<SingleScanner>(scanner) != nullptr)
390  return false;
391  if(std::dynamic_pointer_cast<MultiScanner>(scanner) == nullptr)
392  return false;
393  if(scanner->getScannerId() != "livox-mid-100") return false;
394  if(scanner->getDetector(0)->cfg_device_accuracy_m != 0.02) return false;
395  if(scanner->getDetector(1)->cfg_device_accuracy_m != 0.03) return false;
396  if(scanner->getDetector(2)->cfg_device_accuracy_m != 0.02) return false;
397  if(scanner->getBeamDivergence(0) != 0.0027) return false;
398  if(scanner->getBeamDivergence(1) != 0.0027) return false;
399  if(scanner->getBeamDivergence(2) != 0.0027) return false;
400  if( std::dynamic_pointer_cast<RisleyBeamDeflector>(
401  scanner->getBeamDeflector(0)
402  ) == nullptr
403  ) return false;
404  if( std::dynamic_pointer_cast<RisleyBeamDeflector>(
405  scanner->getBeamDeflector(1)
406  ) == nullptr
407  ) return false;
408  if( std::dynamic_pointer_cast<RisleyBeamDeflector>(
409  scanner->getBeamDeflector(2)
410  ) != nullptr
411  ) return false;
412  if( std::dynamic_pointer_cast<ConicBeamDeflector>(
413  scanner->getBeamDeflector(2)
414  ) == nullptr
415  ) return false;
416  pfs = scanner->getSupportedPulseFreqs_Hz();
417  if(pfs.size() != 1) return false;
418  if(pfs.front() != 50000) return false;
419  if(scanner->getPulseLength_ns(0) != 4) return false;
420  if(scanner->getPulseLength_ns(1) != 4) return false;
421  if(scanner->getPulseLength_ns(2) != 4) return false;
422  if(scanner->getDetector(0)->cfg_device_rangeMin_m != 2) return false;
423  if(scanner->getDetector(1)->cfg_device_rangeMin_m != 2) return false;
424  if(scanner->getDetector(2)->cfg_device_rangeMin_m != 2) return false;
425  if( std::fabs(
426  scanner->getBeamDeflector(0)->cfg_device_scanAngleMax_rad-0.6108652
427  ) > eps
428  ) return false;
429  if( std::fabs(
430  scanner->getBeamDeflector(1)->cfg_device_scanAngleMax_rad-0.6108652
431  ) > eps
432  ) return false;
433  if( std::fabs(
434  scanner->getBeamDeflector(2)->cfg_device_scanAngleMax_rad-0.6108652
435  ) > eps
436  ) return false;
437  if( std::fabs(
438  std::dynamic_pointer_cast<RisleyBeamDeflector>(
439  scanner->getBeamDeflector(0)
440  )->rotorSpeed_rad_1 - 1114.084602
441  ) > eps
442  ) return false;
443  if( std::fabs(
444  std::dynamic_pointer_cast<RisleyBeamDeflector>(
445  scanner->getBeamDeflector(1)
446  )->rotorSpeed_rad_1 - 1160.876155
447  ) > eps
448  ) return false;
449  if( std::fabs(
450  std::dynamic_pointer_cast<RisleyBeamDeflector>(
451  scanner->getBeamDeflector(0)
452  )->rotorSpeed_rad_2 + 636.6197724
453  ) > eps
454  ) return false;
455  if( std::fabs(
456  std::dynamic_pointer_cast<RisleyBeamDeflector>(
457  scanner->getBeamDeflector(1)
458  )->rotorSpeed_rad_2 + 742.298655
459  ) > eps
460  ) return false;
461  if(std::fabs(scanner->getWavelength(0)-905e-9) > eps) return false;
462  if(std::fabs(scanner->getWavelength(1)-905e-9) > eps) return false;
463  if(std::fabs(scanner->getWavelength(2)-905e-9) > eps) return false;
464  if(scanner->getFWFSettings(0).beamSampleQuality != 2) return false;
465  if(scanner->getFWFSettings(1).beamSampleQuality != 3) return false;
466  if(scanner->getFWFSettings(2).beamSampleQuality != 4) return false;
467  epdiff = scanner->getHeadRelativeEmitterPosition(0)-glm::dvec3(0, 0, 0.1);
468  if(
469  std::fabs(epdiff[0]) > eps ||
470  std::fabs(epdiff[1]) > eps ||
471  std::fabs(epdiff[2]) > eps
472  ) return false;
473  epdiff = scanner->getHeadRelativeEmitterPosition(1) -
474  glm::dvec3(0, 0, -0.1);
475  if(
476  std::fabs(epdiff[0]) > eps ||
477  std::fabs(epdiff[1]) > eps ||
478  std::fabs(epdiff[2]) > eps
479  ) return false;
480  epdiff = scanner->getHeadRelativeEmitterPosition(2);
481  if(
482  std::fabs(epdiff[0]) > eps ||
483  std::fabs(epdiff[1]) > eps ||
484  std::fabs(epdiff[2]) > eps
485  ) return false;
486  eatt = scanner->getHeadRelativeEmitterAttitude(0);
487  if(
488  std::fabs(eatt.getQ0()-0.965926) > eps ||
489  std::fabs(eatt.getQ1()) > eps ||
490  std::fabs(eatt.getQ2()) > eps ||
491  std::fabs(eatt.getQ3()-0.258819) > eps
492  ) return false;
493  eatt = scanner->getHeadRelativeEmitterAttitude(1);
494  if(
495  std::fabs(eatt.getQ0()-1) > eps ||
496  std::fabs(eatt.getQ1()) > eps ||
497  std::fabs(eatt.getQ2()) > eps ||
498  std::fabs(eatt.getQ3()) > eps
499  ) return false;
500  eatt = scanner->getHeadRelativeEmitterAttitude(2);
501  if(
502  std::fabs(eatt.getQ0()-0.965926) > eps ||
503  std::fabs(eatt.getQ1()) > eps ||
504  std::fabs(eatt.getQ2()) > eps ||
505  std::fabs(eatt.getQ3()+0.258819) > eps
506  ) return false;
507  eraxis = scanner->getScannerHead(0)->cfg_device_rotateAxis;
508  if(eraxis[0] != 1 || eraxis[1] != 0 || eraxis[2] != 0) return false;
509  eraxis = scanner->getScannerHead(1)->cfg_device_rotateAxis;
510  if(eraxis[0] != 0 || eraxis[1] != 1 || eraxis[2] != 0) return false;
511  eraxis = scanner->getScannerHead(2)->cfg_device_rotateAxis;
512  if(eraxis[0] != 0 || eraxis[1] != 1 || eraxis[2] != 0) return false;
513  // Load and validate unexistent scanner
514  try{
515  scanner = std::dynamic_pointer_cast<Scanner>(loader.getAssetById(
516  "scanner", "_unexistent_scanner_", nullptr
517  ));
518  return false; // Must not be reached, exception before
519  }
520  catch(HeliosException &hex){}
521  return true;
522 }
523 
525  // Prepare platform loading
526  std::string testPlatformsPath = "data/test/test_platforms.xml";
527  std::string assetsPath = "assets/";
528  XmlAssetsLoader loader(testPlatformsPath, assetsPath);
529  // Load and validate Quadrocopter UAV
530  std::shared_ptr<Platform> platf = std::dynamic_pointer_cast<Platform>(
531  loader.getAssetById("platform", "quadcopter", nullptr)
532  );
533  std::shared_ptr<HelicopterPlatform> hplatf = std::dynamic_pointer_cast<
535  >(platf);
536  if(hplatf == nullptr) return false;
537  if(platf->name != "Quadrocopter UAV") return false;
538  if(hplatf->mCfg_drag != 0.0099) return false;
539  if(hplatf->ef_xy_max != 0.099) return false;
540  if(hplatf->cfg_speedup_magnitude != 1.99) return false;
541  if(hplatf->cfg_slowdown_magnitude != 1.99) return false;
542  if(hplatf->cfg_slowdown_dist_xy != 4.99) return false;
543  if(std::fabs(hplatf->cfg_pitch_base+0.0959931) > eps) return false;
544  if(std::fabs(hplatf->cfg_roll_speed-0.5087635) > eps) return false;
545  if(std::fabs(hplatf->cfg_pitch_speed-1.5086626) > eps) return false;
546  if(std::fabs(hplatf->cfg_yaw_speed-1.4999360) > eps) return false;
547  if(std::fabs(hplatf->cfg_max_roll_offset-0.4433136) > eps) return false;
548  if(std::fabs(hplatf->cfg_max_pitch_offset-0.6038839) > eps) return false;
549  glm::dvec3 mpdiff = platf->cfg_device_relativeMountPosition - glm::dvec3(
550  0, 0, 0.21
551  );
552  if(
553  std::fabs(mpdiff[0]) > eps ||
554  std::fabs(mpdiff[1]) > eps ||
555  std::fabs(mpdiff[2]) > eps
556  ) return false;
557  Rotation matt = platf->cfg_device_relativeMountAttitude;
558  if(
559  std::fabs(matt.getQ0()-0) > eps ||
560  std::fabs(matt.getQ1()-0) > eps ||
561  std::fabs(matt.getQ2()+1) > eps ||
562  std::fabs(matt.getQ3()-0) > eps
563  ) return false;
564  // Load and validate Cirrus SR-22
565  platf = std::dynamic_pointer_cast<Platform>(loader.getAssetById(
566  "platform", "sr22", nullptr
567  ));
568  if(platf->name != "Cirrus SR-22") return false;
569  mpdiff = platf->cfg_device_relativeMountPosition - glm::dvec3(0, 0, 0.7);
570  if(
571  std::fabs(mpdiff[0]) > eps ||
572  std::fabs(mpdiff[1]) > eps ||
573  std::fabs(mpdiff[2]) > eps
574  ) return false;
575  matt = platf->cfg_device_relativeMountAttitude;
576  if(
577  std::fabs(matt.getQ0()-0.5) > eps ||
578  std::fabs(matt.getQ1()-0.5) > eps ||
579  std::fabs(matt.getQ2()-0.5) > eps ||
580  std::fabs(matt.getQ3()+0.5) > eps
581  ) return false;
582  if(platf->positionXNoiseSource->getClipMin()!=0.0) return false;
583  if(platf->positionXNoiseSource->getClipMax()!=0.0) return false;
584  if(platf->positionXNoiseSource->isClipEnabled()) return false;
585  if(platf->positionXNoiseSource->getFixedLifespan()!=5) return false;
586  std::shared_ptr<NormalNoiseSource<double>> nns = std::dynamic_pointer_cast<
588  >(platf->positionXNoiseSource);
589  if(nns == nullptr) return false;
590  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
591  platf->positionXNoiseSource
592  ) != nullptr
593  ) return false;
594  if(nns->getMean()!=0.01) return false;
595  if(nns->getStdev()!=0.021) return false;
596  if(platf->positionYNoiseSource->getClipMin()!=-0.01) return false;
597  if(platf->positionYNoiseSource->getClipMax()!=0.0) return false;
598  if(platf->positionYNoiseSource->isClipEnabled()) return false;
599  if(platf->positionYNoiseSource->getFixedLifespan()!=7) return false;
600  nns = std::dynamic_pointer_cast<NormalNoiseSource<double>>(
601  platf->positionYNoiseSource);
602  if(nns == nullptr) return false;
603  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
604  platf->positionYNoiseSource
605  ) != nullptr
606  ) return false;
607  if(nns->getMean()!=-0.01) return false;
608  if(nns->getStdev()!=0.019) return false;
609  if(platf->positionZNoiseSource->getClipMin()!=-0.03) return false;
610  if(platf->positionZNoiseSource->getClipMax()!=0.03) return false;
611  if(!platf->positionZNoiseSource->isClipEnabled()) return false;
612  if(platf->positionZNoiseSource->getFixedLifespan()!=1) return false;
613  nns = std::dynamic_pointer_cast<NormalNoiseSource<double>>(
614  platf->positionZNoiseSource);
615  if(nns == nullptr) return false;
616  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
617  platf->positionZNoiseSource
618  ) != nullptr
619  ) return false;
620  if(nns->getMean()!=0.0) return false;
621  if(nns->getStdev()!=0.02) return false;
622  if(platf->attitudeXNoiseSource->getClipMin()!=0.0) return false;
623  if(platf->attitudeXNoiseSource->getClipMax()!=0.0) return false;
624  if(platf->attitudeXNoiseSource->isClipEnabled()) return false;
625  if(platf->attitudeXNoiseSource->getFixedLifespan()!=1) return false;
626  nns = std::dynamic_pointer_cast<NormalNoiseSource<double>>(
627  platf->attitudeXNoiseSource
628  );
629  if(nns == nullptr) return false;
630  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
631  platf->attitudeXNoiseSource
632  ) != nullptr
633  ) return false;
634  if(nns->getMean()!=0.0) return false;
635  if(nns->getStdev()!=0.001) return false;
636  if(platf->attitudeYNoiseSource->getClipMin()!=0.0) return false;
637  if(platf->attitudeYNoiseSource->getClipMax()!=0.0) return false;
638  if(platf->attitudeYNoiseSource->isClipEnabled()) return false;
639  if(platf->attitudeYNoiseSource->getFixedLifespan()!=3) return false;
640  nns = std::dynamic_pointer_cast<NormalNoiseSource<double>>(
641  platf->attitudeYNoiseSource
642  );
643  if(nns == nullptr) return false;
644  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
645  platf->attitudeYNoiseSource
646  ) != nullptr
647  ) return false;
648  if(nns->getMean()!=0.0) return false;
649  if(nns->getStdev()!=0.001) return false;
650  if(platf->attitudeZNoiseSource->getClipMin()!=0.0) return false;
651  if(platf->attitudeZNoiseSource->getClipMax()!=0.0) return false;
652  if(platf->attitudeZNoiseSource->isClipEnabled()) return false;
653  if(platf->attitudeZNoiseSource->getFixedLifespan()!=11) return false;
654  nns = std::dynamic_pointer_cast<NormalNoiseSource<double>>(
655  platf->attitudeZNoiseSource
656  );
657  if(nns == nullptr) return false;
658  if( std::dynamic_pointer_cast<UniformNoiseSource<double>>(
659  platf->attitudeZNoiseSource
660  ) != nullptr
661  ) return false;
662  if(nns->getMean()!=0.0) return false;
663  if(nns->getStdev()!=0.001) return false;
664  // Load and validate Tractor
665  platf = std::dynamic_pointer_cast<Platform>(loader.getAssetById(
666  "platform", "tractor"
667  ));
668  if(platf->name != "Tractor") return false;
669  mpdiff = platf->cfg_device_relativeMountPosition - glm::dvec3(0, 1, 4);
670  if(
671  std::fabs(mpdiff[0]) > eps ||
672  std::fabs(mpdiff[1]) > eps ||
673  std::fabs(mpdiff[2]) > eps
674  ) return false;
675  matt = platf->cfg_device_relativeMountAttitude;
676  if(
677  std::fabs(matt.getQ0()-0.6830127) > eps ||
678  std::fabs(matt.getQ1()+0.1830127) > eps ||
679  std::fabs(matt.getQ2()-0.1830127) > eps ||
680  std::fabs(matt.getQ3()+0.6830127) > eps
681  ) return false;
682  std::shared_ptr<GroundVehiclePlatform> gplatf = std::dynamic_pointer_cast<
683  GroundVehiclePlatform>(platf);
684  if(gplatf == nullptr) return false;
685  if(gplatf->mCfg_drag != 0.00499) return false;
686  // Load and validate Tripod
687  platf = std::dynamic_pointer_cast<Platform>(
688  loader.getAssetById("platform", "tripod", nullptr)
689  );
690  if(platf->name != "TLS Tripod") return false;
691  mpdiff = platf->cfg_device_relativeMountPosition - glm::dvec3(0, 0, 1.5);
692  if(
693  std::fabs(mpdiff[0]) > eps ||
694  std::fabs(mpdiff[1]) > eps ||
695  std::fabs(mpdiff[2]) > eps
696  ) return false;
697  return true;
698 }
699 
701  // TODO Rethink : Implement
702  return true;
703 }
704 
706  // TODO Rethink : Implement
707  return true;
708 }
709 
711  // TODO Rethink : Implement
712  return true;
713 }
714 
716  // TODO Rethink : Implement
717  return true;
718 }
719 
721  // TODO Rethink : Implement
722  return true;
723 }
724 
726  // TODO Rethink : Implement
727  return true;
728 }
729 
730 
731 }
Class representing a ground vehicle platform.
Definition: GroundVehiclePlatform.h:11
Class representing a helicopter platform.
Definition: HelicopterPlatform.h:12
Base class for Helios exceptions.
Definition: HeliosException.h:12
Asset loading tests.
Definition: AssetLoadingTest.h:30
double const eps
Decimal precision tolerance.
Definition: AssetLoadingTest.h:37
bool testSceneLoading()
Test scene loading.
Definition: AssetLoadingTest.h:720
bool testObjLoading()
Test Wavefront OBJ loading.
Definition: AssetLoadingTest.h:700
bool testScannerLoading()
Test scanner loading.
Definition: AssetLoadingTest.h:121
bool testSurveyLoading()
Test survey loading.
Definition: AssetLoadingTest.h:725
bool testDetailedVoxelLoading()
Test detailed voxel loading.
Definition: AssetLoadingTest.h:710
bool testTiffLoading()
Test TIFF loading.
Definition: AssetLoadingTest.h:715
AssetLoadingTest()
Asset loading test constructor.
Definition: AssetLoadingTest.h:44
bool testPlatformLoading()
Test platform loading.
Definition: AssetLoadingTest.h:524
bool run() override
Definition: AssetLoadingTest.h:100
bool testVoxelLoading()
Test voxel loading.
Definition: AssetLoadingTest.h:705
BaseTest class.
Definition: BaseTest.h:20
Class for normal noise handling.
Definition: NormalNoiseSource.h:16
glm::dvec3 cfg_device_relativeMountPosition
Device mount position relative to the platform.
Definition: Platform.h:29
Definition: Rotation.h:80
double getQ2() const
Get the second coordinate of the vectorial part of the quaternion.
Definition: Rotation.h:130
double getQ1() const
Get the first coordinate of the vectorial part of the quaternion.
Definition: Rotation.h:122
double getQ3() const
Get the third coordinate of the vectorial part of the quaternion.
Definition: Rotation.h:137
double getQ0() const
Get the scalar coordinate of the quaternion.
Definition: Rotation.h:115
Class for asset loading from XML file.
Definition: XmlAssetsLoader.h:28
std::shared_ptr< Asset > getAssetById(std::string type, std::string id, void *extraOutput=nullptr)
Get asset by its identifier.
Definition: XmlAssetsLoader.cpp:1546