gtsam/gtsam_unstable/slam/SmartProjectionFactorsCreat...

180 lines
6.5 KiB
C++

/*
* SmartProjectionFactorsCreator.h
*
* Created on: Oct 8, 2013
* @author Zsolt Kira
*/
#ifndef SMARTPROJECTIONFACTORSCREATOR_H_
#define SMARTPROJECTIONFACTORSCREATOR_H_
#include <gtsam/geometry/PinholeCamera.h>
#include <gtsam/linear/NoiseModel.h>
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
// Use a map to store landmark/smart factor pairs
#include <gtsam/base/FastMap.h>
// #include <gtsam_unstable/slam/SmartProjectionFactor.h>
#include <gtsam_unstable/slam/SmartProjectionHessianFactor.h>
#include <boost/foreach.hpp>
#include <boost/assign/std/vector.hpp>
#include <fstream>
#include <iostream>
#include <utility>
namespace gtsam {
template<class POSE, class LANDMARK, class CALIBRATION = Cal3_S2>
class SmartProjectionFactorsCreator {
typedef SmartProjectionHessianFactor<Pose3, Point3, CALIBRATION> SmartFactor;
typedef FastMap<Key, boost::shared_ptr<SmartProjectionHessianFactorState> > SmartFactorToStateMap;
typedef FastMap<Key, boost::shared_ptr<SmartFactor> > SmartFactorMap;
public:
SmartProjectionFactorsCreator(const SharedNoiseModel& model,
const boost::shared_ptr<CALIBRATION>& K,
const double rankTol,
const double linThreshold,
boost::optional<POSE> 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<Key> views;
std::vector<Point2> 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<SmartProjectionHessianFactorState> smartFactorState(new SmartProjectionHessianFactorState());
boost::shared_ptr<SmartFactor> 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<CALIBRATION>& Ki,
NonlinearFactorGraph &graph) {
std::vector<Key> views;
std::vector<Point2> 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<SmartProjectionHessianFactorState> smartFactorState(new SmartProjectionHessianFactorState());
boost::shared_ptr<SmartFactor> 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<CALIBRATION> 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<POSE> 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_ */