36template <
class CAMERA>
37class CameraSet :
public std::vector<CAMERA, Eigen::aligned_allocator<CAMERA>> {
39 using Base = std::vector<CAMERA, typename Eigen::aligned_allocator<CAMERA>>;
45 typedef typename CAMERA::Measurement
Z;
46 typedef typename CAMERA::MeasurementVector ZVector;
52 static Vector
ErrorVector(
const ZVector& predicted,
const ZVector& measured) {
54 size_t m = predicted.size();
55 if (measured.size() != m)
56 throw std::runtime_error(
"CameraSet::errors: size mismatch");
60 for (
size_t i = 0, row = 0; i < m; i++, row +=
ZDim) {
62 if (
ZDim == 3 && std::isnan(bi(1))) {
66 b.segment<
ZDim>(row) = bi;
78 using MatrixZD = Eigen::Matrix<double, ZDim, D>;
79 using FBlocks = std::vector<MatrixZD, Eigen::aligned_allocator<MatrixZD>>;
86 virtual void print(
const std::string& s =
"")
const {
87 std::cout << s <<
"CameraSet, cameras = \n";
88 for (
size_t k = 0; k < this->size(); ++k) this->at(k).print(s);
93 if (this->size() != p.size())
return false;
94 bool camerasAreEqual =
true;
95 for (
size_t i = 0; i < this->size(); i++) {
96 if (this->at(i).
equals(p.at(i), tol) ==
false) camerasAreEqual =
false;
99 return camerasAreEqual;
108 template <
class POINT>
110 FBlocks* Fs =
nullptr,
111 Matrix* E =
nullptr)
const {
112 static const int N = FixedDimension<POINT>::value;
115 size_t m = this->size();
120 if (E) E->resize(
ZDim * m, N);
121 if (Fs) Fs->resize(m);
124 for (
size_t i = 0; i < m; i++) {
126 Eigen::Matrix<double, ZDim, N> Ei;
127 z.emplace_back(this->at(i).
project2(point, Fs ? &Fi : 0, E ? &Ei : 0));
128 if (Fs) (*Fs)[i] = Fi;
129 if (E) E->block<
ZDim, N>(
ZDim * i, 0) = Ei;
141 template <
class POINT,
class... OptArgs>
142 typename std::enable_if<(
sizeof...(OptArgs) != 0), ZVector>::type
project2(
143 const POINT& point, OptArgs&... args)
const {
149 template <
class POINT>
151 FBlocks* Fs =
nullptr,
152 Matrix* E =
nullptr)
const {
160 template <
class POINT,
class... OptArgs,
typename = std::enable_if_t<
sizeof...(OptArgs)!=0>>
162 OptArgs&... args)
const {
177 Eigen::Matrix<double, ZDim, ND>,
178 Eigen::aligned_allocator<Eigen::Matrix<double, ZDim, ND>>>& Fs,
179 const Matrix& E,
const Eigen::Matrix<double, N, N>& P,
const Vector& b) {
181 size_t m = Fs.size();
185 size_t M1 = ND * m + 1;
186 std::vector<DenseIndex> dims(m + 1);
187 std::fill(dims.begin(), dims.end() - 1, ND);
192 for (
size_t i = 0; i < m; i++) {
194 const Eigen::Matrix<double, ZDim, ND>& Fi = Fs[i];
195 const auto FiT = Fi.transpose();
196 const Eigen::Matrix<double, ZDim, N> Ei_P =
212 FiT * (Fi - Ei_P * E.block(
ZDim * i, 0,
ZDim, N).transpose() * Fi));
215 for (
size_t j = i + 1; j < m; j++) {
216 const Eigen::Matrix<double, ZDim, ND>& Fj = Fs[j];
221 -FiT * (Ei_P * E.block(
ZDim * j, 0,
ZDim, N).transpose() * Fj));
226 return augmentedHessian;
242 template <
int N,
int ND,
int NDD>
245 Eigen::Matrix<double, ZDim, ND>,
246 Eigen::aligned_allocator<Eigen::Matrix<double, ZDim, ND>>>& Fs,
247 const Matrix& E,
const Eigen::Matrix<double, N, N>& P,
const Vector& b,
249 size_t nrNonuniqueKeys = jacobianKeys.size();
250 size_t nrUniqueKeys = hessianKeys.size();
256 std::vector<DenseIndex> dims(nrUniqueKeys + 1);
257 std::fill(dims.begin(), dims.end() - 1, NDD);
262 if (nrUniqueKeys == nrNonuniqueKeys) {
269 std::vector<DenseIndex> nonuniqueDims(nrNonuniqueKeys + 1);
270 std::fill(nonuniqueDims.begin(), nonuniqueDims.end() - 1, NDD);
271 nonuniqueDims.back() = 1;
277 std::map<Key, size_t> keyToSlotMap;
278 for (
size_t k = 0; k < nrUniqueKeys; k++) {
279 keyToSlotMap[hessianKeys[k]] = k;
284 dims, Matrix::Zero(NDD * nrUniqueKeys + 1, NDD * nrUniqueKeys + 1));
289 for (
size_t i = 0; i < nrNonuniqueKeys; i++) {
290 Key key_i = jacobianKeys.at(i);
294 keyToSlotMap[key_i], nrUniqueKeys,
298 for (
size_t j = i; j < nrNonuniqueKeys; j++) {
299 Key key_j = jacobianKeys.at(j);
304 if (keyToSlotMap[key_i] != keyToSlotMap[key_j]) {
306 keyToSlotMap[key_i], keyToSlotMap[key_j],
320 nrUniqueKeys, augmentedHessian.
diagonalBlock(nrNonuniqueKeys));
322 return augmentedHessianUniqueKeys;
335 const FBlocks& Fs,
const Matrix& E,
const Eigen::Matrix<double, N, N>& P,
345 const Matrix& E,
double lambda,
346 bool diagonalDamping =
false) {
347 Matrix EtE = E.transpose() * E;
349 if (diagonalDamping) {
350 EtE.diagonal() += lambda * EtE.diagonal();
353 EtE += lambda * Eigen::MatrixXd::Identity(n, n);
360 static Matrix
PointCov(
const Matrix& E,
const double lambda = 0.0,
361 bool diagonalDamping =
false) {
378 const Matrix& E,
const Vector& b,
379 const double lambda = 0.0,
380 bool diagonalDamping =
false) {
399 const FBlocks& Fs,
const Matrix& E,
const Eigen::Matrix<double, N, N>& P,
402 assert(keys.size() == Fs.size());
403 assert(keys.size() <= allKeys.size());
406 for (
size_t slot = 0; slot < allKeys.size(); slot++)
407 KeySlotMap.emplace(allKeys[slot], slot);
414 size_t m = Fs.size();
415 size_t M = (augmentedHessian.
rows() - 1) /
D;
416 assert(allKeys.size() == M);
419 for (
size_t i = 0; i < m; i++) {
422 const auto FiT = Fi.transpose();
423 const Eigen::Matrix<double, 2, N> Ei_P =
424 E.template block<ZDim, N>(
ZDim * i, 0) * P;
451 Ei_P * E.template block<ZDim, N>(
ZDim * i, 0).transpose() * Fi)))
455 for (
size_t j = i + 1; j < m; j++) {
466 -FiT * (Ei_P * E.template block<ZDim, N>(
ZDim * j, 0).transpose() *
475#if GTSAM_ENABLE_BOOST_SERIALIZATION
477 friend class boost::serialization::access;
478 template <
class ARCHIVE>
479 void serialize(ARCHIVE& ar,
const unsigned int ) {
485template <
class CAMERA>
488template <
class CAMERA>
491template <
class CAMERA>
494template <
class CAMERA>
A thin wrapper around std::map that uses boost's fast_pool_allocator.
Access to matrices via blocks of pre-defined sizes.
Concept check for values that can be used in unit tests.
Calibrated camera for which only pose is unknown.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition types.h:49
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
FastMap is a thin wrapper around std::map that uses the boost fast_pool_allocator instead of the defa...
Definition FastMap.h:40
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
This class stores a dense matrix and allows it to be accessed as a collection of blocks.
Definition SymmetricBlockMatrix.h:80
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block.
Definition SymmetricBlockMatrix.h:251
void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Set an off-diagonal block.
Definition SymmetricBlockMatrix.h:259
constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const
Get block above the diagonal (I, J).
Definition SymmetricBlockMatrix.h:205
DenseIndex rows() const
Row size.
Definition SymmetricBlockMatrix.h:153
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Update an off diagonal block.
Definition SymmetricBlockMatrix.h:325
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
Definition SymmetricBlockMatrix.h:191
void updateDiagonalBlock(DenseIndex I, const XprType &xpr)
Increment the diagonal block by the values in xpr.
Definition SymmetricBlockMatrix.h:271
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView(DenseIndex I, DenseIndex J) const
Return the square sub-matrix that contains blocks(i:j, i:j).
Definition SymmetricBlockMatrix.h:211
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152
A set of cameras, all with their own calibration.
Definition CameraSet.h:37
ZVector project2(const POINT &point, FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Project a point (possibly Unit3 at infinity), with derivatives Note that F is a sparse block-diagonal...
Definition CameraSet.h:109
virtual void print(const std::string &s="") const
print
Definition CameraSet.h:86
static void ComputePointCovariance(Eigen::Matrix< double, N, N > &P, const Matrix &E, double lambda, bool diagonalDamping=false)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix G = F' * F - F' * E * P * ...
Definition CameraSet.h:344
std::enable_if<(sizeof...(OptArgs)!=0), ZVector >::type project2(const POINT &point, OptArgs &... args) const
An overload of the project2 function to accept full matrices and vectors and pass it to the pointer v...
Definition CameraSet.h:142
static SymmetricBlockMatrix SchurComplement(const FBlocks &Fblocks, const Matrix &E, const Vector &b, const double lambda=0.0, bool diagonalDamping=false)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix Dynamic version.
Definition CameraSet.h:377
CAMERA::Measurement Z
2D measurement and noise model for each of the m views The order is kept the same as the keys that we...
Definition CameraSet.h:45
virtual ~CameraSet()=default
Destructor.
Vector reprojectionError(const POINT &point, const ZVector &measured, FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Calculate vector [project2(point)-z] of re-projection errors.
Definition CameraSet.h:150
bool equals(const CameraSet &p, double tol=1e-9) const
equals
Definition CameraSet.h:92
static Matrix PointCov(const Matrix &E, const double lambda=0.0, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter, dynamic version.
Definition CameraSet.h:360
static Vector ErrorVector(const ZVector &predicted, const ZVector &measured)
Make a vector of re-projection errors.
Definition CameraSet.h:52
static void UpdateSchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const KeyVector &allKeys, const KeyVector &keys, SymmetricBlockMatrix &augmentedHessian)
Applies Schur complement (exploiting block structure) to get a smart factor on cameras,...
Definition CameraSet.h:398
static SymmetricBlockMatrix SchurComplementAndRearrangeBlocks(const std::vector< Eigen::Matrix< double, ZDim, ND >, Eigen::aligned_allocator< Eigen::Matrix< double, ZDim, ND > > > &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const KeyVector &jacobianKeys, const KeyVector &hessianKeys)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix G = F' * F - F' * E * P * ...
Definition CameraSet.h:243
static SymmetricBlockMatrix SchurComplement(const std::vector< Eigen::Matrix< double, ZDim, ND >, Eigen::aligned_allocator< Eigen::Matrix< double, ZDim, ND > > > &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix G = F' * F - F' * E * P * ...
Definition CameraSet.h:175
static const int ZDim
Definition CameraSet.h:49
static const int D
Definition CameraSet.h:48
Eigen::Matrix< double, ZDim, D > MatrixZD
Definitions for blocks of F.
Definition CameraSet.h:78
Vector reprojectionError(const POINT &point, const ZVector &measured, OptArgs &... args) const
An overload o the reprojectionError function to accept full matrices and vectors and pass it to the p...
Definition CameraSet.h:161