gtsam
Loading...
Searching...
No Matches
LeggedEstimator.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
17
18#pragma once
19
30
31#include <memory>
32#include <optional>
33#include <string>
34#include <vector>
35
36namespace gtsam {
37
40 size_t foot = 0;
41 Vector3 bodyPoint = Vector3::Zero();
43 bool touchdown = false;
44};
45
48 std::shared_ptr<PreintegrationParams> preintegrationParams;
49 Pose3 body_P_imu = Pose3(Rot3(), Point3(0.30, 0.0, 0.15));
50 double footholdProcessSigma = 1e-4;
51 double footholdInitSigma = 5e-1;
52 Matrix3 contactCovariance =
53 (Vector3(0.03 * 0.03, 0.03 * 0.03, 0.02 * 0.02)).asDiagonal();
54 double heightPriorSigma = 0.15;
58 double robustContactHuberK = 2.0;
69};
70
72class GTSAM_EXPORT LeggedEstimator {
73 public:
75 virtual ~LeggedEstimator() = default;
76
79 terrainHeight_ = terrainHeight;
80 }
81
83 void turnHeightPriorOff() { terrainHeight_.reset(); }
84
86 virtual void predict(const Vector3& omegaBody,
87 const Vector3& specificForceBody, double dt) = 0;
88
90 virtual void processContacts(
91 const std::vector<ContactMeasurement>& activeContacts) = 0;
92
100 virtual ExtendedPose3d estimate() const = 0;
101
104
105 protected:
107 const std::optional<double>& terrainHeight() const { return terrainHeight_; }
108
110 static ExtendedPose3d MakeEstimate(const NavState& navState,
111 const Matrix& footholds);
112
114 static NavState EstimateNavState(const ExtendedPose3d& estimate) {
115 return NavState(estimate.rotation(), estimate.x(0), estimate.x(1));
116 }
117
119 static Matrix EstimateFootholds(const ExtendedPose3d& estimate);
120
121 private:
122 std::optional<double> terrainHeight_;
123};
124
140class GTSAM_EXPORT LeggedInvariantEKF : public LeftLinearEKF<ExtendedPose3d>,
141 public LeggedEstimator {
142 public:
143 using EkfBase = LeftLinearEKF<ExtendedPose3d>;
144 using TangentVector = typename EkfBase::TangentVector;
145 using Jacobian = typename EkfBase::Jacobian;
146 using Covariance = typename EkfBase::Covariance;
147
149 LeggedInvariantEKF(const NavState& navState0, const Matrix& footholds0,
150 const Matrix& P0, const LeggedEstimatorParams& params,
151 const std::vector<std::string>& footNames = {});
152
154 Matrix covariance() const { return EkfBase::covariance(); }
155
157 size_t numFeet() const { return numFeet_; }
158
160 const std::vector<std::string>& footNames() const { return footNames_; }
161
163 const LeggedEstimatorParams& params() const { return params_; }
164
166 ExtendedPose3d estimate() const override {
167 return MakeEstimate(baseState(), footholdMatrix());
168 }
169
172 return params_.imuBias;
173 }
174
176 void predict(const Vector3& omegaBody, const Vector3& specificForceBody,
177 double dt) override;
178
180 void processContacts(
181 const std::vector<ContactMeasurement>& activeContacts) override;
182
186 explicit AutonomousFlow(size_t numFeet, double dt)
187 : numFeet(numFeet), dt(dt) {}
188
190 Matrix dIdentity() const {
191 Matrix Phi = Matrix::Identity(9 + 3 * static_cast<int>(numFeet),
192 9 + 3 * static_cast<int>(numFeet));
193 Phi.block(3, 6, 3, 3) = I_3x3 * dt;
194 return Phi;
195 }
196
198 ExtendedPose3d operator()(const ExtendedPose3d& state) const {
199 Matrix blocks = state.xMatrix();
200 blocks.col(0) += blocks.col(1) * dt;
201 return ExtendedPose3d(state.rotation(), blocks);
202 }
203 size_t numFeet;
204 double dt;
205 };
206
208 static ExtendedPose3d MakeState(const NavState& navState,
209 const Matrix& footholds);
210
212 static ExtendedPose3d GravityIncrement(size_t numFeet, const Vector3& gravity,
213 double dt);
214
216 static ExtendedPose3d ImuIncrement(size_t numFeet, const Vector3& omegaBody,
217 const Vector3& specificForceBody,
218 double dt);
219
221 static size_t FootColumn(size_t foot) { return 2 + foot; }
222
223 protected:
224 NavState baseState() const {
225 return {this->X_.rotation(), this->X_.x(0), this->X_.x(1)};
226 }
227 Matrix footholdMatrix() const {
228 return this->X_.xMatrix().rightCols(static_cast<Eigen::Index>(numFeet()));
229 }
230 void resetFootToMeasurement(size_t foot, const Vector3& bodyPoint);
231 void marginalizeFoot(size_t foot);
232 virtual void applyContactUpdate(
233 const std::vector<ContactMeasurement>& activeContacts);
234 bool awaitingFullContactInitialization() const {
235 return params_.useFullContactInitialization && !fullContactInitialized_;
236 }
237
238 private:
239 bool maybeInitializeFromFullContact(
240 const std::vector<ContactMeasurement>& activeContacts,
241 const std::vector<bool>& activeFeet);
242 Covariance processNoise(double dt) const;
243 void applySingleContactUpdate(size_t foot, const Vector3& bodyPoint,
244 const Matrix3& covariance);
245 void applySingleHeightPrior(size_t foot, double terrainHeight);
246
247 size_t numFeet_;
248 LeggedEstimatorParams params_;
249 std::vector<std::string> footNames_;
250 std::vector<bool> inContact_;
251 std::vector<bool> initialized_;
252 bool fullContactInitialized_ = false;
253};
254
263class GTSAM_EXPORT LeggedInvariantIEKF : public LeggedInvariantEKF {
264 public:
266 LeggedInvariantIEKF(const NavState& navState0, const Matrix& footholds0,
267 const Matrix& P0, const LeggedEstimatorParams& params,
268 const std::vector<std::string>& footNames = {});
269
270 protected:
271 void applyContactUpdate(
272 const std::vector<ContactMeasurement>& activeContacts) override;
273};
274
292class GTSAM_EXPORT LeggedFixedLagSmoother : public LeggedEstimator {
293 public:
295 LeggedFixedLagSmoother(const NavState& navState0, const Matrix& footholds0,
296 const Matrix9& baseCovariance0,
297 const LeggedEstimatorParams& params, double lagSeconds,
298 const std::vector<std::string>& footNames = {});
299
302
304 size_t numFeet() const { return numFeet_; }
305
307 ExtendedPose3d estimate() const override;
308
310 imuBias::ConstantBias estimateBias() const override { return biasEstimate_; }
311
313 void predict(const Vector3& omegaBody, const Vector3& specificForceBody,
314 double dt) override;
315
317 void processContacts(
318 const std::vector<ContactMeasurement>& activeContacts) override;
319
320 private:
321 bool maybeInitializeFromFullContact(
322 const std::vector<ContactMeasurement>& activeContacts,
323 const std::vector<bool>& activeFeet);
324 void refreshEstimateFromSmoother();
325 NavState currentBaseState() const { return optimizedBaseState_; }
326 Key currentBaseKey() const { return MakeBaseKey(step_); }
327 static Key MakeBaseKey(size_t step) {
328 return Symbol('x', static_cast<uint64_t>(step));
329 }
330 static Key MakeBiasKey() { return Symbol('b', 0); }
331 static Key MakeFootKey(size_t foot, size_t episode) {
332 return Symbol('f', static_cast<uint64_t>(1000 * foot + episode));
333 }
334 bool hasPendingImu() const { return pim_.deltaTij() > 0.0; }
335 bool graphInitialized() const {
336 return !params_.useFullContactInitialization || fullContactInitialized_;
337 }
338 bool awaitingFullContactInitialization() const {
339 return params_.useFullContactInitialization && !fullContactInitialized_;
340 }
341
342 size_t numFeet_;
343 LeggedEstimatorParams params_;
344 std::vector<std::string> footNames_;
345 Matrix initialFootholds_;
346 Matrix9 baseCovariance0_;
347 BatchFixedLagSmoother smoother_;
348 PreintegratedImuMeasurements pim_;
349 size_t step_ = 0;
350 double currentTime_ = 0.0;
351 std::vector<bool> inContact_;
352 std::vector<bool> initialized_;
353 std::vector<size_t> footEpisodes_;
354 std::vector<std::optional<Key>> activeFootKeys_;
355 NavState optimizedBaseState_;
356 NavState deadReckonedState_;
357 imuBias::ConstantBias biasEstimate_;
358 bool fullContactInitialized_ = false;
359};
360
377 public:
380 const NavState& navState0, const Matrix& footholds0,
381 const Matrix9& baseCovariance0, const LeggedEstimatorParams& params,
382 double lagSeconds, const std::vector<std::string>& footNames = {});
383
386
388 size_t numFeet() const { return numFeet_; }
389
391 ExtendedPose3d estimate() const override;
392
394 imuBias::ConstantBias estimateBias() const override { return biasEstimate_; }
395
397 void predict(const Vector3& omegaBody, const Vector3& specificForceBody,
398 double dt) override;
399
401 void processContacts(
402 const std::vector<ContactMeasurement>& activeContacts) override;
403
404 private:
405 bool maybeInitializeFromFullContact(
406 const std::vector<ContactMeasurement>& activeContacts,
407 const std::vector<bool>& activeFeet);
408 void refreshEstimateFromSmoother();
409 NavState currentBaseState() const { return optimizedBaseState_; }
410 Key currentPoseKey() const { return MakePoseKey(step_); }
411 Key currentVelocityKey() const { return MakeVelocityKey(step_); }
412 Key currentBiasKey() const { return MakeBiasKey(step_); }
413 static Key MakePoseKey(size_t step) {
414 return Symbol('x', static_cast<uint64_t>(step));
415 }
416 static Key MakeVelocityKey(size_t step) {
417 return Symbol('v', static_cast<uint64_t>(step));
418 }
419 static Key MakeBiasKey(size_t step) {
420 return Symbol('b', static_cast<uint64_t>(step));
421 }
422 static Key MakeFootKey(size_t foot, size_t episode) {
423 return Symbol('f', static_cast<uint64_t>(1000 * foot + episode));
424 }
425 bool hasPendingImu() const { return pim_.deltaTij() > 0.0; }
426 bool graphInitialized() const {
427 return !params_.useFullContactInitialization || fullContactInitialized_;
428 }
429 bool awaitingFullContactInitialization() const {
430 return params_.useFullContactInitialization && !fullContactInitialized_;
431 }
432
433 size_t numFeet_;
434 LeggedEstimatorParams params_;
435 std::vector<std::string> footNames_;
436 Matrix initialFootholds_;
437 Matrix9 baseCovariance0_;
438 BatchFixedLagSmoother smoother_;
439 PreintegratedCombinedMeasurements pim_;
440 size_t step_ = 0;
441 double currentTime_ = 0.0;
442 std::vector<bool> inContact_;
443 std::vector<bool> initialized_;
444 std::vector<size_t> footEpisodes_;
445 std::vector<std::optional<Key>> activeFootKeys_;
446 NavState optimizedBaseState_;
447 NavState deadReckonedState_;
448 imuBias::ConstantBias biasEstimate_;
449 bool fullContactInitialized_ = false;
450};
451
452} // namespace gtsam
Macros for Matrix constants to avoid excessive template instantiation.
Extended pose Lie group SE_k(3), with static or dynamic k.
3D Pose manifold SO(3) x R^3 and group SE(3)
Navigation state composing of attitude, position, and velocity.
EKF on a Lie group with a general left–linear prediction model.
An LM-based fixed-lag smoother.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
Vector3 Point3
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point3 to Vector3...
Definition Point3.h:38
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
A 3D pose (R,t) : (Rot3,Point3).
Definition Pose3.h:42
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition Rot3.h:65
Definition ImuBias.h:34
Body-frame contact measurement for one foot.
Definition LeggedEstimator.h:39
bool touchdown
True when this measurement corresponds to a new swing-to-stance touchdown.
Definition LeggedEstimator.h:43
Common estimator parameters shared by all four variants.
Definition LeggedEstimator.h:47
bool useFullContactInitialization
Run the one-time full-contact initializer when available.
Definition LeggedEstimator.h:66
double robustContactHuberK
Scalar-Huber threshold for robust contact factors in graph-based variants.
Definition LeggedEstimator.h:58
imuBias::ConstantBias imuBias
Constant IMU bias removed from the raw gyroscope and accelerometer data.
Definition LeggedEstimator.h:60
double biasAccRandomWalkSigma
Accelerometer bias random-walk sigma used by the combined smoother.
Definition LeggedEstimator.h:62
bool useRobustContactNoise
Enable robust contact noise for graph-based variants.
Definition LeggedEstimator.h:56
double biasOmegaRandomWalkSigma
Gyroscope bias random-walk sigma used by the combined smoother.
Definition LeggedEstimator.h:64
bool marginalizeLeavingFoot
Replace a leaving foot by a fresh independent prior.
Definition LeggedEstimator.h:68
Common runtime interface shared by all four legged estimator variants.
Definition LeggedEstimator.h:72
virtual void predict(const Vector3 &omegaBody, const Vector3 &specificForceBody, double dt)=0
Predict the estimator forward with one IMU sample.
virtual ExtendedPose3d estimate() const =0
Return the current propagated estimate as ExtendedPose3d.
virtual ~LeggedEstimator()=default
Destroy the estimator interface.
const std::optional< double > & terrainHeight() const
Optional terrain height used internally for contact height priors.
Definition LeggedEstimator.h:107
virtual void processContacts(const std::vector< ContactMeasurement > &activeContacts)=0
Process the currently active contacts at the current estimator time.
void turnHeightPriorOn(double terrainHeight)
Enable contact height priors at the supplied terrain height.
Definition LeggedEstimator.h:78
static NavState EstimateNavState(const ExtendedPose3d &estimate)
Recover the base NavState from an ExtendedPose3d estimate.
Definition LeggedEstimator.h:114
virtual imuBias::ConstantBias estimateBias() const =0
Return the IMU bias used or estimated by the current estimator.
static ExtendedPose3d MakeEstimate(const NavState &navState, const Matrix &footholds)
Build the shared ExtendedPose3d state layout used by all estimators.
Definition LeggedEstimator.cpp:443
void turnHeightPriorOff()
Disable contact height priors.
Definition LeggedEstimator.h:83
imuBias::ConstantBias estimateBias() const override
Return the fixed IMU bias used by the filter.
Definition LeggedEstimator.h:171
const LeggedEstimatorParams & params() const
Shared estimator parameters.
Definition LeggedEstimator.h:163
ExtendedPose3d estimate() const override
Current estimate in the shared ExtendedPose3d layout.
Definition LeggedEstimator.h:166
static size_t FootColumn(size_t foot)
Return the ExtendedPose3 block index corresponding to a foot number.
Definition LeggedEstimator.h:221
Matrix covariance() const
Return the current full covariance.
Definition LeggedEstimator.h:154
size_t numFeet() const
Number of feet tracked by the estimator.
Definition LeggedEstimator.h:157
LeggedInvariantEKF(const NavState &navState0, const Matrix &footholds0, const Matrix &P0, const LeggedEstimatorParams &params, const std::vector< std::string > &footNames={})
Construct the ExtendedPose3-based EKF.
Definition LeggedEstimator.cpp:465
const std::vector< std::string > & footNames() const
Foot names in state order.
Definition LeggedEstimator.h:160
ExtendedPose3d operator()(const ExtendedPose3d &state) const
Advance the position block while keeping velocity and footholds fixed.
Definition LeggedEstimator.h:198
Matrix dIdentity() const
Return the differential of the flow at the identity.
Definition LeggedEstimator.h:190
AutonomousFlow(size_t numFeet, double dt)
Construct the autonomous-flow functor.
Definition LeggedEstimator.h:186
LeggedInvariantIEKF(const NavState &navState0, const Matrix &footholds0, const Matrix &P0, const LeggedEstimatorParams &params, const std::vector< std::string > &footNames={})
Construct the graph-update ExtendedPose3 estimator.
Definition LeggedEstimator.cpp:675
imuBias::ConstantBias estimateBias() const override
Return the current single shared IMU bias estimate.
Definition LeggedEstimator.h:310
size_t numFeet() const
Number of feet tracked by the smoother front-end.
Definition LeggedEstimator.h:304
~LeggedFixedLagSmoother() override
Destroy the fixed-lag smoother variant.
LeggedFixedLagSmoother(const NavState &navState0, const Matrix &footholds0, const Matrix9 &baseCovariance0, const LeggedEstimatorParams &params, double lagSeconds, const std::vector< std::string > &footNames={})
Construct the fixed-lag smoother variant.
Definition LeggedEstimator.cpp:713
imuBias::ConstantBias estimateBias() const override
Return the current per-window bias estimate at the latest event.
Definition LeggedEstimator.h:394
LeggedCombinedFixedLagSmoother(const NavState &navState0, const Matrix &footholds0, const Matrix9 &baseCovariance0, const LeggedEstimatorParams &params, double lagSeconds, const std::vector< std::string > &footNames={})
Construct the combined-IMU fixed-lag smoother variant.
Definition LeggedEstimator.cpp:999
size_t numFeet() const
Number of feet tracked by the smoother front-end.
Definition LeggedEstimator.h:388
~LeggedCombinedFixedLagSmoother() override
Destroy the combined-IMU fixed-lag smoother variant.
const G & state() const
Definition ManifoldEKF.h:92
const Covariance & covariance() const
Definition ManifoldEKF.h:95
Navigation state: Pose (rotation, translation) + velocity Following Barrau20icra, this class belongs ...
Definition NavState.h:45