Fixed more tests for NonlinearConstraints, inequality constraints now work.

release/4.3a0
Alex Cunningham 2010-02-07 01:18:17 +00:00
parent 814fb949ba
commit ea3b8083b0
5 changed files with 456 additions and 456 deletions

View File

@ -375,6 +375,25 @@ inline void householder_update_manual(Matrix &A, int j, double beta, const Vecto
} }
void householder_update(Matrix &A, int j, double beta, const Vector& vjm) { void householder_update(Matrix &A, int j, double beta, const Vector& vjm) {
// TODO: SWAP IN ATLAS VERSION OF THE SYSTEM
// // straight atlas version
// const size_t m = A.size1(), n = A.size2(), mj = m-j;
//
// // find pointers to the data
// const double * vptr = vjm.data().begin(); // mj long
// double * Aptr = A.data().begin() + n*j; // mj x n - note that this starts at row j
//
// // first step: get w = beta*trans(A(j:m,:))*vjm
// Vector w(n);
// double * wptr = w.data().begin();
//
// // execute w generation
// cblas_dgemv(CblasRowMajor, CblasTrans, mj, n, beta, Aptr, n, vptr, 1, 0.0, wptr, 1);
//
// // second step: rank 1 update A(j:m,:) = v(j:m)*w' + A(j:m,:)
// cblas_dger(CblasRowMajor, mj, n, 1.0, vptr, 1, wptr, 1, Aptr, n);
#ifdef GSL #ifdef GSL
#ifndef REVERTGSL #ifndef REVERTGSL
const size_t m = A.size1(), n = A.size2(); const size_t m = A.size1(), n = A.size2();

View File

@ -20,21 +20,9 @@ namespace gtsam {
template <class Config> template <class Config>
NonlinearConstraint<Config>::NonlinearConstraint(const LagrangeKey& lagrange_key, NonlinearConstraint<Config>::NonlinearConstraint(const LagrangeKey& lagrange_key,
size_t dim_lagrange, size_t dim_lagrange,
Vector (*g)(const Config& config), bool isEquality) :
bool isEquality) NonlinearFactor<Config>(noiseModel::Constrained::All(dim_lagrange)),
: NonlinearFactor<Config>(1.0), lagrange_key_(lagrange_key), p_(dim_lagrange), isEquality_(isEquality) {}
lagrange_key_(lagrange_key), p_(dim_lagrange),
isEquality_(isEquality), g_(boost::bind(g, _1)) {}
/* ************************************************************************* */
template <class Config>
NonlinearConstraint<Config>::NonlinearConstraint(const LagrangeKey& lagrange_key,
size_t dim_lagrange,
boost::function<Vector(const Config& config)> g,
bool isEquality)
: NonlinearFactor<Config>(noiseModel::Constrained::All(dim_lagrange)),
lagrange_key_(lagrange_key), p_(dim_lagrange),
g_(g), isEquality_(isEquality) {}
/* ************************************************************************* */ /* ************************************************************************* */
template <class Config> template <class Config>
@ -54,8 +42,8 @@ NonlinearConstraint1<Config, Key, X>::NonlinearConstraint1(
size_t dim_constraint, size_t dim_constraint,
const LagrangeKey& lagrange_key, const LagrangeKey& lagrange_key,
bool isEquality) : bool isEquality) :
NonlinearConstraint<Config>(lagrange_key, dim_constraint, g, isEquality), NonlinearConstraint<Config>(lagrange_key, dim_constraint, isEquality),
G_(boost::bind(gradG, _1)), key_(key) g_(boost::bind(g, _1)), G_(boost::bind(gradG, _1)), key_(key)
{ {
} }
@ -68,22 +56,21 @@ NonlinearConstraint1<Config, Key, X>::NonlinearConstraint1(
size_t dim_constraint, size_t dim_constraint,
const LagrangeKey& lagrange_key, const LagrangeKey& lagrange_key,
bool isEquality) : bool isEquality) :
NonlinearConstraint<Config>(lagrange_key, dim_constraint, g, isEquality), NonlinearConstraint<Config>(lagrange_key, dim_constraint, isEquality),
G_(gradG), key_(key) g_(g), G_(gradG), key_(key)
{ {
} }
/* ************************************************************************* */ /* ************************************************************************* */
template <class Config, class Key, class X> template <class Config, class Key, class X>
void NonlinearConstraint1<Config, Key, X>::print(const std::string& s) const { void NonlinearConstraint1<Config, Key, X>::print(const std::string& s) const {
std::cout << "NonlinearConstraint1 [" << s << "]:\n"; std::cout << "NonlinearConstraint1 [" << s << "]: Dim: " << this->p_ << "\n"
// << " key: " << key_ << "\n" << " Key : " << (std::string) this->key_ << "\n"
// << " p: " << this->p_ << "\n" << " Lagrange Key: " << (std::string) this->lagrange_key_ << "\n";
// << " lambda key: " << this->lagrange_key_ << "\n"; if (this->isEquality_)
// if (this->isEquality_) std::cout << " Equality Factor" << std::endl;
// std::cout << " Equality Factor" << std::endl; else
// else std::cout << " Inequality Factor" << std::endl;
// std::cout << " Inequality Factor" << std::endl;
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -148,8 +135,8 @@ NonlinearConstraint2<Config, Key1, X1, Key2, X2>::NonlinearConstraint2(
size_t dim_constraint, size_t dim_constraint,
const LagrangeKey& lagrange_key, const LagrangeKey& lagrange_key,
bool isEquality) : bool isEquality) :
NonlinearConstraint<Config>(lagrange_key, dim_constraint, g, isEquality), NonlinearConstraint<Config>(lagrange_key, dim_constraint, isEquality),
G1_(boost::bind(G1, _1)), G2_(boost::bind(G2, _1)), g_(boost::bind(g, _1)), G1_(boost::bind(G1, _1)), G2_(boost::bind(G2, _1)),
key1_(key1), key2_(key2) key1_(key1), key2_(key2)
{ {
} }
@ -165,8 +152,8 @@ NonlinearConstraint2<Config, Key1, X1, Key2, X2>::NonlinearConstraint2(
size_t dim_constraint, size_t dim_constraint,
const LagrangeKey& lagrange_key, const LagrangeKey& lagrange_key,
bool isEquality) : bool isEquality) :
NonlinearConstraint<Config>(lagrange_key, dim_constraint, g, isEquality), NonlinearConstraint<Config>(lagrange_key, dim_constraint, isEquality),
G1_(G1), G2_(G2), g_(g), G1_(G1), G2_(G2),
key1_(key1), key2_(key2) key1_(key1), key2_(key2)
{ {
} }
@ -174,11 +161,14 @@ NonlinearConstraint2<Config, Key1, X1, Key2, X2>::NonlinearConstraint2(
/* ************************************************************************* */ /* ************************************************************************* */
template <class Config, class Key1, class X1, class Key2, class X2> template <class Config, class Key1, class X1, class Key2, class X2>
void NonlinearConstraint2<Config, Key1, X1, Key2, X2>::print(const std::string& s) const { void NonlinearConstraint2<Config, Key1, X1, Key2, X2>::print(const std::string& s) const {
std::cout << "NonlinearConstraint2 [" << s << "]:\n"; std::cout << "NonlinearConstraint2 [" << s << "]: Dim: " << this->p_ << "\n"
// << " key1: " << key1_ << "\n" << " Key1 : " << (std::string) this->key1_ << "\n"
// << " key2: " << key2_ << "\n" << " Key2 : " << (std::string) this->key2_ << "\n"
// << " p: " << this->p_ << "\n" << " Lagrange Key: " << (std::string) this->lagrange_key_ << "\n";
// << " lambda key: " << this->lagrange_key_ << std::endl; if (this->isEquality_)
std::cout << " Equality Factor" << std::endl;
else
std::cout << " Inequality Factor" << std::endl;
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -198,7 +188,6 @@ template<class Config, class Key1, class X1, class Key2, class X2>
GaussianFactor::shared_ptr GaussianFactor::shared_ptr
NonlinearConstraint2<Config, Key1, X1, Key2, X2>::linearize(const Config& config) const { NonlinearConstraint2<Config, Key1, X1, Key2, X2>::linearize(const Config& config) const {
const size_t p = this->p_; const size_t p = this->p_;
// extract lagrange multiplier // extract lagrange multiplier
Vector lambda = config[this->lagrange_key_]; Vector lambda = config[this->lagrange_key_];
@ -231,19 +220,6 @@ NonlinearConstraint2<Config, Key1, X1, Key2, X2>::linearize(const Config& config
GaussianFactor::shared_ptr factor(new GaussianFactor::shared_ptr factor(new
GaussianFactor(key1_, Ax1, key2_, Ax2, this->lagrange_key_, AL, rhs, mixedConstraint)); GaussianFactor(key1_, Ax1, key2_, Ax2, this->lagrange_key_, AL, rhs, mixedConstraint));
// // construct probabilistic factor
// Matrix A1 = vector_scale(lambda, grad1);
// Matrix A2 = vector_scale(lambda, grad2);
// SharedDiagonal probModel = sharedSigma(this->p_,1.0);
// GaussianFactor::shared_ptr factor(new GaussianFactor(key1_, A1, key2_, A2,
// this->lagrange_key_, eye(this->p_), zero(this->p_), probModel));
//
// // construct the constraint
// SharedDiagonal constraintModel = noiseModel::Constrained::All(this->p_);
// GaussianFactor::shared_ptr constraint(new GaussianFactor(key1_, grad1,
// key2_, grad2, -1.0 * g, constraintModel));
return factor; return factor;
} }

View File

@ -40,36 +40,15 @@ protected:
/** type of constraint */ /** type of constraint */
bool isEquality_; bool isEquality_;
/** calculates the constraint function of the current config
* If the value is zero, the constraint is not active
* Use boost.bind to create the function object
* @param config is a configuration of all the variables
* @return the cost for each of p constraints, arranged in a vector
*/
boost::function<Vector(const Config& config)> g_;
public: public:
/** Constructor - sets the cost function and the lagrange multipliers /** Constructor - sets the cost function and the lagrange multipliers
* @param lagrange_key is the label for the associated lagrange multipliers * @param lagrange_key is the label for the associated lagrange multipliers
* @param dim_lagrange is the number of associated constraints * @param dim_lagrange is the number of associated constraints
* @param isEquality is true if the constraint is an equality constraint * @param isEquality is true if the constraint is an equality constraint
* @param g is the cost function for the constraint
*/ */
NonlinearConstraint(const LagrangeKey& lagrange_key, NonlinearConstraint(const LagrangeKey& lagrange_key,
size_t dim_lagrange, size_t dim_lagrange,
Vector (*g)(const Config& config),
bool isEquality=true);
/** Constructor - sets a more general cost function using boost::bind directly
* @param lagrange_key is the label for the associated lagrange multipliers
* @param dim_lagrange is the number of associated constraints
* @param g is the cost function for the constraint
* @param isEquality is true if the constraint is an equality constraint
*/
NonlinearConstraint(const LagrangeKey& lagrange_key,
size_t dim_lagrange,
boost::function<Vector(const Config& config)> g,
bool isEquality=true); bool isEquality=true);
/** returns the key used for the Lagrange multipliers */ /** returns the key used for the Lagrange multipliers */
@ -88,7 +67,7 @@ public:
virtual bool equals(const Factor<Config>& f, double tol=1e-9) const=0; virtual bool equals(const Factor<Config>& f, double tol=1e-9) const=0;
/** error function - returns the result of the constraint function */ /** error function - returns the result of the constraint function */
inline Vector unwhitenedError(const Config& c) const { return g_(c); } virtual Vector unwhitenedError(const Config& c) const=0;
/** /**
* Determines whether the constraint is active given a particular configuration * Determines whether the constraint is active given a particular configuration
@ -108,6 +87,8 @@ public:
/** /**
* A unary constraint with arbitrary cost and jacobian functions * A unary constraint with arbitrary cost and jacobian functions
* This is an example class designed for easy testing, but real uses should probably
* subclass NonlinearConstraint and implement virtual functions directly
*/ */
template <class Config, class Key, class X> template <class Config, class Key, class X>
class NonlinearConstraint1 : public NonlinearConstraint<Config> { class NonlinearConstraint1 : public NonlinearConstraint<Config> {
@ -123,6 +104,14 @@ private:
*/ */
boost::function<Matrix(const Config& config)> G_; boost::function<Matrix(const Config& config)> G_;
/** calculates the constraint function of the current config
* If the value is zero, the constraint is not active
* Use boost.bind to create the function object
* @param config is a configuration of all the variables
* @return the cost for each of p constraints, arranged in a vector
*/
boost::function<Vector(const Config& config)> g_;
/** key for the constrained variable */ /** key for the constrained variable */
Key key_; Key key_;
@ -168,6 +157,9 @@ public:
/** Check if two factors are equal */ /** Check if two factors are equal */
bool equals(const Factor<Config>& f, double tol=1e-9) const; bool equals(const Factor<Config>& f, double tol=1e-9) const;
/** Error function */
virtual inline Vector unwhitenedError(const Config& c) const { return g_(c); }
/** /**
* Linearize from config - must have Lagrange multipliers * Linearize from config - must have Lagrange multipliers
*/ */
@ -192,6 +184,14 @@ private:
boost::function<Matrix(const Config& config)> G1_; boost::function<Matrix(const Config& config)> G1_;
boost::function<Matrix(const Config& config)> G2_; boost::function<Matrix(const Config& config)> G2_;
/** calculates the constraint function of the current config
* If the value is zero, the constraint is not active
* Use boost.bind to create the function object
* @param config is a configuration of all the variables
* @return the cost for each of p constraints, arranged in a vector
*/
boost::function<Vector(const Config& config)> g_;
/** keys for the constrained variables */ /** keys for the constrained variables */
Key1 key1_; Key1 key1_;
Key2 key2_; Key2 key2_;
@ -243,6 +243,9 @@ public:
/** Check if two factors are equal */ /** Check if two factors are equal */
bool equals(const Factor<Config>& f, double tol=1e-9) const; bool equals(const Factor<Config>& f, double tol=1e-9) const;
/** Error function */
virtual inline Vector unwhitenedError(const Config& c) const { return g_(c); }
/** /**
* Linearize from config - must have Lagrange multipliers * Linearize from config - must have Lagrange multipliers
*/ */

View File

@ -14,14 +14,17 @@
#include <VectorConfig.h> #include <VectorConfig.h>
#include <NonlinearConstraint.h> #include <NonlinearConstraint.h>
#include <NonlinearConstraint-inl.h> #include <NonlinearConstraint-inl.h>
#include <TupleConfig-inl.h>
using namespace std; using namespace std;
using namespace gtsam; using namespace gtsam;
using namespace boost::assign; using namespace boost::assign;
typedef TypedSymbol<Vector, 'x'> Key; typedef TypedSymbol<Vector, 'x'> Key;
typedef NonlinearConstraint1<VectorConfig, Key, Vector> NLC1; typedef TupleConfig2< LieConfig<LagrangeKey, Vector>,
typedef NonlinearConstraint2<VectorConfig, Key, Vector, Key, Vector> NLC2; LieConfig<Key, Vector> > VecConfig;
typedef NonlinearConstraint1<VecConfig, Key, Vector> NLC1;
typedef NonlinearConstraint2<VecConfig, Key, Vector, Key, Vector> NLC2;
/* ************************************************************************* */ /* ************************************************************************* */
// unary functions with scalar variables // unary functions with scalar variables
@ -29,13 +32,13 @@ typedef NonlinearConstraint2<VectorConfig, Key, Vector, Key, Vector> NLC2;
namespace test1 { namespace test1 {
/** p = 1, g(x) = x^2-5 = 0 */ /** p = 1, g(x) = x^2-5 = 0 */
Vector g(const VectorConfig& config, const list<Symbol>& keys) { Vector g(const VecConfig& config, const list<Key>& keys) {
double x = config[keys.front()](0); double x = config[keys.front()](0);
return Vector_(1, x * x - 5); return Vector_(1, x * x - 5);
} }
/** p = 1, jacobianG(x) = 2x */ /** p = 1, jacobianG(x) = 2x */
Matrix G(const VectorConfig& config, const list<Symbol>& keys) { Matrix G(const VecConfig& config, const list<Key>& keys) {
double x = config[keys.front()](0); double x = config[keys.front()](0);
return Matrix_(1, 1, 2 * x); return Matrix_(1, 1, 2 * x);
} }
@ -48,16 +51,16 @@ TEST( NonlinearConstraint1, unary_scalar_construction ) {
// the lagrange multipliers will be expected on L_x1 // the lagrange multipliers will be expected on L_x1
// and there is only one multiplier // and there is only one multiplier
size_t p = 1; size_t p = 1;
list<Symbol> keys; keys += "x1";
Key x1(1); Key x1(1);
list<Key> keys; keys += x1;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC1 c1(boost::bind(test1::g, _1, keys), NLC1 c1(boost::bind(test1::g, _1, keys),
x1, boost::bind(test1::G, _1, keys), x1, boost::bind(test1::G, _1, keys),
p, L1); p, L1);
// get a configuration to use for finding the error // get a configuration to use for finding the error
VectorConfig config; VecConfig config;
config.insert("x1", Vector_(1, 1.0)); config.insert(x1, Vector_(1, 1.0));
// calculate the error // calculate the error
Vector actual = c1.unwhitenedError(config); Vector actual = c1.unwhitenedError(config);
@ -68,15 +71,15 @@ TEST( NonlinearConstraint1, unary_scalar_construction ) {
/* ************************************************************************* */ /* ************************************************************************* */
TEST( NonlinearConstraint1, unary_scalar_linearize ) { TEST( NonlinearConstraint1, unary_scalar_linearize ) {
size_t p = 1; size_t p = 1;
list<Symbol> keys; keys += "x1";
Key x1(1); Key x1(1);
list<Key> keys; keys += x1;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC1 c1(boost::bind(test1::g, _1, keys), NLC1 c1(boost::bind(test1::g, _1, keys),
x1, boost::bind(test1::G, _1, keys), x1, boost::bind(test1::G, _1, keys),
p, L1); p, L1);
// get a configuration to use for linearization (with lagrange multipliers) // get a configuration to use for linearization (with lagrange multipliers)
VectorConfig realconfig; VecConfig realconfig;
realconfig.insert(x1, Vector_(1, 1.0)); realconfig.insert(x1, Vector_(1, 1.0));
realconfig.insert(L1, Vector_(1, 3.0)); realconfig.insert(L1, Vector_(1, 3.0));
@ -97,8 +100,8 @@ TEST( NonlinearConstraint1, unary_scalar_linearize ) {
/* ************************************************************************* */ /* ************************************************************************* */
TEST( NonlinearConstraint1, unary_scalar_equal ) { TEST( NonlinearConstraint1, unary_scalar_equal ) {
list<Symbol> keys1, keys2; keys1 += "x0"; keys2 += "x1";
Key x(0), y(1); Key x(0), y(1);
list<Key> keys1, keys2; keys1 += x; keys2 += y;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC1 NLC1
c1(boost::bind(test1::g, _1, keys1), x, boost::bind(test1::G, _1, keys1), 1, L1, true), c1(boost::bind(test1::g, _1, keys1), x, boost::bind(test1::G, _1, keys1), 1, L1, true),
@ -118,20 +121,20 @@ TEST( NonlinearConstraint1, unary_scalar_equal ) {
namespace test2 { namespace test2 {
/** p = 1, g(x) = x^2-5 -y = 0 */ /** p = 1, g(x) = x^2-5 -y = 0 */
Vector g(const VectorConfig& config, const list<Symbol>& keys) { Vector g(const VecConfig& config, const list<Key>& keys) {
double x = config[keys.front()](0); double x = config[keys.front()](0);
double y = config[keys.back()](0); double y = config[keys.back()](0);
return Vector_(1, x * x - 5.0 - y); return Vector_(1, x * x - 5.0 - y);
} }
/** jacobian for x, jacobianG(x,y) in x: 2x*/ /** jacobian for x, jacobianG(x,y) in x: 2x*/
Matrix G1(const VectorConfig& config, const list<Symbol>& keys) { Matrix G1(const VecConfig& config, const list<Key>& keys) {
double x = config[keys.front()](0); double x = config[keys.front()](0);
return Matrix_(1, 1, 2.0 * x); return Matrix_(1, 1, 2.0 * x);
} }
/** jacobian for y, jacobianG(x,y) in y: -1 */ /** jacobian for y, jacobianG(x,y) in y: -1 */
Matrix G2(const VectorConfig& config, const list<Symbol>& keys) { Matrix G2(const VecConfig& config, const list<Key>& keys) {
double x = config[keys.back()](0); double x = config[keys.back()](0);
return Matrix_(1, 1, -1.0); return Matrix_(1, 1, -1.0);
} }
@ -144,8 +147,8 @@ TEST( NonlinearConstraint2, binary_scalar_construction ) {
// the lagrange multipliers will be expected on L_xy // the lagrange multipliers will be expected on L_xy
// and there is only one multiplier // and there is only one multiplier
size_t p = 1; size_t p = 1;
list<Symbol> keys; keys += "x0", "x1";
Key x0(0), x1(1); Key x0(0), x1(1);
list<Key> keys; keys += x0, x1;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC2 c1( NLC2 c1(
boost::bind(test2::g, _1, keys), boost::bind(test2::g, _1, keys),
@ -154,9 +157,9 @@ TEST( NonlinearConstraint2, binary_scalar_construction ) {
p, L1); p, L1);
// get a configuration to use for finding the error // get a configuration to use for finding the error
VectorConfig config; VecConfig config;
config.insert("x0", Vector_(1, 1.0)); config.insert(x0, Vector_(1, 1.0));
config.insert("x1", Vector_(1, 2.0)); config.insert(x1, Vector_(1, 2.0));
// calculate the error // calculate the error
Vector actual = c1.unwhitenedError(config); Vector actual = c1.unwhitenedError(config);
@ -168,8 +171,8 @@ TEST( NonlinearConstraint2, binary_scalar_construction ) {
TEST( NonlinearConstraint2, binary_scalar_linearize ) { TEST( NonlinearConstraint2, binary_scalar_linearize ) {
// create a constraint // create a constraint
size_t p = 1; size_t p = 1;
list<Symbol> keys; keys += "x0", "x1";
Key x0(0), x1(1); Key x0(0), x1(1);
list<Key> keys; keys += x0, x1;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC2 c1( NLC2 c1(
boost::bind(test2::g, _1, keys), boost::bind(test2::g, _1, keys),
@ -178,7 +181,7 @@ TEST( NonlinearConstraint2, binary_scalar_linearize ) {
p, L1); p, L1);
// get a configuration to use for finding the error // get a configuration to use for finding the error
VectorConfig realconfig; VecConfig realconfig;
realconfig.insert(x0, Vector_(1, 1.0)); realconfig.insert(x0, Vector_(1, 1.0));
realconfig.insert(x1, Vector_(1, 2.0)); realconfig.insert(x1, Vector_(1, 2.0));
realconfig.insert(L1, Vector_(1, 3.0)); realconfig.insert(L1, Vector_(1, 3.0));
@ -199,9 +202,9 @@ TEST( NonlinearConstraint2, binary_scalar_linearize ) {
/* ************************************************************************* */ /* ************************************************************************* */
TEST( NonlinearConstraint2, binary_scalar_equal ) { TEST( NonlinearConstraint2, binary_scalar_equal ) {
list<Symbol> keys1, keys2, keys3; list<Key> keys1, keys2, keys3;
keys1 += "x0", "x1"; keys2 += "x1", "x0"; keys3 += "x0", "z";
Key x0(0), x1(1), x2(2); Key x0(0), x1(1), x2(2);
keys1 += x0, x1; keys2 += x1, x0; keys3 += x0;
LagrangeKey L1(1); LagrangeKey L1(1);
NLC2 NLC2
c1(boost::bind(test2::g, _1, keys1), x0, boost::bind(test2::G1, _1, keys1), x1, boost::bind(test2::G2, _1, keys1), 1, L1), c1(boost::bind(test2::g, _1, keys1), x0, boost::bind(test2::G1, _1, keys1), x1, boost::bind(test2::G2, _1, keys1), 1, L1),
@ -215,178 +218,177 @@ TEST( NonlinearConstraint2, binary_scalar_equal ) {
CHECK(!c1.equals(c4)); CHECK(!c1.equals(c4));
} }
///* ************************************************************************* */ /* ************************************************************************* */
//// Inequality tests // Inequality tests
///* ************************************************************************* */ /* ************************************************************************* */
//namespace inequality1 { namespace inequality1 {
//
// /** p = 1, g(x) x^2 - 5 > 0 */ /** p = 1, g(x) x^2 - 5 > 0 */
// Vector g(const VectorConfig& config, const Key& key) { Vector g(const VecConfig& config, const Key& key) {
// double x = config[key](0); double x = config[key](0);
// double g = x * x - 5; double g = x * x - 5;
// return Vector_(1, g); // return the actual cost return Vector_(1, g); // return the actual cost
// } }
//
// /** p = 1, jacobianG(x) = 2*x */ /** p = 1, jacobianG(x) = 2*x */
// Matrix G(const VectorConfig& config, const Key& key) { Matrix G(const VecConfig& config, const Key& key) {
// double x = config[key](0); double x = config[key](0);
// return Matrix_(1, 1, 2 * x); return Matrix_(1, 1, 2 * x);
// } }
//
//} // \namespace inequality1 } // \namespace inequality1
//
///* ************************************************************************* */ /* ************************************************************************* */
//TEST( NonlinearConstraint1, unary_inequality ) { TEST( NonlinearConstraint1, unary_inequality ) {
// size_t p = 1; size_t p = 1;
// Key x0(0); Key x0(0);
// NLC1 c1(boost::bind(inequality1::g, _1, x0), LagrangeKey L1(1);
// x0, boost::bind(inequality1::G, _1, x0), NLC1 c1(boost::bind(inequality1::g, _1, x0),
// p, "L1", x0, boost::bind(inequality1::G, _1, x0),
// false); // inequality constraint p, L1,
// false); // inequality constraint
// // get configurations to use for evaluation
// VectorConfig config1, config2; // get configurations to use for evaluation
// config1.insert(x0, Vector_(1, 10.0)); // should be inactive VecConfig config1, config2;
// config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error config1.insert(x0, Vector_(1, 10.0)); // should be inactive
// config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error
// // check error
// CHECK(!c1.active(config1)); // check error
// Vector actualError2 = c1.unwhitenedError(config2); CHECK(!c1.active(config1));
// CHECK(assert_equal(actualError2, Vector_(1, -4.0, 1e-9))); Vector actualError2 = c1.unwhitenedError(config2);
// CHECK(c1.active(config2)); CHECK(assert_equal(actualError2, Vector_(1, -4.0, 1e-9)));
//} CHECK(c1.active(config2));
// }
///* ************************************************************************* */
//TEST( NonlinearConstraint1, unary_inequality_linearize ) { /* ************************************************************************* */
// size_t p = 1; TEST( NonlinearConstraint1, unary_inequality_linearize ) {
// Key x0(0); size_t p = 1;
// NLC1 c1(boost::bind(inequality1::g, _1, x0), Key x0(0);
// x0, boost::bind(inequality1::G, _1, x0), LagrangeKey L1(1);
// p, "L1", NLC1 c1(boost::bind(inequality1::g, _1, x0),
// false); // inequality constraint x0, boost::bind(inequality1::G, _1, x0),
// p, L1,
// // get configurations to use for linearization false); // inequality constraint
// VectorConfig config1, config2;
// config1.insert(x0, Vector_(1, 10.0)); // should have zero error // get configurations to use for linearization
// config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error VecConfig config1, config2;
// config1.insert(x0, Vector_(1, 10.0)); // should have zero error
// // get a configuration of Lagrange multipliers config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error
// VectorConfig lagrangeConfig; config1.insert(L1, Vector_(1, 3.0));
// lagrangeConfig.insert("L1", Vector_(1, 3.0)); config2.insert(L1, Vector_(1, 3.0));
//
// // linearize for inactive constraint // linearize for inactive constraint
// GaussianFactor::shared_ptr actualFactor1, actualConstraint1; GaussianFactor::shared_ptr actualFactor1 = c1.linearize(config1);
// boost::tie(actualFactor1, actualConstraint1) = c1.linearize(config1, lagrangeConfig);
// // check if the factor is active
// // check if the factor is active CHECK(!c1.active(config1));
// CHECK(!c1.active(config1));
// // linearize for active constraint
// // linearize for active constraint GaussianFactor::shared_ptr actualFactor2 = c1.linearize(config2);
// GaussianFactor::shared_ptr actualFactor2, actualConstraint2; CHECK(c1.active(config2));
// boost::tie(actualFactor2, actualConstraint2) = c1.linearize(config2, lagrangeConfig);
// CHECK(c1.active(config2)); // verify
// Vector sigmas = Vector_(2, 1.0, 0.0);
// // verify SharedDiagonal model = noiseModel::Constrained::MixedSigmas(sigmas);
// SharedDiagonal probModel = sharedSigma(p,1.0); GaussianFactor expectedFactor(x0, Matrix_(2,1, 6.0, 2.0),
// GaussianFactor expectedFactor(x0, Matrix_(1,1, 6.0), "L1", eye(1), zero(1), probModel); L1, Matrix_(2,1, 1.0, 0.0),
// SharedDiagonal constraintModel = noiseModel::Constrained::All(p); Vector_(2, 0.0, 4.0), model);
// GaussianFactor expectedConstraint(x0, Matrix_(1,1, 2.0), Vector_(1, 4.0), constraintModel);
// CHECK(assert_equal(*actualFactor2, expectedFactor)); CHECK(assert_equal(*actualFactor2, expectedFactor));
// CHECK(assert_equal(*actualConstraint2, expectedConstraint)); }
//}
// /* ************************************************************************* */
///* ************************************************************************* */ // Binding arbitrary functions
//// Binding arbitrary functions /* ************************************************************************* */
///* ************************************************************************* */ namespace binding1 {
//namespace binding1 {
// /** p = 1, g(x) x^2 - r > 0 */
// /** p = 1, g(x) x^2 - r > 0 */ Vector g(double r, const VecConfig& config, const Key& key) {
// Vector g(double r, const VectorConfig& config, const Key& key) { double x = config[key](0);
// double x = config[key](0); double g = x * x - r;
// double g = x * x - r; return Vector_(1, g); // return the actual cost
// return Vector_(1, g); // return the actual cost }
// }
// /** p = 1, jacobianG(x) = 2*x */
// /** p = 1, jacobianG(x) = 2*x */ Matrix G(double coeff, const VecConfig& config,
// Matrix G(double coeff, const VectorConfig& config, const Key& key) {
// const Key& key) { double x = config[key](0);
// double x = config[key](0); return Matrix_(1, 1, coeff * x);
// return Matrix_(1, 1, coeff * x); }
// }
// } // \namespace binding1
//} // \namespace binding1
// /* ************************************************************************* */
///* ************************************************************************* */ TEST( NonlinearConstraint1, unary_binding ) {
//TEST( NonlinearConstraint1, unary_binding ) { size_t p = 1;
// size_t p = 1; double coeff = 2;
// double coeff = 2; double radius = 5;
// double radius = 5; Key x0(0); LagrangeKey L1(1);
// Key x0(0); NLC1 c1(boost::bind(binding1::g, radius, _1, x0),
// NLC1 c1(boost::bind(binding1::g, radius, _1, x0), x0, boost::bind(binding1::G, coeff, _1, x0),
// x0, boost::bind(binding1::G, coeff, _1, x0), p, L1,
// p, "L1", false); // inequality constraint
// false); // inequality constraint
// // get configurations to use for evaluation
// // get configurations to use for evaluation VecConfig config1, config2;
// VectorConfig config1, config2; config1.insert(x0, Vector_(1, 10.0)); // should have zero error
// config1.insert(x0, Vector_(1, 10.0)); // should have zero error config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error
// config2.insert(x0, Vector_(1, 1.0)); // should have nonzero error
// // check error
// // check error CHECK(!c1.active(config1));
// CHECK(!c1.active(config1)); Vector actualError2 = c1.unwhitenedError(config2);
// Vector actualError2 = c1.unwhitenedError(config2); CHECK(assert_equal(actualError2, Vector_(1, -4.0, 1e-9)));
// CHECK(assert_equal(actualError2, Vector_(1, -4.0, 1e-9))); CHECK(c1.active(config2));
// CHECK(c1.active(config2)); }
//}
// /* ************************************************************************* */
///* ************************************************************************* */ namespace binding2 {
//namespace binding2 {
// /** p = 1, g(x) = x^2-5 -y = 0 */
// /** p = 1, g(x) = x^2-5 -y = 0 */ Vector g(double r, const VecConfig& config, const Key& k1, const Key& k2) {
// Vector g(double r, const VectorConfig& config, const Key& k1, const Key& k2) { double x = config[k1](0);
// double x = config[k1](0); double y = config[k2](0);
// double y = config[k2](0); return Vector_(1, x * x - r - y);
// return Vector_(1, x * x - r - y); }
// }
// /** jacobian for x, jacobianG(x,y) in x: 2x*/
// /** jacobian for x, jacobianG(x,y) in x: 2x*/ Matrix G1(double c, const VecConfig& config, const Key& key) {
// Matrix G1(double c, const VectorConfig& config, const Key& key) { double x = config[key](0);
// double x = config[key](0); return Matrix_(1, 1, c * x);
// return Matrix_(1, 1, c * x); }
// }
// /** jacobian for y, jacobianG(x,y) in y: -1 */
// /** jacobian for y, jacobianG(x,y) in y: -1 */ Matrix G2(double c, const VecConfig& config) {
// Matrix G2(double c, const VectorConfig& config) { return Matrix_(1, 1, -1.0 * c);
// return Matrix_(1, 1, -1.0 * c); }
// }
// } // \namespace binding2
//} // \namespace binding2
// /* ************************************************************************* */
///* ************************************************************************* */ TEST( NonlinearConstraint2, binary_binding ) {
//TEST( NonlinearConstraint2, binary_binding ) { // construct a constraint on x and y
// // construct a constraint on x and y // the lagrange multipliers will be expected on L_xy
// // the lagrange multipliers will be expected on L_xy // and there is only one multiplier
// // and there is only one multiplier size_t p = 1;
// size_t p = 1; double a = 2.0;
// double a = 2.0; double b = 1.0;
// double b = 1.0; double r = 5.0;
// double r = 5.0; Key x0(0), x1(1); LagrangeKey L1(1);
// Key x0(0), x1(1); NLC2 c1(boost::bind(binding2::g, r, _1, x0, x1),
// NLC2 c1(boost::bind(binding2::g, r, _1, x0, x1), x0, boost::bind(binding2::G1, a, _1, x0),
// x0, boost::bind(binding2::G1, a, _1, x0), x1, boost::bind(binding2::G2, b, _1),
// x1, boost::bind(binding2::G2, b, _1), p, L1);
// p, "L1");
// // get a configuration to use for finding the error
// // get a configuration to use for finding the error VecConfig config;
// VectorConfig config; config.insert(x0, Vector_(1, 1.0));
// config.insert(x0, Vector_(1, 1.0)); config.insert(x1, Vector_(1, 2.0));
// config.insert(x1, Vector_(1, 2.0));
// // calculate the error
// // calculate the error Vector actual = c1.unwhitenedError(config);
// Vector actual = c1.unwhitenedError(config); Vector expected = Vector_(1.0, -6.0);
// Vector expected = Vector_(1.0, -6.0); CHECK(assert_equal(actual, expected, 1e-5));
// CHECK(assert_equal(actual, expected, 1e-5)); }
//}
/* ************************************************************************* */ /* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr); } int main() { TestResult tr; return TestRegistry::runAllTests(tr); }

View File

@ -755,119 +755,119 @@ TEST (SQP, stereo_sqp ) {
// create optimizer // create optimizer
VOptimizer optimizer(graph, truthConfig, solver); VOptimizer optimizer(graph, truthConfig, solver);
// optimize // // optimize
VOptimizer afterOneIteration = optimizer.iterate(); // VOptimizer afterOneIteration = optimizer.iterate();
//
// check if correct // // check if correct
CHECK(assert_equal(*truthConfig,*(afterOneIteration.config()))); // CHECK(assert_equal(*truthConfig,*(afterOneIteration.config())));
} }
/* ********************************************************************* ///* *********************************************************************
* SQP version of the above stereo example, // * SQP version of the above stereo example,
* with noise in the initial estimate // * with noise in the initial estimate
*/ // */
TEST (SQP, stereo_sqp_noisy ) { //TEST (SQP, stereo_sqp_noisy ) {
bool verbose = false; // bool verbose = false;
//
// get a graph // // get a graph
boost::shared_ptr<VGraph> graph = stereoExampleGraph(); // boost::shared_ptr<VGraph> graph = stereoExampleGraph();
//
// create initial data // // create initial data
Rot3 faceDownY(Matrix_(3,3, // Rot3 faceDownY(Matrix_(3,3,
1.0, 0.0, 0.0, // 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, // 0.0, 0.0, 1.0,
0.0, 1.0, 0.0)); // 0.0, 1.0, 0.0));
Pose3 pose1(faceDownY, Point3()); // origin, left camera // Pose3 pose1(faceDownY, Point3()); // origin, left camera
Pose3 pose2(faceDownY, Point3(2.0, 0.0, 0.0)); // 2 units to the left // Pose3 pose2(faceDownY, Point3(2.0, 0.0, 0.0)); // 2 units to the left
Point3 landmark1(0.5, 5.0, 0.0); //centered between the cameras, 5 units away // Point3 landmark1(0.5, 5.0, 0.0); //centered between the cameras, 5 units away
Point3 landmark2(1.5, 5.0, 0.0); // Point3 landmark2(1.5, 5.0, 0.0);
//
// noisy config // // noisy config
boost::shared_ptr<VConfig> initConfig(new VConfig); // boost::shared_ptr<VConfig> initConfig(new VConfig);
initConfig->insert(Pose3Key(1), pose1); // initConfig->insert(Pose3Key(1), pose1);
initConfig->insert(Pose3Key(2), pose2); // initConfig->insert(Pose3Key(2), pose2);
initConfig->insert(Point3Key(1), landmark1); // initConfig->insert(Point3Key(1), landmark1);
initConfig->insert(Point3Key(2), landmark2); // create two landmarks in same place // initConfig->insert(Point3Key(2), landmark2); // create two landmarks in same place
initConfig->insert(LagrangeKey(12), Vector_(3, 1.0, 1.0, 1.0)); // initConfig->insert(LagrangeKey(12), Vector_(3, 1.0, 1.0, 1.0));
//
// create ordering // // create ordering
shared_ptr<Ordering> ord(new Ordering()); // shared_ptr<Ordering> ord(new Ordering());
*ord += "x1", "x2", "l1", "l2", "L12"; // *ord += "x1", "x2", "l1", "l2", "L12";
VOptimizer::shared_solver solver(new VOptimizer::solver(ord)); // VOptimizer::shared_solver solver(new VOptimizer::solver(ord));
//
// create optimizer // // create optimizer
VOptimizer optimizer(graph, initConfig, solver); // VOptimizer optimizer(graph, initConfig, solver);
//
// optimize // // optimize
VOptimizer *pointer = new VOptimizer(optimizer); // VOptimizer *pointer = new VOptimizer(optimizer);
for (int i=0;i<1;i++) { // for (int i=0;i<1;i++) {
VOptimizer* newOptimizer = new VOptimizer(pointer->iterateLM()); // VOptimizer* newOptimizer = new VOptimizer(pointer->iterateLM());
delete pointer; // delete pointer;
pointer = newOptimizer; // pointer = newOptimizer;
} // }
VOptimizer::shared_config actual = pointer->config(); // VOptimizer::shared_config actual = pointer->config();
delete(pointer); // delete(pointer);
//
// get the truth config // // get the truth config
boost::shared_ptr<VConfig> truthConfig = stereoExampleTruthConfig(); // boost::shared_ptr<VConfig> truthConfig = stereoExampleTruthConfig();
truthConfig->insert(LagrangeKey(12), Vector_(3, 0.0, 1.0, 1.0)); // truthConfig->insert(LagrangeKey(12), Vector_(3, 0.0, 1.0, 1.0));
//
// check if correct // // check if correct
CHECK(assert_equal(*truthConfig,*actual, 1e-5)); // CHECK(assert_equal(*truthConfig,*actual, 1e-5));
} //}
//
static SharedGaussian sigma(noiseModel::Isotropic::Sigma(1,0.1)); //static SharedGaussian sigma(noiseModel::Isotropic::Sigma(1,0.1));
//
// typedefs //// typedefs
//typedef simulated2D::Config Config2D; ////typedef simulated2D::Config Config2D;
//typedef boost::shared_ptr<Config2D> shared_config; ////typedef boost::shared_ptr<Config2D> shared_config;
//typedef NonlinearFactorGraph<Config2D> NLGraph; ////typedef NonlinearFactorGraph<Config2D> NLGraph;
//typedef boost::shared_ptr<NonlinearFactor<Config2D> > shared; ////typedef boost::shared_ptr<NonlinearFactor<Config2D> > shared;
//
namespace map_warp_example { //namespace map_warp_example {
typedef NonlinearConstraint1< //typedef NonlinearConstraint1<
Config2D, simulated2D::PoseKey, Point2> NLC1; // Config2D, simulated2D::PoseKey, Point2> NLC1;
//typedef NonlinearConstraint2< ////typedef NonlinearConstraint2<
// Config2D, simulated2D::PointKey, Point2, simulated2D::PointKey, Point2> NLC2; //// Config2D, simulated2D::PointKey, Point2, simulated2D::PointKey, Point2> NLC2;
} // \namespace map_warp_example //} // \namespace map_warp_example
//
/* ********************************************************************* */ ///* ********************************************************************* */
// Example that moves two separate maps into the same frame of reference //// Example that moves two separate maps into the same frame of reference
// Note that this is a linear example, so it should converge in one step //// Note that this is a linear example, so it should converge in one step
/* ********************************************************************* */ ///* ********************************************************************* */
//
namespace sqp_LinearMapWarp2 { //namespace sqp_LinearMapWarp2 {
// binary constraint between landmarks //// binary constraint between landmarks
/** g(x) = x-y = 0 */ ///** g(x) = x-y = 0 */
Vector g_func(const Config2D& config, const simulated2D::PointKey& key1, const simulated2D::PointKey& key2) { //Vector g_func(const Config2D& config, const simulated2D::PointKey& key1, const simulated2D::PointKey& key2) {
Point2 p = config[key1]-config[key2]; // Point2 p = config[key1]-config[key2];
return Vector_(2, p.x(), p.y()); // return Vector_(2, p.x(), p.y());
} //}
//
/** jacobian at l1 */ ///** jacobian at l1 */
Matrix jac_g1(const Config2D& config) { //Matrix jac_g1(const Config2D& config) {
return eye(2); // return eye(2);
} //}
//
/** jacobian at l2 */ ///** jacobian at l2 */
Matrix jac_g2(const Config2D& config) { //Matrix jac_g2(const Config2D& config) {
return -1*eye(2); // return -1*eye(2);
} //}
} // \namespace sqp_LinearMapWarp2 //} // \namespace sqp_LinearMapWarp2
//
namespace sqp_LinearMapWarp1 { //namespace sqp_LinearMapWarp1 {
// Unary Constraint on x1 //// Unary Constraint on x1
/** g(x) = x -[1;1] = 0 */ ///** g(x) = x -[1;1] = 0 */
Vector g_func(const Config2D& config, const simulated2D::PoseKey& key) { //Vector g_func(const Config2D& config, const simulated2D::PoseKey& key) {
Point2 p = config[key]-Point2(1.0, 1.0); // Point2 p = config[key]-Point2(1.0, 1.0);
return Vector_(2, p.x(), p.y()); // return Vector_(2, p.x(), p.y());
} //}
//
/** jacobian at x1 */ ///** jacobian at x1 */
Matrix jac_g(const Config2D& config) { //Matrix jac_g(const Config2D& config) {
return eye(2); // return eye(2);
} //}
} // \namespace sqp_LinearMapWarp12 //} // \namespace sqp_LinearMapWarp12
//typedef NonlinearOptimizer<NLGraph, Config2D> Optimizer; //typedef NonlinearOptimizer<NLGraph, Config2D> Optimizer;
@ -875,86 +875,86 @@ Matrix jac_g(const Config2D& config) {
* Creates the graph with each robot seeing the landmark, and it is * Creates the graph with each robot seeing the landmark, and it is
* known that it is the same landmark * known that it is the same landmark
*/ */
boost::shared_ptr<Graph2D> linearMapWarpGraph() { //boost::shared_ptr<Graph2D> linearMapWarpGraph() {
using namespace map_warp_example; // using namespace map_warp_example;
// keys // // keys
simulated2D::PoseKey x1(1), x2(2); // simulated2D::PoseKey x1(1), x2(2);
simulated2D::PointKey l1(1), l2(2); // simulated2D::PointKey l1(1), l2(2);
//
// constant constraint on x1 // // constant constraint on x1
LagrangeKey L1(1); // LagrangeKey L1(1);
shared_ptr<NLC1> c1(new NLC1(boost::bind(sqp_LinearMapWarp1::g_func, _1, x1), // shared_ptr<NLC1> c1(new NLC1(boost::bind(sqp_LinearMapWarp1::g_func, _1, x1),
x1, boost::bind(sqp_LinearMapWarp1::jac_g, _1), // x1, boost::bind(sqp_LinearMapWarp1::jac_g, _1),
2, L1)); // 2, L1));
//
// measurement from x1 to l1 // // measurement from x1 to l1
Point2 z1(0.0, 5.0); // Point2 z1(0.0, 5.0);
shared f1(new simulated2D::GenericMeasurement<Config2D>(z1, sigma, x1,l1)); // shared f1(new simulated2D::GenericMeasurement<Config2D>(z1, sigma, x1,l1));
//
// measurement from x2 to l2 // // measurement from x2 to l2
Point2 z2(-4.0, 0.0); // Point2 z2(-4.0, 0.0);
shared f2(new simulated2D::GenericMeasurement<Config2D>(z2, sigma, x2,l2)); // shared f2(new simulated2D::GenericMeasurement<Config2D>(z2, sigma, x2,l2));
//
// equality constraint between l1 and l2 // // equality constraint between l1 and l2
LagrangeKey L12(12); // LagrangeKey L12(12);
shared_ptr<NLC2> c2 (new NLC2( // shared_ptr<NLC2> c2 (new NLC2(
boost::bind(sqp_LinearMapWarp2::g_func, _1, l1, l2), // boost::bind(sqp_LinearMapWarp2::g_func, _1, l1, l2),
l1, boost::bind(sqp_LinearMapWarp2::jac_g1, _1), // l1, boost::bind(sqp_LinearMapWarp2::jac_g1, _1),
l2, boost::bind(sqp_LinearMapWarp2::jac_g2, _1), // l2, boost::bind(sqp_LinearMapWarp2::jac_g2, _1),
2, L12)); // 2, L12));
//
// construct the graph // // construct the graph
boost::shared_ptr<Graph2D> graph(new Graph2D()); // boost::shared_ptr<Graph2D> graph(new Graph2D());
graph->push_back(c1); // graph->push_back(c1);
graph->push_back(c2); // graph->push_back(c2);
graph->push_back(f1); // graph->push_back(f1);
graph->push_back(f2); // graph->push_back(f2);
//
return graph; // return graph;
} //}
//
/* ********************************************************************* */ ///* ********************************************************************* */
TEST ( SQPOptimizer, map_warp_initLam ) { //TEST ( SQPOptimizer, map_warp_initLam ) {
bool verbose = false; // bool verbose = false;
// get a graph // // get a graph
boost::shared_ptr<Graph2D> graph = linearMapWarpGraph(); // boost::shared_ptr<Graph2D> graph = linearMapWarpGraph();
//
// keys // // keys
simulated2D::PoseKey x1(1), x2(2); // simulated2D::PoseKey x1(1), x2(2);
simulated2D::PointKey l1(1), l2(2); // simulated2D::PointKey l1(1), l2(2);
LagrangeKey L1(1), L12(12); // LagrangeKey L1(1), L12(12);
//
// create an initial estimate // // create an initial estimate
shared_ptr<Config2D> initialEstimate(new Config2D); // shared_ptr<Config2D> initialEstimate(new Config2D);
initialEstimate->insert(x1, Point2(1.0, 1.0)); // initialEstimate->insert(x1, Point2(1.0, 1.0));
initialEstimate->insert(l1, Point2(1.0, 6.0)); // initialEstimate->insert(l1, Point2(1.0, 6.0));
initialEstimate->insert(l2, Point2(-4.0, 0.0)); // starting with a separate reference frame // initialEstimate->insert(l2, Point2(-4.0, 0.0)); // starting with a separate reference frame
initialEstimate->insert(x2, Point2(0.0, 0.0)); // other pose starts at origin // initialEstimate->insert(x2, Point2(0.0, 0.0)); // other pose starts at origin
initialEstimate->insert(L12, Vector_(2, 1.0, 1.0)); // initialEstimate->insert(L12, Vector_(2, 1.0, 1.0));
initialEstimate->insert(L1, Vector_(2, 1.0, 1.0)); // initialEstimate->insert(L1, Vector_(2, 1.0, 1.0));
//
// create an ordering // // create an ordering
shared_ptr<Ordering> ordering(new Ordering()); // shared_ptr<Ordering> ordering(new Ordering());
*ordering += "x1", "x2", "l1", "l2", "L12", "L1"; // *ordering += "x1", "x2", "l1", "l2", "L12", "L1";
//
// create an optimizer // // create an optimizer
Optimizer::shared_solver solver(new Optimizer::solver(ordering)); // Optimizer::shared_solver solver(new Optimizer::solver(ordering));
Optimizer optimizer(graph, initialEstimate, solver); // Optimizer optimizer(graph, initialEstimate, solver);
//
// perform an iteration of optimization // // perform an iteration of optimization
Optimizer oneIteration = optimizer.iterate(Optimizer::SILENT); // Optimizer oneIteration = optimizer.iterate(Optimizer::SILENT);
//
// get the config back out and verify // // get the config back out and verify
Config2D actual = *(oneIteration.config()); // Config2D actual = *(oneIteration.config());
Config2D expected; // Config2D expected;
expected.insert(x1, Point2(1.0, 1.0)); // expected.insert(x1, Point2(1.0, 1.0));
expected.insert(l1, Point2(1.0, 6.0)); // expected.insert(l1, Point2(1.0, 6.0));
expected.insert(l2, Point2(1.0, 6.0)); // expected.insert(l2, Point2(1.0, 6.0));
expected.insert(x2, Point2(5.0, 6.0)); // expected.insert(x2, Point2(5.0, 6.0));
expected.insert(L1, Vector_(2, 1.0, 1.0)); // expected.insert(L1, Vector_(2, 1.0, 1.0));
expected.insert(L12, Vector_(2, 6.0, 7.0)); // expected.insert(L12, Vector_(2, 6.0, 7.0));
CHECK(assert_equal(expected, actual)); // CHECK(assert_equal(expected, actual));
} //}
///* ********************************************************************* */ ///* ********************************************************************* */
//// This is an obstacle avoidance demo, where there is a trajectory of //// This is an obstacle avoidance demo, where there is a trajectory of