8000 Update Simitary3 with Align feature by Alexma3312 · Pull Request #464 · borglab/gtsam · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Update Simitary3 with Align feature #464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
52e8db6
Merge remote-tracking branch 'origin/develop'
chrisbeall May 20, 2019
467edd0
Merge pull request #118 from borglab/release/4.0.1
varunagrawal Sep 19, 2019
7abba7c
Merge pull request #119 from borglab/release/4.0.2
dellaert Sep 19, 2019
b84c6ef
Bump version to 4.0.2
Ellon Oct 3, 2019
a28806b
Merge pull request #130 from Ellon/fix-4.0.2-version-patch
dellaert Oct 3, 2019
0760858
Install GTSAMConfigVersion.cmake
Ellon Oct 3, 2019
0aaf496
Remove obsolete cmake FindXX modules.
jlblancoc Oct 7, 2019
342f30d
Merge pull request #137 from Ellon/fix/GTSAMConfigVersion.cmake_for_4…
varunagrawal Oct 8, 2019
8425957
Finish Sim3 align and transformFrom functions.
Aug 10, 2020
e6b1599
Fix document.
Aug 10, 2020
8dd9ff5
Improve code quality.
Aug 10, 2020
7cfcbff
Update doc.
Aug 10, 2020
aa2d0f3
Change typedef into using.
Alexma3312 Aug 12, 2020
58ec261
Fix GTSAM_TYPEDEF_POINTS_TO_VECTORS.
Alexma3312 Aug 16, 2020
6f33d00
Correct variable names and refactor code.
Alexma3312 Aug 17, 2020
362c93b
Change sim3 variable from T to S.
Alexma3312 Aug 19, 2020
c80cfe0
Modify the print function print out format.
Alexma3312 Aug 20, 2020
e94aae1
Replace rotAveraging with gtsam::FindKarcherMean.
Alexma3312 Aug 21, 2020
f5611fb
Add Compatibility unittest.
Alexma3312 Aug 21, 2020
9a07a61
reformat pose3 declaration.
Alexma3312 Aug 21, 2020
e00fa56
create a helper function to remove repeat code.
Alexma3312 Aug 22, 2020
a9dd3ed
Add a comment for transformFrom pose.
Alexma3312 Aug 22, 2020
e3bf438
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Aug 22, 2020
4789cd2
Modify comments and move header file declaration.
Alexma3312 Aug 22, 2020
9fd5c66
Add mean function into Point3 class.
Alexma3312 Aug 24, 2020
9890744
Create AlignGivenR function and refactor code.
Alexma3312 Aug 24, 2020
d2209bf
Merge remote-tracking branch 'upstream/master' into sim3
Alexma3312 Aug 24, 2020
f5c0830
Change CMakelist file to fix merge conflict.
Alexma3312 Aug 24, 2020
065896d
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Aug 24, 2020
8fa7686
remove commented out code
Alexma3312 Sep 9, 2020
a1b73b3
document and use std::tie
Alexma3312 Sep 9, 2020
41921c3
Refactor mean and mean_pair test case.
Alexma3312 Sep 9, 2020
66c9a63
Fix double computation.
Alexma3312 Sep 14, 2020
470862e
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Sep 14, 2020
bf0651b
Refactor Align with short functions.
Alexma3312 Sep 20, 2020
a2e1ced
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Sep 20, 2020
463b634
Move private func to .cpp.
Alexma3312 Sep 26, 2020
ffd0d5e
Change getXY to calculateScale.
Alexma3312 Sep 26, 2020
933565c
Emphasize Rdb is a vector.
Alexma3312 Sep 26, 2020
e12d3ba
Change input into centroids.
Alexma3312 Sep 26, 2020
8236d69
Refactor code to increase speed.
Alexma3312 Sep 26, 2020
3727cc6
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Sep 26, 2020
95724be
Fix quaternions test failure.
Alexma3312 Sep 28, 2020
2f32231
Merge remote-tracking branch 'upstream/develop' into sim3
Alexma3312 Sep 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions gtsam/geometry/Point3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ double dot(const Point3 &p, const Point3 &q, OptionalJacobian<1, 3> H1,
return p.x() * q.x() + p.y() * q.y() + p.z() * q.z();
}

