commit
bd8129d3f7
|
@ -66,7 +66,7 @@ option(GTSAM_WITH_EIGEN_MKL_OPENMP "Eigen, when using Intel MKL, will also
|
|||
option(GTSAM_THROW_CHEIRALITY_EXCEPTION "Throw exception when a triangulated point is behind a camera" ON)
|
||||
option(GTSAM_BUILD_PYTHON "Enable/Disable building & installation of Python module" OFF)
|
||||
option(GTSAM_ALLOW_DEPRECATED_SINCE_V4 "Allow use of methods/functions deprecated in GTSAM 4" ON)
|
||||
option(GTSAM_USE_VECTOR3_POINTS "Simply typdef Point3 to eigen::Vector3d" OFF)
|
||||
option(GTSAM_TYPEDEF_POINTS_TO_VECTORS "Typdef Point2 and Point3 to Eigen::Vector equivalents" OFF)
|
||||
option(GTSAM_SUPPORT_NESTED_DISSECTION "Support Metis-based nested dissection" ON)
|
||||
option(GTSAM_TANGENT_PREINTEGRATION "Use new ImuFactor with integration on tangent space" ON)
|
||||
|
||||
|
@ -91,8 +91,8 @@ if(GTSAM_BUILD_PYTHON AND GTSAM_ALLOW_DEPRECATED_SINCE_V4)
|
|||
message(FATAL_ERROR "GTSAM_BUILD_PYTHON and GTSAM_ALLOW_DEPRECATED_SINCE_V4 are both enabled. The python module cannot be compiled with deprecated functions turned on. Turn one of the two options off.")
|
||||
endif()
|
||||
|
||||
if(GTSAM_INSTALL_MATLAB_TOOLBOX AND GTSAM_USE_VECTOR3_POINTS)
|
||||
message(FATAL_ERROR "GTSAM_INSTALL_MATLAB_TOOLBOX and GTSAM_USE_VECTOR3_POINTS are both enabled. For now, the MATLAB toolbox cannot deal with this yet. Please turn one of the two options off.")
|
||||
if(GTSAM_INSTALL_MATLAB_TOOLBOX AND GTSAM_TYPEDEF_POINTS_TO_VECTORS)
|
||||
message(FATAL_ERROR "GTSAM_INSTALL_MATLAB_TOOLBOX and GTSAM_TYPEDEF_POINTS_TO_VECTORS are both enabled. For now, the MATLAB toolbox cannot deal with this yet. Please turn one of the two options off.")
|
||||
endif()
|
||||
|
||||
# Flags for choosing default packaging tools
|
||||
|
@ -491,7 +491,7 @@ print_config_flag(${GTSAM_ENABLE_CONSISTENCY_CHECKS} "Runtime consistency chec
|
|||
print_config_flag(${GTSAM_ROT3_EXPMAP} "Rot3 retract is full ExpMap ")
|
||||
print_config_flag(${GTSAM_POSE3_EXPMAP} "Pose3 retract is full ExpMap ")
|
||||
print_config_flag(${GTSAM_ALLOW_DEPRECATED_SINCE_V4} "Deprecated in GTSAM 4 allowed ")
|
||||
print_config_flag(${GTSAM_USE_VECTOR3_POINTS} "Point3 is typedef to Vector3 ")
|
||||
print_config_flag(${GTSAM_TYPEDEF_POINTS_TO_VECTORS} "Point3 is typedef to Vector3 ")
|
||||
print_config_flag(${GTSAM_SUPPORT_NESTED_DISSECTION} "Metis-based Nested Dissection ")
|
||||
print_config_flag(${GTSAM_TANGENT_PREINTEGRATION} "Use tangent-space preintegration")
|
||||
|
||||
|
|
|
@ -48,8 +48,7 @@ public:
|
|||
virtual Vector evaluateError(const Pose3& pose, boost::optional<Matrix&> H =
|
||||
boost::none) const {
|
||||
SimpleCamera camera(pose, *K_);
|
||||
Point2 reprojectionError(camera.project(P_, H, boost::none, boost::none) - p_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(P_, H, boost::none, boost::none) - p_;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ int main() {
|
|||
|
||||
// Predict the new value with the EKF class
|
||||
Point2 x1_predict = ekf.predict(factor1);
|
||||
x1_predict.print("X1 Predict");
|
||||
traits<Point2>::Print(x1_predict, "X1 Predict");
|
||||
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@ int main() {
|
|||
|
||||
// Update the Kalman Filter with the measurement
|
||||
Point2 x1_update = ekf.update(factor2);
|
||||
x1_update.print("X1 Update");
|
||||
traits<Point2>::Print(x1_update, "X1 Update");
|
||||
|
||||
|
||||
|
||||
|
@ -101,13 +101,13 @@ int main() {
|
|||
difference = Point2(1,0);
|
||||
BetweenFactor<Point2> factor3(x1, x2, difference, Q);
|
||||
Point2 x2_predict = ekf.predict(factor1);
|
||||
x2_predict.print("X2 Predict");
|
||||
traits<Point2>::Print(x2_predict, "X2 Predict");
|
||||
|
||||
// Update
|
||||
Point2 z2(2.0, 0.0);
|
||||
PriorFactor<Point2> factor4(x2, z2, R);
|
||||
Point2 x2_update = ekf.update(factor4);
|
||||
x2_update.print("X2 Update");
|
||||
traits<Point2>::Print(x2_update, "X2 Update");
|
||||
|
||||
|
||||
|
||||
|
@ -117,13 +117,13 @@ int main() {
|
|||
difference = Point2(1,0);
|
||||
BetweenFactor<Point2> factor5(x2, x3, difference, Q);
|
||||
Point2 x3_predict = ekf.predict(factor5);
|
||||
x3_predict.print("X3 Predict");
|
||||
traits<Point2>::Print(x3_predict, "X3 Predict");
|
||||
|
||||
// Update
|
||||
Point2 z3(3.0, 0.0);
|
||||
PriorFactor<Point2> factor6(x3, z3, R);
|
||||
Point2 x3_update = ekf.update(factor6);
|
||||
x3_update.print("X3 Update");
|
||||
traits<Point2>::Print(x3_update, "X3 Update");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
13
gtsam.h
13
gtsam.h
|
@ -266,23 +266,12 @@ class Point2 {
|
|||
|
||||
// Group
|
||||
static gtsam::Point2 identity();
|
||||
gtsam::Point2 inverse() const;
|
||||
gtsam::Point2 compose(const gtsam::Point2& p2) const;
|
||||
gtsam::Point2 between(const gtsam::Point2& p2) const;
|
||||
|
||||
// Manifold
|
||||
gtsam::Point2 retract(Vector v) const;
|
||||
Vector localCoordinates(const gtsam::Point2& p) const;
|
||||
|
||||
// Lie Group
|
||||
static gtsam::Point2 Expmap(Vector v);
|
||||
static Vector Logmap(const gtsam::Point2& p);
|
||||
|
||||
// Standard Interface
|
||||
double x() const;
|
||||
double y() const;
|
||||
Vector vector() const;
|
||||
double dist(const gtsam::Point2& p2) const;
|
||||
double distance(const gtsam::Point2& p2) const;
|
||||
double norm() const;
|
||||
|
||||
// enabling serialization functionality
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#cmakedefine GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
|
||||
// Publish flag about Eigen typedef
|
||||
#cmakedefine GTSAM_USE_VECTOR3_POINTS
|
||||
#cmakedefine GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
// Support Metis-based nested dissection
|
||||
#cmakedefine GTSAM_SUPPORT_NESTED_DISSECTION
|
||||
|
|
|
@ -106,7 +106,7 @@ Point2 Cal3Bundler::calibrate(const Point2& pi, const double tol) const {
|
|||
const int maxIterations = 10;
|
||||
int iteration;
|
||||
for (iteration = 0; iteration < maxIterations; ++iteration) {
|
||||
if (uncalibrate(pn).distance(pi) <= tol)
|
||||
if (distance2(uncalibrate(pn), pi) <= tol)
|
||||
break;
|
||||
const double x = pn.x(), y = pn.y(), xx = x * x, yy = y * y;
|
||||
const double rr = xx + yy;
|
||||
|
|
|
@ -144,7 +144,7 @@ Point2 Cal3DS2_Base::calibrate(const Point2& pi, const double tol) const {
|
|||
const int maxIterations = 10;
|
||||
int iteration;
|
||||
for (iteration = 0; iteration < maxIterations; ++iteration) {
|
||||
if (uncalibrate(pn).distance(pi) <= tol) break;
|
||||
if (distance2(uncalibrate(pn), pi) <= tol) break;
|
||||
const double x = pn.x(), y = pn.y(), xy = x * y, xx = x * x, yy = y * y;
|
||||
const double rr = xx + yy;
|
||||
const double g = (1 + k1_ * rr + k2_ * rr * rr);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <gtsam/geometry/BearingRange.h>
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
#include <gtsam/geometry/Pose3.h>
|
||||
#include <gtsam/base/concepts.h>
|
||||
#include <gtsam/base/Manifold.h>
|
||||
|
@ -28,8 +29,6 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
class Point2;
|
||||
|
||||
class GTSAM_EXPORT CheiralityException: public ThreadsafeException<
|
||||
CheiralityException> {
|
||||
public:
|
||||
|
|
|
@ -56,8 +56,7 @@ protected:
|
|||
// Project and fill error vector
|
||||
Vector b(ZDim * m);
|
||||
for (size_t i = 0, row = 0; i < m; i++, row += ZDim) {
|
||||
Z e = predicted[i] - measured[i];
|
||||
b.segment<ZDim>(row) = e.vector();
|
||||
b.segment<ZDim>(row) = traits<Z>::Local(measured[i], predicted[i]);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
@ -107,7 +106,8 @@ public:
|
|||
|
||||
// Allocate result
|
||||
size_t m = this->size();
|
||||
std::vector<Z> z(m);
|
||||
std::vector<Z> z;
|
||||
z.reserve(m);
|
||||
|
||||
// Allocate derivatives
|
||||
if (E) E->resize(ZDim * m, N);
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
for (size_t i = 0; i < m; i++) {
|
||||
MatrixZD Fi;
|
||||
Eigen::Matrix<double, ZDim, N> Ei;
|
||||
z[i] = this->at(i).project2(point, Fs ? &Fi : 0, E ? &Ei : 0);
|
||||
z.emplace_back(this->at(i).project2(point, Fs ? &Fi : 0, E ? &Ei : 0));
|
||||
if (Fs) (*Fs)[i] = Fi;
|
||||
if (E) E->block<ZDim, N>(ZDim * i, 0) = Ei;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
@ -23,21 +23,11 @@ using namespace std;
|
|||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Point2::print(const string& s) const {
|
||||
cout << s << *this << endl;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool Point2::equals(const Point2& q, double tol) const {
|
||||
return (fabs(x_ - q.x()) < tol && fabs(y_ - q.y()) < tol);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double Point2::norm(OptionalJacobian<1,2> H) const {
|
||||
double r = sqrt(x_ * x_ + y_ * y_);
|
||||
double norm2(const Point2& p, OptionalJacobian<1,2> H) {
|
||||
double r = std::sqrt(p.x() * p.x() + p.y() * p.y());
|
||||
if (H) {
|
||||
if (fabs(r) > 1e-10)
|
||||
*H << x_ / r, y_ / r;
|
||||
*H << p.x() / r, p.y() / r;
|
||||
else
|
||||
*H << 1, 1; // really infinity, why 1 ?
|
||||
}
|
||||
|
@ -45,34 +35,66 @@ double Point2::norm(OptionalJacobian<1,2> H) const {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double Point2::distance(const Point2& point, OptionalJacobian<1,2> H1,
|
||||
OptionalJacobian<1,2> H2) const {
|
||||
Point2 d = point - *this;
|
||||
double distance2(const Point2& p, const Point2& q, OptionalJacobian<1, 2> H1,
|
||||
OptionalJacobian<1, 2> H2) {
|
||||
Point2 d = q - p;
|
||||
if (H1 || H2) {
|
||||
Matrix12 H;
|
||||
double r = d.norm(H);
|
||||
double r = norm2(d, H);
|
||||
if (H1) *H1 = -H;
|
||||
if (H2) *H2 = H;
|
||||
return r;
|
||||
} else
|
||||
} else {
|
||||
return d.norm();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate f and h, respectively the parallel and perpendicular distance of
|
||||
* the intersections of two circles along and from the line connecting the centers.
|
||||
* Both are dimensionless fractions of the distance d between the circle centers.
|
||||
* If the circles do not intersect or they are identical, returns boost::none.
|
||||
* If one solution (touching circles, as determined by tol), h will be exactly zero.
|
||||
* h is a good measure for how accurate the intersection will be, as when circles touch
|
||||
* or nearly touch, the intersection is ill-defined with noisy radius measurements.
|
||||
* @param R_d : R/d, ratio of radius of first circle to distance between centers
|
||||
* @param r_d : r/d, ratio of radius of second circle to distance between centers
|
||||
* @param tol: absolute tolerance below which we consider touching circles
|
||||
*/
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Point2::print(const string& s) const {
|
||||
cout << s << *this << endl;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool Point2::equals(const Point2& q, double tol) const {
|
||||
return (fabs(x() - q.x()) < tol && fabs(y() - q.y()) < tol);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double Point2::norm(OptionalJacobian<1,2> H) const {
|
||||
return gtsam::norm2(*this, H);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double Point2::distance(const Point2& point, OptionalJacobian<1,2> H1,
|
||||
OptionalJacobian<1,2> H2) const {
|
||||
return gtsam::distance2(*this, point, H1, H2);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
ostream &operator<<(ostream &os, const Point2& p) {
|
||||
os << '(' << p.x() << ", " << p.y() << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
boost::optional<Point2> CircleCircleIntersection(double R_d, double r_d, double tol) {
|
||||
return circleCircleIntersection(R_d, r_d, tol);
|
||||
}
|
||||
std::list<Point2> CircleCircleIntersection(Point2 c1, Point2 c2, boost::optional<Point2> fh) {
|
||||
return circleCircleIntersection(c1, c2, fh);
|
||||
}
|
||||
std::list<Point2> CircleCircleIntersection(Point2 c1, double r1, Point2 c2, double r2, double tol) {
|
||||
return circleCircleIntersection(c1, r1, c2, r2, tol);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Math inspired by http://paulbourke.net/geometry/circlesphere/
|
||||
boost::optional<Point2> Point2::CircleCircleIntersection(double R_d, double r_d,
|
||||
boost::optional<Point2> circleCircleIntersection(double R_d, double r_d,
|
||||
double tol) {
|
||||
|
||||
double R2_d2 = R_d*R_d; // Yes, RD-D2 !
|
||||
|
@ -83,11 +105,11 @@ boost::optional<Point2> Point2::CircleCircleIntersection(double R_d, double r_d,
|
|||
// Hence, there are only solutions if >=0
|
||||
if (h2<-tol) return boost::none; // allow *slightly* negative
|
||||
else if (h2<tol) return Point2(f,0.0); // one solution
|
||||
else return Point2(f,sqrt(h2)); // two solutions
|
||||
else return Point2(f,std::sqrt(h2)); // two solutions
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
list<Point2> Point2::CircleCircleIntersection(Point2 c1, Point2 c2,
|
||||
list<Point2> circleCircleIntersection(Point2 c1, Point2 c2,
|
||||
boost::optional<Point2> fh) {
|
||||
|
||||
list<Point2> solutions;
|
||||
|
@ -116,27 +138,21 @@ list<Point2> Point2::CircleCircleIntersection(Point2 c1, Point2 c2,
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
list<Point2> Point2::CircleCircleIntersection(Point2 c1, double r1, Point2 c2,
|
||||
list<Point2> circleCircleIntersection(Point2 c1, double r1, Point2 c2,
|
||||
double r2, double tol) {
|
||||
|
||||
// distance between circle centers.
|
||||
double d = c1.dist(c2);
|
||||
double d = distance2(c1, c2);
|
||||
|
||||
// centers coincide, either no solution or infinite number of solutions.
|
||||
if (d<1e-9) return list<Point2>();
|
||||
|
||||
// Calculate f and h given normalized radii
|
||||
double _d = 1.0/d, R_d = r1*_d, r_d=r2*_d;
|
||||
boost::optional<Point2> fh = CircleCircleIntersection(R_d,r_d);
|
||||
boost::optional<Point2> fh = circleCircleIntersection(R_d,r_d);
|
||||
|
||||
// Call version that takes fh
|
||||
return CircleCircleIntersection(c1, c2, fh);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
ostream &operator<<(ostream &os, const Point2& p) {
|
||||
os << '(' << p.x() << ", " << p.y() << ')';
|
||||
return os;
|
||||
return circleCircleIntersection(c1, c2, fh);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
@ -22,6 +22,14 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
#ifdef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
/// As of GTSAM 4, in order to make GTSAM more lean,
|
||||
/// it is now possible to just typedef Point2 to Vector2
|
||||
typedef Vector2 Point2;
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* A 2D point
|
||||
* Complies with the Testable Concept
|
||||
|
@ -29,69 +37,30 @@ namespace gtsam {
|
|||
* @addtogroup geometry
|
||||
* \nosubgrouping
|
||||
*/
|
||||
class GTSAM_EXPORT Point2 {
|
||||
class GTSAM_EXPORT Point2 : public Vector2 {
|
||||
private:
|
||||
|
||||
double x_, y_;
|
||||
|
||||
public:
|
||||
enum { dimension = 2 };
|
||||
/// @name Standard Constructors
|
||||
/// @{
|
||||
|
||||
/// default constructor
|
||||
Point2(): x_(0), y_(0) {}
|
||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
// Deprecated default constructor initializes to zero, in contrast to new behavior below
|
||||
Point2() { setZero(); }
|
||||
#else
|
||||
Point2() {}
|
||||
#endif
|
||||
|
||||
/// construct from doubles
|
||||
Point2(double x, double y): x_(x), y_(y) {}
|
||||
using Vector2::Vector2;
|
||||
|
||||
/// @}
|
||||
/// @name Advanced Constructors
|
||||
/// @{
|
||||
|
||||
/// construct from 2D vector
|
||||
explicit Point2(const Vector2& v) {
|
||||
x_ = v(0);
|
||||
y_ = v(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Circle-circle intersection, given normalized radii.
|
||||
* Calculate f and h, respectively the parallel and perpendicular distance of
|
||||
* the intersections of two circles along and from the line connecting the centers.
|
||||
* Both are dimensionless fractions of the distance d between the circle centers.
|
||||
* If the circles do not intersect or they are identical, returns boost::none.
|
||||
* If one solution (touching circles, as determined by tol), h will be exactly zero.
|
||||
* h is a good measure for how accurate the intersection will be, as when circles touch
|
||||
* or nearly touch, the intersection is ill-defined with noisy radius measurements.
|
||||
* @param R_d : R/d, ratio of radius of first circle to distance between centers
|
||||
* @param r_d : r/d, ratio of radius of second circle to distance between centers
|
||||
* @param tol: absolute tolerance below which we consider touching circles
|
||||
* @return optional Point2 with f and h, boost::none if no solution.
|
||||
*/
|
||||
static boost::optional<Point2> CircleCircleIntersection(double R_d, double r_d,
|
||||
double tol = 1e-9);
|
||||
|
||||
/*
|
||||
* @brief Circle-circle intersection, from the normalized radii solution.
|
||||
* @param c1 center of first circle
|
||||
* @param c2 center of second circle
|
||||
* @return list of solutions (0,1, or 2). Identical circles will return empty list, as well.
|
||||
*/
|
||||
static std::list<Point2> CircleCircleIntersection(Point2 c1, Point2 c2, boost::optional<Point2>);
|
||||
|
||||
/**
|
||||
* @brief Intersect 2 circles
|
||||
* @param c1 center of first circle
|
||||
* @param r1 radius of first circle
|
||||
* @param c2 center of second circle
|
||||
* @param r2 radius of second circle
|
||||
* @param tol: absolute tolerance below which we consider touching circles
|
||||
* @return list of solutions (0,1, or 2). Identical circles will return empty list, as well.
|
||||
*/
|
||||
static std::list<Point2> CircleCircleIntersection(Point2 c1, double r1,
|
||||
Point2 c2, double r2, double tol = 1e-9);
|
||||
|
||||
explicit Point2(const Vector2& v):Vector2(v) {}
|
||||
/// @}
|
||||
/// @name Testable
|
||||
/// @{
|
||||
|
@ -107,21 +76,7 @@ public:
|
|||
/// @{
|
||||
|
||||
/// identity
|
||||
inline static Point2 identity() {return Point2();}
|
||||
|
||||
/// inverse
|
||||
inline Point2 operator- () const {return Point2(-x_,-y_);}
|
||||
|
||||
/// add vector on right
|
||||
inline Point2 operator +(const Vector2& v) const {
|
||||
return Point2(x_ + v[0], y_ + v[1]);
|
||||
}
|
||||
|
||||
/// add
|
||||
inline Point2 operator + (const Point2& q) const {return Point2(x_+q.x_,y_+q.y_);}
|
||||
|
||||
/// subtract
|
||||
inline Point2 operator - (const Point2& q) const {return Point2(x_-q.x_,y_-q.y_);}
|
||||
inline static Point2 identity() {return Point2(0,0);}
|
||||
|
||||
/// @}
|
||||
/// @name Vector Space
|
||||
|
@ -137,51 +92,44 @@ public:
|
|||
double distance(const Point2& p2, OptionalJacobian<1,2> H1 = boost::none,
|
||||
OptionalJacobian<1,2> H2 = boost::none) const;
|
||||
|
||||
/** @deprecated The following function has been deprecated, use distance above */
|
||||
inline double dist(const Point2& p2) const {
|
||||
return (p2 - *this).norm();
|
||||
}
|
||||
|
||||
/// multiply with a scalar
|
||||
inline Point2 operator * (double s) const {return Point2(x_*s,y_*s);}
|
||||
|
||||
/// divide by a scalar
|
||||
inline Point2 operator / (double q) const {return Point2(x_/q,y_/q);}
|
||||
|
||||
/// @}
|
||||
/// @name Standard Interface
|
||||
/// @{
|
||||
|
||||
/// equality
|
||||
inline bool operator ==(const Point2& q) const {return x_==q.x_ && y_==q.y_;}
|
||||
inline bool operator ==(const Point2& q) const {return x()==q.x() && y()==q.y();}
|
||||
|
||||
/// get x
|
||||
double x() const {return x_;}
|
||||
inline double x() const {return (*this)[0];}
|
||||
|
||||
/// get y
|
||||
double y() const {return y_;}
|
||||
inline double y() const {return (*this)[1];}
|
||||
|
||||
/// return vectorized form (column-wise). TODO: why does this function exist?
|
||||
Vector2 vector() const { return Vector2(x_, y_); }
|
||||
/// return vectorized form (column-wise).
|
||||
const Vector2& vector() const { return *this; }
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Deprecated
|
||||
/// @{
|
||||
inline void operator += (const Point2& q) {x_+=q.x_;y_+=q.y_;}
|
||||
inline void operator *= (double s) {x_*=s;y_*=s;}
|
||||
Point2 inverse() const { return -(*this);}
|
||||
Point2 compose(const Point2& q) const { return (*this)+q;}
|
||||
Point2 between(const Point2& q) const { return q-(*this);}
|
||||
Vector2 localCoordinates(const Point2& q) const { return between(q).vector();}
|
||||
Point2 retract(const Vector2& v) const { return compose(Point2(v));}
|
||||
static Vector2 Logmap(const Point2& p) { return p.vector();}
|
||||
static Point2 Expmap(const Vector2& v) { return Point2(v);}
|
||||
/// @}
|
||||
|
||||
/// Streaming
|
||||
GTSAM_EXPORT friend std::ostream &operator<<(std::ostream &os, const Point2& p);
|
||||
|
||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
/// @name Deprecated
|
||||
/// @{
|
||||
Point2 inverse() const { return -(*this); }
|
||||
Point2 compose(const Point2& q) const { return (*this)+q;}
|
||||
Point2 between(const Point2& q) const { return q-(*this);}
|
||||
Vector2 localCoordinates(const Point2& q) const { return between(q);}
|
||||
Point2 retract(const Vector2& v) const { return compose(Point2(v));}
|
||||
static Vector2 Logmap(const Point2& p) { return p;}
|
||||
static Point2 Expmap(const Vector2& v) { return Point2(v);}
|
||||
inline double dist(const Point2& p2) const {return distance(p2);}
|
||||
static boost::optional<Point2> CircleCircleIntersection(double R_d, double r_d, double tol = 1e-9);
|
||||
static std::list<Point2> CircleCircleIntersection(Point2 c1, Point2 c2, boost::optional<Point2> fh);
|
||||
static std::list<Point2> CircleCircleIntersection(Point2 c1, double r1, Point2 c2, double r2, double tol = 1e-9);
|
||||
/// @}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/// @name Advanced Interface
|
||||
|
@ -192,13 +140,25 @@ private:
|
|||
template<class ARCHIVE>
|
||||
void serialize(ARCHIVE & ar, const unsigned int /*version*/)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(x_);
|
||||
ar & BOOST_SERIALIZATION_NVP(y_);
|
||||
}
|
||||
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Vector2);}
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct traits<Point2> : public internal::VectorSpace<Point2> {
|
||||
};
|
||||
|
||||
#endif // GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
/// Distance of the point from the origin, with Jacobian
|
||||
double norm2(const Point2& p, OptionalJacobian<1, 2> H = boost::none);
|
||||
|
||||
/// distance between two points
|
||||
double distance2(const Point2& p1, const Point2& q,
|
||||
OptionalJacobian<1, 2> H1 = boost::none,
|
||||
OptionalJacobian<1, 2> H2 = boost::none);
|
||||
|
||||
// Convenience typedef
|
||||
typedef std::pair<Point2, Point2> Point2Pair;
|
||||
std::ostream &operator<<(std::ostream &os, const gtsam::Point2Pair &p);
|
||||
|
@ -207,10 +167,45 @@ std::ostream &operator<<(std::ostream &os, const gtsam::Point2Pair &p);
|
|||
typedef std::vector<Point2> Point2Vector;
|
||||
|
||||
/// multiply with scalar
|
||||
inline Point2 operator*(double s, const Point2& p) {return p*s;}
|
||||
inline Point2 operator*(double s, const Point2& p) {
|
||||
return p * s;
|
||||
}
|
||||
|
||||
template<>
|
||||
struct traits<Point2> : public internal::VectorSpace<Point2> {};
|
||||
/*
|
||||
* @brief Circle-circle intersection, given normalized radii.
|
||||
* Calculate f and h, respectively the parallel and perpendicular distance of
|
||||
* the intersections of two circles along and from the line connecting the centers.
|
||||
* Both are dimensionless fractions of the distance d between the circle centers.
|
||||
* If the circles do not intersect or they are identical, returns boost::none.
|
||||
* If one solution (touching circles, as determined by tol), h will be exactly zero.
|
||||
* h is a good measure for how accurate the intersection will be, as when circles touch
|
||||
* or nearly touch, the intersection is ill-defined with noisy radius measurements.
|
||||
* @param R_d : R/d, ratio of radius of first circle to distance between centers
|
||||
* @param r_d : r/d, ratio of radius of second circle to distance between centers
|
||||
* @param tol: absolute tolerance below which we consider touching circles
|
||||
* @return optional Point2 with f and h, boost::none if no solution.
|
||||
*/
|
||||
boost::optional<Point2> circleCircleIntersection(double R_d, double r_d, double tol = 1e-9);
|
||||
|
||||
/*
|
||||
* @brief Circle-circle intersection, from the normalized radii solution.
|
||||
* @param c1 center of first circle
|
||||
* @param c2 center of second circle
|
||||
* @return list of solutions (0,1, or 2). Identical circles will return empty list, as well.
|
||||
*/
|
||||
std::list<Point2> circleCircleIntersection(Point2 c1, Point2 c2, boost::optional<Point2> fh);
|
||||
|
||||
/**
|
||||
* @brief Intersect 2 circles
|
||||
* @param c1 center of first circle
|
||||
* @param r1 radius of first circle
|
||||
* @param c2 center of second circle
|
||||
* @param r2 radius of second circle
|
||||
* @param tol: absolute tolerance below which we consider touching circles
|
||||
* @return list of solutions (0,1, or 2). Identical circles will return empty list, as well.
|
||||
*/
|
||||
std::list<Point2> circleCircleIntersection(Point2 c1, double r1,
|
||||
Point2 c2, double r2, double tol = 1e-9);
|
||||
|
||||
} // \ namespace gtsam
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ using namespace std;
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
#ifndef GTSAM_USE_VECTOR3_POINTS
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
bool Point3::equals(const Point3 &q, double tol) const {
|
||||
return (fabs(x() - q.x()) < tol && fabs(y() - q.y()) < tol &&
|
||||
fabs(z() - q.z()) < tol);
|
||||
|
@ -34,11 +34,11 @@ void Point3::print(const string& s) const {
|
|||
/* ************************************************************************* */
|
||||
double Point3::distance(const Point3 &q, OptionalJacobian<1, 3> H1,
|
||||
OptionalJacobian<1, 3> H2) const {
|
||||
return gtsam::distance(*this,q,H1,H2);
|
||||
return gtsam::distance3(*this,q,H1,H2);
|
||||
}
|
||||
|
||||
double Point3::norm(OptionalJacobian<1,3> H) const {
|
||||
return gtsam::norm(*this, H);
|
||||
return gtsam::norm3(*this, H);
|
||||
}
|
||||
|
||||
Point3 Point3::normalized(OptionalJacobian<3,3> H) const {
|
||||
|
@ -80,8 +80,8 @@ Point3 Point3::sub(const Point3 &q, OptionalJacobian<3,3> H1,
|
|||
|
||||
#endif
|
||||
/* ************************************************************************* */
|
||||
double distance(const Point3 &p1, const Point3 &q, OptionalJacobian<1, 3> H1,
|
||||
OptionalJacobian<1, 3> H2) {
|
||||
double distance3(const Point3 &p1, const Point3 &q, OptionalJacobian<1, 3> H1,
|
||||
OptionalJacobian<1, 3> H2) {
|
||||
double d = (q - p1).norm();
|
||||
if (H1) {
|
||||
*H1 << p1.x() - q.x(), p1.y() - q.y(), p1.z() - q.z();
|
||||
|
@ -94,7 +94,7 @@ double distance(const Point3 &p1, const Point3 &q, OptionalJacobian<1, 3> H1,
|
|||
return d;
|
||||
}
|
||||
|
||||
double norm(const Point3 &p, OptionalJacobian<1, 3> H) {
|
||||
double norm3(const Point3 &p, OptionalJacobian<1, 3> H) {
|
||||
double r = sqrt(p.x() * p.x() + p.y() * p.y() + p.z() * p.z());
|
||||
if (H) {
|
||||
if (fabs(r) > 1e-10)
|
||||
|
@ -106,7 +106,7 @@ double norm(const Point3 &p, OptionalJacobian<1, 3> H) {
|
|||
}
|
||||
|
||||
Point3 normalize(const Point3 &p, OptionalJacobian<3, 3> H) {
|
||||
Point3 normalized = p / norm(p);
|
||||
Point3 normalized = p / p.norm();
|
||||
if (H) {
|
||||
// 3*3 Derivative
|
||||
double x2 = p.x() * p.x(), y2 = p.y() * p.y(), z2 = p.z() * p.z();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
#ifdef GTSAM_USE_VECTOR3_POINTS
|
||||
#ifdef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
/// As of GTSAM 4, in order to make GTSAM more lean,
|
||||
/// it is now possible to just typedef Point3 to Vector3
|
||||
|
@ -124,9 +124,9 @@ class GTSAM_EXPORT Point3 : public Vector3 {
|
|||
Point3 inverse() const { return -(*this);}
|
||||
Point3 compose(const Point3& q) const { return (*this)+q;}
|
||||
Point3 between(const Point3& q) const { return q-(*this);}
|
||||
Vector3 localCoordinates(const Point3& q) const { return between(q).vector();}
|
||||
Vector3 localCoordinates(const Point3& q) const { return between(q);}
|
||||
Point3 retract(const Vector3& v) const { return compose(Point3(v));}
|
||||
static Vector3 Logmap(const Point3& p) { return p.vector();}
|
||||
static Vector3 Logmap(const Point3& p) { return p;}
|
||||
static Point3 Expmap(const Vector3& v) { return Point3(v);}
|
||||
inline double dist(const Point3& q) const { return (q - *this).norm(); }
|
||||
Point3 normalize(OptionalJacobian<3, 3> H = boost::none) const { return normalized(H);}
|
||||
|
@ -153,19 +153,19 @@ struct traits<Point3> : public internal::VectorSpace<Point3> {};
|
|||
template<>
|
||||
struct traits<const Point3> : public internal::VectorSpace<Point3> {};
|
||||
|
||||
#endif
|
||||
#endif // GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
|
||||
// Convenience typedef
|
||||
typedef std::pair<Point3, Point3> Point3Pair;
|
||||
std::ostream &operator<<(std::ostream &os, const gtsam::Point3Pair &p);
|
||||
|
||||
/// distance between two points
|
||||
double distance(const Point3& p1, const Point3& q,
|
||||
OptionalJacobian<1, 3> H1 = boost::none,
|
||||
OptionalJacobian<1, 3> H2 = boost::none);
|
||||
double distance3(const Point3& p1, const Point3& q,
|
||||
OptionalJacobian<1, 3> H1 = boost::none,
|
||||
OptionalJacobian<1, 3> H2 = boost::none);
|
||||
|
||||
/// Distance of the point from the origin, with Jacobian
|
||||
double norm(const Point3& p, OptionalJacobian<1, 3> H = boost::none);
|
||||
double norm3(const Point3& p, OptionalJacobian<1, 3> H = boost::none);
|
||||
|
||||
/// normalize, with optional Jacobian
|
||||
Point3 normalize(const Point3& p, OptionalJacobian<3, 3> H = boost::none);
|
||||
|
@ -193,7 +193,7 @@ struct Range<Point3, Point3> {
|
|||
double operator()(const Point3& p, const Point3& q,
|
||||
OptionalJacobian<1, 3> H1 = boost::none,
|
||||
OptionalJacobian<1, 3> H2 = boost::none) {
|
||||
return distance(p, q, H1, H2);
|
||||
return distance3(p, q, H1, H2);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -53,21 +53,21 @@ void Pose2::print(const string& s) const {
|
|||
|
||||
/* ************************************************************************* */
|
||||
bool Pose2::equals(const Pose2& q, double tol) const {
|
||||
return t_.equals(q.t_, tol) && r_.equals(q.r_, tol);
|
||||
return equal_with_abs_tol(t_, q.t_, tol) && r_.equals(q.r_, tol);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Pose2 Pose2::Expmap(const Vector3& xi, OptionalJacobian<3, 3> H) {
|
||||
if (H) *H = Pose2::ExpmapDerivative(xi);
|
||||
assert(xi.size() == 3);
|
||||
Point2 v(xi(0),xi(1));
|
||||
double w = xi(2);
|
||||
if (H) *H = Pose2::ExpmapDerivative(xi);
|
||||
const Point2 v(xi(0),xi(1));
|
||||
const double w = xi(2);
|
||||
if (std::abs(w) < 1e-10)
|
||||
return Pose2(xi[0], xi[1], xi[2]);
|
||||
else {
|
||||
Rot2 R(Rot2::fromAngle(w));
|
||||
Point2 v_ortho = R_PI_2 * v; // points towards rot center
|
||||
Point2 t = (v_ortho - R.rotate(v_ortho)) / w;
|
||||
const Rot2 R(Rot2::fromAngle(w));
|
||||
const Point2 v_ortho = R_PI_2 * v; // points towards rot center
|
||||
const Point2 t = (v_ortho - R.rotate(v_ortho)) / w;
|
||||
return Pose2(R, t);
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ double Pose2::range(const Point2& point,
|
|||
Point2 d = point - t_;
|
||||
if (!Hpose && !Hpoint) return d.norm();
|
||||
Matrix12 D_r_d;
|
||||
double r = d.norm(D_r_d);
|
||||
double r = norm2(d, D_r_d);
|
||||
if (Hpose) {
|
||||
Matrix23 D_d_pose;
|
||||
D_d_pose << -r_.c(), r_.s(), 0.0,
|
||||
|
@ -267,7 +267,7 @@ double Pose2::range(const Pose2& pose,
|
|||
Point2 d = pose.t() - t_;
|
||||
if (!Hpose && !Hother) return d.norm();
|
||||
Matrix12 D_r_d;
|
||||
double r = d.norm(D_r_d);
|
||||
double r = norm2(d, D_r_d);
|
||||
if (Hpose) {
|
||||
Matrix23 D_d_pose;
|
||||
D_d_pose <<
|
||||
|
@ -311,7 +311,7 @@ boost::optional<Pose2> align(const vector<Point2Pair>& pairs) {
|
|||
if (n<2) return boost::none; // we need at least two pairs
|
||||
|
||||
// calculate centroids
|
||||
Point2 cp,cq;
|
||||
Point2 cp(0,0), cq(0,0);
|
||||
for(const Point2Pair& pair: pairs) {
|
||||
cp += pair.first;
|
||||
cq += pair.second;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
@ -52,7 +52,9 @@ public:
|
|||
/// @{
|
||||
|
||||
/** default constructor = origin */
|
||||
Pose2() {} // default is origin
|
||||
Pose2() :
|
||||
r_(traits<Rot2>::Identity()), t_(traits<Point2>::Identity()) {
|
||||
}
|
||||
|
||||
/** copy constructor */
|
||||
Pose2(const Pose2& pose) : r_(pose.r_), t_(pose.t_) {}
|
||||
|
@ -86,7 +88,7 @@ public:
|
|||
/// @{
|
||||
|
||||
/** Construct from canonical coordinates \f$ [T_x,T_y,\theta] \f$ (Lie algebra) */
|
||||
Pose2(const Vector& v) {
|
||||
Pose2(const Vector& v) : Pose2() {
|
||||
*this = Expmap(v);
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ double Pose3::range(const Point3& point, OptionalJacobian<1, 6> H1,
|
|||
return local.norm();
|
||||
} else {
|
||||
Matrix13 D_r_local;
|
||||
const double r = norm(local, D_r_local);
|
||||
const double r = norm3(local, D_r_local);
|
||||
if (H1) *H1 = D_r_local * D_local_pose;
|
||||
if (H2) *H2 = D_r_local * D_local_point;
|
||||
return r;
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace gtsam {
|
|||
*/
|
||||
static Rot3 AxisAngle(const Point3& axis, double angle) {
|
||||
#ifdef GTSAM_USE_QUATERNIONS
|
||||
return gtsam::Quaternion(Eigen::AngleAxis<double>(angle, axis.vector()));
|
||||
return gtsam::Quaternion(Eigen::AngleAxis<double>(angle, axis));
|
||||
#else
|
||||
return Rot3(SO3::AxisAngle(axis,angle));
|
||||
#endif
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
/// Construct from 2D point in plane at focal length f
|
||||
/// Unit3(p,1) can be viewed as normalized homogeneous coordinates of 2D point
|
||||
explicit Unit3(const Point2& p, double f = 1.0) : p_(p.x(), p.y(), f) {
|
||||
explicit Unit3(const Point2& p, double f) : p_(p.x(), p.y(), f) {
|
||||
p_.normalize();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ TEST( Cal3Bundler, calibrate )
|
|||
Point2 pn(0.5, 0.5);
|
||||
Point2 pi = K.uncalibrate(pn);
|
||||
Point2 pn_hat = K.calibrate(pi);
|
||||
CHECK( pn.equals(pn_hat, 1e-5));
|
||||
CHECK( traits<Point2>::Equals(pn, pn_hat, 1e-5));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -48,7 +48,7 @@ TEST( Cal3DS2, calibrate )
|
|||
Point2 pn(0.5, 0.5);
|
||||
Point2 pi = K.uncalibrate(pn);
|
||||
Point2 pn_hat = K.calibrate(pi);
|
||||
CHECK( pn.equals(pn_hat, 1e-5));
|
||||
CHECK( traits<Point2>::Equals(pn, pn_hat, 1e-5));
|
||||
}
|
||||
|
||||
Point2 uncalibrate_(const Cal3DS2& k, const Point2& pt) { return k.uncalibrate(pt); }
|
||||
|
|
|
@ -59,7 +59,7 @@ TEST( Cal3Unified, calibrate)
|
|||
{
|
||||
Point2 pi = K.uncalibrate(p);
|
||||
Point2 pn_hat = K.calibrate(pi);
|
||||
CHECK( p.equals(pn_hat, 1e-8));
|
||||
CHECK( traits<Point2>::Equals(p, pn_hat, 1e-8));
|
||||
}
|
||||
|
||||
Point2 uncalibrate_(const Cal3Unified& k, const Point2& pt) { return k.uncalibrate(pt); }
|
||||
|
|
|
@ -152,7 +152,7 @@ TEST( CalibratedCamera, Dproject_point_pose_infinity)
|
|||
Point2 result = camera.project2(pointAtInfinity, Dpose, Dpoint);
|
||||
Matrix numerical_pose = numericalDerivative21(projectAtInfinity, camera, pointAtInfinity);
|
||||
Matrix numerical_point = numericalDerivative22(projectAtInfinity, camera, pointAtInfinity);
|
||||
CHECK(assert_equal(Point2(), result));
|
||||
CHECK(assert_equal(Point2(0,0), result));
|
||||
CHECK(assert_equal(numerical_pose, Dpose, 1e-7));
|
||||
CHECK(assert_equal(numerical_point, Dpoint, 1e-7));
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ TEST(CameraSet, Pinhole) {
|
|||
EXPECT(!set.equals(set2));
|
||||
|
||||
// Check measurements
|
||||
Point2 expected;
|
||||
Point2 expected(0,0);
|
||||
ZZ z = set.project2(p);
|
||||
EXPECT(assert_equal(expected, z[0]));
|
||||
EXPECT(assert_equal(expected, z[1]));
|
||||
|
@ -117,7 +117,7 @@ TEST(CameraSet, Pinhole) {
|
|||
Unit3 pointAtInfinity(0, 0, 1000);
|
||||
EXPECT(
|
||||
assert_equal(pointAtInfinity,
|
||||
camera.backprojectPointAtInfinity(Point2())));
|
||||
camera.backprojectPointAtInfinity(Point2(0,0))));
|
||||
actualV = set.reprojectionError(pointAtInfinity, measured, Fs, E);
|
||||
EXPECT(assert_equal(expectedV, actualV));
|
||||
LONGS_EQUAL(2, Fs.size());
|
||||
|
|
|
@ -153,12 +153,12 @@ TEST( PinholeCamera, backproject2)
|
|||
Rot3 rot(1., 0., 0., 0., 0., 1., 0., -1., 0.); // a camera1 looking down
|
||||
Camera camera(Pose3(rot, origin), K);
|
||||
|
||||
Point3 actual = camera.backproject(Point2(), 1.);
|
||||
Point3 actual = camera.backproject(Point2(0,0), 1.);
|
||||
Point3 expected(0., 1., 0.);
|
||||
pair<Point2, bool> x = camera.projectSafe(expected);
|
||||
|
||||
EXPECT(assert_equal(expected, actual));
|
||||
EXPECT(assert_equal(Point2(), x.first));
|
||||
EXPECT(assert_equal(Point2(0,0), x.first));
|
||||
EXPECT(x.second);
|
||||
}
|
||||
|
||||
|
@ -169,12 +169,12 @@ TEST( PinholeCamera, backprojectInfinity2)
|
|||
Rot3 rot(1., 0., 0., 0., 0., 1., 0., -1., 0.); // a camera1 looking down
|
||||
Camera camera(Pose3(rot, origin), K);
|
||||
|
||||
Unit3 actual = camera.backprojectPointAtInfinity(Point2());
|
||||
Unit3 actual = camera.backprojectPointAtInfinity(Point2(0,0));
|
||||
Unit3 expected(0., 1., 0.);
|
||||
Point2 x = camera.project(expected);
|
||||
|
||||
EXPECT(assert_equal(expected, actual));
|
||||
EXPECT(assert_equal(Point2(), x));
|
||||
EXPECT(assert_equal(Point2(0,0), x));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -184,12 +184,12 @@ TEST( PinholeCamera, backprojectInfinity3)
|
|||
Rot3 rot(1., 0., 0., 0., 1., 0., 0., 0., 1.); // identity
|
||||
Camera camera(Pose3(rot, origin), K);
|
||||
|
||||
Unit3 actual = camera.backprojectPointAtInfinity(Point2());
|
||||
Unit3 actual = camera.backprojectPointAtInfinity(Point2(0,0));
|
||||
Unit3 expected(0., 0., 1.);
|
||||
Point2 x = camera.project(expected);
|
||||
|
||||
EXPECT(assert_equal(expected, actual));
|
||||
EXPECT(assert_equal(Point2(), x));
|
||||
EXPECT(assert_equal(Point2(0,0), x));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -278,7 +278,7 @@ TEST( PinholeCamera, range0) {
|
|||
double result = camera.range(point1, D1, D2);
|
||||
Matrix Hexpected1 = numericalDerivative21(range0, camera, point1);
|
||||
Matrix Hexpected2 = numericalDerivative22(range0, camera, point1);
|
||||
EXPECT_DOUBLES_EQUAL(distance(point1, camera.pose().translation()), result,
|
||||
EXPECT_DOUBLES_EQUAL(distance3(point1, camera.pose().translation()), result,
|
||||
1e-9);
|
||||
EXPECT(assert_equal(Hexpected1, D1, 1e-7));
|
||||
EXPECT(assert_equal(Hexpected2, D2, 1e-7));
|
||||
|
|
|
@ -124,12 +124,12 @@ TEST( PinholePose, backproject2)
|
|||
Rot3 rot(1., 0., 0., 0., 0., 1., 0., -1., 0.); // a camera1 looking down
|
||||
Camera camera(Pose3(rot, origin), K);
|
||||
|
||||
Point3 actual = camera.backproject(Point2(), 1.);
|
||||
Point3 actual = camera.backproject(Point2(0,0), 1.);
|
||||
Point3 expected(0., 1., 0.);
|
||||
pair<Point2, bool> x = camera.projectSafe(expected);
|
||||
|
||||
EXPECT(assert_equal(expected, actual));
|
||||
EXPECT(assert_equal(Point2(), x.first));
|
||||
EXPECT(assert_equal(Point2(0,0), x.first));
|
||||
EXPECT(x.second);
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ TEST( PinholePose, range0) {
|
|||
double result = camera.range(point1, D1, D2);
|
||||
Matrix expectedDcamera = numericalDerivative21(range0, camera, point1);
|
||||
Matrix expectedDpoint = numericalDerivative22(range0, camera, point1);
|
||||
EXPECT_DOUBLES_EQUAL(distance(point1, camera.pose().translation()), result, 1e-9);
|
||||
EXPECT_DOUBLES_EQUAL(distance3(point1, camera.pose().translation()), result, 1e-9);
|
||||
EXPECT(assert_equal(expectedDcamera, D1, 1e-7));
|
||||
EXPECT(assert_equal(expectedDpoint, D2, 1e-7));
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ TEST(PinholeSet, Pinhole) {
|
|||
EXPECT(!set.equals(set2));
|
||||
|
||||
// Check measurements
|
||||
Point2 expected;
|
||||
Point2 expected(0,0);
|
||||
ZZ z = set.project2(p);
|
||||
EXPECT(assert_equal(expected, z[0]));
|
||||
EXPECT(assert_equal(expected, z[1]));
|
||||
|
@ -131,7 +131,7 @@ TEST(PinholeSet, Pinhole) {
|
|||
}
|
||||
EXPECT(
|
||||
assert_equal(pointAtInfinity,
|
||||
camera.backprojectPointAtInfinity(Point2())));
|
||||
camera.backprojectPointAtInfinity(Point2(0,0))));
|
||||
{
|
||||
PinholeSet<Camera>::FBlocks Fs;
|
||||
Matrix E;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
@ -27,6 +27,11 @@ using namespace gtsam;
|
|||
GTSAM_CONCEPT_TESTABLE_INST(Point2)
|
||||
GTSAM_CONCEPT_LIE_INST(Point2)
|
||||
|
||||
//******************************************************************************
|
||||
TEST(Point2 , Constructor) {
|
||||
Point2 p;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
TEST(Double , Concept) {
|
||||
BOOST_CONCEPT_ASSERT((IsGroup<double>));
|
||||
|
@ -95,26 +100,26 @@ TEST( Point2, expmap) {
|
|||
|
||||
/* ************************************************************************* */
|
||||
TEST( Point2, arithmetic) {
|
||||
EXPECT(assert_equal( Point2(-5,-6), -Point2(5,6) ));
|
||||
EXPECT(assert_equal( Point2(5,6), Point2(4,5)+Point2(1,1)));
|
||||
EXPECT(assert_equal( Point2(3,4), Point2(4,5)-Point2(1,1) ));
|
||||
EXPECT(assert_equal( Point2(8,6), Point2(4,3)*2));
|
||||
EXPECT(assert_equal( Point2(4,6), 2*Point2(2,3)));
|
||||
EXPECT(assert_equal( Point2(2,3), Point2(4,6)/2));
|
||||
EXPECT(assert_equal<Point2>( Point2(-5,-6), -Point2(5,6) ));
|
||||
EXPECT(assert_equal<Point2>( Point2(5,6), Point2(4,5)+Point2(1,1)));
|
||||
EXPECT(assert_equal<Point2>( Point2(3,4), Point2(4,5)-Point2(1,1) ));
|
||||
EXPECT(assert_equal<Point2>( Point2(8,6), Point2(4,3)*2));
|
||||
EXPECT(assert_equal<Point2>( Point2(4,6), 2*Point2(2,3)));
|
||||
EXPECT(assert_equal<Point2>( Point2(2,3), Point2(4,6)/2));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( Point2, unit) {
|
||||
Point2 p0(10, 0), p1(0, -10), p2(10, 10);
|
||||
EXPECT(assert_equal(Point2(1, 0), p0.unit(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(0,-1), p1.unit(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(sqrt(2.0)/2.0, sqrt(2.0)/2.0), p2.unit(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(1, 0), Point2(p0.normalized()), 1e-6));
|
||||
EXPECT(assert_equal(Point2(0,-1), Point2(p1.normalized()), 1e-6));
|
||||
EXPECT(assert_equal(Point2(sqrt(2.0)/2.0, sqrt(2.0)/2.0), Point2(p2.normalized()), 1e-6));
|
||||
}
|
||||
|
||||
namespace {
|
||||
/* ************************************************************************* */
|
||||
// some shared test values
|
||||
Point2 x1, x2(1, 1), x3(1, 1);
|
||||
Point2 x1(0,0), x2(1, 1), x3(1, 1);
|
||||
Point2 l1(1, 0), l2(1, 1), l3(2, 2), l4(1, 3);
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -126,19 +131,19 @@ TEST( Point2, norm ) {
|
|||
Point2 p0(cos(5.0), sin(5.0));
|
||||
DOUBLES_EQUAL(1, p0.norm(), 1e-6);
|
||||
Point2 p1(4, 5), p2(1, 1);
|
||||
DOUBLES_EQUAL( 5, p1.distance(p2), 1e-6);
|
||||
DOUBLES_EQUAL( 5, distance2(p1, p2), 1e-6);
|
||||
DOUBLES_EQUAL( 5, (p2-p1).norm(), 1e-6);
|
||||
|
||||
Matrix expectedH, actualH;
|
||||
double actual;
|
||||
|
||||
// exception, for (0,0) derivative is [Inf,Inf] but we return [1,1]
|
||||
actual = x1.norm(actualH);
|
||||
actual = norm2(x1, actualH);
|
||||
EXPECT_DOUBLES_EQUAL(0, actual, 1e-9);
|
||||
expectedH = (Matrix(1, 2) << 1.0, 1.0).finished();
|
||||
EXPECT(assert_equal(expectedH,actualH));
|
||||
|
||||
actual = x2.norm(actualH);
|
||||
actual = norm2(x2, actualH);
|
||||
EXPECT_DOUBLES_EQUAL(sqrt(2.0), actual, 1e-9);
|
||||
expectedH = numericalDerivative11(norm_proxy, x2);
|
||||
EXPECT(assert_equal(expectedH,actualH));
|
||||
|
@ -151,20 +156,20 @@ TEST( Point2, norm ) {
|
|||
/* ************************************************************************* */
|
||||
namespace {
|
||||
double distance_proxy(const Point2& location, const Point2& point) {
|
||||
return location.distance(point);
|
||||
return distance2(location, point);
|
||||
}
|
||||
}
|
||||
TEST( Point2, distance ) {
|
||||
Matrix expectedH1, actualH1, expectedH2, actualH2;
|
||||
|
||||
// establish distance is indeed zero
|
||||
EXPECT_DOUBLES_EQUAL(1, x1.distance(l1), 1e-9);
|
||||
EXPECT_DOUBLES_EQUAL(1, distance2(x1, l1), 1e-9);
|
||||
|
||||
// establish distance is indeed 45 degrees
|
||||
EXPECT_DOUBLES_EQUAL(sqrt(2.0), x1.distance(l2), 1e-9);
|
||||
EXPECT_DOUBLES_EQUAL(sqrt(2.0), distance2(x1, l2), 1e-9);
|
||||
|
||||
// Another pair
|
||||
double actual23 = x2.distance(l3, actualH1, actualH2);
|
||||
double actual23 = distance2(x2, l3, actualH1, actualH2);
|
||||
EXPECT_DOUBLES_EQUAL(sqrt(2.0), actual23, 1e-9);
|
||||
|
||||
// Check numerical derivatives
|
||||
|
@ -174,7 +179,7 @@ TEST( Point2, distance ) {
|
|||
EXPECT(assert_equal(expectedH2,actualH2));
|
||||
|
||||
// Another test
|
||||
double actual34 = x3.distance(l4, actualH1, actualH2);
|
||||
double actual34 = distance2(x3, l4, actualH1, actualH2);
|
||||
EXPECT_DOUBLES_EQUAL(2, actual34, 1e-9);
|
||||
|
||||
// Check numerical derivatives
|
||||
|
@ -190,42 +195,42 @@ TEST( Point2, circleCircleIntersection) {
|
|||
double offset = 0.994987;
|
||||
// Test intersections of circle moving from inside to outside
|
||||
|
||||
list<Point2> inside = Point2::CircleCircleIntersection(Point2(0,0),5,Point2(0,0),1);
|
||||
list<Point2> inside = circleCircleIntersection(Point2(0,0),5,Point2(0,0),1);
|
||||
EXPECT_LONGS_EQUAL(0,inside.size());
|
||||
|
||||
list<Point2> touching1 = Point2::CircleCircleIntersection(Point2(0,0),5,Point2(4,0),1);
|
||||
list<Point2> touching1 = circleCircleIntersection(Point2(0,0),5,Point2(4,0),1);
|
||||
EXPECT_LONGS_EQUAL(1,touching1.size());
|
||||
EXPECT(assert_equal(Point2(5,0), touching1.front()));
|
||||
|
||||
list<Point2> common = Point2::CircleCircleIntersection(Point2(0,0),5,Point2(5,0),1);
|
||||
list<Point2> common = circleCircleIntersection(Point2(0,0),5,Point2(5,0),1);
|
||||
EXPECT_LONGS_EQUAL(2,common.size());
|
||||
EXPECT(assert_equal(Point2(4.9, offset), common.front(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(4.9, -offset), common.back(), 1e-6));
|
||||
|
||||
list<Point2> touching2 = Point2::CircleCircleIntersection(Point2(0,0),5,Point2(6,0),1);
|
||||
list<Point2> touching2 = circleCircleIntersection(Point2(0,0),5,Point2(6,0),1);
|
||||
EXPECT_LONGS_EQUAL(1,touching2.size());
|
||||
EXPECT(assert_equal(Point2(5,0), touching2.front()));
|
||||
|
||||
// test rotated case
|
||||
list<Point2> rotated = Point2::CircleCircleIntersection(Point2(0,0),5,Point2(0,5),1);
|
||||
list<Point2> rotated = circleCircleIntersection(Point2(0,0),5,Point2(0,5),1);
|
||||
EXPECT_LONGS_EQUAL(2,rotated.size());
|
||||
EXPECT(assert_equal(Point2(-offset, 4.9), rotated.front(), 1e-6));
|
||||
EXPECT(assert_equal(Point2( offset, 4.9), rotated.back(), 1e-6));
|
||||
|
||||
// test r1<r2
|
||||
list<Point2> smaller = Point2::CircleCircleIntersection(Point2(0,0),1,Point2(5,0),5);
|
||||
list<Point2> smaller = circleCircleIntersection(Point2(0,0),1,Point2(5,0),5);
|
||||
EXPECT_LONGS_EQUAL(2,smaller.size());
|
||||
EXPECT(assert_equal(Point2(0.1, offset), smaller.front(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(0.1, -offset), smaller.back(), 1e-6));
|
||||
|
||||
// test offset case, r1>r2
|
||||
list<Point2> offset1 = Point2::CircleCircleIntersection(Point2(1,1),5,Point2(6,1),1);
|
||||
list<Point2> offset1 = circleCircleIntersection(Point2(1,1),5,Point2(6,1),1);
|
||||
EXPECT_LONGS_EQUAL(2,offset1.size());
|
||||
EXPECT(assert_equal(Point2(5.9, 1+offset), offset1.front(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(5.9, 1-offset), offset1.back(), 1e-6));
|
||||
|
||||
// test offset case, r1<r2
|
||||
list<Point2> offset2 = Point2::CircleCircleIntersection(Point2(6,1),1,Point2(1,1),5);
|
||||
list<Point2> offset2 = circleCircleIntersection(Point2(6,1),1,Point2(1,1),5);
|
||||
EXPECT_LONGS_EQUAL(2,offset2.size());
|
||||
EXPECT(assert_equal(Point2(5.9, 1-offset), offset2.front(), 1e-6));
|
||||
EXPECT(assert_equal(Point2(5.9, 1+offset), offset2.back(), 1e-6));
|
||||
|
@ -233,12 +238,14 @@ TEST( Point2, circleCircleIntersection) {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
TEST( Point2, stream) {
|
||||
Point2 p(1, 2);
|
||||
std::ostringstream os;
|
||||
os << p;
|
||||
EXPECT(os.str() == "(1, 2)");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main () {
|
||||
|
|
|
@ -26,6 +26,11 @@ GTSAM_CONCEPT_LIE_INST(Point3)
|
|||
|
||||
static Point3 P(0.2, 0.7, -2);
|
||||
|
||||
//******************************************************************************
|
||||
TEST(Point3 , Constructor) {
|
||||
Point3 p;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
TEST(Point3 , Concept) {
|
||||
BOOST_CONCEPT_ASSERT((IsGroup<Point3>));
|
||||
|
@ -149,7 +154,7 @@ TEST( Point3, cross2) {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
#ifndef GTSAM_USE_VECTOR3_POINTS
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
TEST( Point3, stream) {
|
||||
Point3 p(1, 2, -3);
|
||||
std::ostringstream os;
|
||||
|
@ -178,20 +183,20 @@ TEST (Point3, norm) {
|
|||
Matrix actualH;
|
||||
Point3 point(3,4,5); // arbitrary point
|
||||
double expected = sqrt(50);
|
||||
EXPECT_DOUBLES_EQUAL(expected, norm(point, actualH), 1e-8);
|
||||
EXPECT_DOUBLES_EQUAL(expected, norm3(point, actualH), 1e-8);
|
||||
Matrix expectedH = numericalDerivative11<double, Point3>(norm_proxy, point);
|
||||
EXPECT(assert_equal(expectedH, actualH, 1e-8));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double testFunc(const Point3& P, const Point3& Q) {
|
||||
return distance(P,Q);
|
||||
return distance3(P, Q);
|
||||
}
|
||||
|
||||
TEST (Point3, distance) {
|
||||
Point3 P(1., 12.8, -32.), Q(52.7, 4.9, -13.3);
|
||||
Matrix H1, H2;
|
||||
double d = distance(P, Q, H1, H2);
|
||||
double d = distance3(P, Q, H1, H2);
|
||||
double expectedDistance = 55.542686;
|
||||
Matrix numH1 = numericalDerivative21(testFunc, P, Q);
|
||||
Matrix numH2 = numericalDerivative22(testFunc, P, Q);
|
||||
|
|
|
@ -43,7 +43,7 @@ TEST(Pose2 , Concept) {
|
|||
|
||||
/* ************************************************************************* */
|
||||
TEST(Pose2, constructors) {
|
||||
Point2 p;
|
||||
Point2 p(0,0);
|
||||
Pose2 pose(0,p);
|
||||
Pose2 origin;
|
||||
assert_equal(pose,origin);
|
||||
|
@ -371,7 +371,7 @@ TEST(Pose2, compose_c)
|
|||
/* ************************************************************************* */
|
||||
TEST(Pose2, inverse )
|
||||
{
|
||||
Point2 origin, t(1,2);
|
||||
Point2 origin(0,0), t(1,2);
|
||||
Pose2 gTl(M_PI/2.0, t); // robot at (1,2) looking towards y
|
||||
|
||||
Pose2 identity, lTg = gTl.inverse();
|
||||
|
@ -409,7 +409,7 @@ namespace {
|
|||
/* ************************************************************************* */
|
||||
TEST( Pose2, matrix )
|
||||
{
|
||||
Point2 origin, t(1,2);
|
||||
Point2 origin(0,0), t(1,2);
|
||||
Pose2 gTl(M_PI/2.0, t); // robot at (1,2) looking towards y
|
||||
Matrix gMl = matrix(gTl);
|
||||
EXPECT(assert_equal((Matrix(3,3) <<
|
||||
|
@ -743,7 +743,7 @@ namespace {
|
|||
/* ************************************************************************* */
|
||||
struct Triangle { size_t i_,j_,k_;};
|
||||
|
||||
boost::optional<Pose2> align(const vector<Point2>& ps, const vector<Point2>& qs,
|
||||
boost::optional<Pose2> align2(const vector<Point2>& ps, const vector<Point2>& qs,
|
||||
const pair<Triangle, Triangle>& trianglePair) {
|
||||
const Triangle& t1 = trianglePair.first, t2 = trianglePair.second;
|
||||
vector<Point2Pair> correspondences;
|
||||
|
@ -762,7 +762,7 @@ TEST(Pose2, align_4) {
|
|||
Triangle t1; t1.i_=0; t1.j_=1; t1.k_=2;
|
||||
Triangle t2; t2.i_=1; t2.j_=2; t2.k_=0;
|
||||
|
||||
boost::optional<Pose2> actual = align(ps, qs, make_pair(t1,t2));
|
||||
boost::optional<Pose2> actual = align2(ps, qs, make_pair(t1,t2));
|
||||
EXPECT(assert_equal(expected, *actual));
|
||||
}
|
||||
|
||||
|
|
|
@ -104,12 +104,12 @@ TEST( SimpleCamera, backproject2)
|
|||
Rot3 rot(1., 0., 0., 0., 0., 1., 0., -1., 0.); // a camera looking down
|
||||
SimpleCamera camera(Pose3(rot, origin), K);
|
||||
|
||||
Point3 actual = camera.backproject(Point2(), 1.);
|
||||
Point3 actual = camera.backproject(Point2(0,0), 1.);
|
||||
Point3 expected(0., 1., 0.);
|
||||
pair<Point2, bool> x = camera.projectSafe(expected);
|
||||
|
||||
CHECK(assert_equal(expected, actual));
|
||||
CHECK(assert_equal(Point2(), x.first));
|
||||
CHECK(assert_equal(Point2(0,0), x.first));
|
||||
CHECK(x.second);
|
||||
}
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ TEST( triangulation, onePose) {
|
|||
vector<Point2> measurements;
|
||||
|
||||
poses += Pose3();
|
||||
measurements += Point2();
|
||||
measurements += Point2(0,0);
|
||||
|
||||
CHECK_EXCEPTION(triangulatePoint3(poses, sharedCal, measurements),
|
||||
TriangulationUnderconstrainedException);
|
||||
|
@ -282,7 +282,7 @@ TEST( triangulation, onePose) {
|
|||
//******************************************************************************
|
||||
TEST( triangulation, StereotriangulateNonlinear ) {
|
||||
|
||||
Cal3_S2Stereo::shared_ptr stereoK(new Cal3_S2Stereo(1733.75, 1733.75, 0, 689.645, 508.835, 0.0699612));
|
||||
auto stereoK = boost::make_shared<Cal3_S2Stereo>(1733.75, 1733.75, 0, 689.645, 508.835, 0.0699612);
|
||||
|
||||
// two camera poses m1, m2
|
||||
Matrix4 m1, m2;
|
||||
|
|
|
@ -112,7 +112,8 @@ std::pair<NonlinearFactorGraph, Values> triangulationGraph(
|
|||
Values values;
|
||||
values.insert(landmarkKey, initialEstimate); // Initial landmark value
|
||||
NonlinearFactorGraph graph;
|
||||
static SharedNoiseModel unit(noiseModel::Unit::Create(CAMERA::Measurement::dimension));
|
||||
static SharedNoiseModel unit(noiseModel::Unit::Create(
|
||||
traits<typename CAMERA::Measurement>::dimension));
|
||||
for (size_t i = 0; i < measurements.size(); i++) {
|
||||
const CAMERA& camera_i = cameras[i];
|
||||
graph.push_back(TriangulationFactor<CAMERA> //
|
||||
|
@ -457,7 +458,7 @@ TriangulationResult triangulateSafe(const std::vector<CAMERA>& cameras,
|
|||
for(const CAMERA& camera: cameras) {
|
||||
const Pose3& pose = camera.pose();
|
||||
if (params.landmarkDistanceThreshold > 0
|
||||
&& distance(pose.translation(), point)
|
||||
&& distance3(pose.translation(), point)
|
||||
> params.landmarkDistanceThreshold)
|
||||
return TriangulationResult::Degenerate();
|
||||
#ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
|
||||
|
@ -471,7 +472,7 @@ TriangulationResult triangulateSafe(const std::vector<CAMERA>& cameras,
|
|||
if (params.dynamicOutlierRejectionThreshold > 0) {
|
||||
const Point2& zi = measured.at(i);
|
||||
Point2 reprojectionError(camera.project(point) - zi);
|
||||
totalReprojError += reprojectionError.vector().norm();
|
||||
totalReprojError += reprojectionError.norm();
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
/// @{
|
||||
NavState deltaXij() const override { return deltaXij_; }
|
||||
Rot3 deltaRij() const override { return deltaXij_.attitude(); }
|
||||
Vector3 deltaPij() const override { return deltaXij_.position().vector(); }
|
||||
Vector3 deltaPij() const override { return deltaXij_.position(); }
|
||||
Vector3 deltaVij() const override { return deltaXij_.velocity(); }
|
||||
|
||||
Matrix3 delRdelBiasOmega() const { return delRdelBiasOmega_; }
|
||||
|
|
|
@ -61,16 +61,14 @@ namespace gtsam {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class VALUE>
|
||||
ExtendedKalmanFilter<VALUE>::ExtendedKalmanFilter(Key key_initial, T x_initial,
|
||||
noiseModel::Gaussian::shared_ptr P_initial) {
|
||||
|
||||
// Set the initial linearization point to the provided mean
|
||||
x_ = x_initial;
|
||||
|
||||
template <class VALUE>
|
||||
ExtendedKalmanFilter<VALUE>::ExtendedKalmanFilter(
|
||||
Key key_initial, T x_initial, noiseModel::Gaussian::shared_ptr P_initial)
|
||||
: x_(x_initial) // Set the initial linearization point
|
||||
{
|
||||
// Create a Jacobian Prior Factor directly P_initial.
|
||||
// Since x0 is set to the provided mean, the b vector in the prior will be zero
|
||||
// TODO Frank asks: is there a reason why noiseModel is not simply P_initial ?
|
||||
// TODO(Frank): is there a reason why noiseModel is not simply P_initial?
|
||||
int n = traits<T>::GetDimension(x_initial);
|
||||
priorFactor_ = JacobianFactor::shared_ptr(
|
||||
new JacobianFactor(key_initial, P_initial->R(), Vector::Zero(n),
|
||||
|
|
|
@ -260,7 +260,7 @@ public:
|
|||
std::cout << s << ": NonlinearEquality1(" << keyFormatter(this->key())
|
||||
<< ")," << "\n";
|
||||
this->noiseModel_->print();
|
||||
value_.print("Value");
|
||||
traits<X>::Print(value_, "Value");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -80,7 +80,7 @@ TEST(Expression, Leaves) {
|
|||
// Unary(Leaf)
|
||||
namespace unary {
|
||||
Point2 f1(const Point3& p, OptionalJacobian<2, 3> H) {
|
||||
return Point2();
|
||||
return Point2(0,0);
|
||||
}
|
||||
double f2(const Point3& p, OptionalJacobian<1, 3> H) {
|
||||
return 0.0;
|
||||
|
@ -111,24 +111,43 @@ TEST(Expression, Unary3) {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
class Class : public Point3 {
|
||||
public:
|
||||
enum {dimension = 3};
|
||||
using Point3::Point3;
|
||||
const Vector3& vector() const { return *this; }
|
||||
inline static Class identity() { return Class(0,0,0); }
|
||||
double norm(OptionalJacobian<1,3> H = boost::none) const {
|
||||
return norm3(*this, H);
|
||||
}
|
||||
bool equals(const Class &q, double tol) const {
|
||||
return (fabs(x() - q.x()) < tol && fabs(y() - q.y()) < tol && fabs(z() - q.z()) < tol);
|
||||
}
|
||||
void print(const string& s) const { cout << s << *this << endl;}
|
||||
};
|
||||
|
||||
namespace gtsam {
|
||||
template<> struct traits<Class> : public internal::VectorSpace<Class> {};
|
||||
}
|
||||
|
||||
// Nullary Method
|
||||
TEST(Expression, NullaryMethod) {
|
||||
// Create expression
|
||||
Expression<Point3> p(67);
|
||||
Expression<double> norm(>sam::norm, p);
|
||||
Expression<Class> p(67);
|
||||
Expression<double> norm_(p, &Class::norm);
|
||||
|
||||
// Create Values
|
||||
Values values;
|
||||
values.insert(67, Point3(3, 4, 5));
|
||||
values.insert(67, Class(3, 4, 5));
|
||||
|
||||
// Check dims as map
|
||||
std::map<Key, int> map;
|
||||
norm.dims(map);
|
||||
norm_.dims(map);
|
||||
LONGS_EQUAL(1, map.size());
|
||||
|
||||
// Get value and Jacobians
|
||||
std::vector<Matrix> H(1);
|
||||
double actual = norm.value(values, H);
|
||||
double actual = norm_.value(values, H);
|
||||
|
||||
// Check all
|
||||
EXPECT(actual == sqrt(50));
|
||||
|
@ -370,7 +389,7 @@ TEST(Expression, TripleSum) {
|
|||
/* ************************************************************************* */
|
||||
TEST(Expression, SumOfUnaries) {
|
||||
const Key key(67);
|
||||
const Double_ norm_(>sam::norm, Point3_(key));
|
||||
const Double_ norm_(>sam::norm3, Point3_(key));
|
||||
const Double_ sum_ = norm_ + norm_;
|
||||
|
||||
Values values;
|
||||
|
@ -389,7 +408,7 @@ TEST(Expression, SumOfUnaries) {
|
|||
TEST(Expression, UnaryOfSum) {
|
||||
const Key key1(42), key2(67);
|
||||
const Point3_ sum_ = Point3_(key1) + Point3_(key2);
|
||||
const Double_ norm_(>sam::norm, sum_);
|
||||
const Double_ norm_(>sam::norm3, sum_);
|
||||
|
||||
map<Key, int> actual_dims, expected_dims = map_list_of<Key, int>(key1, 3)(key2, 3);
|
||||
norm_.dims(actual_dims);
|
||||
|
|
|
@ -139,7 +139,7 @@ public:
|
|||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s);
|
||||
std::cout << " EssentialMatrixFactor2 with measurements\n ("
|
||||
<< dP1_.transpose() << ")' and (" << pn_.vector().transpose()
|
||||
<< dP1_.transpose() << ")' and (" << pn_.transpose()
|
||||
<< ")'" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ public:
|
|||
// The point d*P1 = (x,y,1) is computed in constructor as dP1_
|
||||
|
||||
// Project to normalized image coordinates, then uncalibrate
|
||||
Point2 pn;
|
||||
Point2 pn(0,0);
|
||||
if (!DE && !Dd) {
|
||||
|
||||
Point3 _1T2 = E.direction().point3();
|
||||
|
@ -195,7 +195,7 @@ public:
|
|||
|
||||
}
|
||||
Point2 reprojectionError = pn - pn_;
|
||||
return f_ * reprojectionError.vector();
|
||||
return f_ * reprojectionError;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
*/
|
||||
void print(const std::string& s = "SFMFactor", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,15 +115,14 @@ public:
|
|||
*/
|
||||
bool equals(const NonlinearFactor &p, double tol = 1e-9) const {
|
||||
const This* e = dynamic_cast<const This*>(&p);
|
||||
return e && Base::equals(p, tol) && this->measured_.equals(e->measured_, tol);
|
||||
return e && Base::equals(p, tol) && traits<Point2>::Equals(this->measured_, e->measured_, tol);
|
||||
}
|
||||
|
||||
/** h(x)-z */
|
||||
Vector evaluateError(const CAMERA& camera, const LANDMARK& point,
|
||||
boost::optional<Matrix&> H1=boost::none, boost::optional<Matrix&> H2=boost::none) const {
|
||||
try {
|
||||
Point2 reprojError(camera.project2(point,H1,H2) - measured_);
|
||||
return reprojError.vector();
|
||||
return camera.project2(point,H1,H2) - measured_;
|
||||
}
|
||||
catch( CheiralityException& e) {
|
||||
if (H1) *H1 = JacobianC::Zero();
|
||||
|
@ -145,8 +144,7 @@ public:
|
|||
try {
|
||||
const CAMERA& camera = values.at<CAMERA>(key1);
|
||||
const LANDMARK& point = values.at<LANDMARK>(key2);
|
||||
Point2 reprojError(camera.project2(point, H1, H2) - measured());
|
||||
b = -reprojError.vector();
|
||||
b = measured() - camera.project2(point, H1, H2);
|
||||
} catch (CheiralityException& e) {
|
||||
H1.setZero();
|
||||
H2.setZero();
|
||||
|
@ -243,7 +241,7 @@ public:
|
|||
*/
|
||||
void print(const std::string& s = "SFMFactor2", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,7 +249,7 @@ public:
|
|||
*/
|
||||
bool equals(const NonlinearFactor &p, double tol = 1e-9) const {
|
||||
const This* e = dynamic_cast<const This*>(&p);
|
||||
return e && Base::equals(p, tol) && this->measured_.equals(e->measured_, tol);
|
||||
return e && Base::equals(p, tol) && traits<Point2>::Equals(this->measured_, e->measured_, tol);
|
||||
}
|
||||
|
||||
/** h(x)-z */
|
||||
|
@ -262,8 +260,7 @@ public:
|
|||
{
|
||||
try {
|
||||
Camera camera(pose3,calib);
|
||||
Point2 reprojError(camera.project(point, H1, H2, H3) - measured_);
|
||||
return reprojError.vector();
|
||||
return camera.project(point, H1, H2, H3) - measured_;
|
||||
}
|
||||
catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2, 6);
|
||||
|
|
|
@ -56,7 +56,9 @@ namespace gtsam {
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
GenericProjectionFactor() : throwCheirality_(false), verboseCheirality_(false) {}
|
||||
GenericProjectionFactor() :
|
||||
measured_(0, 0), throwCheirality_(false), verboseCheirality_(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -108,7 +110,7 @@ namespace gtsam {
|
|||
*/
|
||||
void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
std::cout << s << "GenericProjectionFactor, z = ";
|
||||
measured_.print();
|
||||
traits<Point2>::Print(measured_);
|
||||
if(this->body_P_sensor_)
|
||||
this->body_P_sensor_->print(" sensor pose in body frame: ");
|
||||
Base::print("", keyFormatter);
|
||||
|
@ -119,7 +121,7 @@ namespace gtsam {
|
|||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol)
|
||||
&& ((!body_P_sensor_ && !e->body_P_sensor_) || (body_P_sensor_ && e->body_P_sensor_ && body_P_sensor_->equals(*e->body_P_sensor_)));
|
||||
}
|
||||
|
@ -134,16 +136,14 @@ namespace gtsam {
|
|||
PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_, H0), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2, boost::none) - measured_);
|
||||
*H1 = *H1 * H0;
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2, boost::none) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(point, H1, H2, boost::none) - measured_;
|
||||
}
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose, *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2, boost::none) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(point, H1, H2, boost::none) - measured_;
|
||||
}
|
||||
} catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2,6);
|
||||
|
|
|
@ -84,7 +84,7 @@ public:
|
|||
* each degree of freedom.
|
||||
*/
|
||||
ReferenceFrameFactor(Key globalKey, Key transKey, Key localKey, double sigma = 1e-2)
|
||||
: Base(noiseModel::Isotropic::Sigma(POINT::dimension, sigma),
|
||||
: Base(noiseModel::Isotropic::Sigma(traits<POINT>::dimension, sigma),
|
||||
globalKey, transKey, localKey) {}
|
||||
|
||||
virtual ~ReferenceFrameFactor(){}
|
||||
|
@ -100,7 +100,7 @@ public:
|
|||
boost::optional<Matrix&> Dlocal = boost::none) const {
|
||||
Point newlocal = transform_point<Transform,Point>(trans, global, Dtrans, Dforeign);
|
||||
if (Dlocal)
|
||||
*Dlocal = -1* Matrix::Identity(Point::dimension,Point::dimension);
|
||||
*Dlocal = -1* Matrix::Identity(traits<Point>::dimension, traits<Point>::dimension);
|
||||
return traits<Point>::Local(local,newlocal);
|
||||
}
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ public:
|
|||
|
||||
bool areMeasurementsEqual = true;
|
||||
for (size_t i = 0; i < measured_.size(); i++) {
|
||||
if (this->measured_.at(i).equals(e->measured_.at(i), tol) == false)
|
||||
if (traits<Z>::Equals(this->measured_.at(i), e->measured_.at(i), tol) == false)
|
||||
areMeasurementsEqual = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -499,8 +499,8 @@ public:
|
|||
return Base::totalReprojectionError(cameras, *result_);
|
||||
else if (params_.degeneracyMode == HANDLE_INFINITY) {
|
||||
// Otherwise, manage the exceptions with rotation-only factors
|
||||
const Point2& z0 = this->measured_.at(0);
|
||||
Unit3 backprojected = cameras.front().backprojectPointAtInfinity(z0);
|
||||
Unit3 backprojected = cameras.front().backprojectPointAtInfinity(
|
||||
this->measured_.at(0));
|
||||
return Base::totalReprojectionError(cameras, backprojected);
|
||||
} else
|
||||
// if we don't want to manage the exceptions we discard the factor
|
||||
|
|
|
@ -78,12 +78,11 @@ public:
|
|||
bool verboseCheirality = false) :
|
||||
Base(model, pointKey), camera_(camera), measured_(measured), throwCheirality_(
|
||||
throwCheirality), verboseCheirality_(verboseCheirality) {
|
||||
if (model && model->dim() != Measurement::dimension)
|
||||
if (model && model->dim() != traits<Measurement>::dimension)
|
||||
throw std::invalid_argument(
|
||||
"TriangulationFactor must be created with "
|
||||
+ boost::lexical_cast<std::string>((int) Measurement::dimension)
|
||||
+ boost::lexical_cast<std::string>((int) traits<Measurement>::dimension)
|
||||
+ "-dimensional noise model.");
|
||||
|
||||
}
|
||||
|
||||
/** Virtual destructor */
|
||||
|
@ -105,7 +104,7 @@ public:
|
|||
DefaultKeyFormatter) const {
|
||||
std::cout << s << "TriangulationFactor,";
|
||||
camera_.print("camera");
|
||||
measured_.print("z");
|
||||
traits<Measurement>::Print(measured_, "z");
|
||||
Base::print("", keyFormatter);
|
||||
}
|
||||
|
||||
|
@ -113,25 +112,24 @@ public:
|
|||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e && Base::equals(p, tol) && this->camera_.equals(e->camera_, tol)
|
||||
&& this->measured_.equals(e->measured_, tol);
|
||||
&& traits<Measurement>::Equals(this->measured_, e->measured_, tol);
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
Vector evaluateError(const Point3& point, boost::optional<Matrix&> H2 =
|
||||
boost::none) const {
|
||||
try {
|
||||
Measurement error(camera_.project2(point, boost::none, H2) - measured_);
|
||||
return error.vector();
|
||||
return traits<Measurement>::Local(measured_, camera_.project2(point, boost::none, H2));
|
||||
} catch (CheiralityException& e) {
|
||||
if (H2)
|
||||
*H2 = Matrix::Zero(Measurement::dimension, 3);
|
||||
*H2 = Matrix::Zero(traits<Measurement>::dimension, 3);
|
||||
if (verboseCheirality_)
|
||||
std::cout << e.what() << ": Landmark "
|
||||
<< DefaultKeyFormatter(this->key()) << " moved behind camera"
|
||||
<< std::endl;
|
||||
if (throwCheirality_)
|
||||
throw e;
|
||||
return Eigen::Matrix<double,Measurement::dimension,1>::Constant(2.0 * camera_.calibration().fx());
|
||||
return Eigen::Matrix<double,traits<Measurement>::dimension,1>::Constant(2.0 * camera_.calibration().fx());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,14 +151,14 @@ public:
|
|||
// Allocate memory for Jacobian factor, do only once
|
||||
if (Ab.rows() == 0) {
|
||||
std::vector<size_t> dimensions(1, 3);
|
||||
Ab = VerticalBlockMatrix(dimensions, Measurement::dimension, true);
|
||||
A.resize(Measurement::dimension,3);
|
||||
b.resize(Measurement::dimension);
|
||||
Ab = VerticalBlockMatrix(dimensions, traits<Measurement>::dimension, true);
|
||||
A.resize(traits<Measurement>::dimension,3);
|
||||
b.resize(traits<Measurement>::dimension);
|
||||
}
|
||||
|
||||
// Would be even better if we could pass blocks to project
|
||||
const Point3& point = x.at<Point3>(key());
|
||||
b = -(camera_.project2(point, boost::none, A) - measured_).vector();
|
||||
b = traits<Measurement>::Local(camera_.project2(point, boost::none, A), measured_);
|
||||
if (noiseModel_)
|
||||
this->noiseModel_->WhitenSystem(A, b);
|
||||
|
||||
|
|
|
@ -222,8 +222,7 @@ TEST (EssentialMatrixFactor2, factor) {
|
|||
// Check evaluation
|
||||
Point3 P1 = data.tracks[i].p, P2 = data.cameras[1].pose().transform_to(P1);
|
||||
const Point2 pi = PinholeBase::Project(P2);
|
||||
Point2 reprojectionError(pi - pB(i));
|
||||
Vector expected = reprojectionError.vector();
|
||||
Point2 expected(pi - pB(i));
|
||||
|
||||
Matrix Hactual1, Hactual2;
|
||||
double d(baseline / P1.z());
|
||||
|
@ -296,8 +295,7 @@ TEST (EssentialMatrixFactor3, factor) {
|
|||
// Check evaluation
|
||||
Point3 P1 = data.tracks[i].p;
|
||||
const Point2 pi = camera2.project(P1);
|
||||
Point2 reprojectionError(pi - pB(i));
|
||||
Vector expected = reprojectionError.vector();
|
||||
Point2 expected(pi - pB(i));
|
||||
|
||||
Matrix Hactual1, Hactual2;
|
||||
double d(baseline / P1.z());
|
||||
|
@ -438,8 +436,7 @@ TEST (EssentialMatrixFactor2, extraTest) {
|
|||
// Check evaluation
|
||||
Point3 P1 = data.tracks[i].p;
|
||||
const Point2 pi = camera2.project(P1);
|
||||
Point2 reprojectionError(pi - pB(i));
|
||||
Vector expected = reprojectionError.vector();
|
||||
Point2 expected(pi - pB(i));
|
||||
|
||||
Matrix Hactual1, Hactual2;
|
||||
double d(baseline / P1.z());
|
||||
|
@ -507,8 +504,7 @@ TEST (EssentialMatrixFactor3, extraTest) {
|
|||
// Check evaluation
|
||||
Point3 P1 = data.tracks[i].p;
|
||||
const Point2 pi = camera2.project(P1);
|
||||
Point2 reprojectionError(pi - pB(i));
|
||||
Vector expected = reprojectionError.vector();
|
||||
Point2 expected(pi - pB(i));
|
||||
|
||||
Matrix Hactual1, Hactual2;
|
||||
double d(baseline / P1.z());
|
||||
|
|
|
@ -55,8 +55,8 @@ struct traits<PinholeFactor> : public Testable<PinholeFactor> {};
|
|||
|
||||
TEST(SmartFactorBase, Pinhole) {
|
||||
PinholeFactor f= PinholeFactor(unit2);
|
||||
f.add(Point2(), 1);
|
||||
f.add(Point2(), 2);
|
||||
f.add(Point2(0,0), 1);
|
||||
f.add(Point2(0,0), 2);
|
||||
EXPECT_LONGS_EQUAL(2 * 2, f.dim());
|
||||
}
|
||||
|
||||
|
|
|
@ -300,20 +300,14 @@ TEST( SmartProjectionCameraFactor, perturbPoseAndOptimizeFromSfM_tracks ) {
|
|||
|
||||
SfM_Track track1;
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
SfM_Measurement measures;
|
||||
measures.first = i + 1; // cameras are from 1 to 3
|
||||
measures.second = measurements_cam1.at(i);
|
||||
track1.measurements.push_back(measures);
|
||||
track1.measurements.emplace_back(i + 1, measurements_cam1.at(i));
|
||||
}
|
||||
SmartFactor::shared_ptr smartFactor1(new SmartFactor(unit2));
|
||||
smartFactor1->add(track1);
|
||||
|
||||
SfM_Track track2;
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
SfM_Measurement measures;
|
||||
measures.first = i + 1; // cameras are from 1 to 3
|
||||
measures.second = measurements_cam2.at(i);
|
||||
track2.measurements.push_back(measures);
|
||||
track2.measurements.emplace_back(i + 1, measurements_cam2.at(i));
|
||||
}
|
||||
SmartFactor::shared_ptr smartFactor2(new SmartFactor(unit2));
|
||||
smartFactor2->add(track2);
|
||||
|
|
|
@ -172,7 +172,7 @@ double PoseRTV::range(const PoseRTV& other,
|
|||
const Point3 t1 = pose().translation(H1 ? &D_t1_pose : 0);
|
||||
const Point3 t2 = other.pose().translation(H2 ? &D_t2_other : 0);
|
||||
Matrix13 D_d_t1, D_d_t2;
|
||||
double d = distance(t1, t2, H1 ? &D_d_t1 : 0, H2 ? &D_d_t2 : 0);
|
||||
double d = distance3(t1, t2, H1 ? &D_d_t1 : 0, H2 ? &D_d_t2 : 0);
|
||||
if (H1) *H1 << D_d_t1 * D_t1_pose, 0,0,0;
|
||||
if (H2) *H2 << D_d_t2 * D_t2_other, 0,0,0;
|
||||
return d;
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
OptionalJacobian<1, 3> H2 = boost::none) const {
|
||||
static const double Speed = 330;
|
||||
Matrix13 D1, D2;
|
||||
double distance = gtsam::distance(location_, microphone, D1, D2);
|
||||
double distance = gtsam::distance3(location_, microphone, D1, D2);
|
||||
if (H1)
|
||||
// derivative of toa with respect to event
|
||||
*H1 << 1.0, D1 / Speed;
|
||||
|
|
|
@ -46,7 +46,7 @@ SimPolygon2D SimPolygon2D::createRectangle(const Point2& p, double height, doubl
|
|||
bool SimPolygon2D::equals(const SimPolygon2D& p, double tol) const {
|
||||
if (p.size() != size()) return false;
|
||||
for (size_t i=0; i<size(); ++i)
|
||||
if (!landmarks_[i].equals(p.landmarks_[i], tol))
|
||||
if (!traits<Point2>::Equals(landmarks_[i], p.landmarks_[i], tol))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ bool SimPolygon2D::equals(const SimPolygon2D& p, double tol) const {
|
|||
void SimPolygon2D::print(const string& s) const {
|
||||
cout << "SimPolygon " << s << ": " << endl;
|
||||
for(const Point2& p: landmarks_)
|
||||
p.print(" ");
|
||||
traits<Point2>::Print(p, " ");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -151,7 +151,7 @@ SimPolygon2D SimPolygon2D::randomTriangle(
|
|||
Pose2 xC = xB.retract(Vector::Unit(3,0)*dBC);
|
||||
|
||||
// use triangle equality to verify non-degenerate triangle
|
||||
double dAC = xA.t().distance(xC.t());
|
||||
double dAC = distance2(xA.t(), xC.t());
|
||||
|
||||
// form a triangle and test if it meets requirements
|
||||
SimPolygon2D test_tri = SimPolygon2D::createTriangle(xA.t(), xB.t(), xC.t());
|
||||
|
@ -164,7 +164,7 @@ SimPolygon2D SimPolygon2D::randomTriangle(
|
|||
insideBox(side_len, test_tri.landmark(0)) &&
|
||||
insideBox(side_len, test_tri.landmark(1)) &&
|
||||
insideBox(side_len, test_tri.landmark(2)) &&
|
||||
test_tri.landmark(1).distance(test_tri.landmark(2)) > min_side_len &&
|
||||
distance2(test_tri.landmark(1), test_tri.landmark(2)) > min_side_len &&
|
||||
!nearExisting(lms, test_tri.landmark(0), min_vertex_dist) &&
|
||||
!nearExisting(lms, test_tri.landmark(1), min_vertex_dist) &&
|
||||
!nearExisting(lms, test_tri.landmark(2), min_vertex_dist) &&
|
||||
|
@ -260,7 +260,7 @@ Point2 SimPolygon2D::randomBoundedPoint2(double boundary_size,
|
|||
return p;
|
||||
}
|
||||
throw runtime_error("Failed to find a place for a landmark!");
|
||||
return Point2();
|
||||
return Point2(0,0);
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
|
@ -272,7 +272,7 @@ Point2 SimPolygon2D::randomBoundedPoint2(double boundary_size,
|
|||
return p;
|
||||
}
|
||||
throw runtime_error("Failed to find a place for a landmark!");
|
||||
return Point2();
|
||||
return Point2(0,0);
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
|
@ -285,7 +285,7 @@ Point2 SimPolygon2D::randomBoundedPoint2(double boundary_size,
|
|||
return p;
|
||||
}
|
||||
throw runtime_error("Failed to find a place for a landmark!");
|
||||
return Point2();
|
||||
return Point2(0,0);
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
|
@ -303,7 +303,7 @@ Point2 SimPolygon2D::randomBoundedPoint2(
|
|||
return p;
|
||||
}
|
||||
throw runtime_error("Failed to find a place for a landmark!");
|
||||
return Point2();
|
||||
return Point2(0,0);
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
|
@ -320,7 +320,7 @@ bool SimPolygon2D::insideBox(double s, const Point2& p) {
|
|||
bool SimPolygon2D::nearExisting(const std::vector<Point2>& S,
|
||||
const Point2& p, double threshold) {
|
||||
for(const Point2& Sp: S)
|
||||
if (Sp.distance(p) < threshold)
|
||||
if (distance2(Sp, p) < threshold)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,14 @@ using namespace std;
|
|||
/* ************************************************************************* */
|
||||
void SimWall2D::print(const std::string& s) const {
|
||||
std::cout << "SimWall2D " << s << ":" << std::endl;
|
||||
a_.print(" a");
|
||||
b_.print(" b");
|
||||
traits<Point2>::Print(a_, " a");
|
||||
traits<Point2>::Print(b_, " b");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool SimWall2D::equals(const SimWall2D& other, double tol) const {
|
||||
return a_.equals(other.a_, tol) && b_.equals(other.b_, tol);
|
||||
return traits<Point2>::Equals(a_, other.a_, tol) &&
|
||||
traits<Point2>::Equals(b_, other.b_, tol);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -37,8 +38,8 @@ bool SimWall2D::intersects(const SimWall2D& B, boost::optional<Point2&> pt) cons
|
|||
if (debug) cout << "len: " << len << endl;
|
||||
Point2 Ba = transform.transform_to(B.a()),
|
||||
Bb = transform.transform_to(B.b());
|
||||
if (debug) Ba.print("Ba");
|
||||
if (debug) Bb.print("Bb");
|
||||
if (debug) traits<Point2>::Print(Ba, "Ba");
|
||||
if (debug) traits<Point2>::Print(Bb, "Bb");
|
||||
|
||||
// check sides of line
|
||||
if (Ba.y() * Bb.y() > 0.0 ||
|
||||
|
@ -73,7 +74,7 @@ bool SimWall2D::intersects(const SimWall2D& B, boost::optional<Point2&> pt) cons
|
|||
}
|
||||
|
||||
// find lower point by y
|
||||
Point2 low, high;
|
||||
Point2 low(0,0), high(0,0);
|
||||
if (Ba.y() > Bb.y()) {
|
||||
high = Ba;
|
||||
low = Bb;
|
||||
|
@ -81,8 +82,8 @@ bool SimWall2D::intersects(const SimWall2D& B, boost::optional<Point2&> pt) cons
|
|||
high = Bb;
|
||||
low = Ba;
|
||||
}
|
||||
if (debug) high.print("high");
|
||||
if (debug) low.print("low");
|
||||
if (debug) traits<Point2>::Print(high, "high");
|
||||
if (debug) traits<Point2>::Print(low, "low");
|
||||
|
||||
// find x-intercept
|
||||
double slope = (high.y() - low.y())/(high.x() - low.x());
|
||||
|
@ -138,7 +139,7 @@ std::pair<Pose2, bool> moveWithBounce(const Pose2& cur_pose, double step_size,
|
|||
Point2 cur_intersection;
|
||||
if (wall.intersects(traj,cur_intersection)) {
|
||||
collision = true;
|
||||
if (cur_pose.t().distance(cur_intersection) < cur_pose.t().distance(intersection)) {
|
||||
if (distance2(cur_pose.t(), cur_intersection) < distance2(cur_pose.t(), intersection)) {
|
||||
intersection = cur_intersection;
|
||||
closest_wall = wall;
|
||||
}
|
||||
|
@ -154,7 +155,7 @@ std::pair<Pose2, bool> moveWithBounce(const Pose2& cur_pose, double step_size,
|
|||
norm = norm / norm.norm();
|
||||
|
||||
// Simple check to make sure norm is on side closest robot
|
||||
if (cur_pose.t().distance(intersection + norm) > cur_pose.t().distance(intersection - norm))
|
||||
if (distance2(cur_pose.t(), intersection + norm) > distance2(cur_pose.t(), intersection - norm))
|
||||
norm = - norm;
|
||||
|
||||
// using the reflection
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace gtsam {
|
|||
SimWall2D scale(double s) const { return SimWall2D(s*a_, s*b_); }
|
||||
|
||||
/** geometry */
|
||||
double length() const { return a_.distance(b_); }
|
||||
double length() const { return distance2(a_, b_); }
|
||||
Point2 midpoint() const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ const double tol=1e-5;
|
|||
TEST(testPolygon, triangle_basic) {
|
||||
|
||||
// create a triangle from points, extract landmarks/walls, check occupancy
|
||||
Point2 pA, pB(2.0, 0.0), pC(0.0, 1.0);
|
||||
Point2 pA(0,0), pB(2.0, 0.0), pC(0.0, 1.0);
|
||||
|
||||
// construct and extract data
|
||||
SimPolygon2D actTriangle = SimPolygon2D::createTriangle(pA, pB, pC);
|
||||
|
|
|
@ -24,7 +24,7 @@ TEST(testSimWall2D2D, construction ) {
|
|||
|
||||
/* ************************************************************************* */
|
||||
TEST(testSimWall2D2D, equals ) {
|
||||
Point2 p1(1.0, 0.0), p2(1.0, 2.0), p3;
|
||||
Point2 p1(1.0, 0.0), p2(1.0, 2.0), p3(0,0);
|
||||
SimWall2D w1(p1, p2), w2(p1, p3);
|
||||
EXPECT(assert_equal(w1, w1));
|
||||
EXPECT(assert_inequal(w1, w2));
|
||||
|
@ -34,7 +34,7 @@ TEST(testSimWall2D2D, equals ) {
|
|||
/* ************************************************************************* */
|
||||
TEST(testSimWall2D2D, intersection1 ) {
|
||||
SimWall2D w1(2.0, 2.0, 6.0, 2.0), w2(4.0, 4.0, 4.0, 0.0);
|
||||
Point2 pt;
|
||||
Point2 pt(0,0);
|
||||
EXPECT(w1.intersects(w2));
|
||||
EXPECT(w2.intersects(w1));
|
||||
w1.intersects(w2, pt);
|
||||
|
|
|
@ -24,17 +24,17 @@ namespace gtsam {
|
|||
* Ternary factor representing a visual measurement that includes inverse depth
|
||||
*/
|
||||
template<class POSE, class LANDMARK, class INVDEPTH>
|
||||
class InvDepthFactor3: public gtsam::NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> {
|
||||
class InvDepthFactor3: public NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> {
|
||||
protected:
|
||||
|
||||
// Keep a copy of measurement and calibration for I/O
|
||||
gtsam::Point2 measured_; ///< 2D measurement
|
||||
boost::shared_ptr<gtsam::Cal3_S2> K_; ///< shared pointer to calibration object
|
||||
Point2 measured_; ///< 2D measurement
|
||||
boost::shared_ptr<Cal3_S2> K_; ///< shared pointer to calibration object
|
||||
|
||||
public:
|
||||
|
||||
/// shorthand for base class type
|
||||
typedef gtsam::NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> Base;
|
||||
typedef NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> Base;
|
||||
|
||||
/// shorthand for this class
|
||||
typedef InvDepthFactor3<POSE, LANDMARK, INVDEPTH> This;
|
||||
|
@ -43,7 +43,9 @@ public:
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
InvDepthFactor3() : K_(new gtsam::Cal3_S2(444, 555, 666, 777, 888)) {}
|
||||
InvDepthFactor3() :
|
||||
measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -55,8 +57,8 @@ public:
|
|||
* @param invDepthKey is the index of inverse depth
|
||||
* @param K shared pointer to the constant calibration
|
||||
*/
|
||||
InvDepthFactor3(const gtsam::Point2& measured, const gtsam::SharedNoiseModel& model,
|
||||
const gtsam::Key poseKey, gtsam::Key pointKey, gtsam::Key invDepthKey, const Cal3_S2::shared_ptr& K) :
|
||||
InvDepthFactor3(const Point2& measured, const SharedNoiseModel& model,
|
||||
const Key poseKey, Key pointKey, Key invDepthKey, const Cal3_S2::shared_ptr& K) :
|
||||
Base(model, poseKey, pointKey, invDepthKey), measured_(measured), K_(K) {}
|
||||
|
||||
/** Virtual destructor */
|
||||
|
@ -68,44 +70,43 @@ public:
|
|||
* @param keyFormatter optional formatter useful for printing Symbols
|
||||
*/
|
||||
void print(const std::string& s = "InvDepthFactor3",
|
||||
const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const {
|
||||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/// equals
|
||||
virtual bool equals(const gtsam::NonlinearFactor& p, double tol = 1e-9) const {
|
||||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e && Base::equals(p, tol) && this->measured_.equals(e->measured_, tol) && this->K_->equals(*e->K_, tol);
|
||||
return e && Base::equals(p, tol) && traits<Point2>::Equals(this->measured_, e->measured_, tol) && this->K_->equals(*e->K_, tol);
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
gtsam::Vector evaluateError(const POSE& pose, const Vector5& point, const INVDEPTH& invDepth,
|
||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H2=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
||||
Vector evaluateError(const POSE& pose, const Vector5& point, const INVDEPTH& invDepth,
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none,
|
||||
boost::optional<Matrix&> H3=boost::none) const {
|
||||
try {
|
||||
InvDepthCamera3<gtsam::Cal3_S2> camera(pose, K_);
|
||||
gtsam::Point2 reprojectionError(camera.project(point, invDepth, H1, H2, H3) - measured_);
|
||||
return reprojectionError.vector();
|
||||
InvDepthCamera3<Cal3_S2> camera(pose, K_);
|
||||
return camera.project(point, invDepth, H1, H2, H3) - measured_;
|
||||
} catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2,6);
|
||||
if (H2) *H2 = Matrix::Zero(2,5);
|
||||
if (H3) *H2 = Matrix::Zero(2,1);
|
||||
std::cout << e.what() << ": Landmark "<< DefaultKeyFormatter(this->key2()) <<
|
||||
" moved behind camera " << DefaultKeyFormatter(this->key1()) << std::endl;
|
||||
return gtsam::Vector::Ones(2) * 2.0 * K_->fx();
|
||||
return Vector::Ones(2) * 2.0 * K_->fx();
|
||||
}
|
||||
return (gtsam::Vector(1) << 0.0).finished();
|
||||
return (Vector(1) << 0.0).finished();
|
||||
}
|
||||
|
||||
/** return the measurement */
|
||||
const gtsam::Point2& imagePoint() const {
|
||||
const Point2& imagePoint() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
/** return the calibration object */
|
||||
inline const gtsam::Cal3_S2::shared_ptr calibration() const {
|
||||
inline const Cal3_S2::shared_ptr calibration() const {
|
||||
return K_;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,9 @@ public:
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
InvDepthFactorVariant1() : K_(new Cal3_S2(444, 555, 666, 777, 888)) {}
|
||||
InvDepthFactorVariant1() :
|
||||
measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -64,17 +66,17 @@ public:
|
|||
* @param keyFormatter optional formatter useful for printing Symbols
|
||||
*/
|
||||
void print(const std::string& s = "InvDepthFactorVariant1",
|
||||
const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const {
|
||||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/// equals
|
||||
virtual bool equals(const gtsam::NonlinearFactor& p, double tol = 1e-9) const {
|
||||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol);
|
||||
}
|
||||
|
||||
|
@ -86,22 +88,21 @@ public:
|
|||
Point3 world_P_landmark = Point3(x, y, z) + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||
// Project landmark into Pose2
|
||||
PinholeCamera<Cal3_S2> camera(pose, *K_);
|
||||
gtsam::Point2 reprojectionError(camera.project(world_P_landmark) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(world_P_landmark) - measured_;
|
||||
} catch( CheiralityException& e) {
|
||||
std::cout << e.what()
|
||||
<< ": Inverse Depth Landmark [" << DefaultKeyFormatter(this->key2()) << "]"
|
||||
<< " moved behind camera [" << DefaultKeyFormatter(this->key1()) <<"]"
|
||||
<< std::endl;
|
||||
return gtsam::Vector::Ones(2) * 2.0 * K_->fx();
|
||||
return Vector::Ones(2) * 2.0 * K_->fx();
|
||||
}
|
||||
return (gtsam::Vector(1) << 0.0).finished();
|
||||
return (Vector(1) << 0.0).finished();
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
Vector evaluateError(const Pose3& pose, const Vector6& landmark,
|
||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none) const {
|
||||
|
||||
if (H1) {
|
||||
(*H1) = numericalDerivative11<Vector, Pose3>(
|
||||
|
@ -118,7 +119,7 @@ public:
|
|||
}
|
||||
|
||||
/** return the measurement */
|
||||
const gtsam::Point2& imagePoint() const {
|
||||
const Point2& imagePoint() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ public:
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
InvDepthFactorVariant2() : K_(new Cal3_S2(444, 555, 666, 777, 888)) {}
|
||||
InvDepthFactorVariant2() :
|
||||
measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -67,17 +69,17 @@ public:
|
|||
* @param keyFormatter optional formatter useful for printing Symbols
|
||||
*/
|
||||
void print(const std::string& s = "InvDepthFactorVariant2",
|
||||
const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const {
|
||||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/// equals
|
||||
virtual bool equals(const gtsam::NonlinearFactor& p, double tol = 1e-9) const {
|
||||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol)
|
||||
&& traits<Point3>::Equals(this->referencePoint_, e->referencePoint_, tol);
|
||||
}
|
||||
|
@ -89,22 +91,21 @@ public:
|
|||
Point3 world_P_landmark = referencePoint_ + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||
// Project landmark into Pose2
|
||||
PinholeCamera<Cal3_S2> camera(pose, *K_);
|
||||
gtsam::Point2 reprojectionError(camera.project(world_P_landmark) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(world_P_landmark) - measured_;
|
||||
} catch( CheiralityException& e) {
|
||||
std::cout << e.what()
|
||||
<< ": Inverse Depth Landmark [" << DefaultKeyFormatter(this->key2()) << "]"
|
||||
<< " moved behind camera [" << DefaultKeyFormatter(this->key1()) <<"]"
|
||||
<< std::endl;
|
||||
return gtsam::Vector::Ones(2) * 2.0 * K_->fx();
|
||||
return Vector::Ones(2) * 2.0 * K_->fx();
|
||||
}
|
||||
return (gtsam::Vector(1) << 0.0).finished();
|
||||
return (Vector(1) << 0.0).finished();
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
Vector evaluateError(const Pose3& pose, const Vector3& landmark,
|
||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none) const {
|
||||
|
||||
if (H1) {
|
||||
(*H1) = numericalDerivative11<Vector, Pose3>(
|
||||
|
@ -121,7 +122,7 @@ public:
|
|||
}
|
||||
|
||||
/** return the measurement */
|
||||
const gtsam::Point2& imagePoint() const {
|
||||
const Point2& imagePoint() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,9 @@ public:
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
InvDepthFactorVariant3a() : K_(new Cal3_S2(444, 555, 666, 777, 888)) {}
|
||||
InvDepthFactorVariant3a() :
|
||||
measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -66,17 +68,17 @@ public:
|
|||
* @param keyFormatter optional formatter useful for printing Symbols
|
||||
*/
|
||||
void print(const std::string& s = "InvDepthFactorVariant3a",
|
||||
const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const {
|
||||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/// equals
|
||||
virtual bool equals(const gtsam::NonlinearFactor& p, double tol = 1e-9) const {
|
||||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol);
|
||||
}
|
||||
|
||||
|
@ -89,22 +91,21 @@ public:
|
|||
Point3 world_P_landmark = pose.transform_from(pose_P_landmark);
|
||||
// Project landmark into Pose2
|
||||
PinholeCamera<Cal3_S2> camera(pose, *K_);
|
||||
gtsam::Point2 reprojectionError(camera.project(world_P_landmark) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(world_P_landmark) - measured_;
|
||||
} catch( CheiralityException& e) {
|
||||
std::cout << e.what()
|
||||
<< ": Inverse Depth Landmark [" << DefaultKeyFormatter(this->key1()) << "," << DefaultKeyFormatter(this->key2()) << "]"
|
||||
<< " moved behind camera [" << DefaultKeyFormatter(this->key1()) << "]"
|
||||
<< std::endl;
|
||||
return gtsam::Vector::Ones(2) * 2.0 * K_->fx();
|
||||
return Vector::Ones(2) * 2.0 * K_->fx();
|
||||
}
|
||||
return (Vector(1) << 0.0).finished();
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
Vector evaluateError(const Pose3& pose, const Vector3& landmark,
|
||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none) const {
|
||||
|
||||
if(H1) {
|
||||
(*H1) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3a::inverseDepthError, this, _1, landmark), pose);
|
||||
|
@ -117,7 +118,7 @@ public:
|
|||
}
|
||||
|
||||
/** return the measurement */
|
||||
const gtsam::Point2& imagePoint() const {
|
||||
const Point2& imagePoint() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
|
@ -160,7 +161,9 @@ public:
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
InvDepthFactorVariant3b() : K_(new Cal3_S2(444, 555, 666, 777, 888)) {}
|
||||
InvDepthFactorVariant3b() :
|
||||
measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -185,17 +188,17 @@ public:
|
|||
* @param keyFormatter optional formatter useful for printing Symbols
|
||||
*/
|
||||
void print(const std::string& s = "InvDepthFactorVariant3",
|
||||
const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const {
|
||||
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
Base::print(s, keyFormatter);
|
||||
measured_.print(s + ".z");
|
||||
traits<Point2>::Print(measured_, s + ".z");
|
||||
}
|
||||
|
||||
/// equals
|
||||
virtual bool equals(const gtsam::NonlinearFactor& p, double tol = 1e-9) const {
|
||||
virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const {
|
||||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol);
|
||||
}
|
||||
|
||||
|
@ -208,23 +211,22 @@ public:
|
|||
Point3 world_P_landmark = pose1.transform_from(pose1_P_landmark);
|
||||
// Project landmark into Pose2
|
||||
PinholeCamera<Cal3_S2> camera(pose2, *K_);
|
||||
gtsam::Point2 reprojectionError(camera.project(world_P_landmark) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(world_P_landmark) - measured_;
|
||||
} catch( CheiralityException& e) {
|
||||
std::cout << e.what()
|
||||
<< ": Inverse Depth Landmark [" << DefaultKeyFormatter(this->key1()) << "," << DefaultKeyFormatter(this->key3()) << "]"
|
||||
<< " moved behind camera " << DefaultKeyFormatter(this->key2())
|
||||
<< std::endl;
|
||||
return gtsam::Vector::Ones(2) * 2.0 * K_->fx();
|
||||
return Vector::Ones(2) * 2.0 * K_->fx();
|
||||
}
|
||||
return (Vector(1) << 0.0).finished();
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
Vector evaluateError(const Pose3& pose1, const Pose3& pose2, const Vector3& landmark,
|
||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H2=boost::none,
|
||||
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none,
|
||||
boost::optional<Matrix&> H3=boost::none) const {
|
||||
|
||||
if(H1)
|
||||
(*H1) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, _1, pose2, landmark), pose1);
|
||||
|
@ -239,7 +241,7 @@ public:
|
|||
}
|
||||
|
||||
/** return the measurement */
|
||||
const gtsam::Point2& imagePoint() const {
|
||||
const Point2& imagePoint() const {
|
||||
return measured_;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,9 +101,9 @@ namespace gtsam {
|
|||
virtual ~MultiProjectionFactor() {}
|
||||
|
||||
/// @return a deep copy of this factor
|
||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<gtsam::NonlinearFactor>(
|
||||
gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
virtual NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<NonlinearFactor>(
|
||||
NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
|
||||
/**
|
||||
* print
|
||||
|
@ -143,20 +143,20 @@ namespace gtsam {
|
|||
//
|
||||
// if(body_P_sensor_) {
|
||||
// if(H1) {
|
||||
// gtsam::Matrix H0;
|
||||
// Matrix H0;
|
||||
// PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_, H0), *K_);
|
||||
// Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
// *H1 = *H1 * H0;
|
||||
// return reprojectionError.vector();
|
||||
// return reprojectionError;
|
||||
// } else {
|
||||
// PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_), *K_);
|
||||
// Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
// return reprojectionError.vector();
|
||||
// return reprojectionError;
|
||||
// }
|
||||
// } else {
|
||||
// PinholeCamera<CALIBRATION> camera(pose, *K_);
|
||||
// Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
// return reprojectionError.vector();
|
||||
// return reprojectionError;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
@ -168,20 +168,20 @@ namespace gtsam {
|
|||
try {
|
||||
if(body_P_sensor_) {
|
||||
if(H1) {
|
||||
gtsam::Matrix H0;
|
||||
Matrix H0;
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_, H0), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
*H1 = *H1 * H0;
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(*body_P_sensor_), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
}
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose, *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H2) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
}
|
||||
} catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2,6);
|
||||
|
|
|
@ -54,7 +54,9 @@ namespace gtsam {
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
ProjectionFactorPPP() : throwCheirality_(false), verboseCheirality_(false) {}
|
||||
ProjectionFactorPPP() :
|
||||
measured_(0.0, 0.0), throwCheirality_(false), verboseCheirality_(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -94,9 +96,9 @@ namespace gtsam {
|
|||
virtual ~ProjectionFactorPPP() {}
|
||||
|
||||
/// @return a deep copy of this factor
|
||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<gtsam::NonlinearFactor>(
|
||||
gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
virtual NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<NonlinearFactor>(
|
||||
NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
|
||||
/**
|
||||
* print
|
||||
|
@ -105,7 +107,7 @@ namespace gtsam {
|
|||
*/
|
||||
void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
std::cout << s << "ProjectionFactorPPP, z = ";
|
||||
measured_.print();
|
||||
traits<Point2>::Print(measured_);
|
||||
Base::print("", keyFormatter);
|
||||
}
|
||||
|
||||
|
@ -114,7 +116,7 @@ namespace gtsam {
|
|||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol)
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol)
|
||||
&& this->K_->equals(*e->K_, tol);
|
||||
}
|
||||
|
||||
|
@ -125,16 +127,15 @@ namespace gtsam {
|
|||
boost::optional<Matrix&> H3 = boost::none) const {
|
||||
try {
|
||||
if(H1 || H2 || H3) {
|
||||
gtsam::Matrix H0, H02;
|
||||
Matrix H0, H02;
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(transform, H0, H02), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H3, boost::none) - measured_);
|
||||
*H2 = *H1 * H02;
|
||||
*H1 = *H1 * H0;
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(transform), *K_);
|
||||
Point2 reprojectionError(camera.project(point, H1, H3, boost::none) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(point, H1, H3, boost::none) - measured_;
|
||||
}
|
||||
} catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2,6);
|
||||
|
|
|
@ -52,7 +52,9 @@ namespace gtsam {
|
|||
typedef boost::shared_ptr<This> shared_ptr;
|
||||
|
||||
/// Default constructor
|
||||
ProjectionFactorPPPC() : throwCheirality_(false), verboseCheirality_(false) {}
|
||||
ProjectionFactorPPPC() :
|
||||
measured_(0.0, 0.0), throwCheirality_(false), verboseCheirality_(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -89,9 +91,9 @@ namespace gtsam {
|
|||
virtual ~ProjectionFactorPPPC() {}
|
||||
|
||||
/// @return a deep copy of this factor
|
||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<gtsam::NonlinearFactor>(
|
||||
gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
virtual NonlinearFactor::shared_ptr clone() const {
|
||||
return boost::static_pointer_cast<NonlinearFactor>(
|
||||
NonlinearFactor::shared_ptr(new This(*this))); }
|
||||
|
||||
/**
|
||||
* print
|
||||
|
@ -100,7 +102,7 @@ namespace gtsam {
|
|||
*/
|
||||
void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
|
||||
std::cout << s << "ProjectionFactorPPPC, z = ";
|
||||
measured_.print();
|
||||
traits<Point2>::Print(measured_);
|
||||
Base::print("", keyFormatter);
|
||||
}
|
||||
|
||||
|
@ -109,7 +111,7 @@ namespace gtsam {
|
|||
const This *e = dynamic_cast<const This*>(&p);
|
||||
return e
|
||||
&& Base::equals(p, tol)
|
||||
&& this->measured_.equals(e->measured_, tol);
|
||||
&& traits<Point2>::Equals(this->measured_, e->measured_, tol);
|
||||
}
|
||||
|
||||
/// Evaluate error h(x)-z and optionally derivatives
|
||||
|
@ -120,16 +122,15 @@ namespace gtsam {
|
|||
boost::optional<Matrix&> H4 = boost::none) const {
|
||||
try {
|
||||
if(H1 || H2 || H3 || H4) {
|
||||
gtsam::Matrix H0, H02;
|
||||
Matrix H0, H02;
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(transform, H0, H02), K);
|
||||
Point2 reprojectionError(camera.project(point, H1, H3, H4) - measured_);
|
||||
*H2 = *H1 * H02;
|
||||
*H1 = *H1 * H0;
|
||||
return reprojectionError.vector();
|
||||
return reprojectionError;
|
||||
} else {
|
||||
PinholeCamera<CALIBRATION> camera(pose.compose(transform), K);
|
||||
Point2 reprojectionError(camera.project(point, H1, H3, H4) - measured_);
|
||||
return reprojectionError.vector();
|
||||
return camera.project(point, H1, H3, H4) - measured_;
|
||||
}
|
||||
} catch( CheiralityException& e) {
|
||||
if (H1) *H1 = Matrix::Zero(2,6);
|
||||
|
|
|
@ -101,11 +101,11 @@ public:
|
|||
// loop over all circles
|
||||
for(const Circle2& it: circles) {
|
||||
// distance between circle centers.
|
||||
double d = circle1.center.dist(it.center);
|
||||
double d = distance2(circle1.center, it.center);
|
||||
if (d < 1e-9)
|
||||
continue; // skip circles that are in the same location
|
||||
// Find f and h, the intersection points in normalized circles
|
||||
boost::optional<Point2> fh = Point2::CircleCircleIntersection(
|
||||
boost::optional<Point2> fh = circleCircleIntersection(
|
||||
circle1.radius / d, it.radius / d);
|
||||
// Check if this pair is better by checking h = fh->y()
|
||||
// if h is large, the intersections are well defined.
|
||||
|
@ -116,15 +116,15 @@ public:
|
|||
}
|
||||
|
||||
// use best fh to find actual intersection points
|
||||
std::list<Point2> intersections = Point2::CircleCircleIntersection(
|
||||
std::list<Point2> intersections = circleCircleIntersection(
|
||||
circle1.center, best_circle->center, best_fh);
|
||||
|
||||
// pick winner based on other measurements
|
||||
double error1 = 0, error2 = 0;
|
||||
Point2 p1 = intersections.front(), p2 = intersections.back();
|
||||
for(const Circle2& it: circles) {
|
||||
error1 += it.center.dist(p1);
|
||||
error2 += it.center.dist(p2);
|
||||
error1 += distance2(it.center, p1);
|
||||
error2 += distance2(it.center, p2);
|
||||
}
|
||||
return (error1 < error2) ? p1 : p2;
|
||||
//gttoc_(triangulate);
|
||||
|
|
|
@ -48,9 +48,7 @@ public:
|
|||
Vector evaluateError(const Pose2& pose, const Point2& point,
|
||||
boost::optional<Matrix&> H1 = boost::none, boost::optional<Matrix&> H2 =
|
||||
boost::none) const {
|
||||
Point2 d = pose.transform_to(point, H1, H2);
|
||||
Point2 e = d - measured_;
|
||||
return e.vector();
|
||||
return pose.transform_to(point, H1, H2) - measured_;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -99,12 +97,12 @@ public:
|
|||
*H3 = D_e_point_g * D_point_g_base2;
|
||||
if (H4)
|
||||
*H4 = D_e_point_g * D_point_g_point;
|
||||
return (d - measured_).vector();
|
||||
return d - measured_;
|
||||
} else {
|
||||
Pose2 pose_g = base1.compose(pose);
|
||||
Point2 point_g = base2.transform_from(point);
|
||||
Point2 d = pose_g.transform_to(point_g);
|
||||
return (d - measured_).vector();
|
||||
return d - measured_;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
2
matlab.h
2
matlab.h
|
@ -91,7 +91,7 @@ Matrix extractPoint2(const Values& values) {
|
|||
Values::ConstFiltered<Point2> points = values.filter<Point2>();
|
||||
Matrix result(points.size(), 2);
|
||||
for(const auto& key_value: points)
|
||||
result.row(j++) = key_value.value.vector();
|
||||
result.row(j++) = key_value.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,23 +25,26 @@
|
|||
using namespace boost::python;
|
||||
using namespace gtsam;
|
||||
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(print_overloads, Point2::print, 0, 1)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(equals_overloads, Point2::equals, 1, 2)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(compose_overloads, Point2::compose, 1, 3)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(distance_overloads, Point2::distance, 1, 3)
|
||||
#endif
|
||||
|
||||
void exportPoint2(){
|
||||
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
class_<Point2>("Point2", init<>())
|
||||
.def(init<double, double>())
|
||||
.def(init<const Vector2 &>())
|
||||
.def("identity", &Point2::identity)
|
||||
.def("dist", &Point2::dist)
|
||||
.def("distance", &Point2::distance)
|
||||
.def("distance", &Point2::distance, distance_overloads(args("q","H1","H2")))
|
||||
.def("equals", &Point2::equals, equals_overloads(args("q","tol")))
|
||||
.def("norm", &Point2::norm)
|
||||
.def("print", &Point2::print, print_overloads(args("s")))
|
||||
.def("unit", &Point2::unit)
|
||||
.def("vector", &Point2::vector)
|
||||
.def("vector", &Point2::vector, return_value_policy<copy_const_reference>())
|
||||
.def("x", &Point2::x)
|
||||
.def("y", &Point2::y)
|
||||
.def(self * other<double>()) // __mult__
|
||||
|
@ -54,5 +57,5 @@ void exportPoint2(){
|
|||
.def(repr(self))
|
||||
.def(self == self)
|
||||
;
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -25,31 +25,32 @@
|
|||
using namespace boost::python;
|
||||
using namespace gtsam;
|
||||
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(print_overloads, Point3::print, 0, 1)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(equals_overloads, Point3::equals, 1, 2)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(norm_overloads, Point3::norm, 0, 1)
|
||||
#endif
|
||||
|
||||
void exportPoint3(){
|
||||
|
||||
#ifndef GTSAM_TYPEDEF_POINTS_TO_VECTORS
|
||||
class_<Point3>("Point3")
|
||||
.def(init<>())
|
||||
.def(init<double,double,double>())
|
||||
.def(init<const Vector3 &>())
|
||||
.def("identity", &Point3::identity)
|
||||
.staticmethod("identity")
|
||||
.def("cross", &Point3::cross)
|
||||
.def("distance", &Point3::distance)
|
||||
.def("dot", &Point3::dot)
|
||||
.def("equals", &Point3::equals, equals_overloads(args("q","tol")))
|
||||
.def("norm", &Point3::norm, norm_overloads(args("OptionalJacobian<1,3>")))
|
||||
.def("normalized", &Point3::normalized)
|
||||
.def("print", &Point3::print, print_overloads(args("s")))
|
||||
#ifndef GTSAM_USE_VECTOR3_POINTS
|
||||
.def("vector", &Point3::vector, return_value_policy<copy_const_reference>())
|
||||
.def("x", &Point3::x)
|
||||
.def("y", &Point3::y)
|
||||
.def("z", &Point3::z)
|
||||
#endif
|
||||
.def("print", &Point3::print, print_overloads(args("s")))
|
||||
.def("equals", &Point3::equals, equals_overloads(args("q","tol")))
|
||||
.def("distance", &Point3::distance)
|
||||
.def("cross", &Point3::cross)
|
||||
.def("dot", &Point3::dot)
|
||||
.def("norm", &Point3::norm, norm_overloads(args("OptionalJacobian<1,3>")))
|
||||
.def("normalized", &Point3::normalized)
|
||||
.def("identity", &Point3::identity)
|
||||
.staticmethod("identity")
|
||||
.def(self * other<double>())
|
||||
.def(other<double>() * self)
|
||||
.def(self + self)
|
||||
|
@ -58,7 +59,10 @@ class_<Point3>("Point3")
|
|||
.def(self / other<double>())
|
||||
.def(self_ns::str(self))
|
||||
.def(repr(self))
|
||||
.def(self == self)
|
||||
;
|
||||
.def(self == self);
|
||||
#endif
|
||||
|
||||
class_<Point3Pair>("Point3Pair", init<Point3, Point3>())
|
||||
.def_readwrite("first", &Point3Pair::first)
|
||||
.def_readwrite("second", &Point3Pair::second);
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ namespace simulated2D {
|
|||
|
||||
/// Return error and optional derivative
|
||||
Vector evaluateError(const Pose& x, boost::optional<Matrix&> H = boost::none) const {
|
||||
return (prior(x, H) - measured_).vector();
|
||||
return (prior(x, H) - measured_);
|
||||
}
|
||||
|
||||
virtual ~GenericPrior() {}
|
||||
|
@ -186,7 +186,7 @@ namespace simulated2D {
|
|||
Vector evaluateError(const Pose& x1, const Pose& x2,
|
||||
boost::optional<Matrix&> H1 = boost::none,
|
||||
boost::optional<Matrix&> H2 = boost::none) const {
|
||||
return (odo(x1, x2, H1, H2) - measured_).vector();
|
||||
return (odo(x1, x2, H1, H2) - measured_);
|
||||
}
|
||||
|
||||
virtual ~GenericOdometry() {}
|
||||
|
@ -233,7 +233,7 @@ namespace simulated2D {
|
|||
Vector evaluateError(const Pose& x1, const Landmark& x2,
|
||||
boost::optional<Matrix&> H1 = boost::none,
|
||||
boost::optional<Matrix&> H2 = boost::none) const {
|
||||
return (mea(x1, x2, H1, H2) - measured_).vector();
|
||||
return (mea(x1, x2, H1, H2) - measured_);
|
||||
}
|
||||
|
||||
virtual ~GenericMeasurement() {}
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace simulated2D {
|
|||
* @return a scalar distance between values
|
||||
*/
|
||||
template<class T1, class T2>
|
||||
double range_trait(const T1& a, const T2& b) { return a.dist(b); }
|
||||
double range_trait(const T1& a, const T2& b) { return distance2(a, b); }
|
||||
|
||||
/**
|
||||
* Binary inequality constraint forcing the range between points
|
||||
|
|
|
@ -180,7 +180,7 @@ inline boost::shared_ptr<const NonlinearFactorGraph> sharedNonlinearFactorGraph(
|
|||
new NonlinearFactorGraph);
|
||||
|
||||
// prior on x1
|
||||
Point2 mu;
|
||||
Point2 mu(0,0);
|
||||
shared_nlf f1(new simulated2D::Prior(mu, sigma0_1, X(1)));
|
||||
nlfg->push_back(f1);
|
||||
|
||||
|
@ -337,7 +337,7 @@ struct UnaryFactor: public gtsam::NoiseModelFactor1<Point2> {
|
|||
|
||||
Vector evaluateError(const Point2& x, boost::optional<Matrix&> A = boost::none) const {
|
||||
if (A) *A = H(x);
|
||||
return (h(x) - z_).vector();
|
||||
return (h(x) - z_);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -593,11 +593,11 @@ inline boost::tuple<GaussianFactorGraph, VectorValues> planarGraph(size_t N) {
|
|||
Values zeros;
|
||||
for (size_t x = 1; x <= N; x++)
|
||||
for (size_t y = 1; y <= N; y++)
|
||||
zeros.insert(key(x, y), Point2());
|
||||
zeros.insert(key(x, y), Point2(0,0));
|
||||
VectorValues xtrue;
|
||||
for (size_t x = 1; x <= N; x++)
|
||||
for (size_t y = 1; y <= N; y++)
|
||||
xtrue.insert(key(x, y), Point2((double)x, (double)y).vector());
|
||||
xtrue.insert(key(x, y), Point2((double)x, (double)y));
|
||||
|
||||
// linearize around zero
|
||||
boost::shared_ptr<GaussianFactorGraph> gfg = nlfg.linearize(zeros);
|
||||
|
|
|
@ -181,7 +181,7 @@ TEST( testBoundingConstraint, unary_simple_optimization2) {
|
|||
/* ************************************************************************* */
|
||||
TEST( testBoundingConstraint, MaxDistance_basics) {
|
||||
gtsam::Key key1 = 1, key2 = 2;
|
||||
Point2 pt1, pt2(1.0, 0.0), pt3(2.0, 0.0), pt4(3.0, 0.0);
|
||||
Point2 pt1(0,0), pt2(1.0, 0.0), pt3(2.0, 0.0), pt4(3.0, 0.0);
|
||||
iq2D::PoseMaxDistConstraint rangeBound(key1, key2, 2.0, mu);
|
||||
EXPECT_DOUBLES_EQUAL(2.0, rangeBound.threshold(), tol);
|
||||
EXPECT(!rangeBound.isGreaterThan());
|
||||
|
@ -220,7 +220,7 @@ TEST( testBoundingConstraint, MaxDistance_basics) {
|
|||
/* ************************************************************************* */
|
||||
TEST( testBoundingConstraint, MaxDistance_simple_optimization) {
|
||||
|
||||
Point2 pt1, pt2_init(5.0, 0.0), pt2_goal(2.0, 0.0);
|
||||
Point2 pt1(0,0), pt2_init(5.0, 0.0), pt2_goal(2.0, 0.0);
|
||||
Symbol x1('x',1), x2('x',2);
|
||||
|
||||
NonlinearFactorGraph graph;
|
||||
|
@ -246,7 +246,7 @@ TEST( testBoundingConstraint, avoid_demo) {
|
|||
|
||||
Symbol x1('x',1), x2('x',2), x3('x',3), l1('l',1);
|
||||
double radius = 1.0;
|
||||
Point2 x1_pt, x2_init(2.0, 0.5), x2_goal(2.0, 1.0), x3_pt(4.0, 0.0), l1_pt(2.0, 0.0);
|
||||
Point2 x1_pt(0,0), x2_init(2.0, 0.5), x2_goal(2.0, 1.0), x3_pt(4.0, 0.0), l1_pt(2.0, 0.0);
|
||||
Point2 odo(2.0, 0.0);
|
||||
|
||||
NonlinearFactorGraph graph;
|
||||
|
|
|
@ -193,7 +193,7 @@ TEST(ExpressionFactor, Binary) {
|
|||
internal::ExecutionTraceStorage traceStorage[size];
|
||||
internal::ExecutionTrace<Point2> trace;
|
||||
Point2 value = binary.traceExecution(values, trace, traceStorage);
|
||||
EXPECT(assert_equal(Point2(),value, 1e-9));
|
||||
EXPECT(assert_equal(Point2(0,0),value, 1e-9));
|
||||
// trace.print();
|
||||
|
||||
// Expected Jacobians
|
||||
|
@ -248,7 +248,7 @@ TEST(ExpressionFactor, Shallow) {
|
|||
internal::ExecutionTraceStorage traceStorage[size];
|
||||
internal::ExecutionTrace<Point2> trace;
|
||||
Point2 value = expression.traceExecution(values, trace, traceStorage);
|
||||
EXPECT(assert_equal(Point2(),value, 1e-9));
|
||||
EXPECT(assert_equal(Point2(0,0),value, 1e-9));
|
||||
// trace.print();
|
||||
|
||||
// Expected Jacobians
|
||||
|
|
|
@ -226,7 +226,7 @@ public:
|
|||
*H2 = Matrix::Identity(dim(),dim());
|
||||
|
||||
// Return the error between the prediction and the supplied value of p2
|
||||
return (p2 - prediction).vector();
|
||||
return (p2 - prediction);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -400,7 +400,7 @@ TEST( ExtendedKalmanFilter, nonlinear ) {
|
|||
ExtendedKalmanFilter<Point2> ekf(X(0), x_initial, P_initial);
|
||||
|
||||
// Enter Predict-Update Loop
|
||||
Point2 x_predict, x_update;
|
||||
Point2 x_predict(0,0), x_update(0,0);
|
||||
for(unsigned int i = 0; i < 10; ++i){
|
||||
// Create motion factor
|
||||
NonlinearMotionModel motionFactor(X(i), X(i+1));
|
||||
|
|
|
@ -40,7 +40,7 @@ template<> struct traits<Product> : internal::LieGroupTraits<Product> {
|
|||
<< m.second.theta() << ")" << endl;
|
||||
}
|
||||
static bool Equals(const Product& m1, const Product& m2, double tol = 1e-8) {
|
||||
return m1.first.equals(m2.first, tol) && m1.second.equals(m2.second, tol);
|
||||
return traits<Point2>::Equals(m1.first, m2.first, tol) && m1.second.equals(m2.second, tol);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ TEST(Manifold, Identity) {
|
|||
EXPECT_DOUBLES_EQUAL(0.0, traits<double>::Identity(), 0.0);
|
||||
EXPECT(assert_equal(Matrix(Matrix24::Zero()), Matrix(traits<Matrix24>::Identity())));
|
||||
EXPECT(assert_equal(Pose3(), traits<Pose3>::Identity()));
|
||||
EXPECT(assert_equal(Point2(), traits<Point2>::Identity()));
|
||||
EXPECT(assert_equal(Point2(0,0), traits<Point2>::Identity()));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -166,7 +166,7 @@ template<> struct traits<MyPoint2Pair> : internal::ManifoldTraits<MyPoint2Pair>
|
|||
|
||||
TEST(Manifold, ProductManifold) {
|
||||
BOOST_CONCEPT_ASSERT((IsManifold<MyPoint2Pair>));
|
||||
MyPoint2Pair pair1;
|
||||
MyPoint2Pair pair1(Point2(0,0),Point2(0,0));
|
||||
Vector4 d;
|
||||
d << 1,2,3,4;
|
||||
MyPoint2Pair expected(Point2(1,2),Point2(3,4));
|
||||
|
|
|
@ -417,7 +417,7 @@ TEST( testNonlinearEqualityConstraint, odo_simple_optimize ) {
|
|||
graph.push_back(factor);
|
||||
|
||||
Values initValues;
|
||||
initValues.insert(key1, Point2());
|
||||
initValues.insert(key1, Point2(0,0));
|
||||
initValues.insert(key2, badPt);
|
||||
|
||||
Values actual = LevenbergMarquardtOptimizer(graph, initValues).optimize();
|
||||
|
@ -454,7 +454,7 @@ TEST (testNonlinearEqualityConstraint, two_pose ) {
|
|||
|
||||
Values initialEstimate;
|
||||
initialEstimate.insert(x1, pt_x1);
|
||||
initialEstimate.insert(x2, Point2());
|
||||
initialEstimate.insert(x2, Point2(0,0));
|
||||
initialEstimate.insert(l1, Point2(1.0, 6.0)); // ground truth
|
||||
initialEstimate.insert(l2, Point2(-4.0, 0.0)); // starting with a separate reference frame
|
||||
|
||||
|
|
|
@ -117,9 +117,9 @@ TEST(testNonlinearISAM, markov_chain_with_disconnects ) {
|
|||
new_factors += PriorFactor<Point2>(lm3, landmark3, model2);
|
||||
|
||||
// Initialize to origin
|
||||
new_init.insert(lm1, Point2());
|
||||
new_init.insert(lm2, Point2());
|
||||
new_init.insert(lm3, Point2());
|
||||
new_init.insert(lm1, Point2(0,0));
|
||||
new_init.insert(lm2, Point2(0,0));
|
||||
new_init.insert(lm3, Point2(0,0));
|
||||
}
|
||||
|
||||
isamChol.update(new_factors, new_init);
|
||||
|
@ -194,9 +194,9 @@ TEST(testNonlinearISAM, markov_chain_with_reconnect ) {
|
|||
new_factors += PriorFactor<Point2>(lm3, landmark3, model2);
|
||||
|
||||
// Initialize to origin
|
||||
new_init.insert(lm1, Point2());
|
||||
new_init.insert(lm2, Point2());
|
||||
new_init.insert(lm3, Point2());
|
||||
new_init.insert(lm1, Point2(0,0));
|
||||
new_init.insert(lm2, Point2(0,0));
|
||||
new_init.insert(lm3, Point2(0,0));
|
||||
}
|
||||
|
||||
// Reconnect with observation later
|
||||
|
|
|
@ -68,7 +68,7 @@ int main() {
|
|||
values.insert(2,Vector3(0,0,1));
|
||||
typedef AdaptAutoDiff<SnavelyProjection, 2, 9, 3> AdaptedSnavely;
|
||||
Expression<Vector2> expression(AdaptedSnavely(), Expression<Vector9>(1), Expression<Vector3>(2));
|
||||
f2 = boost::make_shared<ExpressionFactor<Vector2> >(model, z.vector(), expression);
|
||||
f2 = boost::make_shared<ExpressionFactor<Vector2> >(model, z, expression);
|
||||
time("Point2_(AdaptedSnavely(), camera, point): ", f2, values);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -64,7 +64,7 @@ int main()
|
|||
long timeLog = clock();
|
||||
Point2 measurement(0,0);
|
||||
for(int i = 0; i < n; i++)
|
||||
measurement.localCoordinates(camera.project(point1));
|
||||
camera.project(point1)-measurement;
|
||||
long timeLog2 = clock();
|
||||
double seconds = (double)(timeLog2-timeLog)/CLOCKS_PER_SEC;
|
||||
cout << ((double)seconds*1e9/n) << " nanosecs/call" << endl;
|
||||
|
|
|
@ -62,11 +62,11 @@ int main(int argc, char* argv[]) {
|
|||
// readBAL converts to GTSAM format, so we need to convert back !
|
||||
Pose3 openGLpose = gtsam2openGL(camera.pose());
|
||||
Vector9 v9;
|
||||
v9 << Pose3::Logmap(openGLpose), camera.calibration().vector();
|
||||
v9 << Pose3::Logmap(openGLpose), camera.calibration();
|
||||
initial.insert(C(i++), v9);
|
||||
}
|
||||
for (const SfM_Track& track: db.tracks) {
|
||||
Vector3 v3 = track.p.vector();
|
||||
Vector3 v3 = track.p;
|
||||
initial.insert(P(j++), v3);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue