Prototype (faster?) linearize
							parent
							
								
									7ec26ff323
								
							
						
					
					
						commit
						171793aad3
					
				| 
						 | 
				
			
			@ -19,13 +19,13 @@
 | 
			
		|||
#include <gtsam/slam/GeneralSFMFactor.h>
 | 
			
		||||
#include <gtsam/slam/RangeFactor.h>
 | 
			
		||||
#include <gtsam/slam/PriorFactor.h>
 | 
			
		||||
#include <gtsam/geometry/Cal3_S2.h>
 | 
			
		||||
#include <gtsam/geometry/PinholeCamera.h>
 | 
			
		||||
#include <gtsam/nonlinear/NonlinearEquality.h>
 | 
			
		||||
#include <gtsam/inference/Symbol.h>
 | 
			
		||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
			
		||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
 | 
			
		||||
#include <gtsam/linear/VectorValues.h>
 | 
			
		||||
#include <gtsam/geometry/Cal3_S2.h>
 | 
			
		||||
#include <gtsam/geometry/PinholeCamera.h>
 | 
			
		||||
#include <gtsam/inference/Symbol.h>
 | 
			
		||||
#include <gtsam/base/Testable.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -101,8 +101,8 @@ TEST( GeneralSFMFactor, equals )
 | 
			
		|||
/* ************************************************************************* */
 | 
			
		||||
