Partially implemented version of a recursive TupleConfig that is still very much under testing.
parent
2f16d8f6a1
commit
a66a405dd5
|
@ -35,6 +35,9 @@ namespace gtsam {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// typedefs
|
||||||
|
typedef T Value_t;
|
||||||
|
|
||||||
// Constructors:
|
// Constructors:
|
||||||
|
|
||||||
TypedSymbol():j_(0) {}
|
TypedSymbol():j_(0) {}
|
||||||
|
|
|
@ -141,4 +141,100 @@ namespace gtsam {
|
||||||
template<class J1, class X1, class J2, class X2>
|
template<class J1, class X1, class J2, class X2>
|
||||||
inline VectorConfig logmap(const PairConfig<J1,X1,J2,X2> c0, const PairConfig<J1,X1,J2,X2>& cp) { return c0.logmap(cp); }
|
inline VectorConfig logmap(const PairConfig<J1,X1,J2,X2> c0, const PairConfig<J1,X1,J2,X2>& cp) { return c0.logmap(cp); }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tuple configs to handle subconfigs of LieConfigs
|
||||||
|
*
|
||||||
|
* This uses a recursive structure of config pairs to form a lisp-like
|
||||||
|
* list, with a special case (TupleConfigEnd) that contains only one config
|
||||||
|
* at the end. In a final use case, this should be aliased to something clearer
|
||||||
|
* but still with the same recursive type machinery.
|
||||||
|
*
|
||||||
|
* STILL UNDER TESTING - DO NOT USE
|
||||||
|
*/
|
||||||
|
template<class Config1, class Config2>
|
||||||
|
class TupleConfig : public Testable<TupleConfig<Config1, Config2> > {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Data for internal configs
|
||||||
|
Config1 first_;
|
||||||
|
Config2 second_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// typedefs
|
||||||
|
typedef class Config1::Key Key1;
|
||||||
|
typedef class Config1::Value Value1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TupleConfig() {}
|
||||||
|
virtual ~TupleConfig() {}
|
||||||
|
|
||||||
|
/** Print */
|
||||||
|
void print(const std::string& s = "") const {}
|
||||||
|
|
||||||
|
/** Test for equality in keys and values */
|
||||||
|
bool equals(const TupleConfig<Config1, Config2>& c, double tol=1e-9) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert function that uses the second (recursive) config
|
||||||
|
template<class Key, class Value>
|
||||||
|
void insert(const Key& key, const Value& value) {second_.insert(key, value);}
|
||||||
|
void insert(const Key1& key, const Value1& value) {first_.insert(key, value);}
|
||||||
|
|
||||||
|
// erase an element by key
|
||||||
|
template<class Key>
|
||||||
|
void erase(const Key& j) { }
|
||||||
|
void erase(const Key1& j) { }
|
||||||
|
|
||||||
|
// determine whether an element exists
|
||||||
|
template<class Key>
|
||||||
|
bool exists(const Key& j) const { return second_.exists(j); }
|
||||||
|
bool exists(const Key1& j) const { return first_.exists(j); }
|
||||||
|
|
||||||
|
// access operator - currently configs after the first one will not be found
|
||||||
|
template<class Key, class Value>
|
||||||
|
const Value& operator[](const Key& j) const { return second_[j]; }
|
||||||
|
const Value1& operator[](const Key1& j) const { return first_[j]; }
|
||||||
|
|
||||||
|
template<class Key, class Value>
|
||||||
|
const Value& at(const Key& j) const { return second_.at(j); }
|
||||||
|
const Value1& at(const Key1& j) const { return first_.at(j); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Config>
|
||||||
|
class TupleConfigEnd : public Testable<TupleConfigEnd<Config> > {
|
||||||
|
protected:
|
||||||
|
// Data for internal configs
|
||||||
|
Config first_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// typedefs
|
||||||
|
typedef class Config::Key Key1;
|
||||||
|
typedef class Config::Value Value1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TupleConfigEnd() {}
|
||||||
|
virtual ~TupleConfigEnd() {}
|
||||||
|
|
||||||
|
/** Print */
|
||||||
|
void print(const std::string& s = "") const {}
|
||||||
|
|
||||||
|
/** Test for equality in keys and values */
|
||||||
|
bool equals(const TupleConfigEnd<Config>& c, double tol=1e-9) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(const Key1& key, const Value1& value) {first_.insert(key, value); }
|
||||||
|
|
||||||
|
const Value1& operator[](const Key1& j) const { return first_[j]; }
|
||||||
|
|
||||||
|
void erase(const Key1& j) { }
|
||||||
|
|
||||||
|
bool exists(const Key1& j) const { return first_.exists(j); }
|
||||||
|
|
||||||
|
const Value1& at(const Key1& j) const { return first_.at(j); }
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,66 @@ TEST(PairConfig, expmap)
|
||||||
CHECK(assert_equal(expected, expmap(cfg1, increment)));
|
CHECK(assert_equal(expected, expmap(cfg1, increment)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
// some key types
|
||||||
|
typedef TypedSymbol<Pose2, 'x'> PoseKey;
|
||||||
|
typedef TypedSymbol<Point2, 'l'> PointKey;
|
||||||
|
typedef TypedSymbol<Vector, 'L'> LamKey;
|
||||||
|
|
||||||
|
// some config types
|
||||||
|
typedef LieConfig<PoseKey, Pose2> PoseConfig;
|
||||||
|
typedef LieConfig<PointKey, Point2> PointConfig;
|
||||||
|
typedef LieConfig<LamKey, Vector> LamConfig;
|
||||||
|
|
||||||
|
// some TupleConfig types
|
||||||
|
typedef TupleConfig<PoseConfig, TupleConfigEnd<PointConfig> > ConfigA;
|
||||||
|
typedef TupleConfig<PoseConfig, TupleConfig<PointConfig, TupleConfigEnd<LamConfig> > > ConfigB;
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(TupleConfig, create_insert) {
|
||||||
|
// create some tuple configs
|
||||||
|
ConfigA configA;
|
||||||
|
ConfigB configB;
|
||||||
|
|
||||||
|
PoseKey x1(1);
|
||||||
|
PointKey l1(1);
|
||||||
|
LamKey L1(1);
|
||||||
|
Pose2 pose1(1.0, 2.0, 0.3);
|
||||||
|
Point2 point1(2.0, 3.0);
|
||||||
|
Vector lam1 = Vector_(1, 2.3);
|
||||||
|
|
||||||
|
// Insert
|
||||||
|
configA.insert(x1, pose1);
|
||||||
|
configA.insert(l1, point1);
|
||||||
|
|
||||||
|
configB.insert(x1, pose1);
|
||||||
|
configB.insert(l1, point1);
|
||||||
|
configB.insert(L1, lam1);
|
||||||
|
|
||||||
|
// bracket operator - FAILS on config types after first one
|
||||||
|
CHECK(assert_equal(configA[x1], pose1));
|
||||||
|
// CHECK(assert_equal(configA[l1], point1));
|
||||||
|
CHECK(assert_equal(configB[x1], pose1));
|
||||||
|
// CHECK(assert_equal(configB[l1], point1));
|
||||||
|
// CHECK(assert_equal(configB[L1], lam1));
|
||||||
|
|
||||||
|
// exists
|
||||||
|
CHECK(configA.exists(x1));
|
||||||
|
CHECK(configA.exists(l1));
|
||||||
|
CHECK(configB.exists(x1));
|
||||||
|
CHECK(configB.exists(l1));
|
||||||
|
CHECK(configB.exists(L1));
|
||||||
|
|
||||||
|
// at - access function - FAILS as with bracket operator
|
||||||
|
CHECK(assert_equal(configA.at(x1), pose1));
|
||||||
|
// CHECK(assert_equal(configA.at(l1), point1));
|
||||||
|
CHECK(assert_equal(configB.at(x1), pose1));
|
||||||
|
// CHECK(assert_equal(configB.at(l1), point1));
|
||||||
|
// CHECK(assert_equal(configB.at(L1), lam1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue