/* * SmartProjectionFactorsCreator.h * * Created on: Oct 8, 2013 * @author Zsolt Kira */ #ifndef SMARTPROJECTIONFACTORSCREATOR_H_ #define SMARTPROJECTIONFACTORSCREATOR_H_ #include #include #include // Use a map to store landmark/smart factor pairs #include // #include #include #include #include #include #include #include namespace gtsam { template class SmartProjectionFactorsCreator { typedef SmartProjectionHessianFactor SmartFactor; typedef FastMap > SmartFactorToStateMap; typedef FastMap > SmartFactorMap; public: SmartProjectionFactorsCreator(const SharedNoiseModel& model, const boost::shared_ptr& K, const double rankTol, const double linThreshold, boost::optional body_P_sensor = boost::none) : noise_(model), K_(K), rankTolerance_(rankTol), linearizationThreshold_(linThreshold), body_P_sensor_(body_P_sensor), totalNumMeasurements(0), numLandmarks(0) {}; void computePoints(Values& values) { typename SmartFactorMap::iterator fit; // Check if landmark exists in mapping for(fit = smartFactors.begin(); fit != smartFactors.end(); fit++) { Key pointKey = (*fit).first; Point3 currentPoint; if((*fit).second->point() && !(*fit).second->isDegenerate()){ currentPoint = *((*fit).second->point()); }else{ currentPoint = Point3(); // if we cannot the smartFactor is degenerate } values.insert(pointKey, currentPoint); } } void add(Key landmarkKey, Key poseKey, Point2 measurement, NonlinearFactorGraph &graph) { std::vector views; std::vector measurements; bool debug = false; // Check if landmark exists in mapping SmartFactorToStateMap::iterator fsit = smartFactorStates.find(landmarkKey); typename SmartFactorMap::iterator fit = smartFactors.find(landmarkKey); if (fsit != smartFactorStates.end() && fit != smartFactors.end()) { if (debug) fprintf(stderr,"Adding measurement to existing landmark\n"); // Add measurement to smart factor (*fit).second->add(measurement, poseKey, noise_, K_); totalNumMeasurements++; if (debug) (*fit).second->print(); } else { if (debug) fprintf(stderr,"New landmark (%d,%d)\n", fsit != smartFactorStates.end(), fit != smartFactors.end()); views.push_back(poseKey); measurements.push_back(measurement); // This is a new landmark, create a new factor and add to mapping boost::shared_ptr smartFactorState(new SmartProjectionHessianFactorState()); boost::shared_ptr smartFactor(new SmartFactor(rankTolerance_, linearizationThreshold_)); smartFactor->add(measurement, poseKey, noise_, K_); smartFactorStates.insert( std::make_pair(landmarkKey, smartFactorState) ); smartFactors.insert( std::make_pair(landmarkKey, smartFactor) ); graph.push_back(smartFactor); numLandmarks++; //landmarkKeys.push_back( L(l) ); totalNumMeasurements++; views.clear(); measurements.clear(); } } void add(Key landmarkKey, Key poseKey, Point2 measurement, const SharedNoiseModel& model, const boost::shared_ptr& Ki, NonlinearFactorGraph &graph) { std::vector views; std::vector measurements; // std::cout << "matrix : " << K->K() << std::endl; bool debug = false; // Check if landmark exists in mapping SmartFactorToStateMap::iterator fsit = smartFactorStates.find(landmarkKey); typename SmartFactorMap::iterator fit = smartFactors.find(landmarkKey); if (fsit != smartFactorStates.end() && fit != smartFactors.end()) { if (debug) fprintf(stderr,"Adding measurement to existing landmark\n"); // (*fit).second->print("before: "); // Add measurement to smart factor (*fit).second->add(measurement, poseKey, model, Ki); // (*fit).second->print("after: "); totalNumMeasurements++; if (debug) (*fit).second->print(); } else { if (debug) std::cout <<"landmark " << DefaultKeyFormatter(landmarkKey) << "pose " << DefaultKeyFormatter(poseKey) << std::endl; // if (debug) fprintf(stderr,"landmarkKey %d poseKey %d measurement\n", landmarkKey, fit != smartFactors.end()); // This is a new landmark, create a new factor and add to mapping boost::shared_ptr smartFactorState(new SmartProjectionHessianFactorState()); boost::shared_ptr smartFactor(new SmartFactor(rankTolerance_, linearizationThreshold_)); smartFactor->add(measurement, poseKey, model, Ki); // smartFactor->print("created: "); // smartFactor->print(" "); smartFactorStates.insert( std::make_pair(landmarkKey, smartFactorState) ); smartFactors.insert( std::make_pair(landmarkKey, smartFactor) ); graph.push_back(smartFactor); if (debug) std::cout <<" graph size " << graph.size() << std::endl; numLandmarks++; totalNumMeasurements++; } } unsigned int getTotalNumMeasurements() { return totalNumMeasurements; } unsigned int getNumLandmarks() { return numLandmarks; } protected: const SharedNoiseModel noise_; ///< noise model used ///< (important that the order is the same as the keys that we use to create the factor) boost::shared_ptr K_; ///< shared pointer to calibration object double rankTolerance_; ///< threshold to decide whether triangulation is degenerate double linearizationThreshold_; ///< threshold to decide whether to re-linearize boost::optional body_P_sensor_; ///< The pose of the sensor in the body frame SmartFactorToStateMap smartFactorStates; SmartFactorMap smartFactors; unsigned int totalNumMeasurements; //landmarkKeys.push_back( L(l) ); unsigned int numLandmarks; }; } #endif /* SMARTPROJECTIONFACTORSCREATOR_H_ */