TEST( GeneralSFMFactor, error ) {
 | 
			
		||||
  Point2 z(3.,0.);
 | 
			
		||||
  const SharedNoiseModel sigma(noiseModel::Unit::Create(1));
 | 
			
		||||
  boost::shared_ptr<Projection>  factor(new Projection(z, sigma, X(1), L(1)));
 | 
			
		||||
  const SharedNoiseModel sigma(noiseModel::Unit::Create(2));
 | 
			
		||||
  Projection factor(z, sigma, X(1), L(1));
 | 
			
		||||
  // For the following configuration, the factor predicts 320,240
 | 
			
		||||
  Values values;
 | 
			
		||||
  Rot3 R;
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ TEST( GeneralSFMFactor, error ) {
 | 
			
		|||
  Pose3 x1(R,t1);
 | 
			
		||||
  values.insert(X(1), GeneralCamera(x1));
 | 
			
		||||
  Point3 l1;  values.insert(L(1), l1);
 | 
			
		||||
  EXPECT(assert_equal(((Vector) Vector2(-3.0, 0.0)), factor->unwhitenedError(values)));
 | 
			
		||||
  EXPECT(assert_equal(((Vector) Vector2(-3.0, 0.0)), factor.unwhitenedError(values)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const double baseline = 5.0 ;
 | 
			
		||||
| 
						 | 
				
			
			@ -430,6 +430,95 @@ TEST(GeneralSFMFactor, CalibratedCameraPoseRange) {
 | 
			
		|||
  EXPECT(assert_equal(expected, actual, 1e-4));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
 | 
			
		||||
static const int DimC = 11, DimL = 3;
 | 
			
		||||
 | 
			
		||||
/// Linearize using fixed-size matrices
 | 
			
		||||
boost::shared_ptr<GaussianFactor> linearize(const Projection& factor,
 | 
			
		||||
                                            const Values& values) {
 | 
			
		||||
  // Only linearize if the factor is active
 | 
			
		||||
  if (!factor.active(values)) return boost::shared_ptr<JacobianFactor>();
 | 
			
		||||
 | 
			
		||||
  const Key key1 = factor.key1(), key2 = factor.key2();
 | 
			
		||||
  Eigen::Matrix<double, 2, DimC> H1;
 | 
			
		||||
  Eigen::Matrix<double, 2, DimL> H2;
 | 
			
		||||
  Vector2 b;
 | 
			
		||||
  try {
 | 
			
		||||
    const GeneralCamera& camera = values.at<GeneralCamera>(key1);
 | 
			
		||||
    const Point3& point = values.at<Point3>(key2);
 | 
			
		||||
    Point2 reprojError(camera.project2(point, H1, H2) - factor.measured());
 | 
			
		||||
    b = -reprojError.vector();
 | 
			
		||||
  } catch (CheiralityException& e) {
 | 
			
		||||
    // TODO warn if verbose output asked for
 | 
			
		||||
    return boost::make_shared<JacobianFactor>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Whiten the system if needed
 | 
			
		||||
  const SharedNoiseModel& noiseModel = factor.get_noiseModel();
 | 
			
		||||
  if (noiseModel && !noiseModel->isUnit()) {
 | 
			
		||||
    // TODO: implement WhitenSystem for fixed size matrices and include above
 | 
			
		||||
    H1 = noiseModel->Whiten(H1);
 | 
			
		||||
    H2 = noiseModel->Whiten(H2);
 | 
			
		||||
    b = noiseModel->Whiten(b);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (noiseModel && noiseModel->isConstrained()) {
 | 
			
		||||
    using noiseModel::Constrained;
 | 
			
		||||
    return boost::make_shared<JacobianFactor>(
 | 
			
		||||
        key1, H1, key2, H2, b,
 | 
			
		||||
        boost::static_pointer_cast<Constrained>(noiseModel)->unit());
 | 
			
		||||
  } else {
 | 
			
		||||
    return boost::make_shared<JacobianFactor>(key1, H1, key2, H2, b);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
TEST(GeneralSFMFactor, Linearize) {
 | 
			
		||||
  Point2 z(3.,0.);
 | 
			
		||||
 | 
			
		||||
  // Create Values
 | 
			
		||||
  Values values;
 | 
			
		||||
  Rot3 R;
 | 
			
		||||
  Point3 t1(0,0,-6);
 | 
			
		||||
  Pose3 x1(R,t1);
 | 
			
		||||
  values.insert(X(1), GeneralCamera(x1));
 | 
			
		||||
  Point3 l1;  values.insert(L(1), l1);
 | 
			
		||||
 | 
			
		||||
  // Test with Empty Model
 | 
			
		||||
  {
 | 
			
		||||
  const SharedNoiseModel model;
 | 
			
		||||
  Projection factor(z, model, X(1), L(1));
 | 
			
		||||
  GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values);
 | 
			
		||||
  GaussianFactor::shared_ptr actual = linearize(factor, values);
 | 
			
		||||
  EXPECT(assert_equal(*expected,*actual,1e-9));
 | 
			
		||||
  }
 | 
			
		||||
  // Test with Unit Model
 | 
			
		||||
  {
 | 
			
		||||
  const SharedNoiseModel model(noiseModel::Unit::Create(2));
 | 
			
		||||
  Projection factor(z, model, X(1), L(1));
 | 
			
		||||
  GaussianFactor::shared_ptr expected = factor.linearize(values);
 | 
			
		||||
  GaussianFactor::shared_ptr actual = linearize(factor, values);
 | 
			
		||||
  EXPECT(assert_equal(*expected,*actual,1e-9));
 | 
			
		||||
  }
 | 
			
		||||
  // Test with Isotropic noise
 | 
			
		||||
  {
 | 
			
		||||
  const SharedNoiseModel model(noiseModel::Isotropic::Sigma(2,0.5));
 | 
			
		||||
  Projection factor(z, model, X(1), L(1));
 | 
			
		||||
  GaussianFactor::shared_ptr expected = factor.linearize(values);
 | 
			
		||||
  GaussianFactor::shared_ptr actual = linearize(factor, values);
 | 
			
		||||
  EXPECT(assert_equal(*expected,*actual,1e-9));
 | 
			
		||||
  }
 | 
			
		||||
  // Test with Constrained Model
 | 
			
		||||
  {
 | 
			
		||||
  const SharedNoiseModel model(noiseModel::Constrained::All(2));
 | 
			
		||||
  Projection factor(z, model, X(1), L(1));
 | 
			
		||||
  GaussianFactor::shared_ptr expected = factor.linearize(values);
 | 
			
		||||
  GaussianFactor::shared_ptr actual = linearize(factor, values);
 | 
			
		||||
  EXPECT(assert_equal(*expected,*actual,1e-9));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue