2019-04-17 11:46:08 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
* GTSAM Copyright 2010-2019, 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
|
|
|
|
|
|
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @file SOn.h
|
2019-11-29 09:35:46 +08:00
|
|
|
* @brief N*N matrix representation of SO(N). N can be Eigen::Dynamic
|
2019-04-17 11:46:08 +08:00
|
|
|
* @author Frank Dellaert
|
|
|
|
|
* @date March 2019
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
#include <gtsam/base/Lie.h>
|
2019-04-17 11:46:08 +08:00
|
|
|
#include <gtsam/base/Manifold.h>
|
2020-06-21 10:21:17 +08:00
|
|
|
#include <gtsam/base/make_shared.h>
|
2019-12-28 06:57:32 +08:00
|
|
|
#include <gtsam/dllexport.h>
|
2019-04-17 11:46:08 +08:00
|
|
|
#include <Eigen/Core>
|
|
|
|
|
|
2022-02-17 04:08:28 +08:00
|
|
|
#include <boost/serialization/nvp.hpp>
|
|
|
|
|
|
2020-05-28 17:25:33 +08:00
|
|
|
#include <iostream> // TODO(frank): how to avoid?
|
2019-05-06 23:07:09 +08:00
|
|
|
#include <string>
|
2019-06-16 04:03:47 +08:00
|
|
|
#include <type_traits>
|
2019-05-07 07:13:26 +08:00
|
|
|
#include <vector>
|
2020-05-28 17:25:33 +08:00
|
|
|
#include <random>
|
2019-04-17 11:46:08 +08:00
|
|
|
|
|
|
|
|
namespace gtsam {
|
2019-05-06 23:07:09 +08:00
|
|
|
|
2019-04-17 11:46:08 +08:00
|
|
|
namespace internal {
|
2019-05-06 23:07:09 +08:00
|
|
|
/// Calculate dimensionality of SO<N> manifold, or return Dynamic if so
|
|
|
|
|
constexpr int DimensionSO(int N) {
|
|
|
|
|
return (N < 0) ? Eigen::Dynamic : N * (N - 1) / 2;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-17 11:46:08 +08:00
|
|
|
// Calculate N^2 at compile time, or return Dynamic if so
|
2019-05-06 23:07:09 +08:00
|
|
|
constexpr int NSquaredSO(int N) { return (N < 0) ? Eigen::Dynamic : N * N; }
|
2019-04-17 11:46:08 +08:00
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
|
|
/**
|
2019-05-06 23:07:09 +08:00
|
|
|
* Manifold of special orthogonal rotation matrices SO<N>.
|
2019-11-29 09:35:46 +08:00
|
|
|
* Template paramater N can be a fixed integer or can be Eigen::Dynamic
|
2019-04-17 11:46:08 +08:00
|
|
|
*/
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N>
|
|
|
|
|
class SO : public LieGroup<SO<N>, internal::DimensionSO(N)> {
|
2019-04-17 11:46:08 +08:00
|
|
|
public:
|
2019-05-06 23:07:09 +08:00
|
|
|
enum { dimension = internal::DimensionSO(N) };
|
|
|
|
|
using MatrixNN = Eigen::Matrix<double, N, N>;
|
|
|
|
|
using VectorN2 = Eigen::Matrix<double, internal::NSquaredSO(N), 1>;
|
|
|
|
|
using MatrixDD = Eigen::Matrix<double, dimension, dimension>;
|
|
|
|
|
|
2020-06-25 05:15:00 +08:00
|
|
|
GTSAM_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
|
2019-11-19 00:27:08 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
protected:
|
|
|
|
|
MatrixNN matrix_; ///< Rotation matrix
|
|
|
|
|
|
|
|
|
|
// enable_if_t aliases, used to specialize constructors/methods, see
|
|
|
|
|
// https://www.fluentcpp.com/2018/05/18/make-sfinae-pretty-2-hidden-beauty-sfinae/
|
|
|
|
|
template <int N_>
|
2019-06-16 04:03:47 +08:00
|
|
|
using IsDynamic = typename std::enable_if<N_ == Eigen::Dynamic, void>::type;
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N_>
|
2019-06-16 04:03:47 +08:00
|
|
|
using IsFixed = typename std::enable_if<N_ >= 2, void>::type;
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N_>
|
2019-06-16 04:03:47 +08:00
|
|
|
using IsSO3 = typename std::enable_if<N_ == 3, void>::type;
|
2019-04-17 11:46:08 +08:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/// @name Constructors
|
|
|
|
|
/// @{
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/// Construct SO<N> identity for N >= 2
|
|
|
|
|
template <int N_ = N, typename = IsFixed<N_>>
|
|
|
|
|
SO() : matrix_(MatrixNN::Identity()) {}
|
2019-04-21 04:49:20 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/// Construct SO<N> identity for N == Eigen::Dynamic
|
|
|
|
|
template <int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
explicit SO(size_t n = 0) {
|
2019-05-15 08:43:44 +08:00
|
|
|
// We allow for n=0 as the default constructor, needed for serialization,
|
|
|
|
|
// wrappers etc.
|
2019-05-06 23:07:09 +08:00
|
|
|
matrix_ = Eigen::MatrixXd::Identity(n, n);
|
2019-04-17 11:46:08 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-15 08:43:44 +08:00
|
|
|
/// Constructor from Eigen Matrix, dynamic version
|
2019-05-06 23:07:09 +08:00
|
|
|
template <typename Derived>
|
|
|
|
|
explicit SO(const Eigen::MatrixBase<Derived>& R) : matrix_(R.eval()) {}
|
|
|
|
|
|
2019-05-15 08:43:44 +08:00
|
|
|
/// Named constructor from Eigen Matrix
|
|
|
|
|
template <typename Derived>
|
|
|
|
|
static SO FromMatrix(const Eigen::MatrixBase<Derived>& R) {
|
|
|
|
|
return SO(R);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-28 17:25:33 +08:00
|
|
|
/// Named constructor from lower dimensional matrix
|
|
|
|
|
template <typename Derived, int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
static SO Lift(size_t n, const Eigen::MatrixBase<Derived> &R) {
|
|
|
|
|
Matrix Q = Matrix::Identity(n, n);
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
const int p = R.rows();
|
|
|
|
|
assert(p >= 0 && p <= static_cast<int>(n) && R.cols() == p);
|
2020-05-28 17:25:33 +08:00
|
|
|
Q.topLeftCorner(p, p) = R;
|
|
|
|
|
return SO(Q);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-07 06:45:16 +08:00
|
|
|
/// Construct dynamic SO(n) from Fixed SO<M>
|
|
|
|
|
template <int M, int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
explicit SO(const SO<M>& R) : matrix_(R.matrix()) {}
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/// Constructor from AngleAxisd
|
|
|
|
|
template <int N_ = N, typename = IsSO3<N_>>
|
2019-11-29 09:35:46 +08:00
|
|
|
explicit SO(const Eigen::AngleAxisd& angleAxis) : matrix_(angleAxis) {}
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-07 07:13:26 +08:00
|
|
|
/// Constructor from axis and angle. Only defined for SO3
|
|
|
|
|
static SO AxisAngle(const Vector3& axis, double theta);
|
|
|
|
|
|
|
|
|
|
/// Named constructor that finds SO(n) matrix closest to M in Frobenius norm,
|
|
|
|
|
/// currently only defined for SO3.
|
|
|
|
|
static SO ClosestTo(const MatrixNN& M);
|
|
|
|
|
|
2022-07-27 04:00:33 +08:00
|
|
|
/// Named constructor that finds chordal mean
|
|
|
|
|
/// \f$ mu = argmin_R \sum sqr(|R-R_i|_F) \f$,
|
2019-05-07 07:13:26 +08:00
|
|
|
/// currently only defined for SO3.
|
|
|
|
|
static SO ChordalMean(const std::vector<SO>& rotations);
|
|
|
|
|
|
2019-06-16 05:52:33 +08:00
|
|
|
/// Random SO(n) element (no big claims about uniformity). SO(3) is specialized in SO3.cpp
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N_ = N, typename = IsDynamic<N_>>
|
2019-06-16 05:52:33 +08:00
|
|
|
static SO Random(std::mt19937& rng, size_t n = 0) {
|
2019-05-06 23:07:09 +08:00
|
|
|
if (n == 0) throw std::runtime_error("SO: Dimensionality not known.");
|
2019-06-16 05:52:33 +08:00
|
|
|
// TODO(frank): this might need to be re-thought
|
|
|
|
|
static std::uniform_real_distribution<double> randomAngle(-M_PI, M_PI);
|
2019-05-06 23:07:09 +08:00
|
|
|
const size_t d = SO::Dimension(n);
|
2019-04-17 11:46:08 +08:00
|
|
|
Vector xi(d);
|
|
|
|
|
for (size_t j = 0; j < d; j++) {
|
|
|
|
|
xi(j) = randomAngle(rng);
|
|
|
|
|
}
|
2019-05-06 23:07:09 +08:00
|
|
|
return SO::Retract(xi);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Random SO(N) element (no big claims about uniformity)
|
|
|
|
|
template <int N_ = N, typename = IsFixed<N_>>
|
2019-06-16 05:52:33 +08:00
|
|
|
static SO Random(std::mt19937& rng) {
|
2019-05-06 23:07:09 +08:00
|
|
|
// By default, use dynamic implementation above. Specialized for SO(3).
|
|
|
|
|
return SO(SO<Eigen::Dynamic>::Random(rng, N).matrix());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
/// @name Standard methods
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
|
|
/// Return matrix
|
|
|
|
|
const MatrixNN& matrix() const { return matrix_; }
|
|
|
|
|
|
|
|
|
|
size_t rows() const { return matrix_.rows(); }
|
|
|
|
|
size_t cols() const { return matrix_.cols(); }
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
/// @name Testable
|
|
|
|
|
/// @{
|
|
|
|
|
|
2020-03-18 03:20:54 +08:00
|
|
|
void print(const std::string& s = std::string()) const;
|
2019-05-06 23:07:09 +08:00
|
|
|
|
|
|
|
|
bool equals(const SO& other, double tol) const {
|
|
|
|
|
return equal_with_abs_tol(matrix_, other.matrix_, tol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
/// @name Group
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
|
|
/// Multiplication
|
2019-05-09 06:41:53 +08:00
|
|
|
SO operator*(const SO& other) const {
|
|
|
|
|
assert(dim() == other.dim());
|
|
|
|
|
return SO(matrix_ * other.matrix_);
|
|
|
|
|
}
|
2019-05-06 23:07:09 +08:00
|
|
|
|
|
|
|
|
/// SO<N> identity for N >= 2
|
|
|
|
|
template <int N_ = N, typename = IsFixed<N_>>
|
|
|
|
|
static SO identity() {
|
|
|
|
|
return SO();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// SO<N> identity for N == Eigen::Dynamic
|
|
|
|
|
template <int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
static SO identity(size_t n = 0) {
|
|
|
|
|
return SO(n);
|
2019-04-17 11:46:08 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/// inverse of a rotation = transpose
|
|
|
|
|
SO inverse() const { return SO(matrix_.transpose()); }
|
|
|
|
|
|
2019-04-17 11:46:08 +08:00
|
|
|
/// @}
|
|
|
|
|
/// @name Manifold
|
|
|
|
|
/// @{
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
using TangentVector = Eigen::Matrix<double, dimension, 1>;
|
|
|
|
|
using ChartJacobian = OptionalJacobian<dimension, dimension>;
|
|
|
|
|
|
|
|
|
|
/// Return compile-time dimensionality: fixed size N or Eigen::Dynamic
|
|
|
|
|
static int Dim() { return dimension; }
|
|
|
|
|
|
|
|
|
|
// Calculate manifold dimensionality for SO(n).
|
|
|
|
|
// Available as dimension or Dim() for fixed N.
|
|
|
|
|
static size_t Dimension(size_t n) { return n * (n - 1) / 2; }
|
|
|
|
|
|
|
|
|
|
// Calculate ambient dimension n from manifold dimensionality d.
|
|
|
|
|
static size_t AmbientDim(size_t d) { return (1 + std::sqrt(1 + 8 * d)) / 2; }
|
|
|
|
|
|
|
|
|
|
// Calculate run-time dimensionality of manifold.
|
|
|
|
|
// Available as dimension or Dim() for fixed N.
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
size_t dim() const { return Dimension(static_cast<size_t>(matrix_.rows())); }
|
2019-05-06 23:07:09 +08:00
|
|
|
|
2019-04-17 11:46:08 +08:00
|
|
|
/**
|
|
|
|
|
* Hat operator creates Lie algebra element corresponding to d-vector, where d
|
|
|
|
|
* is the dimensionality of the manifold. This function is implemented
|
|
|
|
|
* recursively, and the d-vector is assumed to laid out such that the last
|
2019-04-30 20:47:34 +08:00
|
|
|
* element corresponds to so(2), the last 3 to so(3), the last 6 to so(4)
|
2019-04-17 11:46:08 +08:00
|
|
|
* etc... For example, the vector-space isomorphic to so(5) is laid out as:
|
|
|
|
|
* a b c d | u v w | x y | z
|
|
|
|
|
* where the latter elements correspond to "telescoping" sub-algebras:
|
2020-05-28 17:25:33 +08:00
|
|
|
* 0 -z y w -d
|
|
|
|
|
* z 0 -x -v c
|
|
|
|
|
* -y x 0 u -b
|
|
|
|
|
* -w v -u 0 a
|
|
|
|
|
* d -c b -a 0
|
2019-04-17 11:46:08 +08:00
|
|
|
* This scheme behaves exactly as expected for SO(2) and SO(3).
|
|
|
|
|
*/
|
2019-05-07 06:45:16 +08:00
|
|
|
static MatrixNN Hat(const TangentVector& xi);
|
2019-04-17 11:46:08 +08:00
|
|
|
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
/// In-place version of Hat (see details there), implements recursion.
|
|
|
|
|
static void Hat(const Vector &xi, Eigen::Ref<MatrixNN> X);
|
|
|
|
|
|
|
|
|
|
/// Inverse of Hat. See note about xi element order in Hat.
|
2019-05-07 06:45:16 +08:00
|
|
|
static TangentVector Vee(const MatrixNN& X);
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
// Chart at origin
|
|
|
|
|
struct ChartAtOrigin {
|
|
|
|
|
/**
|
|
|
|
|
* Retract uses Cayley map. See note about xi element order in Hat.
|
|
|
|
|
* Deafault implementation has no Jacobian implemented
|
|
|
|
|
*/
|
2019-05-07 03:37:04 +08:00
|
|
|
static SO Retract(const TangentVector& xi, ChartJacobian H = boost::none);
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/**
|
|
|
|
|
* Inverse of Retract. See note about xi element order in Hat.
|
|
|
|
|
*/
|
2019-05-07 03:37:04 +08:00
|
|
|
static TangentVector Local(const SO& R, ChartJacobian H = boost::none);
|
2019-05-06 23:07:09 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Return dynamic identity DxD Jacobian for given SO(n)
|
|
|
|
|
template <int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
static MatrixDD IdentityJacobian(size_t n) {
|
|
|
|
|
const size_t d = Dimension(n);
|
|
|
|
|
return MatrixDD::Identity(d, d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
/// @name Lie Group
|
|
|
|
|
/// @{
|
|
|
|
|
|
2019-05-07 04:37:34 +08:00
|
|
|
/// Adjoint map
|
|
|
|
|
MatrixDD AdjointMap() const;
|
2019-05-06 23:07:09 +08:00
|
|
|
|
2019-04-17 11:46:08 +08:00
|
|
|
/**
|
2019-05-06 23:07:09 +08:00
|
|
|
* Exponential map at identity - create a rotation from canonical coordinates
|
2019-04-17 11:46:08 +08:00
|
|
|
*/
|
2019-05-07 04:37:34 +08:00
|
|
|
static SO Expmap(const TangentVector& omega, ChartJacobian H = boost::none);
|
|
|
|
|
|
|
|
|
|
/// Derivative of Expmap, currently only defined for SO3
|
|
|
|
|
static MatrixDD ExpmapDerivative(const TangentVector& omega);
|
2019-04-17 11:46:08 +08:00
|
|
|
|
|
|
|
|
/**
|
2019-05-06 23:07:09 +08:00
|
|
|
* Log map at identity - returns the canonical coordinates of this rotation
|
2019-04-17 11:46:08 +08:00
|
|
|
*/
|
2019-05-07 04:37:34 +08:00
|
|
|
static TangentVector Logmap(const SO& R, ChartJacobian H = boost::none);
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-07 04:37:34 +08:00
|
|
|
/// Derivative of Logmap, currently only defined for SO3
|
|
|
|
|
static MatrixDD LogmapDerivative(const TangentVector& omega);
|
2019-05-07 03:37:04 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
// inverse with optional derivative
|
|
|
|
|
using LieGroup<SO<N>, internal::DimensionSO(N)>::inverse;
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-04-21 04:49:20 +08:00
|
|
|
/// @}
|
|
|
|
|
/// @name Other methods
|
|
|
|
|
/// @{
|
|
|
|
|
|
2019-04-30 20:47:34 +08:00
|
|
|
/**
|
|
|
|
|
* Return vectorized rotation matrix in column order.
|
|
|
|
|
* Will use dynamic matrices as intermediate results, but returns a fixed size
|
|
|
|
|
* X and fixed-size Jacobian if dimension is known at compile time.
|
|
|
|
|
* */
|
2019-05-06 23:07:09 +08:00
|
|
|
VectorN2 vec(OptionalJacobian<internal::NSquaredSO(N), dimension> H =
|
2019-05-07 03:37:04 +08:00
|
|
|
boost::none) const;
|
2020-08-02 03:41:19 +08:00
|
|
|
|
|
|
|
|
/// Calculate N^2 x dim matrix of vectorized Lie algebra generators for SO(N)
|
|
|
|
|
template <int N_ = N, typename = IsFixed<N_>>
|
|
|
|
|
static Matrix VectorizedGenerators() {
|
|
|
|
|
constexpr size_t N2 = static_cast<size_t>(N * N);
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
Eigen::Matrix<double, N2, dimension> G;
|
2020-08-02 03:41:19 +08:00
|
|
|
for (size_t j = 0; j < dimension; j++) {
|
|
|
|
|
const auto X = Hat(Vector::Unit(dimension, j));
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
G.col(j) = Eigen::Map<const VectorN2>(X.data());
|
2020-08-02 03:41:19 +08:00
|
|
|
}
|
|
|
|
|
return G;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Calculate n^2 x dim matrix of vectorized Lie algebra generators for SO(n)
|
|
|
|
|
template <int N_ = N, typename = IsDynamic<N_>>
|
|
|
|
|
static Matrix VectorizedGenerators(size_t n = 0) {
|
|
|
|
|
const size_t n2 = n * n, dim = Dimension(n);
|
|
|
|
|
Matrix G(n2, dim);
|
|
|
|
|
for (size_t j = 0; j < dim; j++) {
|
|
|
|
|
const auto X = Hat(Vector::Unit(dim, j));
|
|
|
|
|
G.col(j) = Eigen::Map<const Matrix>(X.data(), n2, 1);
|
|
|
|
|
}
|
|
|
|
|
return G;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @{
|
|
|
|
|
/// @name Serialization
|
|
|
|
|
/// @{
|
2019-05-07 07:27:06 +08:00
|
|
|
|
2020-07-08 17:30:19 +08:00
|
|
|
template <class Archive>
|
|
|
|
|
friend void save(Archive&, SO&, const unsigned int);
|
|
|
|
|
template <class Archive>
|
|
|
|
|
friend void load(Archive&, SO&, const unsigned int);
|
2019-05-07 07:27:06 +08:00
|
|
|
template <class Archive>
|
2019-05-07 22:48:55 +08:00
|
|
|
friend void serialize(Archive&, SO&, const unsigned int);
|
2019-05-07 07:27:06 +08:00
|
|
|
friend class boost::serialization::access;
|
2019-05-07 22:48:55 +08:00
|
|
|
friend class Rot3; // for serialize
|
2020-08-02 03:41:19 +08:00
|
|
|
|
|
|
|
|
/// @}
|
2019-04-17 11:46:08 +08:00
|
|
|
};
|
|
|
|
|
|
2019-05-07 03:37:04 +08:00
|
|
|
using SOn = SO<Eigen::Dynamic>;
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/*
|
2019-05-07 06:45:16 +08:00
|
|
|
* Specialize dynamic Hat and Vee, because recursion depends on dynamic nature.
|
|
|
|
|
* The definition is in SOn.cpp. Fixed-size SO3 and SO4 have their own version,
|
|
|
|
|
* and implementation for other fixed N is in SOn-inl.h.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
template <>
|
2019-12-28 06:57:32 +08:00
|
|
|
GTSAM_EXPORT
|
2019-05-07 06:45:16 +08:00
|
|
|
Matrix SOn::Hat(const Vector& xi);
|
|
|
|
|
|
|
|
|
|
template <>
|
2019-12-28 06:57:32 +08:00
|
|
|
GTSAM_EXPORT
|
2019-05-07 06:45:16 +08:00
|
|
|
Vector SOn::Vee(const Matrix& X);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Specialize dynamic compose and between, because the derivative is unknowable
|
|
|
|
|
* by the LieGroup implementations, who return a fixed-size matrix for H2.
|
2019-05-06 23:07:09 +08:00
|
|
|
*/
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-07 03:37:04 +08:00
|
|
|
using DynamicJacobian = OptionalJacobian<Eigen::Dynamic, Eigen::Dynamic>;
|
|
|
|
|
|
|
|
|
|
template <>
|
2022-02-18 00:14:09 +08:00
|
|
|
GTSAM_EXPORT
|
2019-05-07 03:37:04 +08:00
|
|
|
SOn LieGroup<SOn, Eigen::Dynamic>::compose(const SOn& g, DynamicJacobian H1,
|
|
|
|
|
DynamicJacobian H2) const;
|
|
|
|
|
|
|
|
|
|
template <>
|
2022-02-18 00:14:09 +08:00
|
|
|
GTSAM_EXPORT
|
2019-05-07 03:37:04 +08:00
|
|
|
SOn LieGroup<SOn, Eigen::Dynamic>::between(const SOn& g, DynamicJacobian H1,
|
|
|
|
|
DynamicJacobian H2) const;
|
2019-04-17 11:46:08 +08:00
|
|
|
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
/*
|
|
|
|
|
* Specialize dynamic vec.
|
|
|
|
|
*/
|
2022-02-18 00:14:09 +08:00
|
|
|
template <>
|
|
|
|
|
GTSAM_EXPORT
|
|
|
|
|
typename SOn::VectorN2 SOn::vec(DynamicJacobian H) const;
|
Feature/shonan averaging (#473)
Shonan Rotation Averaging.
199 commit messages below, many are obsolete as design has changed quite a bit over time, especially from the earlier period where I thought we only needed SO(4).
* prototyping weighted sampler
* Moved WeightedSampler into its own header
* Random now uses std header <random>.
* Removed boost/random usage from linear and discrete directories
* Made into class
* Now using new WeightedSampler class
* Inlined random direction generation
* eradicated last vestiges of boost/random in gtsam_unstable
* Added 3D example g2o file
* Added Frobenius norm factors
* Shonan averaging algorithm, using SOn class
* Wrapping Frobenius and Shonan
* Fixed issues with <<
* Use Builder parameters
* Refactored Shonan interface
* Fixed << issues as well as MATLAB segfault, using eval(), as discussed in issue #451
* ShonanAveragingParameters
* New factor FrobeniusWormholeFactorP computes |Rj*P - Ri*P*Rij|
* Fixed broken GetDimension for Lie groups with variable dimension.
* Removed all but Shonan averaging factor and made everything work with new SOn
* Just a single WormholeFactor, wrapped noise model
* Use std <random>
* comments/todos
* added timing script
* add script to process ShonanAveraging timing results
* Now producing a CSV file
* Parse csv file and make combined plot
* Fixed range
* change p value and set two flags on
* input file path, all the csv files proceeses at the same time
* add check convergence rate part
* csv file have name according to input data name
* correct one mistake in initialization
* generate the convergence rate for each p value
* add yticks for the bar plot
* add noises to the measurements
* test add noise
* Basic structure for checkOptimalityAt
* change optimizer method to cholesky
* buildQ now working. Tests should be better but visually inspected.
* multiple test with cholesky
* back
* computeLambda now works
* make combined plots while make bar plot
* Calculate minimum eigenvalue - the very expensive version
* Exposed computeMinEigenValue
* make plots and bar togenter
* method change to jacobi
* add time for check optimality, min_eigen_value, sub_bound
* updated plot min_eigen value and subounds
* Adding Spectra headers
* David's min eigenvalue code inserted and made to compile.
* Made it work
* Made "run" method work.
* add rim.g2o name
* Fixed bug in shifting eigenvalues
* roundSolution which replaces projectFrom
* removed extra arguments
* Added to wrapper
* Add SOn to template lists
* roundSolution delete the extra arguement p
* only calculate p=5 and change to the correct way computing f_R
* Fixed conflict and made Google-style name changes
* prototype descent code and unit test for initializeWithDescent
* add averaging cost/time part in processing data
* initializewithDescent success in test
* Formatting and find example rather than hardcode
* Removed accidentally checked in cmake files
* give value to xi by block
* correct gradient descent
* correct xi
* }
* Fix wrapper
* Make Hat/Vee have alternating signs
* MakeATangentVector helpder function
* Fixed cmake files
* changed sign
* add line search
* unit test for line search
* test real data with line search
* correct comment
* Fix boost::uniform_real
* add save .dat file
* correct test case
* add explanation
* delete redundant cout
* add name to .dat output file
* correct checkR
* add get poses_ in shonan
* add Vector Point type for savig data
* Remove cmake file which magically re-appeared??
* Switched to std random library.
* Prepare Klaus test
* Add klaus3.g2o data.
* fix comment
* Fix derivatives
* Fixed broken GetDimension for Lie groups with variable dimension.
* Fix SOn tests to report correct dimension
* Added tests for Klaus3 data
* Add runWithRandomKlaus test for shonan.
* Finish runWithRandomKlaus unittest.
* Correct datafile.
* Correct the format.
* Added measured and keys methods
* Shonan works on Klaus data
* Create dense versions for wrappers, for testing
* Now store D, Q, and L
* Remove another cmake file incorrectly checked in.
* Found and fixed the bug in ComputeLambda !
* Now using Q in Lambdas calculation, so Lambdas agree with Eriksson18cvpr.
* Make FrobeniusFactor not use deprecated methods
* FrobeniusWormholeFactor takes Rot3 as argument
* Wrapped some more methods.
* Wrapped more methods
* Allow creating and populating BetweenFactorPose3s in python
* New constructors for ShonanAveraging
* add function of get measurements number
* Remove option not to use noise model
* wrap Use nrMeasurements
* Made Logmap a bit more tolerant of slightly degenerate rotations (with trace < -1)
* Allow for Anchor index
* Fix anchor bug
* Change outside view to Rot3 rather than SO3
* Add Lift in SOn class
* Make comet working
* Small fixes
* Delete extra function
* Add SOn::Lift
* Removed hardcoded flag
* Moved Frobenius factor to gtsam from unstable
* Added new tests and made an old regression pass again
* Cleaned up formatting and some comments, added EXPORT directives
* Throw exception if wrongly dimensioned values are given
* static_cast and other throw
* Fixed run-time dimension
* Added gauge-constraining factor
* LM parameters now passed in, added Gauge fixing
* 2D test scaffold
* Comments
* Pre-allocated generators
* Document API
* Add optional weight
* New prior weeights infrastructure
* Made d a template parameter
* Recursive Hat and RetractJacobian test
* Added Spectra 0.9.0 to 3rdparty
* Enabling 2D averaging
* Templatized Wormhole factor
* ignore xcode folder
* Fixed vec and VectorizedGenerators templates for fixed N!=3 or 4
* Simplifying constructors
Moved file loading to tests (for now)
All unit tests pass for d==3!
* Templated some methods internally
* Very generic parseToVector
* refactored load2d
* Very much improved FrobeniusWormholeFactor (Shonan) Jacobians
* SO(2) averaging works !
* Templated parse methods
* Switched to new Dataset paradigm
* Moved Shonan to gtsam
* Checked noise model is correctly gotten from file
* Fixed covariance bug
* Making Shonan wrapper work
* Renamed FrobeniusWormholeFactor to ShonanFactor and moved into its own compilation unit in gtsam/sfm
* Fixed wrong include
* Simplified interface (removed irrelevant random inits) and fixed eigenvector test
* Removed stray boost::none
* Added citation as suggested by Jose
* Made descent test deterministic
* Fixed some comments, commented out flaky test
Co-authored-by: Jing Wu <jingwu@gatech.edu>
Co-authored-by: jingwuOUO <wujing2951@gmail.com>
Co-authored-by: swang <swang736@gatech.edu>
Co-authored-by: ss <ss>
Co-authored-by: Fan Jiang <prof.fan@foxmail.com>
2020-08-17 19:43:10 +08:00
|
|
|
|
2020-07-08 17:30:19 +08:00
|
|
|
/** Serialization function */
|
|
|
|
|
template<class Archive>
|
|
|
|
|
void serialize(
|
|
|
|
|
Archive& ar, SOn& Q,
|
|
|
|
|
const unsigned int file_version
|
|
|
|
|
) {
|
|
|
|
|
Matrix& M = Q.matrix_;
|
2020-07-15 04:03:21 +08:00
|
|
|
ar& BOOST_SERIALIZATION_NVP(M);
|
2020-07-08 17:30:19 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
/*
|
|
|
|
|
* Define the traits. internal::LieGroup provides both Lie group and Testable
|
|
|
|
|
*/
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N>
|
|
|
|
|
struct traits<SO<N>> : public internal::LieGroup<SO<N>> {};
|
2019-04-17 11:46:08 +08:00
|
|
|
|
2019-05-06 23:07:09 +08:00
|
|
|
template <int N>
|
|
|
|
|
struct traits<const SO<N>> : public internal::LieGroup<SO<N>> {};
|
2019-04-17 11:46:08 +08:00
|
|
|
|
|
|
|
|
} // namespace gtsam
|
2019-05-07 03:37:04 +08:00
|
|
|
|
2019-05-07 04:37:34 +08:00
|
|
|
#include "SOn-inl.h"
|