gtsam/gtsam_unstable/slam/SmartProjectionFactorsCreat...

116 lines
3.9 KiB
C++

/*
* SmartProjectionFactorsCreator.h
*
* Created on: Oct 8, 2013
* Author: aspn
*/
#ifndef SMARTPROJECTIONFACTORSCREATOR_H_
#define SMARTPROJECTIONFACTORSCREATOR_H_
// Both relative poses and recovered trajectory poses will be stored as Pose3 objects
#include <gtsam/geometry/Pose3.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/geometry/PinholeCamera.h>
#include <boost/foreach.hpp>
#include <boost/assign.hpp>
#include <boost/assign/std/vector.hpp>
#include <fstream>
#include <iostream>
#include <utility>
namespace gtsam {
typedef SmartProjectionFactor<Pose3, Point3, Cal3_S2> SmartFactor;
typedef FastMap<Key, boost::shared_ptr<SmartProjectionFactorState> > SmartFactorToStateMap;
typedef FastMap<Key, boost::shared_ptr<SmartFactor> > SmartFactorMap;
template<class POSE, class LANDMARK, class CALIBRATION = Cal3_S2>
class SmartProjectionFactorsCreator {
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 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);
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);
totalNumMeasurements++;
if (debug) (*fit).second->print();
} else {
if (debug) fprintf(stderr,"New landmark (%d,%d)\n", fsit != smartFactorStates.end(), fit != smartFactors.end());
views += poseKey;
measurements += measurement;
// This is a new landmark, create a new factor and add to mapping
boost::shared_ptr<SmartProjectionFactorState> smartFactorState(new SmartProjectionFactorState());
SmartFactor::shared_ptr smartFactor(new SmartFactor(views, measurements, noise_, K_, rankTolerance_, linearizationThreshold_));
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();
}
}
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;
unsigned int numLandmarks;
};
}
#endif /* SMARTPROJECTIONFACTORSCREATOR_H_ */