GTSAM  4.0.2
C++ library for smoothing and mapping (SAM)
SmartStereoProjectionFactorPP.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
19 #pragma once
20 
22 
23 namespace gtsam {
43 class GTSAM_UNSTABLE_EXPORT SmartStereoProjectionFactorPP
45  protected:
47  std::vector<std::shared_ptr<Cal3_S2Stereo>> K_all_;
48 
51 
54 
55  public:
56  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
57 
60 
63 
65  typedef std::shared_ptr<This> shared_ptr;
66 
67  static const int DimBlock = 12;
68  static const int DimPose = 6;
69  static const int ZDim = 3;
70  typedef Eigen::Matrix<double, ZDim, DimBlock> MatrixZD; // F blocks (derivatives wrt camera)
71  typedef std::vector<MatrixZD, Eigen::aligned_allocator<MatrixZD> > FBlocks; // vector of F blocks
72 
78  SmartStereoProjectionFactorPP(const SharedNoiseModel& sharedNoiseModel,
79  const SmartStereoProjectionParams& params =
81 
90  void add(const StereoPoint2& measured, const Key& world_P_body_key,
91  const Key& body_P_cam_key,
92  const std::shared_ptr<Cal3_S2Stereo>& K);
93 
103  void add(const std::vector<StereoPoint2>& measurements,
104  const KeyVector& w_P_body_keys, const KeyVector& body_P_cam_keys,
105  const std::vector<std::shared_ptr<Cal3_S2Stereo>>& Ks);
106 
117  void add(const std::vector<StereoPoint2>& measurements,
118  const KeyVector& w_P_body_keys, const KeyVector& body_P_cam_keys,
119  const std::shared_ptr<Cal3_S2Stereo>& K);
120 
126  void print(const std::string& s = "", const KeyFormatter& keyFormatter =
127  DefaultKeyFormatter) const override;
128 
130  bool equals(const NonlinearFactor& p, double tol = 1e-9) const override;
131 
134  return body_P_cam_keys_;
135  }
136 
140  double error(const Values& values) const override;
141 
143  inline std::vector<std::shared_ptr<Cal3_S2Stereo>> calibration() const {
144  return K_all_;
145  }
146 
154  Base::Cameras cameras(const Values& values) const override;
155 
165  FBlocks& Fs, Matrix& E, Vector& b, const Values& values) const {
166  if (!result_) {
167  throw("computeJacobiansWithTriangulatedPoint");
168  } else { // valid result: compute jacobians
169  size_t numViews = measured_.size();
170  E = Matrix::Zero(3 * numViews, 3); // a StereoPoint2 for each view (point jacobian)
171  b = Vector::Zero(3 * numViews); // a StereoPoint2 for each view
172  Matrix dPoseCam_dPoseBody_i, dPoseCam_dPoseExt_i, dProject_dPoseCam_i, Ei;
173 
174  for (size_t i = 0; i < numViews; i++) { // for each camera/measurement
175  Pose3 w_P_body = values.at<Pose3>(world_P_body_keys_.at(i));
176  Pose3 body_P_cam = values.at<Pose3>(body_P_cam_keys_.at(i));
177  StereoCamera camera(
178  w_P_body.compose(body_P_cam, dPoseCam_dPoseBody_i, dPoseCam_dPoseExt_i),
179  K_all_[i]);
180  // get jacobians and error vector for current measurement
181  StereoPoint2 reprojectionError_i = StereoPoint2(
182  camera.project(*result_, dProject_dPoseCam_i, Ei) - measured_.at(i));
183  Eigen::Matrix<double, ZDim, DimBlock> J; // 3 x 12
184  J.block<ZDim, 6>(0, 0) = dProject_dPoseCam_i * dPoseCam_dPoseBody_i; // (3x6) * (6x6)
185  J.block<ZDim, 6>(0, 6) = dProject_dPoseCam_i * dPoseCam_dPoseExt_i; // (3x6) * (6x6)
186  // if the right pixel is invalid, fix jacobians
187  if (std::isnan(measured_.at(i).uR()))
188  {
189  J.block<1, 12>(1, 0) = Matrix::Zero(1, 12);
190  Ei.block<1, 3>(1, 0) = Matrix::Zero(1, 3);
191  reprojectionError_i = StereoPoint2(reprojectionError_i.uL(), 0.0,
192  reprojectionError_i.v());
193  }
194  // fit into the output structures
195  Fs.push_back(J);
196  size_t row = 3 * i;
197  b.segment<ZDim>(row) = -reprojectionError_i.vector();
198  E.block<3, 3>(row, 0) = Ei;
199  }
200  }
201  }
202 
204  std::shared_ptr<RegularHessianFactor<DimPose> > createHessianFactor(
205  const Values& values, const double lambda = 0.0, bool diagonalDamping =
206  false) const {
207 
208  // we may have multiple cameras sharing the same extrinsic cals, hence the number
209  // of keys may be smaller than 2 * nrMeasurements (which is the upper bound where we
210  // have a body key and an extrinsic calibration key for each measurement)
211  size_t nrUniqueKeys = keys_.size();
212 
213  // Create structures for Hessian Factors
214  KeyVector js;
215  std::vector < Matrix > Gs(nrUniqueKeys * (nrUniqueKeys + 1) / 2);
216  std::vector<Vector> gs(nrUniqueKeys);
217 
218  if (this->measured_.size() != cameras(values).size())
219  throw std::runtime_error("SmartStereoProjectionHessianFactor: this->"
220  "measured_.size() inconsistent with input");
221 
222  // triangulate 3D point at given linearization point
223  triangulateSafe(cameras(values));
224 
225  if (!result_) { // failed: return "empty/zero" Hessian
226  for (Matrix& m : Gs)
227  m = Matrix::Zero(DimPose, DimPose);
228  for (Vector& v : gs)
229  v = Vector::Zero(DimPose);
230  return std::make_shared < RegularHessianFactor<DimPose>
231  > (keys_, Gs, gs, 0.0);
232  }
233 
234  // compute Jacobian given triangulated 3D Point
235  FBlocks Fs;
236  Matrix F, E;
237  Vector b;
238  computeJacobiansAndCorrectForMissingMeasurements(Fs, E, b, values);
239 
240  // Whiten using noise model
241  noiseModel_->WhitenSystem(E, b);
242  for (size_t i = 0; i < Fs.size(); i++)
243  Fs[i] = noiseModel_->Whiten(Fs[i]);
244 
245  // build augmented Hessian (with last row/column being the information vector)
246  Matrix3 P;
247  Cameras::ComputePointCovariance <3> (P, E, lambda, diagonalDamping);
248 
249  // these are the keys that correspond to the blocks in augmentedHessian (output of SchurComplement)
250  KeyVector nonuniqueKeys;
251  for (size_t i = 0; i < world_P_body_keys_.size(); i++) {
252  nonuniqueKeys.push_back(world_P_body_keys_.at(i));
253  nonuniqueKeys.push_back(body_P_cam_keys_.at(i));
254  }
255  // but we need to get the augumented hessian wrt the unique keys in key_
256  SymmetricBlockMatrix augmentedHessianUniqueKeys =
257  Cameras::SchurComplementAndRearrangeBlocks<3,DimBlock,DimPose>(Fs,E,P,b,
258  nonuniqueKeys, keys_);
259 
260  return std::make_shared < RegularHessianFactor<DimPose>
261  > (keys_, augmentedHessianUniqueKeys);
262  }
263 
269  std::shared_ptr<GaussianFactor> linearizeDamped(
270  const Values& values, const double lambda = 0.0) const {
271  // depending on flag set on construction we may linearize to different linear factors
272  switch (params_.linearizationMode) {
273  case HESSIAN:
274  return createHessianFactor(values, lambda);
275  default:
276  throw std::runtime_error(
277  "SmartStereoProjectionFactorPP: unknown linearization mode");
278  }
279  }
280 
282  std::shared_ptr<GaussianFactor> linearize(const Values& values) const
283  override {
284  return linearizeDamped(values);
285  }
286 
287  private:
288 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION
289  friend class boost::serialization::access;
291  template<class ARCHIVE>
292  void serialize(ARCHIVE& ar, const unsigned int /*version*/) {
293  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
294  ar & BOOST_SERIALIZATION_NVP(K_all_);
295  }
296 #endif
297 };
298 // end of class declaration
299 
301 template<>
303  SmartStereoProjectionFactorPP> {
304 };
305 
306 } // namespace gtsam
const KeyVector & getExtrinsicPoseKeys() const
equals
Definition: SmartStereoProjectionFactorPP.h:133
const MATRIX::ConstRowXpr row(const MATRIX &A, size_t j)
Definition: Matrix.h:221
Definition: SmartFactorParams.h:42
std::string serialize(const T &input)
serializes to a string
Definition: serialization.h:113
const ValueType at(Key j) const
Definition: Values-inl.h:204
Definition: Testable.h:152
Definition: Group.h:43
Definition: NonlinearFactor.h:68
Smart stereo factor on StereoCameras (pose)
std::vector< std::shared_ptr< Cal3_S2Stereo > > calibration() const
Definition: SmartStereoProjectionFactorPP.h:143
Definition: SymmetricBlockMatrix.h:53
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef SmartStereoProjectionFactor Base
shorthand for base class type
Definition: SmartStereoProjectionFactorPP.h:59
std::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor
Definition: SmartStereoProjectionFactorPP.h:65
Definition: Testable.h:112
std::shared_ptr< RegularHessianFactor< DimPose > > createHessianFactor(const Values &values, const double lambda=0.0, bool diagonalDamping=false) const
linearize and return a Hessianfactor that is an approximation of error(p)
Definition: SmartStereoProjectionFactorPP.h:204
GTSAM_EXPORT void print(const Matrix &A, const std::string &s, std::ostream &stream)
std::shared_ptr< GaussianFactor > linearizeDamped(const Values &values, const double lambda=0.0) const
Definition: SmartStereoProjectionFactorPP.h:269
KeyVector body_P_cam_keys_
The keys corresponding to the extrinsic pose calibration for each view (pose that transform from came...
Definition: SmartStereoProjectionFactorPP.h:53
TriangulationResult triangulateSafe(const CameraSet< CAMERA > &cameras, const typename CAMERA::MeasurementVector &measured, const TriangulationParameters &params)
triangulateSafe: extensive checking of the outcome
Definition: triangulation.h:687
std::vector< std::shared_ptr< Cal3_S2Stereo > > K_all_
shared pointer to calibration object (one for each camera)
Definition: SmartStereoProjectionFactorPP.h:47
Definition: Values.h:65
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:35
std::shared_ptr< GaussianFactor > linearize(const Values &values) const override
linearize
Definition: SmartStereoProjectionFactorPP.h:282
Definition: chartTesting.h:28
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
Definition: StereoPoint2.h:34
Definition: SmartStereoProjectionFactor.h:55
Definition: StereoCamera.h:47
SmartStereoProjectionFactorPP This
shorthand for this class
Definition: SmartStereoProjectionFactorPP.h:62
Definition: Pose3.h:37
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:102
noiseModel::Base::shared_ptr SharedNoiseModel
Definition: NoiseModel.h:741
void computeJacobiansAndCorrectForMissingMeasurements(FBlocks &Fs, Matrix &E, Vector &b, const Values &values) const
Definition: SmartStereoProjectionFactorPP.h:164
Definition: SmartStereoProjectionFactorPP.h:43
KeyVector world_P_body_keys_
The keys corresponding to the pose of the body (with respect to an external world frame) for each vie...
Definition: SmartStereoProjectionFactorPP.h:50