Faster linearize now in class
							parent
							
								
									171793aad3
								
							
						
					
					
						commit
						5dc149fe23
					
				|  | @ -116,7 +116,6 @@ namespace gtsam { | ||||||
|     /** h(x)-z */ |     /** h(x)-z */ | ||||||
|     Vector evaluateError(const CAMERA& camera, const LANDMARK& point, |     Vector evaluateError(const CAMERA& camera, const LANDMARK& point, | ||||||
|         boost::optional<Matrix&> H1=boost::none, boost::optional<Matrix&> H2=boost::none) const { |         boost::optional<Matrix&> H1=boost::none, boost::optional<Matrix&> H2=boost::none) const { | ||||||
| 
 |  | ||||||
|       try { |       try { | ||||||
|         Point2 reprojError(camera.project2(point,H1,H2) - measured_); |         Point2 reprojError(camera.project2(point,H1,H2) - measured_); | ||||||
|         return reprojError.vector(); |         return reprojError.vector(); | ||||||
|  | @ -124,12 +123,50 @@ namespace gtsam { | ||||||
|       catch( CheiralityException& e) { |       catch( CheiralityException& e) { | ||||||
|         if (H1) *H1 = zeros(2, DimC); |         if (H1) *H1 = zeros(2, DimC); | ||||||
|         if (H2) *H2 = zeros(2, DimL); |         if (H2) *H2 = zeros(2, DimL); | ||||||
|         std::cout << e.what() << ": Landmark "<< DefaultKeyFormatter(this->key2()) |         // TODO warn if verbose output asked for
 | ||||||
|                               << " behind Camera " << DefaultKeyFormatter(this->key1()) << std::endl; |  | ||||||
|         return zero(2); |         return zero(2); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Linearize using fixed-size matrices
 | ||||||
|  |     boost::shared_ptr<GaussianFactor> linearize(const Values& values) { | ||||||
|  |       // Only linearize if the factor is active
 | ||||||
|  |       if (!this->active(values)) return boost::shared_ptr<JacobianFactor>(); | ||||||
|  | 
 | ||||||
|  |       const Key key1 = this->key1(), key2 = this->key2(); | ||||||
|  |       Eigen::Matrix<double, 2, DimC> H1; | ||||||
|  |       Eigen::Matrix<double, 2, DimL> H2; | ||||||
|  |       Vector2 b; | ||||||
|  |       try { | ||||||
|  |         const CAMERA& camera = values.at<CAMERA>(key1); | ||||||
|  |         const LANDMARK& point = values.at<LANDMARK>(key2); | ||||||
|  |         Point2 reprojError(camera.project2(point, H1, H2) - 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 = this->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); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** return the measured */ |     /** return the measured */ | ||||||
|     inline const Point2 measured() const { |     inline const Point2 measured() const { | ||||||
|       return measured_; |       return measured_; | ||||||
|  |  | ||||||
|  | @ -430,49 +430,6 @@ TEST(GeneralSFMFactor, CalibratedCameraPoseRange) { | ||||||
|   EXPECT(assert_equal(expected, actual, 1e-4)); |   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) { | TEST(GeneralSFMFactor, Linearize) { | ||||||
|   Point2 z(3.,0.); |   Point2 z(3.,0.); | ||||||
|  | @ -490,31 +447,31 @@ TEST(GeneralSFMFactor, Linearize) { | ||||||
|   const SharedNoiseModel model; |   const SharedNoiseModel model; | ||||||
|   Projection factor(z, model, X(1), L(1)); |   Projection factor(z, model, X(1), L(1)); | ||||||
|   GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values); |   GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values); | ||||||
|   GaussianFactor::shared_ptr actual = linearize(factor, values); |   GaussianFactor::shared_ptr actual = factor.linearize(values); | ||||||
|   EXPECT(assert_equal(*expected,*actual,1e-9)); |   EXPECT(assert_equal(*expected,*actual,1e-9)); | ||||||
|   } |   } | ||||||
|   // Test with Unit Model
 |   // Test with Unit Model
 | ||||||
|   { |   { | ||||||
|   const SharedNoiseModel model(noiseModel::Unit::Create(2)); |   const SharedNoiseModel model(noiseModel::Unit::Create(2)); | ||||||
|   Projection factor(z, model, X(1), L(1)); |   Projection factor(z, model, X(1), L(1)); | ||||||
|   GaussianFactor::shared_ptr expected = factor.linearize(values); |   GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values); | ||||||
|   GaussianFactor::shared_ptr actual = linearize(factor, values); |   GaussianFactor::shared_ptr actual = factor.linearize(values); | ||||||
|   EXPECT(assert_equal(*expected,*actual,1e-9)); |   EXPECT(assert_equal(*expected,*actual,1e-9)); | ||||||
|   } |   } | ||||||
|   // Test with Isotropic noise
 |   // Test with Isotropic noise
 | ||||||
|   { |   { | ||||||
|   const SharedNoiseModel model(noiseModel::Isotropic::Sigma(2,0.5)); |   const SharedNoiseModel model(noiseModel::Isotropic::Sigma(2,0.5)); | ||||||
|   Projection factor(z, model, X(1), L(1)); |   Projection factor(z, model, X(1), L(1)); | ||||||
|   GaussianFactor::shared_ptr expected = factor.linearize(values); |   GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values); | ||||||
|   GaussianFactor::shared_ptr actual = linearize(factor, values); |   GaussianFactor::shared_ptr actual = factor.linearize(values); | ||||||
|   EXPECT(assert_equal(*expected,*actual,1e-9)); |   EXPECT(assert_equal(*expected,*actual,1e-9)); | ||||||
|   } |   } | ||||||
|   // Test with Constrained Model
 |   // Test with Constrained Model
 | ||||||
|   { |   { | ||||||
|   const SharedNoiseModel model(noiseModel::Constrained::All(2)); |   const SharedNoiseModel model(noiseModel::Constrained::All(2)); | ||||||
|   Projection factor(z, model, X(1), L(1)); |   Projection factor(z, model, X(1), L(1)); | ||||||
|   GaussianFactor::shared_ptr expected = factor.linearize(values); |   GaussianFactor::shared_ptr expected = factor.NoiseModelFactor::linearize(values); | ||||||
|   GaussianFactor::shared_ptr actual = linearize(factor, values); |   GaussianFactor::shared_ptr actual = factor.linearize(values); | ||||||
|   EXPECT(assert_equal(*expected,*actual,1e-9)); |   EXPECT(assert_equal(*expected,*actual,1e-9)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue