00001
00020
00021
00022
00023
00024
00025
00026 #define RANSAC_FIRST 1
00027
00028
00029
00030
00031
00032 #define ATRV 0
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #define VISIBILITY_MAP 0
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #define RELEVANCE_TEST 0
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 #define RELEVANCE_TEST_P 0
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 #define SEGMENT_BASED 0
00112 #if SEGMENT_BASED>1
00113 #define SEGMENT_NOISE_FACTOR 5
00114 #else
00115 #define SEGMENT_NOISE_FACTOR 1
00116 #endif
00117
00118 #if SEGMENT_BASED
00119 #ifndef HAVE_MODULE_DSEG
00120 #error "dseg module is required for segment based slam"
00121 #endif
00122 #endif
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 #define REAL_TIME_LIVE_RUN 0
00133
00134
00135
00136
00137
00138
00139
00140
00141 #define STATE_HISTORY 0
00142
00143
00149 #include <iostream>
00150 #include <boost/shared_ptr.hpp>
00151
00152 #include <boost/filesystem.hpp>
00153 #include <time.h>
00154 #include <signal.h>
00155 #include <map>
00156 #include <getopt.h>
00157 #include "kernel/keyValueFile.hpp"
00158
00159
00160 #include "kernel/jafarDebug.hpp"
00161 #include "kernel/timingTools.hpp"
00162 #include "kernel/dataLog.hpp"
00163 #include "kernel/threads.hpp"
00164 #include "jmath/random.hpp"
00165 #include "jmath/matlab.hpp"
00166 #include "jmath/ublasExtra.hpp"
00167 #include "jmath/angle.hpp"
00168
00169 #include "rtslam/rtSlam.hpp"
00170 #include "rtslam/rawProcessors.hpp"
00171 #include "rtslam/rawSegProcessors.hpp"
00172 #include "rtslam/robotOdometry.hpp"
00173 #include "rtslam/robotConstantVelocity.hpp"
00174 #include "rtslam/robotConstantMotionModel.hpp"
00175 #include "rtslam/robotInertial.hpp"
00176 #include "rtslam/sensorPinhole.hpp"
00177 #include "rtslam/sensorAbsloc.hpp"
00178 #include "rtslam/landmarkAnchoredHomogeneousPoint.hpp"
00179 #include "rtslam/landmarkAnchoredHomogeneousPointsLine.hpp"
00180
00181 #include "rtslam/observationFactory.hpp"
00182 #include "rtslam/observationMakers.hpp"
00183 #include "rtslam/activeSearch.hpp"
00184 #include "rtslam/activeSegmentSearch.hpp"
00185 #include "rtslam/featureAbstract.hpp"
00186 #include "rtslam/rawImage.hpp"
00187 #include "rtslam/descriptorImagePoint.hpp"
00188 #include "rtslam/descriptorSeg.hpp"
00189 #include "rtslam/dataManagerOnePointRansac.hpp"
00190 #include "rtslam/sensorManager.hpp"
00191 #include "rtslam/historyManager.hpp"
00192
00193 #include "rtslam/hardwareSensorCameraFirewire.hpp"
00194 #include "rtslam/hardwareSensorCameraUeye.hpp"
00195 #include "rtslam/hardwareSensorMti.hpp"
00196 #include "rtslam/hardwareSensorGpsGenom.hpp"
00197 #include "rtslam/hardwareSensorMocap.hpp"
00198 #include "rtslam/hardwareEstimatorOdo.hpp"
00199 #include "rtslam/hardwareSensorExternalLoc.hpp"
00200 #include "rtslam/hardwareSensorOdomRmp400Genom.hpp"
00201
00202 #include "rtslam/display_qt.hpp"
00203 #include "rtslam/display_gdhe.hpp"
00204
00205 #include "rtslam/simuRawProcessors.hpp"
00206 #include "rtslam/hardwareSensorAdhocSimulator.hpp"
00207 #include "rtslam/hardwareSensorInertialAdhocSimulator.hpp"
00208 #include "rtslam/exporterSocket.hpp"
00209
00210
00216 using namespace jblas;
00217 using namespace jafar;
00218 using namespace jafar::jmath;
00219 using namespace jafar::jmath::ublasExtra;
00220 using namespace jafar::rtslam;
00221 using namespace boost;
00222
00223
00224 typedef ImagePointObservationMaker<ObservationPinHoleEuclideanPoint, SensorPinhole, LandmarkEuclideanPoint,
00225 AppearanceImagePoint, SensorAbstract::PINHOLE, LandmarkAbstract::PNT_EUC> PinholeEucpObservationMaker;
00226 typedef ImagePointObservationMaker<ObservationPinHoleEuclideanPoint, SensorPinhole, LandmarkEuclideanPoint,
00227 simu::AppearanceSimu, SensorAbstract::PINHOLE, LandmarkAbstract::PNT_EUC> PinholeEucpSimuObservationMaker;
00228 typedef ImagePointObservationMaker<ObservationPinHoleAnchoredHomogeneousPoint, SensorPinhole, LandmarkAnchoredHomogeneousPoint,
00229 AppearanceImagePoint, SensorAbstract::PINHOLE, LandmarkAbstract::PNT_AH> PinholeAhpObservationMaker;
00230 typedef ImagePointObservationMaker<ObservationPinHoleAnchoredHomogeneousPoint, SensorPinhole, LandmarkAnchoredHomogeneousPoint,
00231 simu::AppearanceSimu, SensorAbstract::PINHOLE, LandmarkAbstract::PNT_AH> PinholeAhpSimuObservationMaker;
00232
00233 typedef DataManagerOnePointRansac<RawImage, SensorPinhole, FeatureImagePoint, image::ConvexRoi, ActiveSearchGrid, ImagePointHarrisDetector, ImagePointZnccMatcher> DataManager_ImagePoint_Ransac;
00234 typedef DataManagerOnePointRansac<simu::RawSimu, SensorPinhole, simu::FeatureSimu, image::ConvexRoi, ActiveSearchGrid, simu::DetectorSimu<image::ConvexRoi>, simu::MatcherSimu<image::ConvexRoi> > DataManager_ImagePoint_Ransac_Simu;
00235
00236 #if SEGMENT_BASED
00237 typedef SegmentObservationMaker<ObservationPinHoleAnchoredHomogeneousPointsLine, SensorPinhole, LandmarkAnchoredHomogeneousPointsLine,
00238 AppearanceImageSegment, SensorAbstract::PINHOLE, LandmarkAbstract::LINE_AHPL> PinholeAhplObservationMaker;
00239 typedef SegmentObservationMaker<ObservationPinHoleAnchoredHomogeneousPointsLine, SensorPinhole, LandmarkAnchoredHomogeneousPointsLine,
00240 simu::AppearanceSimu, SensorAbstract::PINHOLE, LandmarkAbstract::LINE_AHPL> PinholeAhplSimuObservationMaker;
00241
00242 typedef DataManagerOnePointRansac<RawImage, SensorPinhole, FeatureImageSegment, image::ConvexRoi, ActiveSegmentSearchGrid, HDsegDetector, DsegMatcher> DataManager_ImageSeg_Test;
00243 typedef DataManagerOnePointRansac<simu::RawSimu, SensorPinhole, simu::FeatureSimu, image::ConvexRoi, ActiveSegmentSearchGrid, simu::DetectorSimu<image::ConvexRoi>, simu::MatcherSimu<image::ConvexRoi> > DataManager_Segment_Ransac_Simu;
00244 #endif
00245
00246 hardware::Mode mode = hardware::mOnline;
00247 time_t rseed;
00248
00249
00255 enum { iDispQt = 0, iDispGdhe, iRenderAll, iReplay, iDump, iRandSeed, iPause, iVerbose, iMap, iRobot, iCamera, iTrigger, iGps, iOdom, iExtloc, iSimu, iExport, iCamsFilter, nIntOpts };
00256 int intOpts[nIntOpts] = {0};
00257 const int nFirstIntOpt = 0, nLastIntOpt = nIntOpts-1;
00258
00259 enum { fFreq = 0, fShutter, fHeading, fNoisySensors, nFloatOpts };
00260 double floatOpts[nFloatOpts] = {0.0};
00261 const int nFirstFloatOpt = nIntOpts, nLastFloatOpt = nIntOpts+nFloatOpts-1;
00262
00263 enum { sDataPath = 0, sConfigSetup, sConfigEstimation, sLog, nStrOpts };
00264 std::string strOpts[nStrOpts];
00265 const int nFirstStrOpt = nIntOpts+nFloatOpts, nLastStrOpt = nIntOpts+nFloatOpts+nStrOpts-1;
00266
00267 enum { bHelp = 0, bUsage, nBreakingOpts };
00268 const int nFirstBreakingOpt = nIntOpts+nFloatOpts+nStrOpts, nLastBreakingOpt = nIntOpts+nFloatOpts+nStrOpts+nBreakingOpts-1;
00269
00271
00272 struct option long_options[] = {
00273
00274 {"disp-2d", 2, 0, 0},
00275 {"disp-3d", 2, 0, 0},
00276 {"render-all", 2, 0, 0},
00277 {"replay", 2, 0, 0},
00278 {"dump", 2, 0, 0},
00279 {"rand-seed", 2, 0, 0},
00280 {"pause", 2, 0, 0},
00281 {"verbose", 2, 0, 0},
00282 {"map", 2, 0, 0},
00283 {"robot", 2, 0, 0},
00284 {"camera", 2, 0, 0},
00285 {"trigger", 2, 0, 0},
00286 {"gps", 2, 0, 0},
00287 {"odom", 2, 0, 0},
00288 {"extloc", 2, 0, 0},
00289 {"simu", 2, 0, 0},
00290 {"export", 2, 0, 0},
00291 {"cams-filter", 2, 0, 0},
00292
00293 {"freq", 2, 0, 0},
00294 {"shutter", 2, 0, 0},
00295 {"heading", 2, 0, 0},
00296 {"noisy-sensors", 2, 0, 0},
00297
00298 {"data-path", 1, 0, 0},
00299 {"config-setup", 1, 0, 0},
00300 {"config-estimation", 1, 0, 0},
00301 {"log", 1, 0, 0},
00302
00303 {"help",0,0,0},
00304 {"usage",0,0,0},
00305 };
00306
00312 const int slam_sched = SCHED_RR;
00313 const int slam_priority = 30;
00314 const int display_niceness = 10;
00315 const int display_period = 100;
00316
00317
00318 class ConfigSetup: public kernel::KeyValueFileSaveLoad
00319 {
00320 public:
00322 jblas::vec CAMERA_POSE_CONSTVEL[2];
00323 jblas::vec CAMERA_POSE_INERTIAL[2];
00324 jblas::vec GPS_POSE;
00325 jblas::vec ROBOT_POSE;
00326
00327 unsigned CAMERA_TYPE[2];
00328 unsigned CAMERA_FORMAT[2];
00329 std::string CAMERA_DEVICE[2];
00330 unsigned CAMERA_IMG_WIDTH[2];
00331 unsigned CAMERA_IMG_HEIGHT[2];
00332 jblas::vec4 CAMERA_INTRINSIC[2];
00333 jblas::vec3 CAMERA_DISTORTION[2];
00334 std::string CAMERA_CALIB[2];
00335
00337 unsigned CAMERA_IMG_WIDTH_SIMU[2];
00338 unsigned CAMERA_IMG_HEIGHT_SIMU[2];
00339 jblas::vec4 CAMERA_INTRINSIC_SIMU[2];
00340 jblas::vec3 CAMERA_DISTORTION_SIMU[2];
00341
00343 double UNCERT_VLIN;
00344 double UNCERT_VANG;
00345 double PERT_VLIN;
00346 double PERT_VANG;
00347
00349 std::string MTI_DEVICE;
00350 double ACCELERO_FULLSCALE;
00351 double ACCELERO_NOISE;
00352 double GYRO_FULLSCALE;
00353 double GYRO_NOISE;
00354
00355 double INITIAL_GRAVITY;
00356 double UNCERT_GRAVITY;
00357 double UNCERT_ABIAS;
00358 double UNCERT_WBIAS;
00359 double PERT_AERR;
00360 double PERT_WERR;
00361 double PERT_RANWALKACC;
00362 double PERT_RANWALKGYRO;
00363
00364 double INITIAL_HEADING;
00365 double UNCERT_HEADING;
00366 double UNCERT_ATTITUDE;
00367
00368 double IMU_TIMESTAMP_CORRECTION;
00369 double GPS_TIMESTAMP_CORRECTION;
00370
00372 double dxNDR;
00373 double dvNDR;
00374
00375 double ODO_TIMESTAMP_CORRECTION;
00376 jblas::vec4 ODO_CALIB;
00377 double GPS_MAX_CONSIST_SIG;
00378
00380 double SIMU_IMU_TIMESTAMP_CORRECTION;
00381 double SIMU_IMU_FREQ;
00382 double SIMU_IMU_GRAVITY;
00383 double SIMU_IMU_GYR_BIAS;
00384 double SIMU_IMU_GYR_BIAS_NOISESTD;
00385 double SIMU_IMU_GYR_GAIN;
00386 double SIMU_IMU_GYR_GAIN_NOISESTD;
00387 double SIMU_IMU_RANDWALKGYR_FACTOR;
00388 double SIMU_IMU_ACC_BIAS;
00389 double SIMU_IMU_ACC_BIAS_NOISESTD;
00390 double SIMU_IMU_ACC_GAIN;
00391 double SIMU_IMU_ACC_GAIN_NOISESTD;
00392 double SIMU_IMU_RANDWALKACC_FACTOR;
00393
00394 private:
00395 void processKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile, bool read);
00396 public:
00397 virtual void loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile);
00398 virtual void saveKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile);
00399 } configSetup;
00400
00401
00402
00403 class ConfigEstimation: public kernel::KeyValueFileSaveLoad
00404 {
00405 public:
00407 unsigned CORRECTION_SIZE;
00408
00410 unsigned MAP_SIZE;
00411 double PIX_NOISE;
00412 double PIX_NOISE_SIMUFACTOR;
00413
00415 double D_MIN;
00416 double REPARAM_TH;
00417
00418 unsigned GRID_HCELLS;
00419 unsigned GRID_VCELLS;
00420 unsigned GRID_MARGIN;
00421 unsigned GRID_SEPAR;
00422
00423 double RELEVANCE_TH;
00424 double MAHALANOBIS_TH;
00425 unsigned N_UPDATES_TOTAL;
00426 unsigned N_UPDATES_RANSAC;
00427 unsigned N_INIT;
00428 unsigned N_RECOMP_GAINS;
00429 double RANSAC_LOW_INNOV;
00430
00431 unsigned RANSAC_NTRIES;
00432 bool MULTIPLE_DEPTH_HYPOS;
00433
00435 unsigned HARRIS_CONV_SIZE;
00436 double HARRIS_TH;
00437 double HARRIS_EDDGE;
00438
00439 unsigned DESC_SIZE;
00440 bool MULTIVIEW_DESCRIPTOR;
00441 double DESC_SCALE_STEP;
00442 double DESC_ANGLE_STEP;
00443 int DESC_PREDICTION_TYPE;
00444
00445 unsigned PATCH_SIZE;
00446 unsigned MAX_SEARCH_SIZE;
00447 unsigned KILL_SEARCH_SIZE;
00448 double MATCH_TH;
00449 double MIN_SCORE;
00450 double HI_MATCH_TH;
00451 double HI_LIMIT;
00452 double PARTIAL_POSITION;
00453
00454 private:
00455 void processKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile, bool read);
00456 public:
00457 virtual void loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile);
00458 virtual void saveKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile);
00459 } configEstimation;
00460
00461
00462
00468
00469 template<typename T>
00470 class VariableConditionPlus: public kernel::VariableCondition<T>
00471 {
00472 public:
00473 VariableConditionPlus(const T &val_init): kernel::VariableCondition<T>(val_init) {}
00474 template<typename Pred, typename duration_type>
00475 bool timed_wait(Pred pred, duration_type const & rel_time, bool unlock = true)
00476 {
00477 boost::unique_lock<boost::mutex> l(kernel::VariableMutex<T>::m);
00478 while(!pred(kernel::VariableMutex<T>::var))
00479 if(!kernel::VariableCondition<T>::c.timed_wait(l, rel_time)) return pred(kernel::VariableMutex<T>::var);
00480 return true;
00481 }
00482 };
00483
00484
00485
00486 boost::scoped_ptr<kernel::LoggerTask> loggerTask;
00487 boost::scoped_ptr<kernel::DataLogger> dataLogger;
00488 sensor_manager_ptr_t sensorManager;
00489 boost::shared_ptr<ExporterAbstract> exporter;
00490 world_ptr_t worldPtr;
00491 #ifdef HAVE_MODULE_QDISPLAY
00492 display::ViewerQt *viewerQt = NULL;
00493 #endif
00494 #ifdef HAVE_MODULE_GDHE
00495 display::ViewerGdhe *viewerGdhe = NULL;
00496 #endif
00497 VariableConditionPlus<int> rawdata_condition(0);
00498 kernel::VariableCondition<int> estimatordata_condition(0);
00499 bool ready = false;
00500 boost::shared_ptr<hardware::HardwareSensorMti> trigger;
00501
00502
00503 bool demo_slam_init()
00504 { JFR_GLOBAL_TRY
00505
00507
00511
00512 ready = false;
00513
00515 if (strOpts[sLog].size() == 1)
00516 {
00517 if (strOpts[sLog][0] == '0') strOpts[sLog] = ""; else
00518 if (strOpts[sLog][0] == '1') strOpts[sLog] = "rtslam.log";
00519 }
00520
00521 if (!(intOpts[iReplay] & 1) && (intOpts[iDump] & 2))
00522 { std::cerr << "Warning: dump==2 only valid with replay==1 or 3" << std::endl; intOpts[iDump] &= (~2); }
00523
00524 if (!(intOpts[iReplay] & 1) && ((intOpts[iDump] & 1) || strOpts[sLog].size() != 0))
00525 {
00526 if (!boost::filesystem::exists(strOpts[sDataPath]))
00527 {
00528 if (!boost::filesystem::create_directory(strOpts[sDataPath]))
00529 std::cerr << "Error: failed to create directory data-path \"" << strOpts[sDataPath] << "\"" << std::endl;
00530 } else
00531 {
00532 if (!boost::filesystem::is_directory(strOpts[sDataPath]))
00533 std::cerr << "Error: data-path \"" << strOpts[sDataPath] << "\" is not a directory" << std::endl;
00534 else
00535 {
00536
00537 std::ostringstream oss; oss << "cd " << strOpts[sDataPath] << " ; rm -f *.log ; rm -f *.dat ; rm -f *.pgm ; rm -f *.time ;" << std::endl;
00538 int r = std::system(oss.str().c_str());
00539 if (!r) std::cerr << "Failed to clean data path with error " << r << std::endl;
00540 }
00541 }
00542 }
00543
00544 if (intOpts[iReplay] & 1) mode = hardware::mOffline; else
00545 if (intOpts[iDump] & 1) mode = hardware::mOnlineDump; else
00546 mode = hardware::mOnline;
00547 if (strOpts[sConfigSetup] == "#!@")
00548 {
00549 if (intOpts[iReplay] & 1)
00550 strOpts[sConfigSetup] = strOpts[sDataPath] + "/setup.cfg";
00551 else
00552 strOpts[sConfigSetup] = "data/setup.cfg";
00553 }
00554 if (intOpts[iReplay] & 1) intOpts[iExport] = 0;
00555 if (strOpts[sConfigSetup][0] == '@' && strOpts[sConfigSetup][1] == '/')
00556 strOpts[sConfigSetup] = strOpts[sDataPath] + strOpts[sConfigSetup].substr(1);
00557 if (strOpts[sConfigEstimation][0] == '@' && strOpts[sConfigEstimation][1] == '/')
00558 strOpts[sConfigEstimation] = strOpts[sDataPath] + strOpts[sConfigEstimation].substr(1);
00559 if (!(intOpts[iReplay] & 1) && (intOpts[iDump] & 1))
00560 {
00561 boost::filesystem::remove(strOpts[sDataPath] + "/setup.cfg");
00562 boost::filesystem::remove(strOpts[sDataPath] + "/setup.cfg.maybe");
00563 boost::filesystem::remove(strOpts[sDataPath] + "/estimation.cfg");
00564 boost::filesystem::remove(strOpts[sDataPath] + "/estimation.cfg.maybe");
00565 if (intOpts[iReplay] == 2)
00566 {
00567 boost::filesystem::copy_file(strOpts[sConfigSetup], strOpts[sDataPath] + "/setup.cfg.maybe");
00568 boost::filesystem::copy_file(strOpts[sConfigEstimation], strOpts[sDataPath] + "/estimation.cfg.maybe");
00569 }
00570 else
00571 {
00572 boost::filesystem::copy_file(strOpts[sConfigSetup], strOpts[sDataPath] + "/setup.cfg");
00573 boost::filesystem::copy_file(strOpts[sConfigEstimation], strOpts[sDataPath] + "/estimation.cfg");
00574 }
00575 }
00576 if (intOpts[iCamera] < 10 && intOpts[iCamera] > 0) intOpts[iCamera] += 9;
00577 #ifndef HAVE_MODULE_QDISPLAY
00578 intOpts[iDispQt] = 0;
00579 #endif
00580 #ifndef HAVE_MODULE_GDHE
00581 intOpts[iDispGdhe] = 0;
00582 #endif
00583
00584 std::cout << "Loading config files " << strOpts[sConfigSetup] << " and " << strOpts[sConfigEstimation] << std::endl;
00585 configSetup.load(strOpts[sConfigSetup]);
00586 configEstimation.load(strOpts[sConfigEstimation]);
00587
00589 rseed = jmath::get_srand();
00590 if (intOpts[iRandSeed] != 0 && intOpts[iRandSeed] != 1)
00591 rseed = intOpts[iRandSeed];
00592 if (!(intOpts[iReplay] & 1) && (intOpts[iDump] & 1)) {
00593 std::fstream f((strOpts[sDataPath] + std::string("/rseed.log")).c_str(), std::ios_base::out);
00594 f << rseed << std::endl;
00595 f.close();
00596 }
00597 else if ((intOpts[iReplay] & 1) && intOpts[iRandSeed] == 1) {
00598 std::fstream f((strOpts[sDataPath] + std::string("/rseed.log")).c_str(), std::ios_base::in);
00599 f >> rseed;
00600 f.close();
00601 }
00602 intOpts[iRandSeed] = rseed;
00603 std::cout << "Random seed " << rseed << std::endl;
00604 rtslam::srand(rseed);
00605
00607 worldPtr.reset(new WorldAbstract());
00608
00610 #ifdef HAVE_MODULE_QDISPLAY
00611 if (intOpts[iDispQt])
00612 {
00613 display::ViewerQt *viewerQt = new display::ViewerQt(8, configEstimation.MAHALANOBIS_TH, false, "data/rendered2D_%02d-%06d.png");
00614 worldPtr->addDisplayViewer(viewerQt, display::ViewerQt::id());
00615 }
00616 #endif
00617 #ifdef HAVE_MODULE_GDHE
00618 if (intOpts[iDispGdhe])
00619 {
00620 #if ATRV
00621 display::ViewerGdhe *viewerGdhe = new display::ViewerGdhe("atrv", configEstimation.MAHALANOBIS_TH, "localhost");
00622 #else
00623 display::ViewerGdhe *viewerGdhe = new display::ViewerGdhe("camera", configEstimation.MAHALANOBIS_TH, "localhost");
00624 #endif
00625 boost::filesystem::path ram_path("/mnt/ram");
00626 if (boost::filesystem::exists(ram_path) && boost::filesystem::is_directory(ram_path))
00627 viewerGdhe->setConvertTempPath("/mnt/ram");
00628 worldPtr->addDisplayViewer(viewerGdhe, display::ViewerGdhe::id());
00629 }
00630 #endif
00631
00633 if (!strOpts[sLog].empty() || intOpts[iDump])
00634 loggerTask.reset(new kernel::LoggerTask(display_niceness));
00635
00636 if (!strOpts[sLog].empty())
00637 {
00638 dataLogger.reset(new kernel::DataLogger(strOpts[sDataPath] + "/" + strOpts[sLog]));
00639 dataLogger->setLoggerTask(loggerTask.get());
00640 dataLogger->writeCurrentDate();
00641 dataLogger->writeNewLine();
00642
00643
00644 std::ostringstream oss;
00645 for(int i = 0; i < nIntOpts; ++i)
00646 { oss << long_options[i+nFirstIntOpt].name << " = " << intOpts[i]; dataLogger->writeComment(oss.str()); oss.str(""); }
00647 for(int i = 0; i < nFloatOpts; ++i)
00648 { oss << long_options[i+nFirstFloatOpt].name << " = " << floatOpts[i]; dataLogger->writeComment(oss.str()); oss.str(""); }
00649 for(int i = 0; i < nStrOpts; ++i)
00650 { oss << long_options[i+nFirstStrOpt].name << " = " << strOpts[i]; dataLogger->writeComment(oss.str()); oss.str(""); }
00651 dataLogger->writeNewLine();
00652 }
00653
00655 switch (intOpts[iVerbose])
00656 {
00657 case 0: debug::DebugStream::setLevel("rtslam", debug::DebugStream::Off); break;
00658 case 1: debug::DebugStream::setLevel("rtslam", debug::DebugStream::Trace); break;
00659 case 2: debug::DebugStream::setLevel("rtslam", debug::DebugStream::Warning); break;
00660 case 3: debug::DebugStream::setLevel("rtslam", debug::DebugStream::Debug); break;
00661 case 4: debug::DebugStream::setLevel("rtslam", debug::DebugStream::VerboseDebug); break;
00662 default: debug::DebugStream::setLevel("rtslam", debug::DebugStream::VeryVerboseDebug); break;
00663 }
00664
00665
00669
00670
00671
00672 int camsi = intOpts[iCamera]/10;
00673 const int ncam = 3;
00674 int ncams = 0; bool cams[ncam]; for(int i = 0; i < ncam; i++) { cams[i] = camsi&(1<<i); if (cams[i]) ncams++; }
00675 bool load_calib = ((intOpts[iCamera]%10) > 0);
00676
00677 int filter_mods[ncam]; for(int i = 0; i < ncam; ++i) filter_mods[i] = 0;
00678 int filter_div = 1;
00679 if (intOpts[iCamsFilter] != 100000)
00680 {
00681 int p = 1; for(int i = 0; i < ncams; i++) p *= 10;
00682 filter_div = intOpts[iCamsFilter] / p;
00683 if (filter_div == 0) { std::cerr << "not enough digits for --cams-filter, expecting " << ncams+1 << std::endl; worldPtr->error = eParam; return false; }
00684 for(int i = 0; i < ncam; ++i) if (cams[i]) { p /= 10; filter_mods[i] = (intOpts[iCamsFilter] / p) % 10; }
00685 }
00686
00687 if (ncams > 1) { configEstimation.GRID_HCELLS--; }
00688
00689 vec intrinsic[2], distortion[2];
00690 int img_width[2], img_height[2];
00691 for(int c = 0; c < ncam; ++c)
00692 {
00693 if (!cams[c]) continue;
00694 if (intOpts[iSimu] != 0)
00695 {
00696 img_width[c] = configSetup.CAMERA_IMG_WIDTH_SIMU[c];
00697 img_height[c] = configSetup.CAMERA_IMG_HEIGHT_SIMU[c];
00698 intrinsic[c] = configSetup.CAMERA_INTRINSIC_SIMU[c];
00699 distortion[c] = configSetup.CAMERA_DISTORTION_SIMU[c];
00700 } else
00701 {
00702 img_width[c] = configSetup.CAMERA_IMG_WIDTH[c];
00703 img_height[c] = configSetup.CAMERA_IMG_HEIGHT[c];
00704 intrinsic[c] = configSetup.CAMERA_INTRINSIC[c];
00705 distortion[c] = configSetup.CAMERA_DISTORTION[c];
00706 }
00707 }
00708
00709
00710 double cell_fov, min_cell_fov = 1e10;
00711 for(int c = 0; c < ncam; ++c)
00712 {
00713 if (!cams[c]) continue;
00714 cell_fov = 2. * atan(img_width[c] / (2. * intrinsic[c](2))) / configEstimation.GRID_HCELLS;
00715 if (cell_fov < min_cell_fov) min_cell_fov = cell_fov;
00716 cell_fov = 2. * atan(img_height[c] / (2. * intrinsic[c](3))) / configEstimation.GRID_VCELLS;
00717 if (cell_fov < min_cell_fov) min_cell_fov = cell_fov;
00718 }
00719 min_cell_fov /= 2.;
00720 min_cell_fov *= 180./M_PI;
00721
00722
00723 map_ptr_t mapPtr(new MapAbstract(configEstimation.MAP_SIZE));
00724 mapPtr->linkToParentWorld(worldPtr);
00725
00726
00727 landmark_factory_ptr_t pointLmkFactory;
00728 landmark_factory_ptr_t segLmkFactory;
00729 #if SEGMENT_BASED
00730 segLmkFactory.reset(new LandmarkFactory<LandmarkAnchoredHomogeneousPointsLine, LandmarkAnchoredHomogeneousPointsLine>());
00731 #endif
00732 #if SEGMENT_BASED != 1
00733 pointLmkFactory.reset(new LandmarkFactory<LandmarkAnchoredHomogeneousPoint, LandmarkEuclideanPoint>());
00734 #endif
00735 map_manager_ptr_t mmPoint;
00736 map_manager_ptr_t mmSeg;
00737 const double gridDistInit = 0.5;
00738 const double gridDistFactor = 2.0;
00739 const int gridNDist = 5;
00740 const double gridPhiFactor = 1.2;
00741
00742 switch(intOpts[iMap])
00743 {
00744 case 0: {
00745 if(pointLmkFactory != NULL)
00746 mmPoint.reset(new MapManagerOdometry(pointLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE,
00747 min_cell_fov, gridDistInit, gridDistFactor, gridNDist, gridPhiFactor));
00748 if(segLmkFactory != NULL)
00749 mmSeg.reset(new MapManagerOdometry(segLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE,
00750 min_cell_fov, gridDistInit, gridDistFactor, gridNDist, gridPhiFactor));
00751 break;
00752 }
00753 case 1: {
00754 const int killSearchTh = 20;
00755 const double killMatchTh = 0.5;
00756 const double killConsistencyTh = 0.5;
00757 const double killUncertaintyTh = 0.5;
00758
00759 if(pointLmkFactory != NULL)
00760 mmPoint.reset(new MapManagerGlobal(pointLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE,
00761 killSearchTh, killMatchTh, killConsistencyTh, killUncertaintyTh, min_cell_fov, gridDistInit, gridDistFactor, gridNDist, gridPhiFactor));
00762 if(segLmkFactory != NULL)
00763 mmSeg.reset(new MapManagerGlobal(segLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE,
00764 killSearchTh, killMatchTh, killConsistencyTh, killUncertaintyTh, min_cell_fov, gridDistInit, gridDistFactor, gridNDist, gridPhiFactor));
00765 break;
00766 }
00767 case 2: {
00768 if(pointLmkFactory != NULL)
00769 mmPoint.reset(new MapManagerLocal(pointLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE));
00770 if(segLmkFactory != NULL)
00771 mmSeg.reset(new MapManagerLocal(segLmkFactory, configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE));
00772 break;
00773 }
00774 }
00775 if(mmPoint != NULL)
00776 mmPoint->linkToParentMap(mapPtr);
00777 if(mmSeg != NULL)
00778 mmSeg->linkToParentMap(mapPtr);
00779
00780
00781 boost::shared_ptr<simu::AdhocSimulator> simulator;
00782 if (intOpts[iSimu] != 0)
00783 {
00784 simulator.reset(new simu::AdhocSimulator());
00785 #if SEGMENT_BASED
00786 jblas::vec11 pose;
00787 #else
00788 jblas::vec3 pose;
00789 #endif
00790
00791 const int maxnpoints = 1000;
00792 int npoints = 0;
00793 #if SEGMENT_BASED
00794 double points[maxnpoints][11];
00795 #else
00796 double points[maxnpoints][3];
00797 #endif
00798
00799 switch (intOpts[iSimu]/10)
00800 {
00801 #if SEGMENT_BASED
00802 case 1: {
00803
00804 const int npoints_ = 36; npoints = npoints_;
00805 double tmp[npoints_][11] = {
00806 {0,0,0,5,-1,-1,1,5,-1, 1,1}, {0,0,0,5,1,1,1,5,1,-1,1}, {0,0,0,5,-1,1,1,5, 1,1,1}, {0,0,0,5,-1,-1,1,5,1,-1,1},
00807 {0,0,0,3,-1,-1,1,3,-1, 1,1}, {0,0,0,3,1,1,1,3,1,-1,1}, {0,0,0,3,-1,1,1,3, 1,1,1}, {0,0,0,3,-1,-1,1,3,1,-1,1},
00808 {0,0,0,5,-1,-1,1,3,-1,-1,1}, {0,0,0,5,1,1,1,3,1, 1,1}, {0,0,0,5,-1,1,1,3,-1,1,1}, {0,0,0,5, 1,-1,1,3,1,-1,1},
00809 {0,0,0,5,-4,-1,1,5,-4, 1,1}, {0,0,0,5,-2,1,1,5,-2,-1,1}, {0,0,0,5,-4,1,1,5,-2,1,1}, {0,0,0,5,-4,-1,1,5,-2,-1,1},
00810 {0,0,0,3,-4,-1,1,3,-4, 1,1}, {0,0,0,3,-2,1,1,3,-2,-1,1}, {0,0,0,3,-4,1,1,3,-2,1,1}, {0,0,0,3,-4,-1,1,3,-2,-1,1},
00811 {0,0,0,5,-4,-1,1,3,-4,-1,1}, {0,0,0,5,-2,1,1,3,-2, 1,1}, {0,0,0,5,-4,1,1,3,-4,1,1}, {0,0,0,5,-2,-1,1,3,-2,-1,1},
00812 {0,0,0,5, 2,-1,1,5, 2, 1,1}, {0,0,0,5,4,1,1,5,4,-1,1}, {0,0,0,5,2,1,1,5, 4,1,1}, {0,0,0,5, 2,-1,1,5,4,-1,1},
00813 {0,0,0,3, 2,-1,1,3, 2, 1,1}, {0,0,0,3,4,1,1,3,4,-1,1}, {0,0,0,3,2,1,1,3, 4,1,1}, {0,0,0,3, 2,-1,1,3,4,-1,1},
00814 {0,0,0,5, 2,-1,1,3, 2,-1,1}, {0,0,0,5,4,1,1,3,4, 1,1}, {0,0,0,5,2,1,1,3, 2,1,1}, {0,0,0,5, 4,-1,1,3,4,-1,1}
00815 };
00816 memcpy(points, tmp, npoints*11*sizeof(double));
00817 break;
00818 }
00819 case 2: {
00820
00821 const int npoints_ = 4; npoints = npoints_;
00822 double tmp[npoints_][11] = {
00823 {0,0,0,5,-1,-1,1,5,-1,1,1}, {0,0,0,5,1,1,1,5,1,-1,1}, {0,0,0,5,-1,1,1,5,1,1,1}, {0,0,0,5,-1,-1,1,5,1,-1,1}
00824 };
00825 memcpy(points, tmp, npoints*11*sizeof(double));
00826 break;
00827 }
00828 case 3: {
00829
00830 const int npoints_ = 4; npoints = npoints_;
00831 double tmp[npoints_][11] = {
00832 {0,0,0,4,-1,-1,1,4,-1,1,1}, {0,0,0,4,1,1,1,4,1,-1,1}, {0,0,0,5,-1,1,1,5,1,1,1}, {0,0,0,5,-1,-1,1,5,1,-1,1}
00833 };
00834 memcpy(points, tmp, npoints*11*sizeof(double));
00835 break;
00836 }
00837 default: npoints = 0;
00838 #else
00839 case 1: {
00840
00841 const int npoints_ = 3*11*13; npoints = npoints_;
00842 for(int i = 0, z = -1; z <= 1; ++z) for(int y = -3; y <= 7; ++y) for(int x = -6; x <= 6; ++x, ++i)
00843 { points[i][0] = x*1.0; points[i][1] = y*1.0; points[i][2] = z*1.0; }
00844 break;
00845 }
00846 case 2: {
00847
00848 const int npoints_ = 5; npoints = npoints_;
00849 double tmp[npoints_][3] = { {5,-1,-1}, {5,-1,1}, {5,1,1}, {5,1,-1}, {5,0,0} };
00850 memcpy(points, tmp, npoints*3*sizeof(double));
00851 break;
00852 }
00853 case 3: {
00854
00855 const int npoints_ = 5; npoints = npoints_;
00856 double tmp[npoints_][3] = { {5,-1,-1}, {5,-1,1}, {5,1,1}, {5,1,-1}, {4,0,0} };
00857 memcpy(points, tmp, npoints*3*sizeof(double));
00858 break;
00859 }
00860 case 4: {
00861
00862 const int npoints_ = 3*11*13; npoints = npoints_;
00863 for(int i = 0, z = -1; z <= 1; ++z) for(int y = -3; y <= 7; ++y) for(int x = -6; x <= 6; ++x, ++i)
00864 { points[i][0] = x*1.0+100; points[i][1] = y*10.0; points[i][2] = z*10.0; }
00865 break;
00866 }
00867
00868 default: npoints = 0;
00869 #endif
00870 }
00871
00872
00873 for(int i = 0; i < npoints; ++i)
00874 {
00875 pose(0) = points[i][0]; pose(1) = points[i][1]; pose(2) = points[i][2];
00876 #if !SEGMENT_BASED
00877 simu::Landmark *lmk = new simu::Landmark(LandmarkAbstract::POINT, pose);
00878 #else
00879 pose(3) = points[i][3]; pose(4) = points[i][4]; pose(5) = points[i][5];
00880 pose(6) = points[i][6]; pose(7) = points[i][7]; pose(8) = points[i][8];
00881 pose(9) = points[i][9]; pose(10) = points[i][10];
00882 simu::Landmark *lmk = new simu::Landmark(LandmarkAbstract::LINE, pose);
00883 #endif
00884 simulator->addLandmark(lmk);
00885 }
00886 }
00887
00888
00892
00893 double trigger_construction_date = -1;
00894 robot_ptr_t robPtr1;
00895 switch (intOpts[iRobot])
00896 {
00897 case 0: {
00898 boost::shared_ptr<RobotConstantVelocity> robPtr(new RobotConstantVelocity(mapPtr));
00899 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00900 case 10: case 100: {
00901 boost::shared_ptr<RobotConstantMotionModel<0,0> > robPtr(new RobotConstantMotionModel<0,0>(mapPtr));
00902 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00903
00904 case 11: case 111: {
00905 boost::shared_ptr<RobotConstantMotionModel<1,1> > robPtr(new RobotConstantMotionModel<1,1>(mapPtr));
00906 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00907 case 12: case 122: {
00908 boost::shared_ptr<RobotConstantMotionModel<2,2> > robPtr(new RobotConstantMotionModel<2,2>(mapPtr));
00909 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00910 case 121: {
00911 boost::shared_ptr<RobotConstantMotionModel<2,1> > robPtr(new RobotConstantMotionModel<2,1>(mapPtr));
00912 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00913 case 13: case 133: {
00914 boost::shared_ptr<RobotConstantMotionModel<3,3> > robPtr(new RobotConstantMotionModel<3,3>(mapPtr));
00915 robPtr->setVelocityStd(configSetup.UNCERT_VLIN, configSetup.UNCERT_VANG); robPtr1 = robPtr; break; }
00916 }
00917
00918 if (intOpts[iRobot] == 0 || intOpts[iRobot] >= 10)
00919 {
00920 double _v[6] = {
00921 configSetup.PERT_VLIN, configSetup.PERT_VLIN, configSetup.PERT_VLIN,
00922 configSetup.PERT_VANG, configSetup.PERT_VANG, configSetup.PERT_VANG };
00923 vec pertStd = createVector<6>(_v);
00924 robPtr1->perturbation.set_std_continuous(pertStd);
00925
00926 if (intOpts[iTrigger] != 0)
00927 {
00928
00929 trigger.reset(new hardware::HardwareSensorMti(
00930 NULL, configSetup.MTI_DEVICE, intOpts[iTrigger], floatOpts[fFreq], floatOpts[fShutter], 1, mode, strOpts[sDataPath], loggerTask.get()));
00931 trigger_construction_date = kernel::Clock::getTime();
00932 floatOpts[fFreq] = trigger->getFreq();
00933 }
00934 }
00935 else
00936 if (intOpts[iRobot] == 1)
00937 {
00938 robinertial_ptr_t robPtr1_(new RobotInertial(mapPtr));
00939 robPtr1_->setInitialStd(
00940 configSetup.UNCERT_VLIN,
00941 configSetup.UNCERT_ABIAS*configSetup.ACCELERO_FULLSCALE,
00942 configSetup.UNCERT_WBIAS*configSetup.GYRO_FULLSCALE,
00943 configSetup.UNCERT_GRAVITY*configSetup.INITIAL_GRAVITY);
00944 robPtr1_->setInitialParams(configSetup.INITIAL_GRAVITY);
00945
00946 double aerr = configSetup.PERT_AERR * configSetup.ACCELERO_NOISE;
00947 double werr = configSetup.PERT_WERR * configSetup.GYRO_NOISE;
00948 double _v[12] = {
00949 aerr, aerr, aerr, werr, werr, werr,
00950 configSetup.PERT_RANWALKACC, configSetup.PERT_RANWALKACC, configSetup.PERT_RANWALKACC,
00951 configSetup.PERT_RANWALKGYRO, configSetup.PERT_RANWALKGYRO, configSetup.PERT_RANWALKGYRO};
00952 vec pertStd = createVector<12>(_v);
00953 #if ESTIMATE_BIASES
00954 robPtr1_->perturbation.set_std_continuous(pertStd);
00955 #else
00956 robPtr1_->perturbation.set_std_continuous(ublas::subrange(pertStd,0,6));
00957 #endif
00958
00959 hardware::hardware_sensorprop_ptr_t hardEst1;
00960 if (intOpts[iSimu] != 0)
00961 {
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 } else
00976 {
00977 boost::shared_ptr<hardware::HardwareSensorMti> hardEst1_(new hardware::HardwareSensorMti(
00978 &estimatordata_condition, configSetup.MTI_DEVICE, intOpts[iTrigger], floatOpts[fFreq], floatOpts[fShutter], 1024, mode, strOpts[sDataPath], loggerTask.get()));
00979 trigger_construction_date = kernel::Clock::getTime();
00980 if (intOpts[iTrigger] != 0) floatOpts[fFreq] = hardEst1_->getFreq();
00981 hardEst1_->setSyncConfig(configSetup.IMU_TIMESTAMP_CORRECTION);
00982
00983
00984
00985 hardEst1 = hardEst1_;
00986 }
00987 robPtr1_->setHardwareEstimator(hardEst1);
00988
00989 robPtr1 = robPtr1_;
00990 } else
00991 if (intOpts[iRobot] == 2)
00992 {
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 }
01011
01012 robPtr1->linkToParentMap(mapPtr);
01013 robPtr1->setRobotPose(ublas::subrange(configSetup.ROBOT_POSE,0,6), true);
01014 double heading = (floatOpts[fHeading] < 1e4 ? floatOpts[fHeading] : configSetup.INITIAL_HEADING);
01015 robPtr1->setOrientationStd(0,0,heading,
01016 configSetup.UNCERT_ATTITUDE,configSetup.UNCERT_ATTITUDE,configSetup.UNCERT_HEADING, false);
01017 if (dataLogger) dataLogger->addLoggable(*robPtr1.get());
01018
01019
01020 #if STATE_HISTORY
01021 history_manager_ptr_t hm(new HistoryManagerSparse(mapPtr, robPtr1->pose.ia(), 1.0, 5.0, 3));
01022
01023 robPtr1->setHistoryManager(hm);
01024 #endif
01025
01026
01027 if (intOpts[iSimu] != 0)
01028 {
01029 simu::Robot *rob = new simu::Robot(robPtr1->id(), 6);
01030 if (dataLogger) dataLogger->addLoggable(*rob);
01031
01032 switch (intOpts[iSimu]%10)
01033 {
01034
01035 case 1: {
01036 double VEL = 0.5;
01037 rob->addWaypoint(0,0,0, 0,0,0, 0,0,0, 0,0,0);
01038 rob->addWaypoint(1,0,0, 0,0,0, VEL,0,0, 0,0,0);
01039 rob->addWaypoint(3,2,0, 0,0,0, 0,VEL,0, 0,0,0);
01040 rob->addWaypoint(1,4,0, 0,0,0, -VEL,0,0, 0,0,0);
01041 rob->addWaypoint(-1,4,0, 0,0,0, -VEL,0,0, 0,0,0);
01042 rob->addWaypoint(-3,2,0, 0,0,0, 0,-VEL,0, 0,0,0);
01043 rob->addWaypoint(-1,0,0, 0,0,0, VEL,0,0, 0,0,0);
01044 rob->addWaypoint(0,0,0, 0,0,0, 0,0,0, 0,0,0);
01045 break;
01046 }
01047
01048 case 2: {
01049 double VEL = 0.5;
01050 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01051 rob->addWaypoint(0 ,0 ,+1, 0,0,0, 0,-VEL,0 , 0,0,0);
01052 rob->addWaypoint(0 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01053 rob->addWaypoint(0 ,0 ,-1, 0,0,0, 0,+VEL,0 , 0,0,0);
01054
01055 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01056 rob->addWaypoint(0 ,0 ,+1, 0,0,0, 0,-VEL,0 , 0,0,0);
01057 rob->addWaypoint(0 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01058 rob->addWaypoint(0 ,0 ,-1, 0,0,0, 0,+VEL,0 , 0,0,0);
01059
01060 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01061 break;
01062 }
01063
01064
01065 case 3: {
01066 double VEL = 0.5;
01067 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01068 rob->addWaypoint(0.25,0 ,+1, 0,0,0, VEL/4,-VEL,0 , 0,0,0);
01069 rob->addWaypoint(0.5 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01070 rob->addWaypoint(0.25,0 ,-1, 0,0,0, -VEL/4,+VEL,0 , 0,0,0);
01071
01072 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01073 rob->addWaypoint(-0.25,0 ,+1, 0,0,0, -VEL/4,-VEL,0 , 0,0,0);
01074 rob->addWaypoint(-0.5 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01075 rob->addWaypoint(-0.25,0 ,-1, 0,0,0, VEL/4,+VEL,0 , 0,0,0);
01076
01077 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01078 break;
01079 }
01080
01081
01082 case 4: {
01083 double VEL = 0.5;
01084 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,0, 0,0,0);
01085 rob->addWaypoint(0 ,+1,0.1 , 0,0,0, 0,0 ,+VEL/2, 0,0,0);
01086 rob->addWaypoint(0 ,+1,0.5 , 0,0,0, 0,0 ,+VEL/2, 0,0,0);
01087 rob->addWaypoint(0.25,0 ,+1, 0,0,0, VEL/4,-VEL,0 , 0,0,0);
01088 rob->addWaypoint(0.5 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01089 rob->addWaypoint(0.25,0 ,-1, 0,0,0, -VEL/4,+VEL,0 , 0,0,0);
01090
01091 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,+VEL, 0,0,0);
01092 rob->addWaypoint(-0.25,0 ,+1, 0,0,0, -VEL/4,-VEL,0 , 0,0,0);
01093 rob->addWaypoint(-0.5 ,-1,0 , 0,0,0, 0,0 ,-VEL, 0,0,0);
01094 rob->addWaypoint(-0.25,0 ,-1, 0,0,0, VEL/4,+VEL,0 , 0,0,0);
01095
01096 rob->addWaypoint(0 ,+1,-0.5 , 0,0,0, 0,0 ,+VEL/2, 0,0,0);
01097 rob->addWaypoint(0 ,+1,-0.1 , 0,0,0, 0,0 ,+VEL/2, 0,0,0);
01098 rob->addWaypoint(0 ,+1,0 , 0,0,0, 0,0 ,0, 0,0,0);
01099 break;
01100 }
01101
01102
01103 case 5: {
01104 double VEL = 0.5;
01105 rob->addWaypoint(0,0,0, 0,0,0, VEL/5,0,0, 0,0,0);
01106 rob->addWaypoint(1,0,0, 0,0,0, VEL,0,0, 0,0,0);
01107 rob->addWaypoint(3,2,0, 1*M_PI/2,0,0, 0,VEL,0, 100,0,0);
01108 rob->addWaypoint(1,4,0, 2*M_PI/2,0,0, -VEL,0,0, 0,0,0);
01109 rob->addWaypoint(-1,4,0, 2*M_PI/2,0,0, -VEL,0,0, 0,0,0);
01110 rob->addWaypoint(-3,2,0, 3*M_PI/2,0,0, 0,-VEL,0, 100,0,0);
01111 rob->addWaypoint(-1,0,0, 4*M_PI/2,0,0, VEL,0,0, 0,0,0);
01112 rob->addWaypoint(0,0,0, 4*M_PI/2,0,0, 0,0,0, 0,0,0);
01113 break;
01114 }
01115
01116
01117 case 6: {
01118 double VEL = 0.5;
01119 rob->addWaypoint(0,0,0, 0,0,0, 0,0,0, 0,0,0);
01120 rob->addWaypoint(1,0,0, 0,0,0, VEL,0,0, 0,0,0);
01121 rob->addWaypoint(20,0,0, 0,0,0, VEL,0,0, 0,0,0);
01122 break;
01123 }
01124 }
01125
01126 simulator->addRobot(rob);
01127
01128 }
01129
01130
01131
01135
01136
01138 boost::shared_ptr<ObservationFactory> obsFact(new ObservationFactory());
01139 #if SEGMENT_BASED
01140 if (intOpts[iSimu] != 0)
01141 {
01142 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeAhplSimuObservationMaker(
01143 configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE, 30, 0.5, 0.5, configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01144 } else
01145 {
01146 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeAhplObservationMaker(
01147 configEstimation.REPARAM_TH, configEstimation.KILL_SEARCH_SIZE, 30, 0.5, 0.5, configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01148 }
01149 #endif
01150 #if SEGMENT_BASED != 1
01151 if (intOpts[iSimu] != 0)
01152 {
01153 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeEucpSimuObservationMaker(
01154 configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01155 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeAhpSimuObservationMaker(
01156 configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01157 } else
01158 {
01159 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeEucpObservationMaker(
01160 configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01161 obsFact->addMaker(boost::shared_ptr<ObservationMakerAbstract>(new PinholeAhpObservationMaker(
01162 configEstimation.D_MIN, configEstimation.PATCH_SIZE)));
01163 }
01164 #endif
01165
01166 int ncam_built = 0;
01167 pinhole_ptr_t cams_built[ncam];
01168 bool initialized_cameras ;
01169 const int ntrya = 4;
01170 for(int itrya = 0; itrya < ntrya; ++itrya) { initialized_cameras = true;
01171 for(int c = 0; c < ncam && initialized_cameras; ++c)
01172 {
01173 if (!cams[c]) continue;
01174 pinhole_ptr_t senPtr11;
01175 if (c < ncam_built) senPtr11 = cams_built[c]; else {
01176
01177 jblas::vec camera_pose = (intOpts[iRobot] == 1 ? configSetup.CAMERA_POSE_INERTIAL[c] : configSetup.CAMERA_POSE_CONSTVEL[c]);
01178 int cp_size = camera_pose.size();
01179 if (cp_size != 6 && cp_size != 12) { std::cerr << "Camera pose must have size 6 or 12 (with uncertainties), not " << cp_size << std::endl; worldPtr->error = eConfig; return false; }
01180 senPtr11 = pinhole_ptr_t(new SensorPinhole(robPtr1, (cp_size == 6 ? MapObject::UNFILTERED : MapObject::FILTERED)));
01181 senPtr11->linkToParentRobot(robPtr1);
01182 if (ncams == 1) senPtr11->name("cam"); else { std::ostringstream oss; oss << "cam" << c; senPtr11->name(oss.str()); }
01183 if (cp_size == 6)
01184 {
01185 senPtr11->setPose(camera_pose(0), camera_pose(1), camera_pose(2), camera_pose(3), camera_pose(4), camera_pose(5));
01186 } else
01187 {
01188 senPtr11->setPoseStd(camera_pose(0), camera_pose(1), camera_pose(2), camera_pose(3), camera_pose(4), camera_pose(5),
01189 camera_pose(6), camera_pose(7), camera_pose(8), camera_pose(9), camera_pose(10), camera_pose(11));
01190 }
01191
01192 senPtr11->params.setIntrinsicCalibration(img_width[c], img_height[c], intrinsic[c], distortion[c], configEstimation.CORRECTION_SIZE);
01193
01194 senPtr11->params.setMiscellaneous(configEstimation.PIX_NOISE, configEstimation.D_MIN);
01195
01196 if (dataLogger) dataLogger->addLoggable(*senPtr11.get());
01197
01198 if (intOpts[iSimu] != 0)
01199 {
01200 jblas::vec6 pose;
01201 subrange(pose, 0, 3) = subrange(senPtr11->pose.x(), 0, 3);
01202 subrange(pose, 3, 6) = quaternion::q2e(subrange(senPtr11->pose.x(), 3, 7));
01203 std::swap(pose(3), pose(5));
01204 simu::Sensor *sen = new simu::Sensor(senPtr11->id(), pose, senPtr11);
01205 simulator->addSensor(robPtr1->id(), sen);
01206 simulator->addObservationModel(robPtr1->id(), senPtr11->id(), LandmarkAbstract::POINT, new ObservationModelPinHoleEuclideanPoint(senPtr11));
01207 #if SEGMENT_BASED
01208 simulator->addObservationModel(robPtr1->id(), senPtr11->id(), LandmarkAbstract::LINE, new ObservationModelPinHoleAnchoredHomogeneousPointsLine(senPtr11));
01209 #endif
01210 } else
01211 {
01212 senPtr11->setIntegrationPolicy(false);
01213 senPtr11->setUseForInit(false);
01214 senPtr11->setNeedInit(true);
01215 }
01216
01217
01218 boost::shared_ptr<ActiveSearchGrid> asGrid(new ActiveSearchGrid(img_width[c], img_height[c], configEstimation.GRID_HCELLS, configEstimation.GRID_VCELLS, configEstimation.GRID_MARGIN, configEstimation.GRID_SEPAR));
01219 boost::shared_ptr<ActiveSegmentSearchGrid> assGrid(new ActiveSegmentSearchGrid(img_width[c], img_height[c], configEstimation.GRID_HCELLS, configEstimation.GRID_VCELLS, configEstimation.GRID_MARGIN, configEstimation.GRID_SEPAR));
01220
01221 #if RANSAC_FIRST
01222 int ransac_ntries = configEstimation.RANSAC_NTRIES;
01223 #else
01224 int ransac_ntries = 0;
01225 #endif
01226
01227 if (intOpts[iSimu] != 0)
01228 {
01229 #if SEGMENT_BASED
01230 boost::shared_ptr<simu::DetectorSimu<image::ConvexRoi> > detector(new simu::DetectorSimu<image::ConvexRoi>(LandmarkAbstract::LINE, 4, configEstimation.PATCH_SIZE, configEstimation.PIX_NOISE, configEstimation.PIX_NOISE*configEstimation.PIX_NOISE_SIMUFACTOR));
01231 boost::shared_ptr<simu::MatcherSimu<image::ConvexRoi> > matcher(new simu::MatcherSimu<image::ConvexRoi>(LandmarkAbstract::LINE, 4, configEstimation.PATCH_SIZE, configEstimation.MAX_SEARCH_SIZE, configEstimation.RANSAC_LOW_INNOV, configEstimation.MATCH_TH, configEstimation.MAHALANOBIS_TH, configEstimation.RELEVANCE_TH, configEstimation.PIX_NOISE, configEstimation.PIX_NOISE*configEstimation.PIX_NOISE_SIMUFACTOR));
01232
01233 boost::shared_ptr<DataManager_Segment_Ransac_Simu> dmPt11(new DataManager_Segment_Ransac_Simu(detector, matcher, assGrid, configEstimation.N_UPDATES_TOTAL, configEstimation.N_UPDATES_RANSAC, ransac_ntries, configEstimation.N_INIT, configEstimation.N_RECOMP_GAINS, configEstimation.MULTIPLE_DEPTH_HYPOS, (intOpts[iDump]&2) ? loggerTask.get() : NULL));
01234
01235 dmPt11->linkToParentSensorSpec(senPtr11);
01236 dmPt11->linkToParentMapManager(mmPoint);
01237 dmPt11->setObservationFactory(obsFact);
01238
01239 hardware::hardware_sensorext_ptr_t hardSen11(new hardware::HardwareSensorAdhocSimulator(&rawdata_condition, floatOpts[fFreq], simulator, robPtr1->id(), senPtr11->id()));
01240 senPtr11->setHardwareSensor(hardSen11);
01241 #else
01242 boost::shared_ptr<simu::DetectorSimu<image::ConvexRoi> > detector(new simu::DetectorSimu<image::ConvexRoi>(LandmarkAbstract::POINT, 2, configEstimation.PATCH_SIZE, configEstimation.PIX_NOISE, configEstimation.PIX_NOISE*configEstimation.PIX_NOISE_SIMUFACTOR));
01243 boost::shared_ptr<simu::MatcherSimu<image::ConvexRoi> > matcher(new simu::MatcherSimu<image::ConvexRoi>(LandmarkAbstract::POINT, 2, configEstimation.PATCH_SIZE, configEstimation.MAX_SEARCH_SIZE, configEstimation.RANSAC_LOW_INNOV, configEstimation.MATCH_TH, configEstimation.HI_MATCH_TH, configEstimation.HI_LIMIT, configEstimation.MAHALANOBIS_TH, configEstimation.RELEVANCE_TH, configEstimation.PIX_NOISE, configEstimation.PIX_NOISE*configEstimation.PIX_NOISE_SIMUFACTOR));
01244
01245 boost::shared_ptr<DataManager_ImagePoint_Ransac_Simu> dmPt11(new DataManager_ImagePoint_Ransac_Simu(detector, matcher, asGrid, configEstimation.N_UPDATES_TOTAL, configEstimation.N_UPDATES_RANSAC, ransac_ntries, configEstimation.N_INIT, configEstimation.N_RECOMP_GAINS, configEstimation.MULTIPLE_DEPTH_HYPOS, (intOpts[iDump]&2) ? loggerTask.get() : NULL));
01246
01247 dmPt11->linkToParentSensorSpec(senPtr11);
01248 dmPt11->linkToParentMapManager(mmPoint);
01249 dmPt11->setObservationFactory(obsFact);
01250
01251 hardware::hardware_sensorext_ptr_t hardSen11(new hardware::HardwareSensorAdhocSimulator(&rawdata_condition, floatOpts[fFreq], simulator, robPtr1->id(), senPtr11->id()));
01252 senPtr11->setHardwareSensor(hardSen11);
01253 #endif
01254 } else
01255 {
01256 boost::shared_ptr<DescriptorFactoryAbstract> pointDescFactory;
01257 boost::shared_ptr<DescriptorFactoryAbstract> segDescFactory;
01258 #if SEGMENT_BASED
01259 if (configEstimation.MULTIVIEW_DESCRIPTOR)
01260 segDescFactory.reset(new DescriptorImageSegMultiViewFactory(configEstimation.DESC_SIZE, configEstimation.DESC_SCALE_STEP, jmath::degToRad(configEstimation.DESC_ANGLE_STEP), (DescriptorImageSegMultiView::PredictionType)configEstimation.DESC_PREDICTION_TYPE));
01261 else
01262 segDescFactory.reset(new DescriptorImageSegFirstViewFactory(configEstimation.DESC_SIZE));
01263
01264 boost::shared_ptr<HDsegDetector> hdsegDetector(new HDsegDetector(configEstimation.PATCH_SIZE, 3,configEstimation.PIX_NOISE*SEGMENT_NOISE_FACTOR,segDescFactory));
01265 boost::shared_ptr<DsegMatcher> dsegMatcher(new DsegMatcher(configEstimation.RANSAC_LOW_INNOV, configEstimation.MATCH_TH, configEstimation.MAHALANOBIS_TH, configEstimation.RELEVANCE_TH, configEstimation.PIX_NOISE*SEGMENT_NOISE_FACTOR));
01266 boost::shared_ptr<DataManager_ImageSeg_Test> dmSeg(new DataManager_ImageSeg_Test(hdsegDetector, dsegMatcher, assGrid, configEstimation.N_UPDATES_TOTAL, configEstimation.N_UPDATES_RANSAC, ransac_ntries, configEstimation.N_INIT, configEstimation.N_RECOMP_GAINS, configEstimation.MULTIPLE_DEPTH_HYPOS, (intOpts[iDump]&2) ? loggerTask.get() : NULL));
01267
01268 dmSeg->linkToParentSensorSpec(senPtr11);
01269 dmSeg->linkToParentMapManager(mmSeg);
01270 dmSeg->setObservationFactory(obsFact);
01271 #endif
01272 #if SEGMENT_BASED != 1
01273 if (configEstimation.MULTIVIEW_DESCRIPTOR)
01274 pointDescFactory.reset(new DescriptorImagePointMultiViewFactory(configEstimation.DESC_SIZE, configEstimation.DESC_SCALE_STEP, jmath::degToRad(configEstimation.DESC_ANGLE_STEP), (DescriptorImagePointMultiView::PredictionType)configEstimation.DESC_PREDICTION_TYPE));
01275 else
01276 pointDescFactory.reset(new DescriptorImagePointFirstViewFactory(configEstimation.DESC_SIZE));
01277
01278 boost::shared_ptr<ImagePointHarrisDetector> harrisDetector(new ImagePointHarrisDetector(configEstimation.HARRIS_CONV_SIZE, configEstimation.HARRIS_TH, configEstimation.HARRIS_EDDGE, configEstimation.PATCH_SIZE, configEstimation.PIX_NOISE, pointDescFactory));
01279 boost::shared_ptr<ImagePointZnccMatcher> znccMatcher(new ImagePointZnccMatcher(configEstimation.MIN_SCORE, configEstimation.PARTIAL_POSITION, configEstimation.PATCH_SIZE, configEstimation.MAX_SEARCH_SIZE, configEstimation.RANSAC_LOW_INNOV, configEstimation.MATCH_TH, configEstimation.HI_MATCH_TH, configEstimation.HI_LIMIT, configEstimation.MAHALANOBIS_TH, configEstimation.RELEVANCE_TH, configEstimation.PIX_NOISE));
01280 boost::shared_ptr<DataManager_ImagePoint_Ransac> dmPt11(new DataManager_ImagePoint_Ransac(harrisDetector, znccMatcher, asGrid, configEstimation.N_UPDATES_TOTAL, configEstimation.N_UPDATES_RANSAC, ransac_ntries, configEstimation.N_INIT, configEstimation.N_RECOMP_GAINS, configEstimation.MULTIPLE_DEPTH_HYPOS, (intOpts[iDump]&2) ? loggerTask.get() : NULL));
01281
01282 dmPt11->linkToParentSensorSpec(senPtr11);
01283 dmPt11->linkToParentMapManager(mmPoint);
01284 dmPt11->setObservationFactory(obsFact);
01285 #endif
01286 if (dataLogger) dataLogger->addLoggable(*dmPt11.get());
01287 }
01288 cams_built[c] = senPtr11;
01289 ncam_built = c+1;
01290 }
01291
01292
01293
01294 if (intOpts[iSimu] == 0)
01295 {
01296 int cam_id = (ncams==1 && mode==hardware::mOnline ? 0 : c+1);
01297 if (configSetup.CAMERA_TYPE[c] == 0 || configSetup.CAMERA_TYPE[c] == 1)
01298 {
01299 #ifdef HAVE_VIAM
01300 viam_hwcrop_t crop;
01301 switch (configSetup.CAMERA_TYPE[c])
01302 {
01303 case 0: crop = VIAM_HW_FIXED; break;
01304 case 1: crop = VIAM_HW_CROP; break;
01305 default: crop = VIAM_HW_FIXED; break;
01306 }
01307 hardware::hardware_sensor_firewire_ptr_t hardSen11;
01308 for(int itry = 0; itry < 2; ++itry)
01309 {
01310 hardSen11 = hardware::hardware_sensor_firewire_ptr_t(new hardware::HardwareSensorCameraFirewire(&rawdata_condition, 500,
01311 configSetup.CAMERA_DEVICE[c], cv::Size(img_width[c],img_height[c]), configSetup.CAMERA_FORMAT[c], crop, floatOpts[fFreq], intOpts[iTrigger],
01312 floatOpts[fShutter], mode, cam_id, load_calib ? configSetup.CAMERA_CALIB[c] : "", strOpts[sDataPath], loggerTask.get()));
01313 if (hardSen11->initialized()) break; else std::cerr << "!HardwareSensorCameraFirewire " << hardSen11->id() << " failed to initialize" << (itry != 1 ? ", reset sensor and retry in 1 second." : ".") << std::endl;
01314 hardSen11.reset();
01315 if (itry != 1) sleep(1);
01316 }
01317 if (!hardSen11)
01318 {
01319 std::cerr << "!!HardwareSensorCameraFirewire " << cam_id << " failed to start" << (itrya != ntrya-1 ? ", resetting bus and retrying." : ", abandoning.") << std::endl ;
01320 initialized_cameras = false;
01321 for(int cc = 0; cc < c; cc++) if (cams[cc]) cams_built[cc]->setHardwareSensor(hardware::hardware_sensorext_ptr_t());
01322 sleep(1);
01323 int r = std::system("dc1394_reset_bus || dc1394_reset_bus2");
01324 if (r) std::cerr << "dc1394_reset_bus failed with error " << r << std::endl;
01325 sleep(1);
01326 break;
01327 }
01328
01329 if (!(intOpts[iReplay] & 1)) hardSen11->assessFirstImage(trigger_construction_date);
01330 hardSen11->setTimingInfos(1.0/hardSen11->getFreq(), 1.0/hardSen11->getFreq());
01331 hardSen11->setFilter(filter_div, filter_mods[c]);
01332 senPtr11->setHardwareSensor(hardSen11);
01333 #else
01334 if (intOpts[iReplay] & 1)
01335 {
01336 hardware::hardware_sensorext_ptr_t hardSen11(new hardware::HardwareSensorCameraFirewire(&rawdata_condition, c+1, cv::Size(img_width[c],img_height[c]),strOpts[sDataPath]));
01337 senPtr11->setHardwareSensor(hardSen11);
01338 } else
01339 {
01340 std::cerr << "You need to install the library viam to use a firewire camera" << std::endl;
01341 worldPtr->error = eDependency; return false;
01342 }
01343 #endif
01344 } else if (configSetup.CAMERA_TYPE[c] == 2)
01345 {
01346 std::cerr << "Generic USB cameras not supported yet ; use firewire of ueye camera" << std::endl;
01347 worldPtr->error = eNotSupported; return false;
01348 } else if (configSetup.CAMERA_TYPE[c] == 3)
01349 {
01350 #ifdef HAVE_UEYE
01351 hardware::hardware_sensor_ueye_ptr_t hardSen11(new hardware::HardwareSensorCameraUeye(&rawdata_condition, 500,
01352 configSetup.CAMERA_DEVICE[c], cv::Size(img_width[c],img_height[c]), floatOpts[fFreq], intOpts[iTrigger],
01353 floatOpts[fShutter], mode, cam_id, strOpts[sDataPath], loggerTask.get()));
01354 hardSen11->setTimingInfos(1.0/hardSen11->getFreq(), 1.0/hardSen11->getFreq());
01355 senPtr11->setHardwareSensor(hardSen11);
01356 #else
01357 if (intOpts[iReplay] & 1)
01358 {
01359 hardware::hardware_sensorext_ptr_t hardSen11(new hardware::HardwareSensorCameraUeye(&rawdata_condition, c+1, cv::Size(img_width[c],img_height[c]),strOpts[sDataPath]));
01360 senPtr11->setHardwareSensor(hardSen11);
01361 } else
01362 {
01363 std::cerr << "You need to install the ueye driver to use a ueye camera" << std::endl;
01364 worldPtr->error = eDependency; return false;
01365 }
01366 #endif
01367 }
01368 }
01369 } if (initialized_cameras) break; }
01370 if (!initialized_cameras)
01371 {
01372 std::cerr << "Could not start all cameras." << std::endl;
01373 worldPtr->error = eNoSensorData;
01374 return false;
01375 }
01376
01377 if (intOpts[iGps])
01378 {
01379 int cp_size = configSetup.GPS_POSE.size();
01380 if (cp_size != 6 && cp_size != 12) { std::cerr << "Gps pose must have size 6 or 12 (with uncertainties), not " << cp_size << std::endl; worldPtr->error = eConfig; return false; }
01381 absloc_ptr_t senPtr13(new SensorAbsloc(robPtr1, (cp_size == 6 ? MapObject::UNFILTERED : MapObject::FILTERED), -1.0, configSetup.GPS_MAX_CONSIST_SIG, true, intOpts[iGps] == 2));
01382 senPtr13->linkToParentRobot(robPtr1);
01383 senPtr13->name("GPS");
01384 hardware::hardware_sensorprop_ptr_t hardGps;
01385 bool init = true;
01386 switch (intOpts[iGps])
01387 {
01388 case 1:
01389 hardGps.reset(new hardware::HardwareSensorGpsGenom(&rawdata_condition, 200, mode, strOpts[sDataPath], loggerTask.get()));
01390 break;
01391 case 2:
01392 hardGps.reset(new hardware::HardwareSensorGpsGenom(&rawdata_condition, 200, mode, strOpts[sDataPath], loggerTask.get()));
01393 break;
01394 case 3:
01395 hardGps.reset(new hardware::HardwareSensorMocap(&rawdata_condition, 200, mode, strOpts[sDataPath], loggerTask.get()));
01396 init = false;
01397 break;
01398 }
01399
01400 hardGps->setSyncConfig(configSetup.GPS_TIMESTAMP_CORRECTION);
01401 hardGps->setTimingInfos(1.0/20.0, 1.5/20.0);
01402 senPtr13->setHardwareSensor(hardGps);
01403 senPtr13->setIntegrationPolicy(true);
01404 senPtr13->setUseForInit(true);
01405 senPtr13->setNeedInit(init);
01406 if (cp_size == 6)
01407 {
01408 senPtr13->setPose(configSetup.GPS_POSE[0], configSetup.GPS_POSE[1], configSetup.GPS_POSE[2],
01409 configSetup.GPS_POSE[3], configSetup.GPS_POSE[4], configSetup.GPS_POSE[5]);
01410 } else
01411 {
01412 senPtr13->setPoseStd(configSetup.GPS_POSE[0], configSetup.GPS_POSE[1], configSetup.GPS_POSE[2],
01413 configSetup.GPS_POSE[3], configSetup.GPS_POSE[4], configSetup.GPS_POSE[5],
01414 configSetup.GPS_POSE[6], configSetup.GPS_POSE[7], configSetup.GPS_POSE[8],
01415 configSetup.GPS_POSE[9], configSetup.GPS_POSE[10], configSetup.GPS_POSE[11]);
01416 }
01417 }
01418
01419 if (intOpts[iOdom])
01420 {
01421 int cp_size = configSetup.ROBOT_POSE.size();
01422 if (cp_size != 6 && cp_size != 12) { std::cerr << "Robot pose must have size 6 or 12 (with uncertainties), not " << cp_size << std::endl; worldPtr->error = eConfig; return false; }
01423 absloc_ptr_t senPtr14(new SensorAbsloc(robPtr1, (cp_size == 6 ? MapObject::UNFILTERED : MapObject::FILTERED), 3.0, 1e9, false, true, false));
01424 senPtr14->linkToParentRobot(robPtr1);
01425 senPtr14->name("odom");
01426
01427 hardware::HardwareSensorOdomRmp400Genom *odomRmp = new hardware::HardwareSensorOdomRmp400Genom(&rawdata_condition, 200, mode, strOpts[sDataPath], loggerTask.get());
01428 odomRmp->setCalib(configSetup.ODO_CALIB);
01429 hardware::hardware_sensorprop_ptr_t hardOdom(odomRmp);
01430
01431 hardOdom->setSyncConfig(configSetup.ODO_TIMESTAMP_CORRECTION);
01432 hardOdom->setTimingInfos(1.0/20.0, 1.5/20.0);
01433 senPtr14->setHardwareSensor(hardOdom);
01434 senPtr14->setIntegrationPolicy(true);
01435 senPtr14->setUseForInit(false);
01436 senPtr14->setNeedInit(false);
01437 senPtr14->setPose(configSetup.ROBOT_POSE[0], configSetup.ROBOT_POSE[1], configSetup.ROBOT_POSE[2],
01438 configSetup.ROBOT_POSE[3], configSetup.ROBOT_POSE[4], configSetup.ROBOT_POSE[5]);
01439 if (cp_size == 6)
01440 {
01441 senPtr14->setPose(configSetup.ROBOT_POSE[0], configSetup.ROBOT_POSE[1], configSetup.ROBOT_POSE[2],
01442 configSetup.ROBOT_POSE[3], configSetup.ROBOT_POSE[4], configSetup.ROBOT_POSE[5]);
01443 } else
01444 {
01445 senPtr14->setPoseStd(configSetup.ROBOT_POSE[0], configSetup.ROBOT_POSE[1], configSetup.ROBOT_POSE[2],
01446 configSetup.ROBOT_POSE[3], configSetup.ROBOT_POSE[4], configSetup.ROBOT_POSE[5],
01447 configSetup.ROBOT_POSE[6], configSetup.ROBOT_POSE[7], configSetup.ROBOT_POSE[8],
01448 configSetup.ROBOT_POSE[9], configSetup.ROBOT_POSE[10], configSetup.ROBOT_POSE[11]);
01449 }
01450 }
01451
01452 if (intOpts[iExtloc]/10)
01453 {
01454 absloc_ptr_t senPtr15(new SensorAbsloc(robPtr1, MapObject::UNFILTERED, -1.0, 1e9, true, false, false));
01455 senPtr15->linkToParentRobot(robPtr1);
01456 senPtr15->name("extloc");
01457 int source = intOpts[iExtloc]/10-1;
01458 hardware::ExtLocType type = (hardware::ExtLocType)(intOpts[iExtloc]%10);
01459 hardware::HardwareSensorExternalLoc *extloc = new hardware::HardwareSensorExternalLoc(&rawdata_condition, 200, type, source, mode, strOpts[sDataPath], loggerTask.get());
01460 hardware::hardware_sensorprop_ptr_t hardExtloc(extloc);
01461
01462 hardExtloc->setTimingInfos(1.0/2.0, (source ? -0.05 : 0.5));
01463 senPtr15->setHardwareSensor(hardExtloc);
01464 senPtr15->setIntegrationPolicy(true);
01465 senPtr15->setUseForInit(false);
01466 senPtr15->setNeedInit(false);
01467 senPtr15->setPose(0,0,0,0,0,0);
01468 }
01469
01470
01472 if (intOpts[iReplay] & 1)
01473 sensorManager.reset(new SensorManagerOffline(mapPtr, (intOpts[iReplay] == 3 ? strOpts[sDataPath] : "")));
01474 else
01475 sensorManager.reset(new SensorManagerOnline(mapPtr, ((intOpts[iDump] & 1) ? strOpts[sDataPath] : ""), loggerTask.get()));
01476
01480
01481
01482 #ifdef HAVE_MODULE_QDISPLAY
01483 if (intOpts[iDispQt])
01484 {
01485 viewerQt = PTR_CAST<display::ViewerQt*> (worldPtr->getDisplayViewer(display::ViewerQt::id()));
01486 viewerQt->bufferize(worldPtr);
01487
01488
01489 boost::unique_lock<boost::mutex> runStatus_lock(viewerQt->runStatus.mutex);
01490 viewerQt->runStatus.pause = intOpts[iPause];
01491 viewerQt->runStatus.render_all = intOpts[iRenderAll];
01492 runStatus_lock.unlock();
01493 }
01494 #endif
01495 #ifdef HAVE_MODULE_GDHE
01496 if (intOpts[iDispGdhe])
01497 {
01498 viewerGdhe = PTR_CAST<display::ViewerGdhe*> (worldPtr->getDisplayViewer(display::ViewerGdhe::id()));
01499 viewerGdhe->bufferize(worldPtr);
01500 }
01501 #endif
01502
01503
01504
01505 switch (intOpts[iExport])
01506 {
01507 case 1: exporter.reset(new ExporterSocket(robPtr1, 30000)); break;
01508 case 2: exporter.reset(new ExporterPoster(robPtr1)); break;
01509 }
01510
01511 return true;
01512 JFR_GLOBAL_CATCH
01513 }
01514
01515
01521 void demo_slam_exit(world_ptr_t *world, boost::thread *thread_main) {
01522 (*world)->exit(true);
01523 (*world)->display_condition.notify_all();
01524
01525 #ifdef HAVE_MODULE_QDISPLAY
01526 if (intOpts[iDispQt])
01527 {
01528 viewerQt->runStatus.pause = 0;
01529 viewerQt->runStatus.condition.notify_all();
01530 }
01531 #endif
01532
01533
01534
01535 thread_main->join();
01536
01537 }
01538
01539 void demo_slam_stop(world_ptr_t *world)
01540 {
01541 sensorManager->printStats();
01542
01543 static int stopped = false;
01544 if (stopped) return;
01545
01546 if (exporter) exporter->stop();
01547 (*world)->slam_blocked(true);
01548
01549
01550 map_ptr_t mapPtr = (*world)->mapList().front();
01551 ready = false;
01552 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01553 robIter != mapPtr->robotList().end(); ++robIter)
01554 {
01555 if ((*robIter)->hardwareEstimatorPtr)
01556 {
01557 std::cout << "Stopping robot " << (*robIter)->id() << " estimator..."; std::cout.flush();
01558 (*robIter)->hardwareEstimatorPtr->stop();
01559 std::cout << " OK." << std::endl;
01560 }
01561 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01562 senIter != (*robIter)->sensorList().end(); ++senIter)
01563 {
01564 std::cout << "Stopping sensor " << (*senIter)->id() << " " << (*senIter)->name() << "..."; std::cout.flush();
01565 (*senIter)->stop();
01566 std::cout << " OK." << std::endl;
01567 }
01568 }
01569
01570 std::cout << "Stopping sensor manager..."; std::cout.flush();
01571 sensorManager->stop();
01572 std::cout << " OK." << std::endl;
01573
01574 if (loggerTask)
01575 {
01576 std::cout << "Stopping and joining logger..."; std::cout.flush();
01577 loggerTask->stop(true);
01578 std::cout << " OK." << std::endl;
01579 }
01580
01581 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01582 robIter != mapPtr->robotList().end(); ++robIter)
01583 {
01584 if ((*robIter)->hardwareEstimatorPtr)
01585 {
01586 std::cout << "Joining robot " << (*robIter)->id() << " estimator..."; std::cout.flush();
01587 (*robIter)->hardwareEstimatorPtr->join();
01588 std::cout << " OK." << std::endl;
01589 }
01590 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01591 senIter != (*robIter)->sensorList().end(); ++senIter)
01592 {
01593 std::cout << "Joining sensor " << (*senIter)->id() << " " << (*senIter)->name() << "..."; std::cout.flush();
01594 if ((*senIter)->join(1000)) std::cout << " OK." << std::endl; else std::cout << " FAILED." << std::endl;
01595 }
01596 }
01597
01598 std::cout << "Quitting" << std::endl;
01599 stopped = true;
01600 }
01601
01602
01603 void set_signals(sig_t catcher)
01604 {
01605 signal(SIGQUIT, catcher);
01606 signal(SIGTERM, catcher);
01607 signal(SIGINT, catcher);
01608
01609 signal(SIGABRT, catcher);
01610 signal(SIGPIPE, catcher);
01611 signal(SIGFPE, catcher);
01612 signal(SIGSEGV, catcher);
01613
01614 }
01615
01616
01617 void signal_catcher(int sig __attribute__((unused)))
01618 {
01619 if (worldPtr->error == eNoError) worldPtr->error = eCrashed;
01620 static bool first = true;
01621 if (first)
01622 {
01623 first = false;
01624 std::cerr << "RT-SLAM is stopping because it received signal " << sig << " \"" << strsignal(sig) << "\"" << std::endl;
01625 demo_slam_stop(&worldPtr);
01626
01627
01628 map_ptr_t mapPtr = worldPtr->mapList().front();
01629 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01630 robIter != mapPtr->robotList().end(); ++robIter)
01631 {
01632 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01633 senIter != (*robIter)->sensorList().end(); ++senIter)
01634 delete (*senIter).get();
01635 if ((*robIter)->hardwareEstimatorPtr.get() != trigger.get()) delete (*robIter).get();
01636 }
01637 delete trigger.get();
01638 }
01639 else std::cerr << "RT-SLAM failed to stop because it received signal " << sig << " \"" << strsignal(sig) << "\"" << std::endl;
01640
01641 signal(sig, SIG_DFL);
01642 raise(sig);
01643 }
01644
01645
01651 #define SHOW_PERIODIC_SENSORS_INFOS 1
01652
01653 void showSensorsInfos(map_ptr_t mapPtr)
01654 {
01655 if (!(intOpts[iReplay] & 1))
01656 {
01657 #if SHOW_PERIODIC_SENSORS_INFOS
01658 std::cout << std::setprecision(16) << kernel::Clock::getTime() << std::endl;
01659 #endif
01660 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01661 robIter != mapPtr->robotList().end(); ++robIter)
01662 {
01663 if ((*robIter)->hardwareEstimatorPtr) (*robIter)->hardwareEstimatorPtr->showInfos();
01664 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01665 senIter != (*robIter)->sensorList().end(); ++senIter)
01666 (*senIter)->showInfos();
01667 }
01668 }
01669 }
01670
01671 void demo_slam_main(world_ptr_t *world)
01672 { JFR_GLOBAL_TRY
01673
01674 if (!(intOpts[iReplay] & 1))
01675 kernel::setCurrentThreadScheduler(slam_sched, slam_priority);
01676
01677 robot_ptr_t robotPtr;
01678
01679
01680 if (intOpts[iDispQt] || intOpts[iDispGdhe])
01681 {
01682 boost::unique_lock<boost::mutex> display_lock(worldPtr->display_mutex);
01683 worldPtr->display_rendered = false;
01684 display_lock.unlock();
01685 worldPtr->display_condition.notify_all();
01686
01687 display_lock.lock();
01688 while(!worldPtr->display_rendered) worldPtr->display_condition.wait(display_lock);
01689 display_lock.unlock();
01690 }
01691
01692 set_signals(signal_catcher);
01693
01694
01695 map_ptr_t mapPtr = (*world)->mapList().front();
01696 bool has_init = false;
01697 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01698 robIter != mapPtr->robotList().end(); ++robIter)
01699 {
01700 if ((*robIter)->hardwareEstimatorPtr) { has_init = true; (*robIter)->hardwareEstimatorPtr->start(); }
01701 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01702 senIter != (*robIter)->sensorList().end(); ++senIter)
01703 {
01704 if ((*senIter)->getNeedInit())
01705 { has_init = true; (*senIter)->start(); }
01706 }
01707 robotPtr = *robIter;
01708 }
01709
01710
01711 if (has_init && !(intOpts[iReplay] & 1))
01712 {
01713 std::cout << "Sensors are calibrating... DON'T MOVE THE SYSTEM!!" << std::flush;
01714 sleep(2);
01715 std::cout << " done." << std::endl;
01716
01717 bool abort = false;
01718 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01719 robIter != mapPtr->robotList().end(); ++robIter)
01720 {
01721 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01722 senIter != (*robIter)->sensorList().end(); ++senIter)
01723 {
01724 if ((*senIter)->getNeedInit())
01725 {
01726 RawInfos infos;
01727 (*senIter)->queryAvailableRaws(infos);
01728 if (infos.available.size() == 0)
01729 {
01730 std::cerr << "Sensor " << (*senIter)->name() << " has no data, stopping." << std::endl;
01731 abort = true;
01732 }
01733 }
01734 }
01735 }
01736 if (abort)
01737 {
01738 worldPtr->error = eNoSensorData;
01739 JFR_ERROR(RtslamException, RtslamException::NO_SENSOR_DATA, "Some sensors have no data.");
01740 }
01741 }
01742
01743
01744
01745 double start_date = kernel::Clock::getTime();
01746 if (intOpts[iSimu]) start_date = 0.0;
01747 if (!(intOpts[iReplay] & 1) && (intOpts[iDump] & 1)) {
01748 std::fstream f((strOpts[sDataPath] + std::string("/sdate.log")).c_str(), std::ios_base::out);
01749 f << std::setprecision(19) << start_date << std::endl;
01750 f.close();
01751 }
01752 else if (intOpts[iReplay] & 1) {
01753 std::fstream f((strOpts[sDataPath] + std::string("/sdate.log")).c_str(), std::ios_base::in);
01754 if (!f.is_open()) { std::cout << "Missing sdate.log file. Please copy the .time file of the first image to sdate.log" << std::endl; return; }
01755 f >> start_date;
01756 f.close();
01757 }
01758 std::cout << "slam start date: " << std::setprecision(16) << start_date << std::endl;
01759 sensorManager->setStartDate(start_date);
01760
01761
01762 for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
01763 robIter != mapPtr->robotList().end(); ++robIter)
01764 {
01765 for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
01766 senIter != (*robIter)->sensorList().end(); ++senIter)
01767 {
01768 if (!(*senIter)->getNeedInit())
01769 (*senIter)->start();
01770 }
01771 }
01772
01773 #if !SHOW_PERIODIC_SENSORS_INFOS
01774 showSensorsInfos(mapPtr);
01775 #endif
01776
01777 #if STATS
01778 jblas::vec robot_prediction;
01779 double average_robot_innovation_pos = 0.;
01780 double average_robot_innovation_ori = 0.;
01781 int n_innovation = 0;
01782 #endif
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 double filterTime = 0.0;
01794 kernel::Chrono chrono;
01795 double next_show_infos = -1;
01796
01797 while (!(*world)->exit())
01798 {
01799 bool had_data = false;
01800 chrono.reset();
01801
01802 SensorManagerAbstract::ProcessInfo pinfo = sensorManager->getNextDataToUse(filterTime);
01803 bool no_more_data = pinfo.no_more_data;
01804
01805 if (pinfo.sen)
01806 {
01807 had_data = true;
01808 robot_ptr_t robPtr = pinfo.sen->robotPtr();
01809 if (intOpts[iReplay] == 2)
01810 pinfo.sen->process_fake(pinfo.id, true);
01811 else
01812 {
01813 double newt = pinfo.date;
01814 #if SHOW_PERIODIC_SENSORS_INFOS
01815 if (newt > next_show_infos) { showSensorsInfos(mapPtr); next_show_infos = newt+2.; }
01816 #endif
01817
01818 JFR_DEBUG("************** FRAME : " << (*world)->t << " (" << std::setprecision(16) << newt << std::setprecision(6) << ") sensor " << pinfo.sen->id());
01819
01820
01821
01822
01823
01824
01825
01826 bool waited = false;
01827 double wait_time;
01828 estimatordata_condition.set(0);
01829 double start_date = kernel::Clock::getTime();
01830 double waitedmove_date = start_date;
01831 bool stop = false;
01832 while (!robPtr->move(newt))
01833 {
01834 if (!waited) wait_time = kernel::Clock::getTime();
01835 waited = true;
01836 if (robPtr->hardwareEstimatorPtr->stopped()) { stop = true; break; }
01837 estimatordata_condition.wait(boost::lambda::_1 != 0);
01838 estimatordata_condition.set(0);
01839 waitedmove_date = kernel::Clock::getTime();
01840 }
01841 double moved_date = kernel::Clock::getTime();
01842 if (stop)
01843 {
01844 std::cout << "No more estimator data, stopping." << std::endl;
01845 break;
01846 }
01847 if (waited)
01848 {
01849 wait_time = kernel::Clock::getTime() - wait_time;
01850 std::cout << "wa(i|s)ted " << wait_time << " for estimator data" << std::endl;
01851 }
01852
01853
01854 if (!ready && sensorManager->allInit())
01855 {
01856 robPtr->reinit_extrapolate();
01857 ready = true;
01858 }
01859
01860 JFR_DEBUG("Robot " << robPtr->id() << " state after move " << robPtr->state.x() << " ; euler " << quaternion::q2e(ublas::subrange(robPtr->state.x(), 3, 7)));
01861 JFR_DEBUG("Robot state stdev after move " << stdevFromCov(robPtr->state.P()));
01862 #if STATS
01863 robot_prediction = robPtr->pose.x();
01864 #endif
01865
01866 #if REAL_TIME_LIVE_RUN
01867 pinfo.sen->process(pinfo.id, pinfo.date_next);
01868 #else
01869 pinfo.sen->process(pinfo.id, -1.);
01870 #endif
01871 pinfo.sen->robotPtr()->last_updated = pinfo.sen;
01872
01873 #if STATE_HISTORY
01874 pinfo.sen->robotPtr()->historyManager->process(newt);
01875
01876 #endif
01877
01878 JFR_DEBUG("Robot state after corrections of sensor " << pinfo.sen->id() << " : " << robPtr->state.x() << " ; euler " << quaternion::q2e(ublasExtra::normalized(ublas::subrange(robPtr->state.x(), 3, 7))));
01879 JFR_DEBUG("Robot state stdev after corrections " << stdevFromCov(robPtr->state.P()));
01880 #if STATS
01881 average_robot_innovation_pos += ublas::norm_2(ublas::subrange(robPtr->pose.x(),0,3) - ublas::subrange(robot_prediction,0,3));
01882 average_robot_innovation_ori += ublas::norm_2(ublas::subrange(robPtr->pose.x(),3,7) - ublas::subrange(robot_prediction,3,7));
01883 n_innovation++;
01884 #endif
01885
01886 robPtr->reinit_extrapolate();
01887 double processed_date = kernel::Clock::getTime();
01888 if (exporter && ready) exporter->exportCurrentState();
01889
01890 sensorManager->logData(pinfo.sen, start_date, waitedmove_date, moved_date, processed_date);
01891 }
01892 filterTime = robPtr->self_time;
01893 }
01894
01895
01896
01897 if (had_data)
01898 {
01899
01900 bool renderAll;
01901 #ifdef HAVE_MODULE_QDISPLAY
01902 if (intOpts[iDispQt])
01903 {
01904 boost::unique_lock<boost::mutex> runStatus_lock(viewerQt->runStatus.mutex);
01905 renderAll = viewerQt->runStatus.render_all;
01906 runStatus_lock.unlock();
01907 } else
01908 #endif
01909 renderAll = (intOpts[iRenderAll] != 0);
01910
01911
01912 if ((intOpts[iDispQt] || intOpts[iDispGdhe]) && renderAll)
01913 {
01914 boost::unique_lock<boost::mutex> display_lock((*world)->display_mutex);
01915 while(!(*world)->display_rendered && !(*world)->exit()) (*world)->display_condition.wait(display_lock);
01916 display_lock.unlock();
01917 }
01918 }
01919
01920
01921
01922 unsigned processed_t = (had_data ? (*world)->t : (*world)->t-1);
01923 if ((*world)->display_t+1 < processed_t+1)
01924 {
01925 boost::unique_lock<boost::mutex> display_lock((*world)->display_mutex);
01926 if ((*world)->display_rendered)
01927 {
01928 #ifdef HAVE_MODULE_QDISPLAY
01929 display::ViewerQt *viewerQt = NULL;
01930 if (intOpts[iDispQt]) viewerQt = PTR_CAST<display::ViewerQt*> ((*world)->getDisplayViewer(display::ViewerQt::id()));
01931 if (intOpts[iDispQt]) viewerQt->bufferize(*world);
01932 #endif
01933 #ifdef HAVE_MODULE_GDHE
01934 display::ViewerGdhe *viewerGdhe = NULL;
01935 if (intOpts[iDispGdhe]) viewerGdhe = PTR_CAST<display::ViewerGdhe*> ((*world)->getDisplayViewer(display::ViewerGdhe::id()));
01936 if (intOpts[iDispGdhe]) viewerGdhe->bufferize(*world);
01937 #endif
01938
01939 (*world)->display_t = (*world)->t;
01940 (*world)->display_rendered = false;
01941 display_lock.unlock();
01942 (*world)->display_condition.notify_all();
01943 } else
01944 display_lock.unlock();
01945 }
01946
01947 if (no_more_data) break;
01948
01949 if (!had_data)
01950 {
01951 if (pinfo.date_next < 0) rawdata_condition.wait(boost::lambda::_1 != 0); else
01952 rawdata_condition.timed_wait(boost::lambda::_1 != 0, boost::posix_time::microseconds((pinfo.date_next-kernel::Clock::getTime())*1e6));
01953 }
01954 rawdata_condition.set(0);
01955
01956 bool doPause;
01957 #ifdef HAVE_MODULE_QDISPLAY
01958 if (intOpts[iDispQt])
01959 {
01960 boost::unique_lock<boost::mutex> runStatus_lock(viewerQt->runStatus.mutex);
01961 doPause = viewerQt->runStatus.pause;
01962 runStatus_lock.unlock();
01963 } else
01964 #endif
01965 doPause = (intOpts[iPause] != 0);
01966 if (doPause && had_data && !(*world)->exit())
01967 {
01968 (*world)->slam_blocked(true);
01969 #ifdef HAVE_MODULE_QDISPLAY
01970 if (intOpts[iDispQt])
01971 {
01972 boost::unique_lock<boost::mutex> runStatus_lock(viewerQt->runStatus.mutex);
01973 do {
01974 viewerQt->runStatus.condition.wait(runStatus_lock);
01975 } while (viewerQt->runStatus.pause && !viewerQt->runStatus.next);
01976 viewerQt->runStatus.next = 0;
01977 runStatus_lock.unlock();
01978 } else
01979 #endif
01980 getchar();
01981 (*world)->slam_blocked(false);
01982 }
01983
01984 if (had_data)
01985 {
01986 (*world)->t++;
01987 if (dataLogger) dataLogger->log();
01988 }
01989 }
01990
01991 std::cout << "Stopping RT-SLAM" << std::endl;
01992 #if STATS
01993 average_robot_innovation_pos /= n_innovation;
01994 average_robot_innovation_ori /= n_innovation;
01995 std::cout << "innovation" <<
01996 " avg " << (*world)->mapList().front()->filterPtr->avg_innov() <<
01997 " max " << (*world)->mapList().front()->filterPtr->max_innov() <<
01998 " robot_pos_avg " << average_robot_innovation_pos <<
01999 " robot_ori_avg " << average_robot_innovation_ori << std::endl;
02000 std::cout << "LandmarkCounts EP " << LandmarkEuclideanPoint::ncreated << " AHP " << LandmarkAnchoredHomogeneousPoint::ncreated << std::endl;
02001 #endif
02002 robot_ptr_t robPtr = (*world)->mapList().front()->robotList().front();
02003 std::cout << "final_robot_position " << robPtr->state.x(0) << " " << robPtr->state.x(1) << " " << robPtr->state.x(2) << std::endl;
02004
02005 demo_slam_stop(world);
02006
02007
02008
02009 JFR_GLOBAL_CATCH
02010 }
02011
02012
02018 bool demo_slam_display_first = true;
02019
02020 void demo_slam_display(world_ptr_t *world)
02021 { JFR_GLOBAL_TRY
02022
02023 if (demo_slam_display_first && !(intOpts[iReplay] & 1))
02024 {
02025 kernel::setCurrentThreadPriority(display_niceness);
02026 demo_slam_display_first = false;
02027 }
02028
02029
02030 kernel::Timer timer(display_period*1000);
02031 while(!(*world)->exit())
02032 {
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046 boost::unique_lock<kernel::VariableMutex<bool> > blocked_lock((*world)->slam_blocked);
02047 if ((*world)->slam_blocked.var)
02048 {
02049 if ((*world)->display_t+1 < (*world)->t+1 && (*world)->display_rendered)
02050 {
02051 #ifdef HAVE_MODULE_QDISPLAY
02052 display::ViewerQt *viewerQt = NULL;
02053 if (intOpts[iDispQt]) viewerQt = PTR_CAST<display::ViewerQt*> ((*world)->getDisplayViewer(display::ViewerQt::id()));
02054 if (intOpts[iDispQt]) viewerQt->bufferize(*world);
02055 #endif
02056 #ifdef HAVE_MODULE_GDHE
02057 display::ViewerGdhe *viewerGdhe = NULL;
02058 if (intOpts[iDispGdhe]) viewerGdhe = PTR_CAST<display::ViewerGdhe*> ((*world)->getDisplayViewer(display::ViewerGdhe::id()));
02059 if (intOpts[iDispGdhe]) viewerGdhe->bufferize(*world);
02060 #endif
02061
02062 (*world)->display_t = (*world)->t;
02063 (*world)->display_rendered = false;
02064 }
02065 }
02066 blocked_lock.unlock();
02067
02068
02069
02070 boost::unique_lock<boost::mutex> display_lock((*world)->display_mutex);
02071 if (intOpts[iDispQt] == 0)
02072 {
02073 while((*world)->display_rendered)
02074 (*world)->display_condition.wait(display_lock);
02075 } else
02076 {
02077 #ifdef HAVE_MODULE_QDISPLAY
02078 int nwait = std::max(1,display_period/10-1);
02079 for(int i = 0; (*world)->display_rendered && i < nwait; ++i)
02080 {
02081 (*world)->display_condition.timed_wait(display_lock, boost::posix_time::milliseconds(10));
02082 display_lock.unlock();
02083 QApplication::instance()->processEvents();
02084 display_lock.lock();
02085 }
02086 if ((*world)->display_rendered) break;
02087 #endif
02088 }
02089 display_lock.unlock();
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102 #ifdef HAVE_MODULE_QDISPLAY
02103 display::ViewerQt *viewerQt = NULL;
02104 if (intOpts[iDispQt]) viewerQt = PTR_CAST<display::ViewerQt*> ((*world)->getDisplayViewer(display::ViewerQt::id()));
02105 if (intOpts[iDispQt]) viewerQt->render();
02106 #endif
02107 #ifdef HAVE_MODULE_GDHE
02108 display::ViewerGdhe *viewerGdhe = NULL;
02109 if (intOpts[iDispGdhe]) viewerGdhe = PTR_CAST<display::ViewerGdhe*> ((*world)->getDisplayViewer(display::ViewerGdhe::id()));
02110 if (intOpts[iDispGdhe]) viewerGdhe->render();
02111 #endif
02112
02113 if (((intOpts[iReplay] & 1) || intOpts[iSimu]) && (intOpts[iDump] & 1) && (*world)->display_t+1 != 0)
02114 {
02115 #ifdef HAVE_MODULE_QDISPLAY
02116 if (intOpts[iDispQt])
02117 {
02118 std::ostringstream oss; oss << strOpts[sDataPath] << "/rendered-2D_%d-" << std::setw(6) << std::setfill('0') << (*world)->display_t << ".png";
02119 viewerQt->dump(oss.str());
02120 }
02121 #endif
02122 #ifdef HAVE_MODULE_GDHE
02123 if (intOpts[iDispGdhe])
02124 {
02125 std::ostringstream oss; oss << strOpts[sDataPath] << "/rendered-3D_" << std::setw(6) << std::setfill('0') << (*world)->display_t << ".png";
02126 viewerGdhe->dump(oss.str());
02127 }
02128 #endif
02129
02130
02131 }
02132
02133
02134
02135
02136
02137
02138 display_lock.lock();
02139 (*world)->display_rendered = true;
02140 display_lock.unlock();
02141 (*world)->display_condition.notify_all();
02142
02143 if (intOpts[iDispQt]) break; else timer.wait();
02144 }
02145
02146 JFR_GLOBAL_CATCH
02147 }
02148
02149
02156 void demo_slam_run() {
02157
02158
02159 demo_slam_display_first = true;
02160
02161
02162 if (intOpts[iDispQt])
02163 {
02164 #ifdef HAVE_MODULE_QDISPLAY
02165 qdisplay::QtAppStart((qdisplay::FUNC)&demo_slam_display,0,(qdisplay::FUNC)&demo_slam_main,0,display_period,&worldPtr,(qdisplay::EXIT_FUNC)&demo_slam_exit);
02166 #else
02167 std::cout << "Please install qdisplay module if you want 2D display" << std::endl;
02168 #endif
02169 } else
02170 if (intOpts[iDispGdhe])
02171 {
02172 #ifdef HAVE_MODULE_GDHE
02173 boost::thread *thread_disp = new boost::thread(boost::bind(demo_slam_display,&worldPtr));
02174 demo_slam_main(&worldPtr);
02175 delete thread_disp;
02176 #else
02177 std::cout << "Please install gdhe module if you want 3D display" << std::endl;
02178 #endif
02179 } else
02180 {
02181 demo_slam_main(&worldPtr);
02182 }
02183
02184 JFR_DEBUG("Terminated");
02185 }
02186
02187
02193 #define TOKENPASTE(x, y, z) x ## y ## z
02194 #define TOKENPASTE2(x, y, z) TOKENPASTE(x, y, z)
02195 #define TOKENSTRING(x) #x
02196
02197
02198 #define KeyValueFile_processItem(k) { read ? keyValueFile.getItem(#k, k) : keyValueFile.setItem(#k, k); }
02199 #define KeyValueFile_processItem_def(k, def) { read ? keyValueFile.getItem(#k, k, def) : keyValueFile.setItem(#k, k); }
02200 #define KeyValueFile_processItem_ind(pref, i, k) { std::ostringstream oss; oss << #pref << i << #k; read ? keyValueFile.getItem(oss.str(), pref##k[i-1]) : keyValueFile.setItem(oss.str(), pref##k[i-1]); }
02201 #define KeyValueFile_processItem_ind_def(pref, i, k, def) { std::ostringstream oss; oss << #pref << i << #k; read ? keyValueFile.getItem(oss.str(), pref##k[i-1], def) : keyValueFile.setItem(oss.str(), pref##k[i-1]); }
02202
02203
02204 void ConfigSetup::loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile)
02205 {
02206 jafar::kernel::KeyValueFile &keyValueFile2 = const_cast<jafar::kernel::KeyValueFile&>(keyValueFile);
02207 processKeyValueFile(keyValueFile2, true);
02208 }
02209 void ConfigSetup::saveKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile)
02210 {
02211 processKeyValueFile(keyValueFile, false);
02212 }
02213
02214 void ConfigSetup::processKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile, bool read)
02215 {
02216 int camsi = intOpts[iCamera]/10;
02217 const int ncam = 3;
02218 int ncams = 0; bool cams[ncam]; for(int i = 0; i < ncam; i++) { cams[i] = camsi&(1<<i); if (cams[i]) ncams++; }
02219 bool load_calib = ((intOpts[iCamera]%10) > 0);
02220
02221 if (intOpts[iRobot] == 1)
02222 {
02223 try { for(int i = 1; i <= ncam; ++i) if (cams[i-1]) KeyValueFile_processItem_ind(CAMERA,i,_POSE_INERTIAL) }
02224 catch (kernel::KernelException &e) { if (ncams == 1 && read) keyValueFile.getItem("SENSOR_POSE_INERTIAL", CAMERA_POSE_INERTIAL[0]); else throw e; }
02225 }
02226 else
02227 {
02228 try { for(int i = 1; i <= ncam; ++i) if (cams[i-1]) KeyValueFile_processItem_ind(CAMERA,i,_POSE_CONSTVEL) }
02229 catch (kernel::KernelException &e) { if (ncams == 1 && read) keyValueFile.getItem("SENSOR_POSE_CONSTVEL", CAMERA_POSE_CONSTVEL[0]); else throw e; }
02230 }
02231 if (!read || intOpts[iGps])
02232 KeyValueFile_processItem(GPS_POSE);
02233 KeyValueFile_processItem(ROBOT_POSE);
02234
02235 if (intOpts[iSimu])
02236 {
02237 try {
02238 for(int i = 1; i <= ncam; ++i)
02239 {
02240 if (!cams[i-1]) continue;
02241 KeyValueFile_processItem_ind(CAMERA,i,_IMG_WIDTH_SIMU);
02242 KeyValueFile_processItem_ind(CAMERA,i,_IMG_HEIGHT_SIMU);
02243 KeyValueFile_processItem_ind(CAMERA,i,_INTRINSIC_SIMU);
02244 KeyValueFile_processItem_ind(CAMERA,i,_DISTORTION_SIMU);
02245 }
02246 } catch (kernel::KernelException &e)
02247 {
02248 if (read && ncams == 1)
02249 {
02250 keyValueFile.getItem("IMG_WIDTH_SIMU", CAMERA_IMG_WIDTH_SIMU[0]);
02251 keyValueFile.getItem("IMG_HEIGHT_SIMU", CAMERA_IMG_HEIGHT_SIMU[0]);
02252 keyValueFile.getItem("INTRINSIC_SIMU", CAMERA_INTRINSIC_SIMU[0]);
02253 keyValueFile.getItem("DISTORTION_SIMU", CAMERA_DISTORTION_SIMU[0]);
02254 } else throw e;
02255 }
02256 } else
02257 {
02258 try {
02259 for(int i = 1; i <= ncam; ++i)
02260 {
02261 if (!cams[i-1]) continue;
02262 KeyValueFile_processItem_ind(CAMERA,i,_TYPE);
02263 KeyValueFile_processItem_ind_def(CAMERA,i,_FORMAT, "0");
02264 KeyValueFile_processItem_ind(CAMERA,i,_DEVICE);
02265 KeyValueFile_processItem_ind(CAMERA,i,_IMG_WIDTH);
02266 KeyValueFile_processItem_ind(CAMERA,i,_IMG_HEIGHT);
02267 KeyValueFile_processItem_ind(CAMERA,i,_INTRINSIC);
02268 KeyValueFile_processItem_ind(CAMERA,i,_DISTORTION);
02269 if (load_calib) KeyValueFile_processItem_ind(CAMERA,i,_CALIB);
02270 }
02271 } catch (kernel::KernelException &e)
02272 {
02273 if (read && ncams == 1)
02274 {
02275 keyValueFile.getItem("CAMERA_TYPE", CAMERA_TYPE[0]);
02276 keyValueFile.getItem("CAMERA_FORMAT", CAMERA_FORMAT[0], "0");
02277 keyValueFile.getItem("CAMERA_DEVICE", CAMERA_DEVICE[0]);
02278 keyValueFile.getItem("IMG_WIDTH", CAMERA_IMG_WIDTH[0]);
02279 keyValueFile.getItem("IMG_HEIGHT", CAMERA_IMG_HEIGHT[0]);
02280 keyValueFile.getItem("INTRINSIC", CAMERA_INTRINSIC[0]);
02281 keyValueFile.getItem("DISTORTION", CAMERA_DISTORTION[0]);
02282 } else throw e;
02283 }
02284 }
02285
02286 KeyValueFile_processItem(UNCERT_VLIN);
02287 KeyValueFile_processItem(UNCERT_VANG);
02288 KeyValueFile_processItem(PERT_VLIN);
02289 KeyValueFile_processItem(PERT_VANG);
02290
02291 if (!read || intOpts[iRobot] == 1 || intOpts[iTrigger] != 0)
02292 KeyValueFile_processItem(MTI_DEVICE);
02293
02294 if (!read || intOpts[iRobot] == 1)
02295 {
02296 KeyValueFile_processItem(ACCELERO_FULLSCALE);
02297 KeyValueFile_processItem(ACCELERO_NOISE);
02298 KeyValueFile_processItem(GYRO_FULLSCALE);
02299 KeyValueFile_processItem(GYRO_NOISE);
02300
02301 try { KeyValueFile_processItem(INITIAL_GRAVITY); }
02302 catch(kernel::KernelException &e) { INITIAL_GRAVITY = 9.806; }
02303 KeyValueFile_processItem(UNCERT_GRAVITY);
02304 KeyValueFile_processItem(UNCERT_ABIAS);
02305 KeyValueFile_processItem(UNCERT_WBIAS);
02306 KeyValueFile_processItem(PERT_AERR);
02307 KeyValueFile_processItem(PERT_WERR);
02308 KeyValueFile_processItem(PERT_RANWALKACC);
02309 KeyValueFile_processItem(PERT_RANWALKGYRO);
02310 }
02311
02312 try { KeyValueFile_processItem(INITIAL_HEADING); }
02313 catch(kernel::KernelException &e) { INITIAL_HEADING = 0.0; }
02314 KeyValueFile_processItem(UNCERT_HEADING);
02315 KeyValueFile_processItem(UNCERT_ATTITUDE);
02316
02317 if (!read || intOpts[iRobot] == 1)
02318 KeyValueFile_processItem(IMU_TIMESTAMP_CORRECTION);
02319 if (!read || intOpts[iGps])
02320 KeyValueFile_processItem(GPS_TIMESTAMP_CORRECTION);
02321
02322 if (!read || intOpts[iRobot] == 2)
02323 {
02324 KeyValueFile_processItem(dxNDR);
02325 KeyValueFile_processItem(dvNDR);
02326 }
02327
02328 if (!read || intOpts[iRobot] == 2 || intOpts[iOdom] != 0)
02329 try { KeyValueFile_processItem(ODO_TIMESTAMP_CORRECTION); }
02330 catch(kernel::KernelException &e) { if (read) keyValueFile.getItem("POS_TIMESTAMP_CORRECTION", ODO_TIMESTAMP_CORRECTION); else throw e; }
02331
02332
02333 if (!read || intOpts[iOdom] != 0)
02334 KeyValueFile_processItem(ODO_CALIB);
02335 if (!read || intOpts[iGps] != 0)
02336 try { KeyValueFile_processItem(GPS_MAX_CONSIST_SIG); }
02337 catch(kernel::KernelException &e) { GPS_MAX_CONSIST_SIG = 1e9; }
02338
02339
02340 if (!read || (intOpts[iRobot] == 1 && intOpts[iSimu]))
02341 {
02342 KeyValueFile_processItem(SIMU_IMU_TIMESTAMP_CORRECTION);
02343 KeyValueFile_processItem(SIMU_IMU_FREQ);
02344 KeyValueFile_processItem(SIMU_IMU_GRAVITY);
02345 KeyValueFile_processItem(SIMU_IMU_GYR_BIAS);
02346 KeyValueFile_processItem(SIMU_IMU_GYR_BIAS_NOISESTD);
02347 KeyValueFile_processItem(SIMU_IMU_GYR_GAIN);
02348 KeyValueFile_processItem(SIMU_IMU_GYR_GAIN_NOISESTD);
02349 KeyValueFile_processItem(SIMU_IMU_RANDWALKGYR_FACTOR);
02350 KeyValueFile_processItem(SIMU_IMU_ACC_BIAS);
02351 KeyValueFile_processItem(SIMU_IMU_ACC_BIAS_NOISESTD);
02352 KeyValueFile_processItem(SIMU_IMU_ACC_GAIN);
02353 KeyValueFile_processItem(SIMU_IMU_ACC_GAIN_NOISESTD);
02354 KeyValueFile_processItem(SIMU_IMU_RANDWALKACC_FACTOR);
02355 }
02356 }
02357
02358
02359 void ConfigEstimation::loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile)
02360 {
02361 jafar::kernel::KeyValueFile &keyValueFile2 = const_cast<jafar::kernel::KeyValueFile&>(keyValueFile);
02362 processKeyValueFile(keyValueFile2, true);
02363 }
02364 void ConfigEstimation::saveKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile)
02365 {
02366 processKeyValueFile(keyValueFile, false);
02367 }
02368
02369 void ConfigEstimation::processKeyValueFile(jafar::kernel::KeyValueFile& keyValueFile, bool read)
02370 {
02371 KeyValueFile_processItem(CORRECTION_SIZE);
02372
02373 KeyValueFile_processItem(MAP_SIZE);
02374 KeyValueFile_processItem(PIX_NOISE);
02375 KeyValueFile_processItem(PIX_NOISE_SIMUFACTOR);
02376
02377 KeyValueFile_processItem(D_MIN);
02378 KeyValueFile_processItem(REPARAM_TH);
02379
02380 KeyValueFile_processItem(GRID_HCELLS);
02381 KeyValueFile_processItem(GRID_VCELLS);
02382 KeyValueFile_processItem(GRID_MARGIN);
02383 KeyValueFile_processItem(GRID_SEPAR);
02384
02385 KeyValueFile_processItem(RELEVANCE_TH);
02386 KeyValueFile_processItem(MAHALANOBIS_TH);
02387 KeyValueFile_processItem(N_UPDATES_TOTAL);
02388 KeyValueFile_processItem(N_UPDATES_RANSAC);
02389 KeyValueFile_processItem(N_INIT);
02390 KeyValueFile_processItem(N_RECOMP_GAINS);
02391 KeyValueFile_processItem(RANSAC_LOW_INNOV);
02392
02393 KeyValueFile_processItem(RANSAC_NTRIES);
02394 try { KeyValueFile_processItem(MULTIPLE_DEPTH_HYPOS); } catch (kernel::KernelException &e) { if (read) MULTIPLE_DEPTH_HYPOS = false; }
02395
02396 KeyValueFile_processItem(HARRIS_CONV_SIZE);
02397 KeyValueFile_processItem(HARRIS_TH);
02398 KeyValueFile_processItem(HARRIS_EDDGE);
02399
02400 KeyValueFile_processItem(DESC_SIZE);
02401 KeyValueFile_processItem(MULTIVIEW_DESCRIPTOR);
02402 KeyValueFile_processItem(DESC_SCALE_STEP);
02403 KeyValueFile_processItem(DESC_ANGLE_STEP);
02404 KeyValueFile_processItem(DESC_PREDICTION_TYPE);
02405
02406 KeyValueFile_processItem(PATCH_SIZE);
02407 KeyValueFile_processItem(MAX_SEARCH_SIZE);
02408 KeyValueFile_processItem(KILL_SEARCH_SIZE);
02409 KeyValueFile_processItem(MATCH_TH);
02410 KeyValueFile_processItem(MIN_SCORE);
02411
02412 try { KeyValueFile_processItem(HI_MATCH_TH) } catch (kernel::KernelException &e) { if (read) HI_MATCH_TH = MATCH_TH; }
02413 try { KeyValueFile_processItem(HI_LIMIT) } catch (kernel::KernelException &e) { if (read) HI_LIMIT = 100; }
02414
02415 KeyValueFile_processItem(PARTIAL_POSITION);
02416 }
02417