| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-11 22:39:48 +08:00
										 |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |  * 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  TSAMFactors.h | 
					
						
							|  |  |  |  *  @brief TSAM 1 Factors, simpler than the hierarchical TSAM 2 | 
					
						
							|  |  |  |  *  @author Frank Dellaert | 
					
						
							|  |  |  |  *  @date May 2014 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/geometry/Pose2.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactor.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * DeltaFactor: relative 2D measurement between Pose2 and Point2 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  | class DeltaFactor: public NoiseModelFactorN<Pose2, Point2> { | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   typedef DeltaFactor This; | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  |   typedef NoiseModelFactorN<Pose2, Point2> Base; | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   typedef std::shared_ptr<This> shared_ptr; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   Point2 measured_; ///< the measurement
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Constructor
 | 
					
						
							|  |  |  |   DeltaFactor(Key i, Key j, const Point2& measured, | 
					
						
							|  |  |  |       const SharedNoiseModel& model) : | 
					
						
							|  |  |  |       Base(model, i, j), measured_(measured) { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Evaluate measurement error h(x)-z
 | 
					
						
							|  |  |  |   Vector evaluateError(const Pose2& pose, const Point2& point, | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |       OptionalMatrixType H1, OptionalMatrixType H2) const override { | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |     return pose.transformTo(point, H1, H2) - measured_; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * DeltaFactorBase: relative 2D measurement between Pose2 and Point2, with Basenodes | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  | class DeltaFactorBase: public NoiseModelFactorN<Pose2, Pose2, Pose2, Point2> { | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   typedef DeltaFactorBase This; | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  |   typedef NoiseModelFactorN<Pose2, Pose2, Pose2, Point2> Base; | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   typedef std::shared_ptr<This> shared_ptr; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   Point2 measured_; ///< the measurement
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |   /// Constructor
 | 
					
						
							|  |  |  |   DeltaFactorBase(Key b1, Key i, Key b2, Key j, const Point2& measured, | 
					
						
							|  |  |  |       const SharedNoiseModel& model) : | 
					
						
							|  |  |  |       Base(model, b1, i, b2, j), measured_(measured) { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Evaluate measurement error h(x)-z
 | 
					
						
							|  |  |  |   Vector evaluateError(const Pose2& base1, const Pose2& pose, | 
					
						
							|  |  |  |       const Pose2& base2, const Point2& point, //
 | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |       OptionalMatrixType H1, OptionalMatrixType H2, //
 | 
					
						
							|  |  |  |       OptionalMatrixType H3, OptionalMatrixType H4) const override { | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |     if (H1 || H2 || H3 || H4) { | 
					
						
							|  |  |  |       // TODO use fixed-size matrices
 | 
					
						
							|  |  |  |       Matrix D_pose_g_base1, D_pose_g_pose; | 
					
						
							|  |  |  |       Pose2 pose_g = base1.compose(pose, D_pose_g_base1, D_pose_g_pose); | 
					
						
							|  |  |  |       Matrix D_point_g_base2, D_point_g_point; | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |       Point2 point_g = base2.transformFrom(point, D_point_g_base2, | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |           D_point_g_point); | 
					
						
							|  |  |  |       Matrix D_e_pose_g, D_e_point_g; | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |       Point2 d = pose_g.transformTo(point_g, D_e_pose_g, D_e_point_g); | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |       if (H1) | 
					
						
							|  |  |  |         *H1 = D_e_pose_g * D_pose_g_base1; | 
					
						
							|  |  |  |       if (H2) | 
					
						
							|  |  |  |         *H2 = D_e_pose_g * D_pose_g_pose; | 
					
						
							|  |  |  |       if (H3) | 
					
						
							|  |  |  |         *H3 = D_e_point_g * D_point_g_base2; | 
					
						
							|  |  |  |       if (H4) | 
					
						
							|  |  |  |         *H4 = D_e_point_g * D_point_g_point; | 
					
						
							| 
									
										
										
										
											2016-06-06 14:52:04 +08:00
										 |  |  |       return d - measured_; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       Pose2 pose_g = base1.compose(pose); | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |       Point2 point_g = base2.transformFrom(point); | 
					
						
							|  |  |  |       Point2 d = pose_g.transformTo(point_g); | 
					
						
							| 
									
										
										
										
											2016-06-06 14:52:04 +08:00
										 |  |  |       return d - measured_; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * OdometryFactorBase: Pose2 odometry, with Basenodes | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  | class OdometryFactorBase: public NoiseModelFactorN<Pose2, Pose2, Pose2, Pose2> { | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   typedef OdometryFactorBase This; | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  |   typedef NoiseModelFactorN<Pose2, Pose2, Pose2, Pose2> Base; | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   typedef std::shared_ptr<This> shared_ptr; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   Pose2 measured_; ///< the measurement
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Constructor
 | 
					
						
							|  |  |  |   OdometryFactorBase(Key b1, Key i, Key b2, Key j, const Pose2& measured, | 
					
						
							|  |  |  |       const SharedNoiseModel& model) : | 
					
						
							|  |  |  |       Base(model, b1, i, b2, j), measured_(measured) { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Evaluate measurement error h(x)-z
 | 
					
						
							|  |  |  |   Vector evaluateError(const Pose2& base1, const Pose2& pose1, | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |       const Pose2& base2, const Pose2& pose2, | 
					
						
							|  |  |  |       OptionalMatrixType H1, OptionalMatrixType H2, | 
					
						
							|  |  |  |       OptionalMatrixType H3, OptionalMatrixType H4) const override { | 
					
						
							| 
									
										
										
										
											2014-05-05 22:14:36 +08:00
										 |  |  |     if (H1 || H2 || H3 || H4) { | 
					
						
							|  |  |  |       // TODO use fixed-size matrices
 | 
					
						
							|  |  |  |       Matrix D_pose1_g_base1, D_pose1_g_pose1; | 
					
						
							|  |  |  |       Pose2 pose1_g = base1.compose(pose1, D_pose1_g_base1, D_pose1_g_pose1); | 
					
						
							|  |  |  |       Matrix D_pose2_g_base2, D_pose2_g_pose2; | 
					
						
							|  |  |  |       Pose2 pose2_g = base2.compose(pose2, D_pose2_g_base2, D_pose2_g_pose2); | 
					
						
							|  |  |  |       Matrix D_e_pose1_g, D_e_pose2_g; | 
					
						
							|  |  |  |       Pose2 d = pose1_g.between(pose2_g, D_e_pose1_g, D_e_pose2_g); | 
					
						
							|  |  |  |       if (H1) | 
					
						
							|  |  |  |         *H1 = D_e_pose1_g * D_pose1_g_base1; | 
					
						
							|  |  |  |       if (H2) | 
					
						
							|  |  |  |         *H2 = D_e_pose1_g * D_pose1_g_pose1; | 
					
						
							|  |  |  |       if (H3) | 
					
						
							|  |  |  |         *H3 = D_e_pose2_g * D_pose2_g_base2; | 
					
						
							|  |  |  |       if (H4) | 
					
						
							|  |  |  |         *H4 = D_e_pose2_g * D_pose2_g_pose2; | 
					
						
							|  |  |  |       return measured_.localCoordinates(d); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       Pose2 pose1_g = base1.compose(pose1); | 
					
						
							|  |  |  |       Pose2 pose2_g = base2.compose(pose2); | 
					
						
							|  |  |  |       Pose2 d = pose1_g.between(pose2_g); | 
					
						
							|  |  |  |       return measured_.localCoordinates(d); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |