41 Vector3 bodyPoint = Vector3::Zero();
48 std::shared_ptr<PreintegrationParams> preintegrationParams;
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;
86 virtual void predict(
const Vector3& omegaBody,
87 const Vector3& specificForceBody,
double dt) = 0;
91 const std::vector<ContactMeasurement>& activeContacts) = 0;
107 const std::optional<double>&
terrainHeight()
const {
return terrainHeight_; }
110 static ExtendedPose3d MakeEstimate(
const NavState& navState,
111 const Matrix& footholds);
119 static Matrix EstimateFootholds(
const ExtendedPose3d& estimate);
122 std::optional<double> terrainHeight_;
143 using EkfBase = LeftLinearEKF<ExtendedPose3d>;
144 using TangentVector =
typename EkfBase::TangentVector;
145 using Jacobian =
typename EkfBase::Jacobian;
146 using Covariance =
typename EkfBase::Covariance;
151 const std::vector<std::string>&
footNames = {});
160 const std::vector<std::string>&
footNames()
const {
return footNames_; }
172 return params_.imuBias;
176 void predict(
const Vector3& omegaBody,
const Vector3& specificForceBody,
180 void processContacts(
181 const std::vector<ContactMeasurement>& activeContacts)
override;
187 : numFeet(numFeet), dt(dt) {}
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;
199 Matrix blocks =
state.xMatrix();
200 blocks.col(0) += blocks.col(1) * dt;
201 return ExtendedPose3d(
state.rotation(), blocks);
208 static ExtendedPose3d MakeState(
const NavState& navState,
209 const Matrix& footholds);
212 static ExtendedPose3d GravityIncrement(
size_t numFeet,
const Vector3& gravity,
216 static ExtendedPose3d ImuIncrement(
size_t numFeet,
const Vector3& omegaBody,
217 const Vector3& specificForceBody,
225 return {this->X_.rotation(), this->X_.x(0), this->X_.x(1)};
227 Matrix footholdMatrix()
const {
228 return this->X_.xMatrix().rightCols(
static_cast<Eigen::Index
>(numFeet()));
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_;
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);
248 LeggedEstimatorParams params_;
249 std::vector<std::string> footNames_;
250 std::vector<bool> inContact_;
251 std::vector<bool> initialized_;
252 bool fullContactInitialized_ =
false;
268 const std::vector<std::string>&
footNames = {});
271 void applyContactUpdate(
272 const std::vector<ContactMeasurement>& activeContacts)
override;
296 const Matrix9& baseCovariance0,
298 const std::vector<std::string>& footNames = {});
307 ExtendedPose3d estimate()
const override;
313 void predict(
const Vector3& omegaBody,
const Vector3& specificForceBody,
317 void processContacts(
318 const std::vector<ContactMeasurement>& activeContacts)
override;
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));
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));
334 bool hasPendingImu()
const {
return pim_.deltaTij() > 0.0; }
335 bool graphInitialized()
const {
336 return !params_.useFullContactInitialization || fullContactInitialized_;
338 bool awaitingFullContactInitialization()
const {
339 return params_.useFullContactInitialization && !fullContactInitialized_;
343 LeggedEstimatorParams params_;
344 std::vector<std::string> footNames_;
345 Matrix initialFootholds_;
346 Matrix9 baseCovariance0_;
347 BatchFixedLagSmoother smoother_;
348 PreintegratedImuMeasurements pim_;
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;
380 const NavState& navState0,
const Matrix& footholds0,
382 double lagSeconds,
const std::vector<std::string>& footNames = {});
391 ExtendedPose3d estimate()
const override;
397 void predict(
const Vector3& omegaBody,
const Vector3& specificForceBody,
401 void processContacts(
402 const std::vector<ContactMeasurement>& activeContacts)
override;
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));
416 static Key MakeVelocityKey(
size_t step) {
417 return Symbol(
'v',
static_cast<uint64_t
>(step));
419 static Key MakeBiasKey(
size_t step) {
420 return Symbol(
'b',
static_cast<uint64_t
>(step));
422 static Key MakeFootKey(
size_t foot,
size_t episode) {
423 return Symbol(
'f',
static_cast<uint64_t
>(1000 * foot + episode));
425 bool hasPendingImu()
const {
return pim_.deltaTij() > 0.0; }
426 bool graphInitialized()
const {
427 return !params_.useFullContactInitialization || fullContactInitialized_;
429 bool awaitingFullContactInitialization()
const {
430 return params_.useFullContactInitialization && !fullContactInitialized_;
434 LeggedEstimatorParams params_;
435 std::vector<std::string> footNames_;
436 Matrix initialFootholds_;
437 Matrix9 baseCovariance0_;
438 BatchFixedLagSmoother smoother_;
439 PreintegratedCombinedMeasurements pim_;
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;
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
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 ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms, 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