Point3Pair mean(const std::vector<Point3Pair> &abPointPairs) {
const size_t n = abPointPairs.size();
Point3 aCentroid(0, 0, 0), bCentroid(0, 0, 0);
for (const Point3Pair &abPair : abPointPairs) {
aCentroid += abPair.first;
bCentroid += abPair.second;
}
const double f = 1.0 / n;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw an exception if n==0?
PS: Sorry for the late comment... :-S

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jlblancoc Thanks for the catch. I will create a new PR to fix it.

aCentroid *= f;
bCentroid *= f;
return make_pair(aCentroid, bCentroid);
}

/* ************************************************************************* */
ostream &operator<<(ostream &os, const gtsam::Point3Pair &p) {
os << p.first << " <-> " << p.second;
Expand Down
12 changes: 12 additions & 0 deletions gtsam/geometry/Point3.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <gtsam/base/Vector.h>
#include <gtsam/dllexport.h>
#include <boost/serialization/nvp.hpp>
#include <numeric>

namespace gtsam {

Expand Down Expand Up @@ -58,6 +59,17 @@ GTSAM_EXPORT double dot(const Point3& p, const Point3& q,
OptionalJacobian<1, 3> H_p = boost::none,
OptionalJacobian<1, 3> H_q = boost::none);

/// mean
template <class CONTAINER>
GTSAM_EXPORT Point3 mean(const CONTAINER& points) {
Point3 sum(0, 0, 0);
sum = std::accumulate(points.begin(), points.end(), sum);
return sum / points.size();
}

/// mean of Point3 pair
GTSAM_EXPORT Point3Pair mean(const std::vector<Point3Pair>& abPointPairs);

template <typename A1, typename A2>
struct Range;

Expand Down
3 changes: 3 additions & 0 deletions gtsam/geometry/Pose3.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@ inline Matrix wedge<Pose3>(const Vector& xi) {
return Pose3::wedge(xi(0), xi(1), xi(2), xi(3), xi(4), xi(5));
}

// Convenience typedef
using Pose3Pair = std::pair<Pose3, Pose3>;

// For MATLAB wrapper
typedef std::vector<Pose3> Pose3Vector;

Expand Down
20 changes: 20 additions & 0 deletions gtsam/geometry/tests/testPoint3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ TEST (Point3, normalize) {
EXPECT(assert_equal(expectedH, actualH, 1e-8));
}

//*************************************************************************
TEST(Point3, mean) {
Point3 expected_a_mean(2, 2, 2);
Point3 a1(0, 0, 0), a2(1, 2, 3), a3(5, 4, 3);
std::vector<Point3> a_points{a1, a2, a3};
Point3 actual_a_mean = mean(a_points);
EXPECT(assert_equal(expected_a_mean, actual_a_mean));
}

TEST(Point3, mean_pair) {
Point3 a_mean(2, 2, 2), b_mean(-1, 1, 0);
Point3Pair expected_mean = std::make_pair(a_mean, b_mean);
Point3 a1(0, 0, 0), a2(1, 2, 3), a3(5, 4, 3);
Point3 b1(-1, 0, 0), b2(-2, 4, 0), b3(0, -1, 0);
std::vector<Point3Pair> point_pairs{{a1,b1},{a2,b2},{a3,b3}};
Point3Pair actual_mean = mean(point_pairs);
EXPECT(assert_equal(expected_mean.first, actual_mean.first));
EXPECT(assert_equal(expected_mean.second, actual_mean.second));
}

//*************************************************************************
double norm_proxy(const Point3& point) {
return double(point.norm());
Expand Down
97 changes: 93 additions & 4 deletions gtsam_unstable/geometry/Similarity3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,61 @@

#include <gtsam/geometry/Pose3.h>
#include <gtsam/base/Manifold.h>
#include <gtsam/slam/KarcherMeanFactor-inl.h>

namespace gtsam {

namespace {
/// Subtract centroids from point pairs.
static std::vector<Point3Pair> subtractCentroids(const std::vector<Point3Pair>& abPointPairs, const Point3Pair& centroids) {
std::vector<Point3Pair> d_abPointPairs;
for (const Point3Pair& abPair : abPointPairs) {
Point3 da = abPair.first - centroids.first;
Point3 db = abPair.second - centroids.second;
d_abPointPairs.emplace_back(da, db);
}
return d_abPointPairs;
}

/// Form inner products x and y and calculate scale.
static const double calculateScale(const std::vector<Point3Pair>& d_abPointPairs, const Rot3& aRb) {
double x = 0, y = 0;
Point3 da, db;
for (const Point3Pair& d_abPair : d_abPointPairs) {
std::tie(da, db) = d_abPair;
const Vector3 da_prime = aRb * db;
y += da.transpose() * da_prime;
x += da_prime.transpose() * da_prime;
}
const double s = y / x;
return s;
}

/// Form outer product H.
static Matrix3 calculateH(const std::vector<Point3Pair>& d_abPointPairs) {
Matrix3 H = Z_3x3;
for (const Point3Pair& d_abPair : d_abPointPairs) {
H += d_abPair.first * d_abPair.second.transpose();
}
return H;
}

/// This method estimates the similarity transform from differences point pairs, given a known or estimated rotation and point centroids.
static Similarity3 align(const std::vector<Point3Pair>& d_abPointPairs, const Rot3& aRb, const Point3Pair& centroids) {
const double s = calculateScale(d_abPointPairs, aRb);
const Point3 aTb = (centroids.first - s * (aRb * centroids.second)) / s;
return Similarity3(aRb, aTb, s);
}

/// This method estimates the similarity transform from point pairs, given a known or estimated rotation.
// Refer to: http://www5.informatik.uni-erlangen.de/Forschung/Publikationen/2005/Zinsser05-PSR.pdf Chapter 3
static Similarity3 alignGivenR(const std::vector<Point3Pair>& abPointPairs, const Rot3& aRb) {
auto centroids = mean(abPointPairs);
auto d_abPointPairs = subtractCentroids(abPointPairs, centroids);
return align(d_abPointPairs, aRb, centroids);
}
} // namespace

Similarity3::Similarity3() :
t_(0,0,0), s_(1) {
}
Expand Down Expand Up @@ -54,15 +106,15 @@ bool Similarity3::operator==(const Similarity3& other) const {
void Similarity3::print(const std::string& s) const {
std::cout << std::endl;
std::cout << s;
rotation().print("R:\n");
std::cout << "t: " << translation().transpose() << "s: " << scale() << std::endl;
rotation().print("\nR:\n");
std::cout << "t: " << translation().transpose() << " s: " << scale() << std::endl;
}

Similarity3 Similarity3::identity() {
return Similarity3();
}
Similarity3 Similarity3::operator*(const Similarity3& T) const {
return Similarity3(R_ * T.R_, ((1.0 / T.s_) * t_) + R_ * T.t_, s_ * T.s_);
Similarity3 Similarity3::operator*(const Similarity3& S) const {
return Similarity3(R_ * S.R_, ((1.0 / S.s_) * t_) + R_ * S.t_, s_ * S.s_);
}

Similarity3 Similarity3::inverse() const {
Expand All @@ -85,10 +137,47 @@ Point3 Similarity3::transformFrom(const Point3& p, //
return s_ * q;
}

Pose3 Similarity3::transformFrom(const Pose3& T) const {
Rot3 R = R_.compose(T.rotation());
Point3 t = Point3(s_ * (R_ * T.translation() + t_));
return Pose3(R, t);
}

Point3 Similarity3::operator*(const Point3& p) const {
return transformFrom(p);
}

Similarity3 Similarity3::Align(const std::vector<Point3Pair>& abPointPairs) {
// Refer to: http://www5.informatik.uni-erlangen.de/Forschung/Publikationen/2005/Zinsser05-PSR.pdf Chapter 3
if (abPointPairs.size() < 3) throw std::runtime_error("input should have at least 3 pairs of points");
auto centroids = mean(abPointPairs);
auto d_abPointPairs = subtractCentroids(abPointPairs, centroids);
Matrix3 H = calculateH(d_abPointPairs);
// ClosestTo finds rotation matrix closest to H in Frobenius sense
Rot3 aRb = Rot3::ClosestTo(H);
return align(d_abPointPairs, aRb, centroids);
}

Similarity3 Similarity3::Align(const std::vector<Pose3Pair>& abPosePairs) {
const size_t n = abPosePairs.size();
if (n < 2) throw std::runtime_error("input should have at least 2 pairs of poses");

// calculate rotation
vector<Rot3> rotations;
vector<Point3Pair> abPointPairs;
rotations.reserve(n);
abPointPairs.reserve(n);
Pose3 wTa, wTb;
for (const Pose3Pair& abPair : abPosePairs) {
std::tie(wTa, wTb) = abPair;
rotations.emplace_back(wTa.rotation().compose(wTb.rotation().inverse()));
abPointPairs.emplace_back(wTa.translation(), wTb.translation());
}
const Rot3 aRb = FindKarcherMean<Rot3>(rotations);

return alignGivenR(abPointPairs, aRb);
}

Matrix4 Similarity3::wedge(const Vector7& xi) {
// http://www.ethaneade.org/latex2html/lie/node29.html
const auto w = xi.head<3>();
Expand Down
29 changes: 27 additions & 2 deletions gtsam_unstable/geometry/Similarity3.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

#include <gtsam/geometry/Rot3.h>
#include <gtsam/geometry/Point3.h>
#include <gtsam/geometry/Pose3.h>
#include <gtsam/base/Lie.h>
#include <gtsam/base/Manifold.h>
#include <gtsam_unstable/dllexport.h>


namespace gtsam {

// Forward declarations
Expand Down Expand Up @@ -87,7 +89,7 @@ class Similarity3: public LieGroup<Similarity3, 7> {
GTSAM_UNSTABLE_EXPORT static Similarity3 identity();

/// Composition
GTSAM_UNSTABLE_EXPORT Similarity3 operator*(const Similarity3& T) const;
GTSAM_UNSTABLE_EXPORT Similarity3 operator*(const Similarity3& S) const;

/// Return the inverse
GTSAM_UNSTABLE_EXPORT Similarity3 inverse() const;
Expand All @@ -101,9 +103,32 @@ class Similarity3: public LieGroup<Similarity3, 7> {
OptionalJacobian<3, 7> H1 = boost::none, //
OptionalJacobian<3, 3> H2 = boost::none) const;

/**
* Action on a pose T.
* |Rs ts| |R t| |Rs*R Rs*t+ts|
* |0 1/s| * |0 1| = | 0 1/s |, the result is still a Sim3 object.
* To retrieve a Pose3, we normalized the scale value into 1.
* |Rs*R Rs*t+ts| |Rs*R s(Rs*t+ts)|
* | 0 1/s | = | 0 1 |
*
* This group action satisfies the compatibility condition.
* For more details, refer to: https://en.wikipedia.org/wiki/Group_action
*/
GTSAM_UNSTABLE_EXPORT Pose3 transformFrom(const Pose3& T) const;

/** syntactic sugar for transformFrom */
GTSAM_UNSTABLE_EXPORT Point3 operator*(const Point3& p) const;

/**
* Create Similarity3 by aligning at least three point pairs
*/
GTSAM_UNSTABLE_EXPORT static Similarity3 Align(const std::vector<Point3Pair>& abPointPairs);

/**
* Create Similarity3 by aligning at least two pose pairs
*/
GTSAM_UNSTABLE_EXPORT static Similarity3 Align(const std::vector<Pose3Pair>& abPosePairs);

/// @}
/// @name Lie Group
/// @{
Expand Down Expand Up @@ -182,8 +207,8 @@ class Similarity3: public LieGroup<Similarity3, 7> {
/// @name Helper functions
/// @{

/// Calculate expmap and logmap coefficients.
private:
/// Calculate expmap and logmap coefficients.
static Matrix3 GetV(Vector3 w, double lambda);

/// @}
Expand Down
Loading
0