Reworked PartialPriorFactor implementation to simpler

release/4.3a0
Alex Cunningham 2011-11-25 19:27:00 +00:00
parent 3eae2dd2b8
commit 9a21cbc76e
2 changed files with 18 additions and 43 deletions

View File

@ -49,8 +49,9 @@ namespace gtsam {
typedef NonlinearFactor1<VALUES, KEY> Base; typedef NonlinearFactor1<VALUES, KEY> Base;
typedef PartialPriorFactor<VALUES, KEY> This; typedef PartialPriorFactor<VALUES, KEY> This;
Vector prior_; /// measurement on logmap parameters, in compressed form Vector prior_; ///< measurement on logmap parameters, in compressed form
std::vector<bool> mask_; /// flags to mask all parameters not measured std::vector<size_t> mask_; ///< indices of values to constrain in compressed prior vector
Matrix H_; ///< Constant jacobian - computed at creation
/** default constructor - only use for serialization */ /** default constructor - only use for serialization */
PartialPriorFactor() {} PartialPriorFactor() {}
@ -58,10 +59,9 @@ namespace gtsam {
/** /**
* constructor with just minimum requirements for a factor - allows more * constructor with just minimum requirements for a factor - allows more
* computation in the constructor. This should only be used by subclasses * computation in the constructor. This should only be used by subclasses
* Sets the size of the mask with all values off
*/ */
PartialPriorFactor(const KEY& key, const SharedNoiseModel& model) PartialPriorFactor(const KEY& key, const SharedNoiseModel& model)
: Base(model, key), mask_(T::Dim(), false) {} : Base(model, key) {}
public: public:
@ -70,31 +70,20 @@ namespace gtsam {
virtual ~PartialPriorFactor() {} virtual ~PartialPriorFactor() {}
/** Full Constructor: requires mask and vector - not for typical use */
PartialPriorFactor(const KEY& key, const std::vector<bool>& mask,
const Vector& prior, const SharedNoiseModel& model) :
Base(model, key), prior_(prior), mask_(mask) {
assert(mask_.size() == T::Dim()); // NOTE: assumes constant size variable
assert(nrTrue() == model->dim());
assert(nrTrue() == prior_.size());
}
/** Single Element Constructor: acts on a single parameter specified by idx */ /** Single Element Constructor: acts on a single parameter specified by idx */
PartialPriorFactor(const KEY& key, size_t idx, double prior, const SharedNoiseModel& model) : PartialPriorFactor(const KEY& key, size_t idx, double prior, const SharedNoiseModel& model) :
Base(model, key), prior_(Vector_(1, prior)), mask_(T::Dim(), false) { Base(model, key), prior_(Vector_(1, prior)), mask_(1, idx), H_(zeros(1, T::Dim())) {
assert(model->dim() == 1); assert(model->dim() == 1);
mask_[idx] = true; this->fillH();
assert(nrTrue() == 1);
} }
/** Indices Constructor: specify the mask with a set of indices */ /** Indices Constructor: specify the mask with a set of indices */
PartialPriorFactor(const KEY& key, const std::vector<size_t>& mask, const Vector& prior, PartialPriorFactor(const KEY& key, const std::vector<size_t>& mask, const Vector& prior,
const SharedNoiseModel& model) : const SharedNoiseModel& model) :
Base(model, key), prior_(prior), mask_(T::Dim(), false) { Base(model, key), prior_(prior), mask_(mask), H_(zeros(mask.size(), T::Dim())) {
assert((size_t)prior_.size() == mask.size()); assert((size_t)prior_.size() == mask.size());
assert(model->dim() == (size_t) prior.size()); assert(model->dim() == (size_t) prior.size());
setMask(mask); this->fillH();
assert(nrTrue() == this->dim());
} }
/** implement functions needed for Testable */ /** implement functions needed for Testable */
@ -117,40 +106,26 @@ namespace gtsam {
/** vector of errors */ /** vector of errors */
Vector evaluateError(const T& p, boost::optional<Matrix&> H = boost::none) const { Vector evaluateError(const T& p, boost::optional<Matrix&> H = boost::none) const {
if (H) (*H) = zeros(this->dim(), p.dim()); if (H) (*H) = H_;
// FIXME: this was originally the generic retraction - may not produce same results // FIXME: this was originally the generic retraction - may not produce same results
Vector full_logmap = T::Logmap(p); Vector full_logmap = T::Logmap(p);
Vector masked_logmap = zero(this->dim()); Vector masked_logmap = zero(this->dim());
size_t masked_idx=0; for (size_t i=0; i<mask_.size(); ++i)
for (size_t i=0;i<mask_.size();++i) masked_logmap(i) = full_logmap(mask_[i]);
if (mask_[i]) {
masked_logmap(masked_idx) = full_logmap(i);
if (H) (*H)(masked_idx, i) = 1.0;
++masked_idx;
}
return masked_logmap - prior_; return masked_logmap - prior_;
} }
// access // access
const Vector& prior() const { return prior_; } const Vector& prior() const { return prior_; }
const std::vector<bool>& mask() const { return mask_; } const std::vector<bool>& mask() const { return mask_; }
const Matrix& H() const { return H_; }
protected: protected:
/** counts true elements in the mask */ /** Constructs the jacobian matrix in place */
size_t nrTrue() const { void fillH() {
size_t result=0;
for (size_t i=0; i<mask_.size(); ++i) for (size_t i=0; i<mask_.size(); ++i)
if (mask_[i]) ++result; H_(i, mask_[i]) = 1.0;
return result;
}
/** sets the mask using a set of indices */
void setMask(const std::vector<size_t>& mask) {
for (size_t i=0; i<mask.size(); ++i) {
assert(mask[i] < mask_.size());
mask_[mask[i]] = true;
}
} }
private: private:
@ -162,6 +137,7 @@ namespace gtsam {
boost::serialization::base_object<Base>(*this)); boost::serialization::base_object<Base>(*this));
ar & BOOST_SERIALIZATION_NVP(prior_); ar & BOOST_SERIALIZATION_NVP(prior_);
ar & BOOST_SERIALIZATION_NVP(mask_); ar & BOOST_SERIALIZATION_NVP(mask_);
ar & BOOST_SERIALIZATION_NVP(H_);
} }
}; // \class PartialPriorFactor }; // \class PartialPriorFactor

View File

@ -107,8 +107,7 @@ TEST(Pose3Graph, partial_prior_height) {
EXPECT(assert_equal(expA, actA)); EXPECT(assert_equal(expA, actA));
pose3SLAM::Graph graph; pose3SLAM::Graph graph;
// graph.add(height); // FAIL - on compile, can't initialize a reference? graph.add(height);
graph.push_back(boost::shared_ptr<Partial>(new Partial(height)));
pose3SLAM::Values values; pose3SLAM::Values values;
values.insert(key, init); values.insert(key, init);
@ -163,7 +162,7 @@ TEST(Pose3Graph, partial_prior_xy) {
EXPECT(assert_equal(expA, actA)); EXPECT(assert_equal(expA, actA));
pose3SLAM::Graph graph; pose3SLAM::Graph graph;
graph.push_back(Partial::shared_ptr(new Partial(priorXY))); graph.add(priorXY);
pose3SLAM::Values values; pose3SLAM::Values values;
values.insert(key, init); values.insert(key, init);