Updated BAL example with readBAL functionality (work in progress)
parent
de5f8ee354
commit
916d730fce
|
|
@ -43,6 +43,7 @@
|
|||
// In GTSAM, measurement functions are represented as 'factors'. Several common factors
|
||||
// have been provided with the library for solving robotics SLAM problems.
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/dataset.h>
|
||||
#include <gtsam_unstable/slam/SmartProjectionFactorsCreator.h>
|
||||
#include <gtsam_unstable/slam/GenericProjectionFactorsCreator.h>
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ using namespace gtsam;
|
|||
using namespace boost::assign;
|
||||
namespace NM = gtsam::noiseModel;
|
||||
|
||||
// #define USE_BUNDLER
|
||||
#define USE_BUNDLER
|
||||
|
||||
using symbol_shorthand::X;
|
||||
using symbol_shorthand::L;
|
||||
|
|
@ -67,11 +68,11 @@ typedef PriorFactor<Pose3> Pose3Prior;
|
|||
typedef FastMap<Key, int> OrderingMap;
|
||||
|
||||
#ifdef USE_BUNDLER
|
||||
typedef SmartProjectionFactorsCreator<Pose3, Point3, Cal3Bundler> SmartFactorsCreator;
|
||||
typedef GenericProjectionFactorsCreator<Pose3, Point3, Cal3Bundler> ProjectionFactorsCreator;
|
||||
typedef SmartProjectionFactorsCreator<Pose3, Point3, Cal3Bundler> SmartFactorsCreator;
|
||||
typedef GenericProjectionFactorsCreator<Pose3, Point3, Cal3Bundler> ProjectionFactorsCreator;
|
||||
#else
|
||||
typedef SmartProjectionFactorsCreator<Pose3, Point3, Cal3_S2> SmartFactorsCreator;
|
||||
typedef GenericProjectionFactorsCreator<Pose3, Point3, Cal3_S2> ProjectionFactorsCreator;
|
||||
typedef SmartProjectionFactorsCreator<Pose3, Point3, Cal3_S2> SmartFactorsCreator;
|
||||
typedef GenericProjectionFactorsCreator<Pose3, Point3, Cal3_S2> ProjectionFactorsCreator;
|
||||
#endif
|
||||
|
||||
bool debug = false;
|
||||
|
|
@ -121,7 +122,7 @@ void optimizeGraphLM(NonlinearFactorGraph &graph, gtsam::Values::shared_ptr grap
|
|||
params.lambdaInitial = 1;
|
||||
params.lambdaFactor = 10;
|
||||
// Profile a single iteration
|
||||
// params.maxIterations = 1;
|
||||
// params.maxIterations = 1;
|
||||
params.maxIterations = 100;
|
||||
std::cout << " LM max iterations: " << params.maxIterations << std::endl;
|
||||
// // params.relativeErrorTol = 1e-5;
|
||||
|
|
@ -152,11 +153,11 @@ void optimizeGraphLM(NonlinearFactorGraph &graph, gtsam::Values::shared_ptr grap
|
|||
params.ordering = *ordering;
|
||||
|
||||
//for (int i = 0; i < 3; i++) {
|
||||
LevenbergMarquardtOptimizer optimizer(graph, *graphValues, params);
|
||||
gttic_(GenericProjectionFactorExample_kitti);
|
||||
result = optimizer.optimize();
|
||||
gttoc_(GenericProjectionFactorExample_kitti);
|
||||
tictoc_finishedIteration_();
|
||||
LevenbergMarquardtOptimizer optimizer(graph, *graphValues, params);
|
||||
gttic_(GenericProjectionFactorExample_kitti);
|
||||
result = optimizer.optimize();
|
||||
gttoc_(GenericProjectionFactorExample_kitti);
|
||||
tictoc_finishedIteration_();
|
||||
//}
|
||||
} else {
|
||||
std::cout << "Using COLAMD ordering\n" << std::endl;
|
||||
|
|
@ -174,11 +175,11 @@ void optimizeGraphLM(NonlinearFactorGraph &graph, gtsam::Values::shared_ptr grap
|
|||
|
||||
//*ordering = params.ordering;
|
||||
if (params.ordering) {
|
||||
std::cout << "Graph size: " << graph.size() << " ORdering: " << params.ordering->size() << std::endl;
|
||||
ordering = boost::make_shared<Ordering>(*(new Ordering()));
|
||||
*ordering = *params.ordering;
|
||||
std::cout << "Graph size: " << graph.size() << " ORdering: " << params.ordering->size() << std::endl;
|
||||
ordering = boost::make_shared<Ordering>(*(new Ordering()));
|
||||
*ordering = *params.ordering;
|
||||
} else {
|
||||
std::cout << "WARNING: NULL ordering!" << std::endl;
|
||||
std::cout << "WARNING: NULL ordering!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,11 +220,15 @@ int main(int argc, char** argv) {
|
|||
double linThreshold = -1.0; // negative is disabled
|
||||
double rankTolerance = 1.0;
|
||||
|
||||
// Get home directory and dataset
|
||||
// Get home directory and default dataset
|
||||
string HOME = getenv("HOME");
|
||||
string datasetFile = HOME + "/data/SfM/BAL/Ladybug/problem-1031-110968-pre.txt";
|
||||
|
||||
// --------------- READ USER INPUTS (main arguments) ------------------------------------
|
||||
if(argc>1){ // if we have any input arguments
|
||||
// Arg1: "smart" or "standard" (select if to use smart factors or standard projection factors)
|
||||
// Arg2: "triangulation=0" or "triangulation=1" (select whether to initialize initial guess for points using triangulation)
|
||||
// Arg3: name of the dataset, e.g., /home/aspn/data/SfM/BAL/Ladybug/problem-1031-110968-pre.txt
|
||||
string useSmartArgument = argv[1];
|
||||
string useTriangulationArgument = argv[2];
|
||||
datasetFile = argv[3];
|
||||
|
|
@ -238,160 +243,108 @@ int main(int argc, char** argv) {
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
if(useTriangulationArgument.compare("do")==0){
|
||||
if(useTriangulationArgument.compare("triangulation=1")==0){
|
||||
doTriangulation=true;
|
||||
} else{
|
||||
if(useTriangulationArgument.compare("dont")==0){
|
||||
if(useTriangulationArgument.compare("triangulation=0")==0){
|
||||
doTriangulation=false;
|
||||
}else{
|
||||
cout << "Selected wrong option for input argument - doTriangulation - not important for SmartFactors" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "PARAM SmartFactor: " << useSmartProjectionFactor << std::endl;
|
||||
std::cout << "PARAM doTriangulation: " << doTriangulation << std::endl;
|
||||
// std::cout << "PARAM LM: " << useLM << std::endl;
|
||||
std::cout << "PARAM linThreshold (negative is disabled): " << linThreshold << std::endl;
|
||||
|
||||
// --------------- PRINT USER's CHOICE ------------------------------------
|
||||
std::cout << "- useSmartFactor: " << useSmartProjectionFactor << std::endl;
|
||||
std::cout << "- doTriangulation: " << doTriangulation << std::endl;
|
||||
std::cout << "- datasetFile: " << datasetFile << std::endl;
|
||||
|
||||
if (linThreshold >= 0)
|
||||
std::cout << "PARAM linThreshold (negative is disabled): " << linThreshold << std::endl;
|
||||
|
||||
if(addNoise)
|
||||
std::cout << "PARAM Noise: " << addNoise << std::endl;
|
||||
|
||||
std::cout << "datasetFile: " << datasetFile << std::endl;
|
||||
// --------------- READ INPUT DATA ----------------------------------------
|
||||
SfM_data inputData;
|
||||
readBAL(datasetFile, inputData);
|
||||
std::cout << "read data from file... " << std::endl;
|
||||
|
||||
// --------------- CREATE FACTOR GRAPH ------------------------------------
|
||||
static SharedNoiseModel pixel_sigma(noiseModel::Unit::Create(2));
|
||||
NonlinearFactorGraph graphSmart, graphProjection;
|
||||
|
||||
gtsam::Values::shared_ptr graphSmartValues(new gtsam::Values());
|
||||
gtsam::Values::shared_ptr graphProjectionValues(new gtsam::Values());
|
||||
gtsam::Values::shared_ptr loadedValues(new gtsam::Values()); // values we read from file
|
||||
Values result;
|
||||
|
||||
// Read in kitti dataset
|
||||
ifstream fin;
|
||||
fin.open((datasetFile).c_str());
|
||||
if(!fin) {
|
||||
cerr << "Could not open dataset" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// read all measurements
|
||||
cout << "Reading dataset... " << endl;
|
||||
unsigned int numLandmarks = 0, numPoses = 0;
|
||||
Key r, l;
|
||||
double u, v;
|
||||
double x, y, z, rotx, roty, rotz, f, k1, k2;
|
||||
std::vector<Key> landmarkKeys, cameraPoseKeys;
|
||||
|
||||
bool optimized = false;
|
||||
boost::shared_ptr<Ordering> ordering(new Ordering());
|
||||
|
||||
#ifdef USE_BUNDLER
|
||||
std::vector< boost::shared_ptr<Cal3Bundler> > K_cameras;
|
||||
boost::shared_ptr<Cal3Bundler> K(new Cal3Bundler());
|
||||
#else
|
||||
std::vector< boost::shared_ptr<Cal3_S2> > K_cameras;
|
||||
Cal3_S2::shared_ptr K(new Cal3_S2());
|
||||
#endif
|
||||
NonlinearFactorGraph graphSmart;
|
||||
gtsam::Values::shared_ptr graphSmartValues(new gtsam::Values());
|
||||
|
||||
NonlinearFactorGraph graphProjection;
|
||||
gtsam::Values::shared_ptr graphProjectionValues(new gtsam::Values());
|
||||
|
||||
#ifdef USE_BUNDLER
|
||||
std::vector< boost::shared_ptr<Cal3Bundler> > K_cameras;
|
||||
boost::shared_ptr<Cal3Bundler> K(new Cal3Bundler());
|
||||
#else
|
||||
std::vector< boost::shared_ptr<Cal3_S2> > K_cameras;
|
||||
Cal3_S2::shared_ptr K(new Cal3_S2());
|
||||
#endif
|
||||
|
||||
SmartFactorsCreator smartCreator(pixel_sigma, K, rankTolerance, linThreshold); // this initial K is not used
|
||||
ProjectionFactorsCreator projectionCreator(pixel_sigma, K); // this initial K is not used
|
||||
int numLandmarks=0;
|
||||
|
||||
// main loop: reads measurements and adds factors (also performs optimization if desired)
|
||||
// r >> pose id
|
||||
// l >> landmark id
|
||||
// (u >> u) >> measurement
|
||||
unsigned int totNumLandmarks=0, totNumPoses=0, totNumMeasurements=0;
|
||||
fin >> totNumPoses >> totNumLandmarks >> totNumMeasurements;
|
||||
|
||||
cout << "Dataset: #poses: " << totNumPoses << " #points: " << totNumLandmarks << " #measurements: " << totNumMeasurements << " " << endl;
|
||||
|
||||
std::vector<double> vector_u;
|
||||
std::vector<double> vector_v;
|
||||
std::vector<int> vector_r;
|
||||
std::vector<int> vector_l;
|
||||
|
||||
// read measurements
|
||||
for(unsigned int i = 0; i < totNumMeasurements; i++){
|
||||
fin >> r >> l >> u >> v;
|
||||
vector_u.push_back(u);
|
||||
vector_v.push_back(v);
|
||||
vector_r.push_back(r);
|
||||
vector_l.push_back(l);
|
||||
if(debug){
|
||||
std::cout << "Constructors for factor creators " << std::endl;
|
||||
std::cout << "inputData.number_cameras() " << inputData.number_cameras() << std::endl;
|
||||
std::cout << "inputData.number_tracks() " << inputData.number_tracks() << std::endl;
|
||||
}
|
||||
|
||||
cout << "last measurement: " << r << " " << l << " " << u << " " << v << endl;
|
||||
|
||||
// create values
|
||||
for(unsigned int i = 0; i < totNumPoses; i++){
|
||||
// R,t,f,k1 and k2.
|
||||
fin >> rotx >> roty >> rotz >> x >> y >> z >> f >> k1 >> k2;
|
||||
#ifdef USE_BUNDLER
|
||||
boost::shared_ptr<Cal3Bundler> Kbundler(new Cal3Bundler(f, k1, k2, 0.0, 0.0));
|
||||
// cout << k1 << " " << k2 << endl;
|
||||
K_cameras.push_back(Kbundler);
|
||||
#else
|
||||
boost::shared_ptr<Cal3_S2> K_S2(new Cal3_S2(f, f, 0.0, 0.0, 0.0));
|
||||
K_cameras.push_back(K_S2);
|
||||
#endif
|
||||
Vector3 rotVect(rotx,roty,rotz);
|
||||
// FORMAT CONVERSION!! R -> R'
|
||||
Rot3 R = Rot3::Expmap(rotVect);
|
||||
Matrix3 R_bal_gtsam_mat = Matrix3::Zero(3,3);
|
||||
R_bal_gtsam_mat(0,0) = 1.0; R_bal_gtsam_mat(1,1) = -1.0; R_bal_gtsam_mat(2,2) = -1.0;
|
||||
Rot3 R_bal_gtsam_ = Rot3(R_bal_gtsam_mat);
|
||||
Pose3 CameraPose((R.inverse()).compose(R_bal_gtsam_), - R.unrotate(Point3(x,y,z)));
|
||||
|
||||
// Load graph values
|
||||
gtsam::Values::shared_ptr loadedValues(new gtsam::Values()); // values we read from file
|
||||
for (size_t i = 0; i < inputData.number_cameras(); i++){ // for each camera
|
||||
Pose3 cameraPose = inputData.cameras[i].pose();
|
||||
if(addNoise){
|
||||
Pose3 noise_pose = Pose3(Rot3::ypr(-M_PI/100, 0., -M_PI/100), gtsam::Point3(0.3,0.1,0.3));
|
||||
CameraPose = CameraPose.compose(noise_pose);
|
||||
cameraPose = cameraPose.compose(noise_pose);
|
||||
}
|
||||
loadedValues->insert(X(i), CameraPose );
|
||||
loadedValues->insert(X(i), cameraPose);
|
||||
graphSmartValues->insert(X(i), cameraPose);
|
||||
}
|
||||
if(debug) std::cout << "Initialized values " << std::endl;
|
||||
|
||||
cout << "last pose: " << x << " " << y << " " << z << " " << rotx << " "
|
||||
<< roty << " " << rotz << " " << f << " " << k1 << " " << k2 << endl;
|
||||
|
||||
// add landmarks in standard projection factors
|
||||
if(!useSmartProjectionFactor){
|
||||
for(unsigned int i = 0; i < totNumLandmarks; i++){
|
||||
fin >> x >> y >> z;
|
||||
// FORMAT CONVERSION!! XPOINT
|
||||
loadedValues->insert(L(i), Point3(x,y,z) );
|
||||
}
|
||||
for (size_t j = 0; j < inputData.number_tracks(); j++){ // for each 3D point
|
||||
Point3 point = inputData.tracks[j].p;
|
||||
loadedValues->insert(L(j), point);
|
||||
}
|
||||
if(debug) std::cout << "Initialized points " << std::endl;
|
||||
|
||||
cout << "last point: " << x << " " << y << " " << z << endl;
|
||||
// Create the graph
|
||||
for (size_t j = 0; j < inputData.number_tracks(); j++){ // for each 3D point
|
||||
SfM_Track track = inputData.tracks[j];
|
||||
Point3 point = track.p;
|
||||
|
||||
// 1: add values and factors to the graph
|
||||
// 1.1: add factors
|
||||
// SMART FACTORS ..
|
||||
for(size_t i = 0; i < vector_u.size(); i++){
|
||||
for (size_t k = 0; k < track.number_measurements(); k++){ // for each measurement of the point
|
||||
SfM_Measurement measurement = track.measurements[k];
|
||||
int i = measurement.first;
|
||||
double u = measurement.second.x();
|
||||
double v = measurement.second.y();
|
||||
boost::shared_ptr<Cal3Bundler> Ki(new Cal3Bundler(inputData.cameras[i].calibration()));
|
||||
//boost::shared_ptr<Cal3_S2> Ki(new Cal3_S2());
|
||||
|
||||
l = vector_l.at(i);
|
||||
r = vector_r.at(i);
|
||||
// FORMAT CONVERSION!! XPOINT
|
||||
u = vector_u.at(i);
|
||||
// FORMAT CONVERSION!! XPOINT
|
||||
v = - vector_v.at(i);
|
||||
|
||||
if (useSmartProjectionFactor) {
|
||||
|
||||
smartCreator.add(L(l), X(r), Point2(u,v), pixel_sigma, K_cameras.at(r), graphSmart);
|
||||
numLandmarks = smartCreator.getNumLandmarks();
|
||||
|
||||
// Add initial pose value if pose does not exist
|
||||
if (!graphSmartValues->exists<Pose3>(X(r)) && loadedValues->exists<Pose3>(X(r))) {
|
||||
graphSmartValues->insert(X(r), loadedValues->at<Pose3>(X(r)));
|
||||
numPoses++;
|
||||
optimized = false;
|
||||
// insert data in a format that can be understood
|
||||
if (useSmartProjectionFactor) {
|
||||
// Use smart factors
|
||||
smartCreator.add(L(j), X(i), Point2(u,v), pixel_sigma, Ki, graphSmart);
|
||||
numLandmarks = smartCreator.getNumLandmarks();
|
||||
} else {
|
||||
// or STANDARD PROJECTION FACTORS
|
||||
projectionCreator.add(L(j), X(i), Point2(u,v), pixel_sigma, Ki, graphProjection);
|
||||
numLandmarks = projectionCreator.getNumLandmarks();
|
||||
}
|
||||
|
||||
} else {
|
||||
// or STANDARD PROJECTION FACTORS
|
||||
projectionCreator.add(L(l), X(r), Point2(u,v), pixel_sigma, K_cameras.at(r), graphProjection);
|
||||
numLandmarks = projectionCreator.getNumLandmarks();
|
||||
optimized = false;
|
||||
}
|
||||
}
|
||||
if(debug) std::cout << "Included measurements in the graph " << std::endl;
|
||||
|
||||
cout << "Number of landmarks " << numLandmarks << endl;
|
||||
|
||||
cout << "Before call to update: ------------------ " << endl;
|
||||
cout << "Poses in SmartGraph values: "<< graphSmartValues->size() << endl;
|
||||
|
|
@ -415,31 +368,26 @@ int main(int argc, char** argv) {
|
|||
cout << "Points in ProjectionGraph values: "<< valuesProjPoints.size() << endl;
|
||||
cout << "---------------------------------------------------------- " << endl;
|
||||
|
||||
Values result;
|
||||
if (useSmartProjectionFactor) {
|
||||
if (useLM)
|
||||
optimizeGraphLM(graphSmart, graphSmartValues, result, ordering);
|
||||
else
|
||||
optimizeGraphISAM2(graphSmart, graphSmartValues, result);
|
||||
|
||||
cout << "Final reprojection error (smart): " << graphSmart.error(result);
|
||||
} else {
|
||||
if (useLM)
|
||||
optimizeGraphLM(graphProjection, graphProjectionValues, result, ordering);
|
||||
else
|
||||
optimizeGraphISAM2(graphProjection, graphProjectionValues, result); // ?
|
||||
|
||||
cout << "Final reprojection error (standard): " << graphProjection.error(result);
|
||||
}
|
||||
|
||||
optimized = true;
|
||||
|
||||
cout << "===================================================" << endl;
|
||||
tictoc_print_();
|
||||
cout << "===================================================" << endl;
|
||||
writeValues("./", result);
|
||||
|
||||
if (debug) cout << numLandmarks << " " << numPoses << " " << optimized << endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @brief Example usage of SmartProjectionFactor using real dataset in a non-batch fashion
|
||||
* @date August, 2013
|
||||
* @author Zsolt Kira
|
||||
* @author Luca Carlone
|
||||
*/
|
||||
|
||||
// Use a map to store landmark/smart factor pairs
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* GenericProjectionFactorsCreator.h
|
||||
*
|
||||
* Created on: Oct 10, 2013
|
||||
* Author: zkira
|
||||
* @author Zsolt Kira
|
||||
*/
|
||||
|
||||
#ifndef GENERICPROJECTIONFACTORSCREATOR_H_
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* SmartProjectionFactorsCreator.h
|
||||
*
|
||||
* Created on: Oct 8, 2013
|
||||
* Author: aspn
|
||||
* @author Zsolt Kira
|
||||
*/
|
||||
|
||||
#ifndef SMARTPROJECTIONFACTORSCREATOR_H_
|
||||
|
|
|
|||
Loading…
Reference in New Issue