A lot more progress making things work. Still a long way to go.

release/4.3a0
Paul Furgale 2014-12-13 12:47:52 +01:00
parent 94c2490b6f
commit 959716ae92
11 changed files with 45 additions and 70 deletions

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include <gtsam/base/concepts.h>
#include <gtsam/base/GenericValue.h> #include <gtsam/base/GenericValue.h>
#include <gtsam/base/Manifold.h> #include <gtsam/base/Manifold.h>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
@ -209,11 +210,11 @@ const Chart& Value::getChart() const {
template<typename T> template<typename T>
ChartValue<T> convertToChartValue(const T& value, ChartValue<T> convertToChartValue(const T& value,
boost::optional< boost::optional<
Eigen::Matrix<double, traits::dimension<T>::value, Eigen::Matrix<double, traits_x<T>::dimension,
traits::dimension<T>::value>&> H = boost::none) { traits_x<T>::dimension>&> H = boost::none) {
if (H) { if (H) {
*H = Eigen::Matrix<double, traits::dimension<T>::value, *H = Eigen::Matrix<double, traits_x<T>::dimension,
traits::dimension<T>::value>::Identity(); traits_x<T>::dimension>::Identity();
} }
return ChartValue<T>(value); return ChartValue<T>(value);
} }

View File

@ -17,7 +17,8 @@
#pragma once #pragma once
#warning "LieScalar.h is deprecated. Please use double/float instead." // TODO(ASL) reenable
//#warning "LieScalar.h is deprecated. Please use double/float instead."
#include <gtsam/dllexport.h> #include <gtsam/dllexport.h>
#include <gtsam/base/DerivedValue.h> #include <gtsam/base/DerivedValue.h>
#include <gtsam/base/Lie.h> #include <gtsam/base/Lie.h>

View File

@ -18,6 +18,7 @@
#pragma once #pragma once
#include <gtsam/base/concepts.h>
#include <gtsam/base/Matrix.h> #include <gtsam/base/Matrix.h>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
@ -69,10 +70,10 @@ struct is_manifold: public boost::false_type {
// dimension, can return Eigen::Dynamic (-1) if not known at compile time // dimension, can return Eigen::Dynamic (-1) if not known at compile time
// defaults to dynamic, TODO makes sense ? // defaults to dynamic, TODO makes sense ?
typedef boost::integral_constant<int, Eigen::Dynamic> Dynamic; typedef boost::integral_constant<int, Eigen::Dynamic> Dynamic;
template<typename T> //template<typename T>
//struct dimension: public Dynamic { //struct dimension: public Dynamic {
struct dimension : public boost::integral_constant<int, 1> { // just temporary fix to minimize compiler errors while refactoring //struct dimension : public boost::integral_constant<int, 1> { // just temporary fix to minimize compiler errors while refactoring
}; //};
/** /**
* zero<T>::value is intended to be the origin of a canonical coordinate system * zero<T>::value is intended to be the origin of a canonical coordinate system
@ -147,7 +148,7 @@ template<typename T>
struct DefaultChart { struct DefaultChart {
//BOOST_STATIC_ASSERT(traits::is_manifold<T>::value); //BOOST_STATIC_ASSERT(traits::is_manifold<T>::value);
typedef T type; typedef T type;
typedef Eigen::Matrix<double, traits::dimension<T>::value, 1> vector; typedef Eigen::Matrix<double, traits_x<T>::dimension, 1> vector;
static vector local(const T& origin, const T& other) { static vector local(const T& origin, const T& other) {
return origin.localCoordinates(other); return origin.localCoordinates(other);

View File

@ -73,6 +73,7 @@ public:
} }
/// Constructor that will resize a dynamic matrix (unless already correct) /// Constructor that will resize a dynamic matrix (unless already correct)
OptionalJacobian(Eigen::MatrixXd& dynamic) : OptionalJacobian(Eigen::MatrixXd& dynamic) :
map_(NULL) { map_(NULL) {
dynamic.resize(Rows, Cols); // no malloc if correct size dynamic.resize(Rows, Cols); // no malloc if correct size
@ -111,5 +112,8 @@ public:
Eigen::Map<Fixed>* operator->(){ return &map_; } Eigen::Map<Fixed>* operator->(){ return &map_; }
}; };
template<>
class OptionalJacobian<-1, -1> {};
} // namespace gtsam } // namespace gtsam

View File

@ -38,7 +38,7 @@ struct additive_group_tag {};
// TODO: Remove // TODO: Remove
namespace traits { namespace traits {
template<typename T> template<typename T>
struct dimension; struct dimension{};
} }
template <typename T> struct traits_x { template <typename T> struct traits_x {
// TODO: remove anything in here ASAP. // TODO: remove anything in here ASAP.

View File

@ -71,7 +71,7 @@ Vector numericalGradient(boost::function<double(const X&)> h, const X& x,
BOOST_STATIC_ASSERT_MSG(traits::is_manifold<X>::value, BOOST_STATIC_ASSERT_MSG(traits::is_manifold<X>::value,
"Template argument X must be a manifold type."); "Template argument X must be a manifold type.");
static const int N = traits::dimension<X>::value; static const int N = traits_x<X>::dimension;
BOOST_STATIC_ASSERT_MSG(N>0, "Template argument X must be fixed-size type."); BOOST_STATIC_ASSERT_MSG(N>0, "Template argument X must be fixed-size type.");
typedef DefaultChart<X> ChartX; typedef DefaultChart<X> ChartX;
typedef typename ChartX::vector TangentX; typedef typename ChartX::vector TangentX;
@ -118,7 +118,7 @@ Matrix numericalDerivative11(boost::function<Y(const X&)> h, const X& x,
BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits_x<X>::structure_category>::value), BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits_x<X>::structure_category>::value),
"Template argument X must be a manifold type."); "Template argument X must be a manifold type.");
static const int N = traits::dimension<X>::value; static const int N = traits_x<X>::dimension;
BOOST_STATIC_ASSERT_MSG(N>0, "Template argument X must be fixed-size type."); BOOST_STATIC_ASSERT_MSG(N>0, "Template argument X must be fixed-size type.");
typedef DefaultChart<X> ChartX; typedef DefaultChart<X> ChartX;
typedef typename ChartX::vector TangentX; typedef typename ChartX::vector TangentX;

View File

@ -111,14 +111,27 @@ struct traits_x<QUATERNION_TYPE> {
} }
} }
static TangentVector Local(const Q& origin, const Q& other, ChartJacobian Horigin=boost::none, ChartJacobian Hother=boost::none) { static TangentVector Local(const Q& origin, const Q& other, ChartJacobian Horigin = boost::none, ChartJacobian Hother = boost::none) {
return Logmap(Between(origin,other,Horigin,Hother)); return Logmap(Between(origin,other,Horigin,Hother));
// TODO: incorporate Jacobian of Logmap // TODO: incorporate Jacobian of Logmap
} }
static Q Retract(const Q& origin, const TangentVector& v, ChartJacobian Horigin, ChartJacobian Hv) { static Q Retract(const Q& origin, const TangentVector& v, ChartJacobian Horigin = boost::none, ChartJacobian Hv = boost::none) {
return Compose(origin, Expmap(v), Horigin, Hv); return Compose(origin, Expmap(v), Horigin, Hv);
// TODO : incorporate Jacobian of Expmap // TODO : incorporate Jacobian of Expmap
} }
static void Print(const Q& q, const std::string& str = "") {
if(str.size() == 0) {
std::cout << "Eigen::Quaternion: ";
} else {
std::cout << str << " ";
}
std::cout << q.vec().transpose() << std::endl;
}
static bool Equals(const Q& q1, const Q& q2, double tol = 1e-8) {
return Between(q1,q2).vec().array().abs().maxCoeff() < tol;
}
}; };
typedef Eigen::Quaternion<double, Eigen::DontAlign> Quaternion; typedef Eigen::Quaternion<double, Eigen::DontAlign> Quaternion;

View File

@ -475,3 +475,4 @@ namespace gtsam {
template<> template<>
struct traits_x<Rot3> : public internal::LieGroup<Rot3> {}; struct traits_x<Rot3> : public internal::LieGroup<Rot3> {};
} }

View File

@ -50,7 +50,7 @@ TEST(Quaternion , Local) {
Q q2(Eigen::AngleAxisd(0.1, z_axis)); Q q2(Eigen::AngleAxisd(0.1, z_axis));
QuaternionJacobian H1,H2; QuaternionJacobian H1,H2;
Vector3 expected(0, 0, 0.1); Vector3 expected(0, 0, 0.1);
Vector3 actual = traits<Q>::Local(q1, q2, H1, H2); Vector3 actual = traits_x<Q>::Local(q1, q2, H1, H2);
EXPECT(assert_equal((Vector)expected,actual)); EXPECT(assert_equal((Vector)expected,actual));
} }
@ -61,7 +61,7 @@ TEST(Quaternion , Retract) {
Q expected(Eigen::AngleAxisd(0.1, z_axis)); Q expected(Eigen::AngleAxisd(0.1, z_axis));
Vector3 v(0, 0, 0.1); Vector3 v(0, 0, 0.1);
QuaternionJacobian Hq,Hv; QuaternionJacobian Hq,Hv;
Q actual = traits<Q>::Retract(q, v, Hq, Hv); Q actual = traits_x<Q>::Retract(q, v, Hq, Hv);
EXPECT(actual.isApprox(expected)); EXPECT(actual.isApprox(expected));
} }

View File

@ -300,57 +300,11 @@ public:
} }
}; };
//-----------------------------------------------------------------------------
/// Leaf Expression
template<class T, class Chart = DefaultChart<T> >
class LeafExpression: public ExpressionNode<T> {
typedef ChartValue<T, Chart> value_type; // perhaps this can be something else like a std::pair<T,Chart> ??
/// The key into values
Key key_;
/// Constructor with a single key
LeafExpression(Key key) :
key_(key) {
}
// todo: do we need a virtual destructor here too?
friend class Expression<value_type> ;
public:
/// Return keys that play in this expression
virtual std::set<Key> keys() const {
std::set<Key> keys;
keys.insert(key_);
return keys;
}
/// Return dimensions for each argument
virtual void dims(std::map<Key, int>& map) const {
// get dimension from the chart; only works for fixed dimension charts
map[key_] = traits::dimension<Chart>::value;
}
/// Return value
virtual const value_type& value(const Values& values) const {
return dynamic_cast<const value_type&>(values.at(key_));
}
/// Construct an execution trace for reverse AD
virtual const value_type& traceExecution(const Values& values,
ExecutionTrace<value_type>& trace,
ExecutionTraceStorage* traceStorage) const {
trace.setLeaf(key_);
return dynamic_cast<const value_type&>(values.at(key_));
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// Leaf Expression, if no chart is given, assume default chart and value_type is just the plain value /// Leaf Expression, if no chart is given, assume default chart and value_type is just the plain value
template<typename T> template<typename T>
class LeafExpression<T, DefaultChart<T> > : public ExpressionNode<T> { class LeafExpression : public ExpressionNode<T> {
typedef T value_type; typedef T value_type;
/// The key into values /// The key into values
@ -375,7 +329,7 @@ public:
/// Return dimensions for each argument /// Return dimensions for each argument
virtual void dims(std::map<Key, int>& map) const { virtual void dims(std::map<Key, int>& map) const {
map[key_] = traits::dimension<T>::value; map[key_] = traits_x<T>::dimension;
} }
/// Return value /// Return value
@ -451,15 +405,15 @@ public:
/// meta-function to generate fixed-size JacobianTA type /// meta-function to generate fixed-size JacobianTA type
template<class T, class A> template<class T, class A>
struct Jacobian { struct Jacobian {
typedef Eigen::Matrix<double, traits::dimension<T>::value, typedef Eigen::Matrix<double, traits_x<T>::dimension,
traits::dimension<A>::value> type; traits_x<A>::dimension> type;
}; };
/// meta-function to generate JacobianTA optional reference /// meta-function to generate JacobianTA optional reference
template<class T, class A> template<class T, class A>
struct MakeOptionalJacobian { struct MakeOptionalJacobian {
typedef OptionalJacobian<traits::dimension<T>::value, typedef OptionalJacobian<traits_x<T>::dimension,
traits::dimension<A>::value> type; traits_x<A>::dimension> type;
}; };
/** /**

View File

@ -173,7 +173,7 @@ private:
assert(H.size()==keys.size()); assert(H.size()==keys.size());
// Pre-allocate and zero VerticalBlockMatrix // Pre-allocate and zero VerticalBlockMatrix
static const int Dim = traits::dimension<T>::value; static const int Dim = traits_x<T>::dimension;
VerticalBlockMatrix Ab(dims, Dim); VerticalBlockMatrix Ab(dims, Dim);
Ab.matrix().setZero(); Ab.matrix().setZero();
JacobianMap jacobianMap(keys, Ab); JacobianMap jacobianMap(keys, Ab);
@ -223,7 +223,7 @@ private:
template<class T> template<class T>
struct apply_compose { struct apply_compose {
typedef T result_type; typedef T result_type;
static const int Dim = traits::dimension<T>::value; static const int Dim = traits_x<T>::dimension;
T operator()(const T& x, const T& y, OptionalJacobian<Dim, Dim> H1 = T operator()(const T& x, const T& y, OptionalJacobian<Dim, Dim> H1 =
boost::none, OptionalJacobian<Dim, Dim> H2 = boost::none) const { boost::none, OptionalJacobian<Dim, Dim> H2 = boost::none) const {
return x.compose(y, H1, H2); return x.compose(y, H1, H2);