From 391386a6540e199f6db5172ebb50795e3a43cccf Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 18 Jun 2015 16:00:54 -0400 Subject: [PATCH] revived SmartProjectionPoseFactor. Compiles now, going to fix unit tests now --- .cproject | 120 +++---------- gtsam/slam/SmartProjectionFactor.h | 20 +-- gtsam/slam/SmartProjectionPoseFactor.h | 160 ++++++++++++++++++ gtsam/slam/tests/smartFactorScenarios.h | 5 +- .../tests/testSmartProjectionPoseFactor.cpp | 91 +++++----- 5 files changed, 243 insertions(+), 153 deletions(-) create mode 100644 gtsam/slam/SmartProjectionPoseFactor.h diff --git a/.cproject b/.cproject index 86952742b..1134896ad 100644 --- a/.cproject +++ b/.cproject @@ -5,13 +5,13 @@ - - + + @@ -60,13 +60,13 @@ - - + + @@ -116,13 +116,13 @@ - - + + @@ -819,10 +819,18 @@ false true - + make - -j4 - SmartStereoProjectionFactorExample.run + -j5 + SmartProjectionFactorExample_kitti_nonbatch.run + true + true + true + + + make + -j5 + SmartProjectionFactorExample_kitti.run true true true @@ -835,14 +843,6 @@ true true - - make - -j4 - SmartProjectionFactorExample.run - true - true - true - make -j2 @@ -1035,30 +1035,6 @@ true true - - make - -j4 - testCameraSet.run - true - true - true - - - make - -j4 - testTriangulation.run - true - true - true - - - make - -j4 - testPinholeSet.run - true - true - true - make -j2 @@ -1147,6 +1123,14 @@ true true + + make + -j5 + testSmartProjectionFactor.run + true + true + true + make -j5 @@ -1546,10 +1530,10 @@ true true - + make - -j4 - testRegularImplicitSchurFactor.run + -j5 + testImplicitSchurFactor.run true true true @@ -1578,30 +1562,6 @@ true true - - make - -j4 - testSmartProjectionCameraFactor.run - true - true - true - - - make - -j4 - testSmartFactorBase.run - true - true - true - - - make - -j4 - testTriangulationFactor.run - true - true - true - make -j3 @@ -2503,14 +2463,6 @@ true true - - make - -j4 - SFMExample_SmartFactorPCG.run - true - true - true - make -j2 @@ -3103,22 +3055,6 @@ true true - - make - -j4 - testRegularHessianFactor.run - true - true - true - - - make - -j4 - testRegularJacobianFactor.run - true - true - true - make -j5 diff --git a/gtsam/slam/SmartProjectionFactor.h b/gtsam/slam/SmartProjectionFactor.h index aad1a27f6..c7b2962e4 100644 --- a/gtsam/slam/SmartProjectionFactor.h +++ b/gtsam/slam/SmartProjectionFactor.h @@ -31,6 +31,16 @@ namespace gtsam { +/// Linearization mode: what factor to linearize to +enum LinearizationMode { + HESSIAN, IMPLICIT_SCHUR, JACOBIAN_Q, JACOBIAN_SVD +}; + +/// How to manage degeneracy +enum DegeneracyMode { + IGNORE_DEGENERACY, ZERO_ON_DEGENERACY, HANDLE_INFINITY +}; + /** * SmartProjectionFactor: triangulates point and keeps an estimate of it around. */ @@ -39,16 +49,6 @@ class SmartProjectionFactor: public SmartFactorBase { public: - /// Linearization mode: what factor to linearize to - enum LinearizationMode { - HESSIAN, IMPLICIT_SCHUR, JACOBIAN_Q, JACOBIAN_SVD - }; - - /// How to manage degeneracy - enum DegeneracyMode { - IGNORE_DEGENERACY, ZERO_ON_DEGENERACY, HANDLE_INFINITY - }; - private: typedef SmartFactorBase Base; typedef SmartProjectionFactor This; diff --git a/gtsam/slam/SmartProjectionPoseFactor.h b/gtsam/slam/SmartProjectionPoseFactor.h new file mode 100644 index 000000000..7a5137bfc --- /dev/null +++ b/gtsam/slam/SmartProjectionPoseFactor.h @@ -0,0 +1,160 @@ +/* ---------------------------------------------------------------------------- + + * GTSAM Copyright 2010, Georgia Tech Research Corporation, + * Atlanta, Georgia 30332-0415 + * All Rights Reserved + * Authors: Frank Dellaert, et al. (see THANKS for the full author list) + + * See LICENSE for the license information + + * -------------------------------------------------------------------------- */ + +/** + * @file SmartProjectionPoseFactor.h + * @brief Produces an Hessian factors on POSES from monocular measurements of a single landmark + * @author Luca Carlone + * @author Chris Beall + * @author Zsolt Kira + */ + +#pragma once + +#include + +namespace gtsam { +/** + * + * @addtogroup SLAM + * + * If you are using the factor, please cite: + * L. Carlone, Z. Kira, C. Beall, V. Indelman, F. Dellaert, Eliminating conditionally + * independent sets in factor graphs: a unifying perspective based on smart factors, + * Int. Conf. on Robotics and Automation (ICRA), 2014. + * + */ + +/** + * The calibration is known here. The factor only constraints poses (variable dimension is 6) + * @addtogroup SLAM + */ +template +class SmartProjectionPoseFactor: public SmartProjectionFactor< + PinholePose > { + +private: + typedef PinholePose Camera; + typedef SmartProjectionFactor Base; + typedef SmartProjectionPoseFactor This; + +protected: + + boost::optional body_P_sensor_; ///< Pose of the camera in the body frame + std::vector > sharedKs_; ///< shared pointer to calibration object (one for each camera) + +public: + + /// shorthand for a smart pointer to a factor + typedef boost::shared_ptr shared_ptr; + + /** + * Constructor + * @param rankTol tolerance used to check if point triangulation is degenerate + * @param linThreshold threshold on relative pose changes used to decide whether to relinearize (selective relinearization) + * @param manageDegeneracy is true, in presence of degenerate triangulation, the factor is converted to a rotation-only constraint, + * otherwise the factor is simply neglected (this functionality is deprecated) + * @param enableEPI if set to true linear triangulation is refined with embedded LM iterations + * @param body_P_sensor is the transform from sensor to body frame (default identity) + */ + SmartProjectionPoseFactor(const double rankTol = 1, + const double linThreshold = -1, const DegeneracyMode manageDegeneracy = IGNORE_DEGENERACY, + const bool enableEPI = false, boost::optional body_P_sensor = boost::none, + LinearizationMode linearizeTo = HESSIAN, double landmarkDistanceThreshold = 1e10, + double dynamicOutlierRejectionThreshold = -1) : + Base(linearizeTo, rankTol, manageDegeneracy, enableEPI, + landmarkDistanceThreshold, dynamicOutlierRejectionThreshold), body_P_sensor_(body_P_sensor) {} + + /** Virtual destructor */ + virtual ~SmartProjectionPoseFactor() {} + + /** + * print + * @param s optional string naming the factor + * @param keyFormatter optional formatter useful for printing Symbols + */ + void print(const std::string& s = "", const KeyFormatter& keyFormatter = + DefaultKeyFormatter) const { + std::cout << s << "SmartProjectionPoseFactor, z = \n "; + if(body_P_sensor_) + body_P_sensor_->print("body_P_sensor_:\n"); + Base::print("", keyFormatter); + } + + /// equals + virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const { + const This *e = dynamic_cast(&p); + return e && Base::equals(p, tol); + } + + /** + * Linearize to Gaussian Factor + * @param values Values structure which must contain camera poses for this factor + * @return + */ + virtual boost::shared_ptr linearize( + const Values& values) const { + // depending on flag set on construction we may linearize to different linear factors +// switch(linearizeTo_){ +// case JACOBIAN_SVD : +// return this->createJacobianSVDFactor(Base::cameras(values), 0.0); +// break; +// case JACOBIAN_Q : +// return this->createJacobianQFactor(Base::cameras(values), 0.0); +// break; +// default: + return this->createHessianFactor(Base::cameras(values)); +// break; +// } + } + + /** + * error calculates the error of the factor. + */ + virtual double error(const Values& values) const { + if (this->active(values)) { + return this->totalReprojectionError(Base::cameras(values)); + } else { // else of active flag + return 0.0; + } + } + + /** return calibration shared pointers */ + inline const std::vector > calibration() const { + return sharedKs_; + } + + Pose3 body_P_sensor() const{ + if(body_P_sensor_) + return *body_P_sensor_; + else + return Pose3(); // if unspecified, the transformation is the identity + } + +private: + + /// Serialization function + friend class boost::serialization::access; + template + void serialize(ARCHIVE & ar, const unsigned int version) { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base); + ar & BOOST_SERIALIZATION_NVP(sharedKs_); + } + +}; // end of class declaration + +/// traits +template +struct traits > : public Testable< + SmartProjectionPoseFactor > { +}; + +} // \ namespace gtsam diff --git a/gtsam/slam/tests/smartFactorScenarios.h b/gtsam/slam/tests/smartFactorScenarios.h index c3598e4c1..e821f9e40 100644 --- a/gtsam/slam/tests/smartFactorScenarios.h +++ b/gtsam/slam/tests/smartFactorScenarios.h @@ -17,6 +17,7 @@ */ #pragma once +#include #include #include #include @@ -66,7 +67,7 @@ typedef GeneralSFMFactor SFMFactor; // default Cal3_S2 poses namespace vanillaPose { typedef PinholePose Camera; -typedef SmartProjectionFactor SmartFactor; +typedef SmartProjectionPoseFactor SmartFactor; static Cal3_S2::shared_ptr sharedK(new Cal3_S2(fov, w, h)); Camera level_camera(level_pose, sharedK); Camera level_camera_right(pose_right, sharedK); @@ -108,7 +109,7 @@ typedef GeneralSFMFactor SFMFactor; // Cal3Bundler poses namespace bundlerPose { typedef PinholePose Camera; -typedef SmartProjectionFactor SmartFactor; +typedef SmartProjectionPoseFactor SmartFactor; static boost::shared_ptr sharedBundlerK( new Cal3Bundler(500, 1e-3, 1e-3, 1000, 2000)); Camera level_camera(level_pose, sharedBundlerK); diff --git a/gtsam/slam/tests/testSmartProjectionPoseFactor.cpp b/gtsam/slam/tests/testSmartProjectionPoseFactor.cpp index 1e21a3afd..790e85dfb 100644 --- a/gtsam/slam/tests/testSmartProjectionPoseFactor.cpp +++ b/gtsam/slam/tests/testSmartProjectionPoseFactor.cpp @@ -59,7 +59,7 @@ TEST( SmartProjectionPoseFactor, Constructor) { /* ************************************************************************* */ TEST( SmartProjectionPoseFactor, Constructor2) { using namespace vanillaPose; - SmartFactor factor1(SmartFactor::HESSIAN, rankTol); + SmartFactor factor1(gtsam::HESSIAN, rankTol); } /* ************************************************************************* */ @@ -72,7 +72,7 @@ TEST( SmartProjectionPoseFactor, Constructor3) { /* ************************************************************************* */ TEST( SmartProjectionPoseFactor, Constructor4) { using namespace vanillaPose; - SmartFactor factor1(SmartFactor::HESSIAN, rankTol); + SmartFactor factor1(gtsam::HESSIAN, rankTol); factor1.add(measurement1, x1, model); } @@ -495,15 +495,15 @@ TEST( SmartProjectionPoseFactor, jacobianSVD ) { projectToMultipleCameras(cam1, cam2, cam3, landmark3, measurements_cam3); SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::JACOBIAN_SVD)); + new SmartFactor(gtsam::JACOBIAN_SVD)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::JACOBIAN_SVD)); + new SmartFactor(gtsam::JACOBIAN_SVD)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::JACOBIAN_SVD)); + new SmartFactor(gtsam::JACOBIAN_SVD)); smartFactor3->add(measurements_cam3, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -549,21 +549,18 @@ TEST( SmartProjectionPoseFactor, landmarkDistance ) { projectToMultipleCameras(cam1, cam2, cam3, landmark3, measurements_cam3); SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, - excludeLandmarksFutherThanDist)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, - excludeLandmarksFutherThanDist)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, - excludeLandmarksFutherThanDist)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist)); smartFactor3->add(measurements_cam3, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -617,27 +614,23 @@ TEST( SmartProjectionPoseFactor, dynamicOutlierRejection ) { measurements_cam4.at(0) = measurements_cam4.at(0) + Point2(10, 10); // add outlier SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, excludeLandmarksFutherThanDist, - dynamicOutlierRejectionThreshold)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist, dynamicOutlierRejectionThreshold)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, excludeLandmarksFutherThanDist, - dynamicOutlierRejectionThreshold)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist, dynamicOutlierRejectionThreshold)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, excludeLandmarksFutherThanDist, - dynamicOutlierRejectionThreshold)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist, dynamicOutlierRejectionThreshold)); smartFactor3->add(measurements_cam3, views, model); SmartFactor::shared_ptr smartFactor4( - new SmartFactor(SmartFactor::JACOBIAN_SVD, 1, - SmartFactor::IGNORE_DEGENERACY, false, excludeLandmarksFutherThanDist, - dynamicOutlierRejectionThreshold)); + new SmartFactor(1, -1, gtsam::IGNORE_DEGENERACY, false, Pose3(), + gtsam::JACOBIAN_SVD, excludeLandmarksFutherThanDist, dynamicOutlierRejectionThreshold)); smartFactor4->add(measurements_cam4, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -680,15 +673,15 @@ TEST( SmartProjectionPoseFactor, jacobianQ ) { projectToMultipleCameras(cam1, cam2, cam3, landmark3, measurements_cam3); SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::JACOBIAN_Q)); + new SmartFactor(gtsam::JACOBIAN_Q)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::JACOBIAN_Q)); + new SmartFactor(gtsam::JACOBIAN_Q)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::JACOBIAN_Q)); + new SmartFactor(gtsam::JACOBIAN_Q)); smartFactor3->add(measurements_cam3, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -799,15 +792,15 @@ TEST( SmartProjectionPoseFactor, CheckHessian) { double rankTol = 10; SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::HESSIAN, rankTol)); + new SmartFactor(gtsam::HESSIAN, rankTol)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::HESSIAN, rankTol)); + new SmartFactor(gtsam::HESSIAN, rankTol)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::HESSIAN, rankTol)); + new SmartFactor(gtsam::HESSIAN, rankTol)); smartFactor3->add(measurements_cam3, views, model); NonlinearFactorGraph graph; @@ -880,13 +873,13 @@ TEST( SmartProjectionPoseFactor, 3poses_2land_rotation_only_smart_projection_fac double rankTol = 50; SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::HANDLE_INFINITY)); + new SmartFactor(gtsam::HESSIAN, rankTol, + gtsam::HANDLE_INFINITY)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::HANDLE_INFINITY)); + new SmartFactor(gtsam::HESSIAN, rankTol, + gtsam::HANDLE_INFINITY)); smartFactor2->add(measurements_cam2, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -961,18 +954,18 @@ TEST( SmartProjectionPoseFactor, 3poses_rotation_only_smart_projection_factor ) double rankTol = 10; SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(gtsam::HESSIAN, rankTol, + gtsam::ZERO_ON_DEGENERACY)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(gtsam::HESSIAN, rankTol, + gtsam::ZERO_ON_DEGENERACY)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(gtsam::HESSIAN, rankTol, + gtsam::ZERO_ON_DEGENERACY)); smartFactor3->add(measurements_cam3, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10); @@ -1168,7 +1161,7 @@ TEST( SmartProjectionPoseFactor, HessianWithRotationDegenerate ) { /* ************************************************************************* */ TEST( SmartProjectionPoseFactor, ConstructorWithCal3Bundler) { using namespace bundlerPose; - SmartFactor factor(SmartFactor::HESSIAN, rankTol); + SmartFactor factor(gtsam::HESSIAN, rankTol); factor.add(measurement1, x1, model); } @@ -1262,18 +1255,18 @@ TEST( SmartProjectionPoseFactor, Cal3BundlerRotationOnly ) { double rankTol = 10; SmartFactor::shared_ptr smartFactor1( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(rankTol, -1.0, gtsam::ZERO_ON_DEGENERACY, + false, Pose3(), gtsam::HESSIAN)); smartFactor1->add(measurements_cam1, views, model); SmartFactor::shared_ptr smartFactor2( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(rankTol, -1, gtsam::ZERO_ON_DEGENERACY, + false, Pose3(), gtsam::HESSIAN)); smartFactor2->add(measurements_cam2, views, model); SmartFactor::shared_ptr smartFactor3( - new SmartFactor(SmartFactor::HESSIAN, rankTol, - SmartFactor::ZERO_ON_DEGENERACY)); + new SmartFactor(rankTol, -1, gtsam::ZERO_ON_DEGENERACY, + false, Pose3(), gtsam::HESSIAN)); smartFactor3->add(measurements_cam3, views, model); const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10);