Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
main.hpp
00001 
00020 /*
00021  * STATUS: working fine, use it
00022  * Ransac ensures that we use correct observations for a few first updates,
00023  * allowing bad observations to be more easily detected by gating
00024  * You can disable it by setting N_UPDATES_RANSAC to 0 in config file
00025  */
00026 #define RANSAC_FIRST 1
00027 
00028 /*
00029  * STATUS: working fine, use it
00030  * This allows to use Dala "atrv" robot model instead of camera (default) model in the Gdhe view display
00031  */
00032 #define ATRV 0
00033 
00034 /*
00035  * STATUS: working fine, use it
00036  * This allows to have 0% cpu used for waiting/idle
00037  */
00038 //#define EVENT_BASED_RAW 1 // always enabled now
00039 
00040 /*
00041  * STATUS: in progress, do not use for now
00042  * This allows to track landmarks longer by updating the reference patch when
00043  * the landmark is not detected anymore and the point of view has changed
00044  * significantly enough
00045  * The problem is that the correlation is not robust enough in a matching
00046  * (opposed to tracking) context, and it can provoke matching errors with a
00047  * progressive appearance drift.
00048  * Also decreasing perfs by 10%, probably because we save a view at each obs,
00049  * or maybe it just because of the different random process
00050  */
00051 //#define MULTIVIEW_DESCRIPTOR 1 // moved in config file
00052 
00053 /*
00054  * STATUS: in progress, do not use for now
00055  * This allows to ignore some landmarks when we have some experience telling
00056  * us that we can't observe this landmarks from here (masking), in order to
00057  * save some time, and to allow creation of other observations in the
00058  * neighborhood to keep localizing with enough landmarks.
00059  * The problem is that sometimes it creates too many landmarks in the same area
00060  * (significantly slowing down slam), and sometimes doesn't create enough of
00061  * them when it is necessary.
00062  */
00063 #define VISIBILITY_MAP 0
00064 
00065 
00066 /*
00067  * STATUS: in progress, do not use for now
00068  * Only update if expectation uncertainty is significant wrt measurement uncertainty.
00069  * 
00070  * Large updates are causing inconsistency because of linearization errors,
00071  * but too numerous updates are also causing inconsistency, 
00072  * so we should avoid to do not significant updates. 
00073  * An update is not significant if there are large odds that it is 
00074  * only measurement noise and that there is not much information.
00075  * 
00076  * When the camera is not moving at all, the landmarks are converging anyway
00077  * quite fast because of this, at very unconsistent positions of course, 
00078  * so that when the camera moves it cannot recover them.
00079  * 
00080  * Some work needs to be done yet to prevent search ellipses from growing
00081  * too much and integrate it better with the whole management, but this was
00082  * for first evaluation purpose.
00083  * 
00084  * Unfortunately it doesn't seem to improve much the situation, even if
00085  * it is still working correctly with less computations.
00086  * The feature is disabled for now.
00087  */
00088 #define RELEVANCE_TEST 0
00089 
00090 /*
00091  * STATUS: seems to improve things, needs more testing but you can try it
00092  * Only update P if expectation uncertainty is significant wrt measurement uncertainty.
00093  *
00094  * This is similar to RELEVANCE_TEST except that we always update mean, and
00095  * update covariance only if innovation is relevant wrt measurement noise,
00096  * and it is more stable than RELEVANCE_TEST.
00097  *
00098  * Needs testing to see if it is stable enough and how to tune the relevance
00099  * threshold.
00100  */
00101 #define RELEVANCE_TEST_P 0
00102 
00103 
00104 /*
00105  * STATUS: in progress, do not use for now
00106  * This uses HDseg powered Segment based slam instead of the usual point based slam.
00107  * 0 use points
00108  * 1 use segments
00109  * 2 use both sgments and points
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  * STATUS: seems to work ok, needs a bit more testing but you can try it
00127  * This option will allocate time to data managers to make them stop
00128  * updating observations when there is no time anymore, in order to avoid
00129  * missing frames.
00130  */
00131 
00132 #define REAL_TIME_LIVE_RUN 0
00133 
00134 
00135 /*
00136  * STATUS: does not work at all, do not use
00137  * This option stores a small sparse history of past positions of the robot
00138  * in the filter's state, but it does not change anything to the estimation
00139  * of the current position.
00140  */
00141 #define STATE_HISTORY 0
00142 
00143 
00149 #include <iostream>
00150 #include <boost/shared_ptr.hpp>
00151 //#include <boost/filesystem/operations.hpp>
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 // jafar debug include
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 //#include "rtslam/landmarkEuclideanPoint.hpp"
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   // int options
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}, // should be in config file
00284   {"camera", 2, 0, 0},
00285   {"trigger", 2, 0, 0}, // should be in config file
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   // double options
00293   {"freq", 2, 0, 0}, // should be in config file
00294   {"shutter", 2, 0, 0}, // should be in config file
00295   {"heading", 2, 0, 0},
00296   {"noisy-sensors", 2, 0, 0},
00297   // string options
00298   {"data-path", 1, 0, 0},
00299   {"config-setup", 1, 0, 0},
00300   {"config-estimation", 1, 0, 0},
00301   {"log", 1, 0, 0},
00302   // breaking options
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; // >0 is higher priority (1;99), needs chown root;chmod u+s or started as root
00314 const int display_niceness = 10; // >0 is lower priority (-20;+20)
00315 const int display_period = 100; // ms
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 // FIXME remove this when kernel is released
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         //boost::filesystem::remove_all(strOpts[sDataPath]); // too dangerous
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"/*, boost::filesystem::copy_option::overwrite_if_exists*/);
00568       boost::filesystem::copy_file(strOpts[sConfigEstimation], strOpts[sDataPath] + "/estimation.cfg.maybe"/*, boost::filesystem::copy_option::overwrite_if_exists*/);
00569     }
00570     else
00571     {
00572       boost::filesystem::copy_file(strOpts[sConfigSetup], strOpts[sDataPath] + "/setup.cfg"/*, boost::filesystem::copy_option::overwrite_if_exists*/);
00573       boost::filesystem::copy_file(strOpts[sConfigEstimation], strOpts[sDataPath] + "/estimation.cfg"/*, boost::filesystem::copy_option::overwrite_if_exists*/);
00574     }
00575   }
00576   if (intOpts[iCamera] < 10 && intOpts[iCamera] > 0) intOpts[iCamera] += 9; // backward compatibility, anyway it does not mean anything with the new convention
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     // write options to log
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   // init some params for the cameras
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   // compute min_cell_fov, min over all camera sensors
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.; // security factor
00720   min_cell_fov *= 180./M_PI;
00721 
00722   // create map
00723   map_ptr_t mapPtr(new MapAbstract(configEstimation.MAP_SIZE));
00724   mapPtr->linkToParentWorld(worldPtr);
00725   
00726    // 1b. Create map manager.
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: { // odometry
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: { // global
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: { // local/multimap
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   // simulation environment
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         // 3D cube
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         // 2D square
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         // almost 2D square
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         // 3D regular grid
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         // 2D square
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         // almost 2D square
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       // far 3D regular grid
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     // add landmarks
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 //    case 0:
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) // constant model
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       // just to initialize the MTI as an external trigger controlling shutter time
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) // inertial
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 /*      boost::shared_ptr<hardware::HardwareEstimatorInertialAdhocSimulator> hardEst1_(
00963         new hardware::HardwareEstimatorInertialAdhocSimulator(configSetup.SIMU_IMU_FREQ, 50, simulator, robPtr1_->id()));
00964       hardEst1_->setSyncConfig(configSetup.SIMU_IMU_TIMESTAMP_CORRECTION);
00965       
00966       hardEst1_->setErrors(configSetup.SIMU_IMU_GRAVITY, 
00967         configSetup.SIMU_IMU_GYR_BIAS, configSetup.SIMU_IMU_GYR_BIAS_NOISESTD,
00968         configSetup.SIMU_IMU_GYR_GAIN, configSetup.SIMU_IMU_GYR_GAIN_NOISESTD,
00969         configSetup.SIMU_IMU_RANDWALKGYR_FACTOR * configSetup.PERT_RANWALKGYRO,
00970         configSetup.SIMU_IMU_ACC_BIAS, configSetup.SIMU_IMU_ACC_BIAS_NOISESTD,
00971         configSetup.SIMU_IMU_ACC_GAIN, configSetup.SIMU_IMU_ACC_GAIN_NOISESTD,
00972         configSetup.SIMU_IMU_RANDWALKACC_FACTOR * configSetup.PERT_RANWALKACC);
00973       
00974       hardEst1 = hardEst1_;
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       //hardEst1_->setUseForInit(true);
00983       //hardEst1_->setNeedInit(true);
00984       //hardEst1_->start();
00985       hardEst1 = hardEst1_;
00986     }
00987     robPtr1_->setHardwareEstimator(hardEst1);
00988 
00989     robPtr1 = robPtr1_;
00990   } else
00991   if (intOpts[iRobot] == 2) // odometry
00992   {
00993 /*    robodo_ptr_t robPtr1_(new RobotOdometry(mapPtr));
00994     std::cout<<"configSetup.dxNDR "<<configSetup.dxNDR<<std::endl;
00995     std::cout<<"configSetup.dvNDR "<<configSetup.dvNDR<<std::endl;
00996     double _v[6] = {configSetup.dxNDR, configSetup.dxNDR, configSetup.dxNDR, 
00997             configSetup.dvNDR, configSetup.dvNDR, configSetup.dvNDR};
00998     vec pertStd = createVector<6>(_v);
00999     robPtr1_->perturbation.set_std_continuous(pertStd);
01000     
01001     hardware::hardware_estimator_ptr_t hardEst2;
01002     boost::shared_ptr<hardware::HardwareEstimatorOdo> hardEst2_(new hardware::HardwareEstimatorOdo(
01003         intOpts[iTrigger], floatOpts[fFreq], floatOpts[fShutter], 1024, mode, strOpts[sDataPath]));
01004     if (intOpts[iTrigger] != 0) floatOpts[fFreq] = hardEst2_->getFreq();
01005     hardEst2_->setSyncConfig(configSetup.POS_TIMESTAMP_CORRECTION);
01006     hardEst2 = hardEst2_;
01007     robPtr1_->setHardwareEstimator(hardEst2); 
01008     robPtr1 = robPtr1_;
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   // history manager
01020   #if STATE_HISTORY
01021   history_manager_ptr_t hm(new HistoryManagerSparse(mapPtr, robPtr1->pose.ia(), 1.0, 5.0, 3));
01022   //history_manager_ptr_t hm(new HistoryManagerSparse(mapPtr, robPtr1->state.ia(), 1.0, 5.0, 3));
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       // horiz loop, no rotation
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       // two coplanar circles
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       // two non-coplanar circles at constant velocity
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       // two non-coplanar circles with start and stop from/to null speed
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       // horiz loop with rotation (always goes forward)
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       // straight line
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 //robPtr1->setPoseStd(0, 0, 0, 0, 0, 0, 20, 20, 20, 10, 10, 10, true);
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     // a. Create camera
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)); // x,y,z,roll,pitch,yaw
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)); // x,y,z,roll,pitch,yaw + std_dev
01190     }
01191     //senPtr11->pose.x(quaternion::originFrame());
01192     senPtr11->params.setIntrinsicCalibration(img_width[c], img_height[c], intrinsic[c], distortion[c], configEstimation.CORRECTION_SIZE);
01193     //JFR_DEBUG("Correction params: " << senPtr11->params.correction);
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)); // FIXME-EULER-CONVENTION
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); // for auto exposure
01215     }
01216 
01217     // b. Create data manager.
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     } // ncam_built
01291 
01292 
01293     // c. Create hardware sensor
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       { // VIAM
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       { // V4L or VIAM ?
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       { // UEYE
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; } // for each camera
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())); // TODO ask to ignore vel
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]); // x,y,z,roll,pitch,yaw
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]); // x,y,z,roll,pitch,yaw + std_dev
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 //    robPtr1->registerRobotQuantity(RobotAbstract::qAngVel);
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]); // x,y,z,roll,pitch,yaw
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]); // x,y,z,roll,pitch,yaw
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]); // x,y,z,roll,pitch,yaw + std_dev
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; // source online poster or manual file
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); // x,y,z,roll,pitch,yaw
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   //--- force a first display with empty slam to ensure that all windows are loaded
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     // initializing stuff for controlling run/pause from viewer
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   //worldPtr->display_mutex.unlock();
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 } // demo_slam_init
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 //  std::cout << "EXITING !!!" << std::endl;
01534   //fputc('\n', stdin);
01535   thread_main->join();
01536   //thread_main->timed_join(boost::posix_time::milliseconds(500));
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   // stop all sensors
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); // ctrl-c
01608 
01609   signal(SIGABRT, catcher);
01610   signal(SIGPIPE, catcher);
01611   signal(SIGFPE, catcher);
01612   signal(SIGSEGV, catcher);
01613   //signal(SIGBUS, catcher);
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     // force deleting sensors object to call their destructor
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   // wait for display to be ready if enabled
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 // std::cout << "SLAM: now waiting for this display to finish" << std::endl;
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   // start hardware sensors that need long init
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   // wait for their init
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   // set the start date
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   // start other hardware sensors
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   // --- LOOP ------------------------------------------------------------------
01786   // ---------------------------------------------------------------------------
01787   // INIT : complete observations set
01788   // loop all sensors
01789   // loop all lmks
01790   // create sen--lmk observation
01791   // Temporal loop
01792   //if (dataLogger) dataLogger->log();
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); // just to release data
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 //std::cout << "Frame " << (*world)->t << " using sen " << pinfo.sen->id() << " at time " << std::setprecision(16) << newt << std::endl;
01821 
01822         // wait to have all the estimator data (ie one after newt) to do this move,
01823         // or it can cause trouble if there are two many missing data,
01824         // and it ensures offline repeatability, and quality will be better
01825         // TODO be smarter and choose an older data if possible
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           /*if (wait_time > 0.001)*/ std::cout << "wa(i|s)ted " << wait_time << " for estimator data" << std::endl;
01851         }
01852 
01853 
01854         if (!ready && sensorManager->allInit())
01855         { // here to ensure that at least one move has been done (to init estimator)
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         //pinfo.sen->robotPtr()->historyManager->print();
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     // wait that display has finished if render all
01897     if (had_data)
01898     {
01899       // get render all status
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       // if render all, wait display has finished
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     // asking for display if display has finished
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(); // wait for key in replay mode
01981       (*world)->slam_blocked(false);
01982     }
01983 
01984     if (had_data)
01985     {
01986       (*world)->t++;
01987       if (dataLogger) dataLogger->log();
01988     }
01989   } // temporal loop
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 //  std::cout << "\nFINISHED ! Press a key to terminate." << std::endl;
02007 //  getchar();
02008 
02009 JFR_GLOBAL_CATCH
02010 } // demo_slam_main
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 //  static unsigned prev_t = 0;
02030   kernel::Timer timer(display_period*1000);
02031   while(!(*world)->exit())
02032   {
02033     /*
02034     if (intOpts[iDispQt])
02035     {
02036       #ifdef HAVE_MODULE_QDISPLAY
02037       qdisplay::qtMutexLock<kernel::FifoMutex>((*world)->display_mutex);
02038       #endif
02039     }
02040     else
02041     {
02042       (*world)->display_mutex.lock();
02043     }
02044     */
02045     // just to display the last frame if slam is blocked or has finished
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     // waiting that display is ready
02069 // std::cout << "DISPLAY: waiting for data" << std::endl;
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 // std::cout << "DISPLAY: ok data here, let's start!" << std::endl;
02091 
02092 //    if ((*world)->t != prev_t)
02093 //    {
02094 //      prev_t = (*world)->t;
02095 //      (*world)->display_rendered = (*world)->t;
02096       
02097 //    !bufferize!
02098 
02099 //      if (!intOpts[iRenderAll]) // strange: if we always unlock here, qt.dump takes much more time...
02100 //        (*world)->display_mutex.unlock();
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 //        if (intOpts[iRenderAll])
02130 //          (*world)->display_mutex.unlock();
02131       }
02132 //    } else
02133 //    {
02134 //      (*world)->display_mutex.unlock();
02135 //      boost::this_thread::yield();
02136 //    }
02137 // std::cout << "DISPLAY: finished display, marking rendered" << std::endl;
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 } // demo_slam_display
02148 
02149 
02156 void demo_slam_run() {
02157 
02158   //kernel::setProcessScheduler(slam_sched, 5); // for whole process, including display thread
02159   demo_slam_display_first = true;
02160 
02161   // to start with qt display
02162   if (intOpts[iDispQt]) // at least 2d
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]) // only 3d
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 // none
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:20 for Jafar by doxygen 1.7.6.1
LAAS-CNRS