| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2021-07-21 08:46:43 +08:00
										 |  |  |  * @file ProjectionFactorRollingShutter.h | 
					
						
							|  |  |  |  * @brief Basic projection factor for rolling shutter cameras | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  |  * @author Yotam Stern | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 11:04:52 +08:00
										 |  |  | #include <gtsam/geometry/Cal3_S2.h>
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  | #include <gtsam/geometry/CalibratedCamera.h>
 | 
					
						
							|  |  |  | #include <gtsam/geometry/PinholeCamera.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactor.h>
 | 
					
						
							| 
									
										
										
										
											2021-12-09 22:37:21 +08:00
										 |  |  | #include <gtsam_unstable/dllexport.h>
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |  * Non-linear factor for 2D projection measurement obtained using a rolling | 
					
						
							|  |  |  |  * shutter camera. The calibration is known here. This version takes rolling | 
					
						
							|  |  |  |  * shutter information into account as follows: consider two consecutive poses A | 
					
						
							|  |  |  |  * and B, and a Point2 measurement taken starting at time A using a rolling | 
					
						
							|  |  |  |  * shutter camera. Pose A has timestamp t_A, and Pose B has timestamp t_B. The | 
					
						
							|  |  |  |  * Point2 measurement has timestamp t_p (with t_A <= t_p <= t_B) corresponding | 
					
						
							|  |  |  |  * to the time of exposure of the row of the image the pixel belongs to. Let us | 
					
						
							|  |  |  |  * define the alpha = (t_p - t_A) / (t_B - t_A), we will use the pose | 
					
						
							|  |  |  |  * interpolated between A and B by the alpha to project the corresponding | 
					
						
							|  |  |  |  * landmark to Point2. | 
					
						
							| 
									
										
										
										
											2022-07-27 04:44:30 +08:00
										 |  |  |  * @ingroup slam | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 22:37:21 +08:00
										 |  |  | class GTSAM_UNSTABLE_EXPORT ProjectionFactorRollingShutter | 
					
						
							| 
									
										
										
										
											2022-12-23 06:25:48 +08:00
										 |  |  |     : public NoiseModelFactorN<Pose3, Pose3, Point3> { | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |  protected: | 
					
						
							|  |  |  |   // Keep a copy of measurement and calibration for I/O
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   Point2 measured_;  ///< 2D measurement
 | 
					
						
							|  |  |  |   double alpha_;     ///< interpolation parameter in [0,1] corresponding to the
 | 
					
						
							|  |  |  |                      ///< point2 measurement
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   std::shared_ptr<Cal3_S2> K_;  ///< shared pointer to calibration object
 | 
					
						
							| 
									
										
										
										
											2023-01-13 06:02:31 +08:00
										 |  |  |   std::optional<Pose3> | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |       body_P_sensor_;  ///< The pose of the sensor in the body frame
 | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   // verbosity handling for Cheirality Exceptions
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   bool throwCheirality_;  ///< If true, rethrows Cheirality exceptions (default:
 | 
					
						
							|  |  |  |                           ///< false)
 | 
					
						
							|  |  |  |   bool verboseCheirality_;  ///< If true, prints text for Cheirality exceptions
 | 
					
						
							|  |  |  |                             ///< (default: false)
 | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |  public: | 
					
						
							|  |  |  |   /// shorthand for base class type
 | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |   typedef NoiseModelFactor3<Pose3, Pose3, Point3> Base; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /// shorthand for this class
 | 
					
						
							|  |  |  |   typedef ProjectionFactorRollingShutter This; | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /// shorthand for a smart pointer to a factor
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   typedef std::shared_ptr<This> shared_ptr; | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /// Default constructor
 | 
					
						
							|  |  |  |   ProjectionFactorRollingShutter() | 
					
						
							|  |  |  |       : measured_(0, 0), | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |         alpha_(0), | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |         throwCheirality_(false), | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |         verboseCheirality_(false) {} | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Constructor | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |    * @param measured is the 2-dimensional pixel location of point in the image | 
					
						
							|  |  |  |    * (the measurement) | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |    * @param alpha in [0,1] is the rolling shutter parameter for the measurement | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |    * @param model is the noise model | 
					
						
							|  |  |  |    * @param poseKey_a is the key of the first camera | 
					
						
							|  |  |  |    * @param poseKey_b is the key of the second camera | 
					
						
							|  |  |  |    * @param pointKey is the key of the landmark | 
					
						
							|  |  |  |    * @param K shared pointer to the constant calibration | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |    * @param body_P_sensor is the transform from body to sensor frame (default | 
					
						
							|  |  |  |    * identity) | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   ProjectionFactorRollingShutter( | 
					
						
							|  |  |  |       const Point2& measured, double alpha, const SharedNoiseModel& model, | 
					
						
							|  |  |  |       Key poseKey_a, Key poseKey_b, Key pointKey, | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |       const std::shared_ptr<Cal3_S2>& K, | 
					
						
							| 
									
										
										
										
											2023-01-13 06:02:31 +08:00
										 |  |  |       std::optional<Pose3> body_P_sensor = {}) | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |       : Base(model, poseKey_a, poseKey_b, pointKey), | 
					
						
							|  |  |  |         measured_(measured), | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |         alpha_(alpha), | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |         K_(K), | 
					
						
							|  |  |  |         body_P_sensor_(body_P_sensor), | 
					
						
							|  |  |  |         throwCheirality_(false), | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |         verboseCheirality_(false) {} | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Constructor with exception-handling flags | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |    * @param measured is the 2-dimensional pixel location of point in the image | 
					
						
							|  |  |  |    * (the measurement) | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |    * @param alpha in [0,1] is the rolling shutter parameter for the measurement | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |    * @param model is the noise model | 
					
						
							|  |  |  |    * @param poseKey_a is the key of the first camera | 
					
						
							|  |  |  |    * @param poseKey_b is the key of the second camera | 
					
						
							|  |  |  |    * @param pointKey is the key of the landmark | 
					
						
							|  |  |  |    * @param K shared pointer to the constant calibration | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |    * @param throwCheirality determines whether Cheirality exceptions are | 
					
						
							|  |  |  |    * rethrown | 
					
						
							|  |  |  |    * @param verboseCheirality determines whether exceptions are printed for | 
					
						
							|  |  |  |    * Cheirality | 
					
						
							|  |  |  |    * @param body_P_sensor is the transform from body to sensor frame  (default | 
					
						
							|  |  |  |    * identity) | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   ProjectionFactorRollingShutter( | 
					
						
							|  |  |  |       const Point2& measured, double alpha, const SharedNoiseModel& model, | 
					
						
							|  |  |  |       Key poseKey_a, Key poseKey_b, Key pointKey, | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |       const std::shared_ptr<Cal3_S2>& K, bool throwCheirality, | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |       bool verboseCheirality, | 
					
						
							| 
									
										
										
										
											2023-01-13 06:02:31 +08:00
										 |  |  |       std::optional<Pose3> body_P_sensor = {}) | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |       : Base(model, poseKey_a, poseKey_b, pointKey), | 
					
						
							|  |  |  |         measured_(measured), | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |         alpha_(alpha), | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |         K_(K), | 
					
						
							|  |  |  |         body_P_sensor_(body_P_sensor), | 
					
						
							|  |  |  |         throwCheirality_(throwCheirality), | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |         verboseCheirality_(verboseCheirality) {} | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** Virtual destructor */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   virtual ~ProjectionFactorRollingShutter() {} | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /// @return a deep copy of this factor
 | 
					
						
							| 
									
										
										
										
											2021-08-29 04:30:25 +08:00
										 |  |  |   gtsam::NonlinearFactor::shared_ptr clone() const override { | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |     return std::static_pointer_cast<gtsam::NonlinearFactor>( | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |         gtsam::NonlinearFactor::shared_ptr(new This(*this))); | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * print | 
					
						
							|  |  |  |    * @param s optional string naming the factor | 
					
						
							|  |  |  |    * @param keyFormatter optional formatter useful for printing Symbols | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   void print( | 
					
						
							|  |  |  |       const std::string& s = "", | 
					
						
							|  |  |  |       const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override { | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |     std::cout << s << "ProjectionFactorRollingShutter, z = "; | 
					
						
							|  |  |  |     traits<Point2>::Print(measured_); | 
					
						
							| 
									
										
										
										
											2021-08-14 09:42:09 +08:00
										 |  |  |     std::cout << " rolling shutter interpolation param = " << alpha_; | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |     if (this->body_P_sensor_) | 
					
						
							|  |  |  |       this->body_P_sensor_->print("  sensor pose in body frame: "); | 
					
						
							|  |  |  |     Base::print("", keyFormatter); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// equals
 | 
					
						
							| 
									
										
										
										
											2021-08-29 04:30:25 +08:00
										 |  |  |   bool equals(const NonlinearFactor& p, double tol = 1e-9) const override { | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |     const This* e = dynamic_cast<const This*>(&p); | 
					
						
							|  |  |  |     return e && Base::equals(p, tol) && (alpha_ == e->alpha()) && | 
					
						
							|  |  |  |            traits<Point2>::Equals(this->measured_, e->measured_, tol) && | 
					
						
							|  |  |  |            this->K_->equals(*e->K_, tol) && | 
					
						
							|  |  |  |            (this->throwCheirality_ == e->throwCheirality_) && | 
					
						
							|  |  |  |            (this->verboseCheirality_ == e->verboseCheirality_) && | 
					
						
							|  |  |  |            ((!body_P_sensor_ && !e->body_P_sensor_) || | 
					
						
							|  |  |  |             (body_P_sensor_ && e->body_P_sensor_ && | 
					
						
							|  |  |  |              body_P_sensor_->equals(*e->body_P_sensor_))); | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Evaluate error h(x)-z and optionally derivatives
 | 
					
						
							| 
									
										
										
										
											2021-08-29 04:30:25 +08:00
										 |  |  |   Vector evaluateError( | 
					
						
							|  |  |  |       const Pose3& pose_a, const Pose3& pose_b, const Point3& point, | 
					
						
							| 
									
										
										
										
											2023-01-10 06:52:56 +08:00
										 |  |  |       OptionalMatrixType H1, OptionalMatrixType H2, OptionalMatrixType H3) const override; | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** return the measurement */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   const Point2& measured() const { return measured_; } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** return the calibration object */ | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   inline const std::shared_ptr<Cal3_S2> calibration() const { return K_; } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** returns the rolling shutter interp param*/ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   inline double alpha() const { return alpha_; } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** return verbosity */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   inline bool verboseCheirality() const { return verboseCheirality_; } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /** return flag for throwing cheirality exceptions */ | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   inline bool throwCheirality() const { return throwCheirality_; } | 
					
						
							| 
									
										
										
										
											2021-04-22 13:52:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2023-01-19 04:03:30 +08:00
										 |  |  | #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION  ///
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   /// Serialization function
 | 
					
						
							|  |  |  |   friend class boost::serialization::access; | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  |   template <class ARCHIVE> | 
					
						
							|  |  |  |   void serialize(ARCHIVE& ar, const unsigned int /*version*/) { | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(measured_); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(alpha_); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(K_); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(body_P_sensor_); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(throwCheirality_); | 
					
						
							|  |  |  |     ar& BOOST_SERIALIZATION_NVP(verboseCheirality_); | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-01-19 04:03:30 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-21 09:06:51 +08:00
										 |  |  |  public: | 
					
						
							|  |  |  |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-07-21 09:29:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /// traits
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  | template <> | 
					
						
							|  |  |  | struct traits<ProjectionFactorRollingShutter> | 
					
						
							|  |  |  |     : public Testable<ProjectionFactorRollingShutter> {}; | 
					
						
							| 
									
										
										
										
											2021-07-21 09:29:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 05:36:14 +08:00
										 |  |  | }  // namespace gtsam
 |