Skip to content
Open
Show file tree
Hide file tree
Changes from 83 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
6a376a1
add SEK3 utils with corresponding tests and adjoint
lucaslibshutz Jun 29, 2026
e000861
reorg file structure (Remove kgroup)
lucaslibshutz Jun 29, 2026
e829f8d
finish invariant state implementation
lucaslibshutz Jun 29, 2026
aeffd6d
propagation model finished with log linear test
lucaslibshutz Jun 29, 2026
a2b73bd
updater stage 1 done with test
lucaslibshutz Jun 29, 2026
7ef0b7d
contact FK implemented
lucaslibshutz Jun 30, 2026
d634983
full EKF file with test done
lucaslibshutz Jun 30, 2026
1fd95cf
EKF factory up, ready to test in SCS2
lucaslibshutz Jun 30, 2026
891672f
first version of comparison testing
lucaslibshutz Jun 30, 2026
f8bab20
added foot switch logic, estimator works better now
lucaslibshutz Jun 30, 2026
1365c4e
add invariant filter to sim testing
lucaslibshutz Jul 1, 2026
60081d6
add logic for IMU and CoM
lucaslibshutz Jul 1, 2026
645b280
add ground truth roll comparison
lucaslibshutz Jul 1, 2026
c193bf2
fixed foot switch logic, estimator works for basic walking
lucaslibshutz Jul 2, 2026
ccdc364
ready to test on robot
lucaslibshutz Jul 2, 2026
99bfa93
Merge branch 'develop' into new-state-estimator
lucaslibshutz Jul 2, 2026
5057aaa
fix frozen state behavior (should)
lucaslibshutz Jul 2, 2026
212c7e6
Merge branch 'develop' into new-state-estimator
lucaslibshutz Jul 2, 2026
bb5a3c2
start adding files for IMU alpha filter tie in
lucaslibshutz Jul 2, 2026
4f6e5fe
alpha complementary filter finsihed
lucaslibshutz Jul 3, 2026
85cdb73
alpha complementary filter finished
lucaslibshutz Jul 3, 2026
fb3660a
Merge remote-tracking branch 'origin/new-estimator/joint-level-fixes'…
lucaslibshutz Jul 3, 2026
958ff90
added alpha filter pre-filter file
lucaslibshutz Jul 3, 2026
7ea0e73
first version of pre-filter framework
lucaslibshutz Jul 3, 2026
569e5a3
pre-filter framework implemented, time to test
lucaslibshutz Jul 3, 2026
fd2c79b
add none option to joint filter
lucaslibshutz Jul 3, 2026
67f4c7f
selectability for joint switch implementation now
lucaslibshutz Jul 6, 2026
eee283a
starting work on joint KF implementation
lucaslibshutz Jul 6, 2026
c9ffc34
joint KF should be finished, time to test
lucaslibshutz Jul 6, 2026
3ee4418
stop garbage buildup, fix SEK3_Utils to pre-alloc
lucaslibshutz Jul 6, 2026
51e906a
Merge branch 'develop' into new-estimator/joint-level-fixes
Jul 6, 2026
312d59d
bias not returning possible fix
lucaslibshutz Jul 6, 2026
0946616
attempt to fix ethercat error
lucaslibshutz Jul 7, 2026
5e2520a
fix unused imports
lucaslibshutz Jul 7, 2026
8861583
add NaN guard to joint filter
lucaslibshutz Jul 7, 2026
2d48313
scs2 charts and yo variables added
lucaslibshutz Jul 7, 2026
0012c8e
more scs2 fixes
lucaslibshutz Jul 7, 2026
c8d8086
add config file and global inekf tuning vars
Jul 7, 2026
275430d
add mass matrix implementation and tests
lucaslibshutz Jul 8, 2026
8533e0e
attempt 1 at fixing unstable problem
lucaslibshutz Jul 8, 2026
5b8307c
added charts that work
Jul 8, 2026
faa2deb
add YoVariables for NIS
lucaslibshutz Jul 8, 2026
1ad2154
process noise change via schur complement
lucaslibshutz Jul 8, 2026
cd982c9
new joint KF maybe
lucaslibshutz Jul 8, 2026
c067844
tuned invariant filter for WBC
Jul 8, 2026
83e5aff
filter divergence possible fix, v2
lucaslibshutz Jul 9, 2026
877ea68
add debugging message for singular inversion
lucaslibshutz Jul 9, 2026
0e81a2b
add noise injection to IMUs
lucaslibshutz Jul 10, 2026
d861029
revert noise values, lower joint noise floor
lucaslibshutz Jul 10, 2026
b6dc400
add gravity update
lucaslibshutz Jul 10, 2026
b9b67b1
clamp biases as possible fix
lucaslibshutz Jul 10, 2026
c7cc22c
Merge branch 'develop' into new-estimator/joint-level-fixes
Jul 10, 2026
1e70d13
add per-joint alpha fixes
lucaslibshutz Jul 10, 2026
6aeca3e
update alpha values to scale
lucaslibshutz Jul 10, 2026
1a01d23
try reverting to original
Jul 10, 2026
d1fc64d
trust pitch less
lucaslibshutz Jul 10, 2026
9404e8d
Merge remote-tracking branch 'origin/develop' into new-estimator/join…
Jul 12, 2026
3740ea6
gravity/pitch possible fix
lucaslibshutz Jul 12, 2026
207bd07
add relevant tests for gravity fix
lucaslibshutz Jul 13, 2026
c367faf
raw gravity fallback with test
lucaslibshutz Jul 13, 2026
f84a65b
add sensor noise params
lucaslibshutz Jul 13, 2026
5d6b6e8
add joint KF as default and first try with changing variances
Jul 14, 2026
eeb58ae
EKF config for SCS2 with more stuff
Jul 14, 2026
f30d631
add encoder measurement model
lucaslibshutz Jul 15, 2026
3dd14dd
added a convenience function (#1396)
rjgriffin42 Jul 15, 2026
9688e3b
add more NIS yoVars for debug
lucaslibshutz Jul 16, 2026
88d8e34
debug YoVariables and wiring
lucaslibshutz Jul 16, 2026
355d530
added a convenience function (#1396)
rjgriffin42 Jul 15, 2026
503141c
add more NIS yoVars for debug
lucaslibshutz Jul 16, 2026
45c1cb9
add reseed flag, time to test
lucaslibshutz Jul 16, 2026
844ef26
add new layout for oscillation debug
lucaslibshutz Jul 16, 2026
75a111b
add filter for 12Hz osc
lucaslibshutz Jul 16, 2026
b942ea0
add low pass filter
lucaslibshutz Jul 16, 2026
fc8d2e7
Merge remote-tracking branch 'origin/develop' into new-estimator/join…
Jul 16, 2026
f4c43e6
add velocity selector
lucaslibshutz Jul 16, 2026
05b96aa
fix multi thread enum and add osc debug config
Jul 16, 2026
a6da545
add band stop filter, and switchable joint filter enum
lucaslibshutz Jul 17, 2026
445110e
Merge remote-tracking branch 'origin/new-estimator/joint-debug' into …
lucaslibshutz Jul 17, 2026
e9e163c
add legacy provider back with enum switch
lucaslibshutz Jul 17, 2026
3e1566d
test suite map added
lucaslibshutz Aug 4, 2026
99e5100
Merge branch 'develop' into new-estimator/joint-debug
lucaslibshutz Aug 4, 2026
3cb3125
Merge branch 'new-estimator/joint-debug' into new-estimator/joint-lev…
lucaslibshutz Aug 4, 2026
d2f7200
fix build issues
Aug 6, 2026
dce1b39
change names of packages to conform to SnakeCase
lucaslibshutz Aug 7, 2026
d04178b
small fixes for code running quicker
lucaslibshutz Aug 10, 2026
0afc90d
axis3D changes and comment label
lucaslibshutz Aug 10, 2026
d514f28
Take gravity from the robot process instead of hard-coding it in the …
lucaslibshutz Aug 10, 2026
5ffc030
Merge branch 'develop' into new-state-estimator
Beomyeong Aug 10, 2026
caf9357
fun lil easter egg
lucaslibshutz Aug 10, 2026
91cba4e
Merge branch 'new-state-estimator' into new-estimator/inekf-gravity
lucaslibshutz Aug 10, 2026
6736d52
Merge pull request #1417 from ihmcrobotics/new-estimator/inekf-gravity
lucaslibshutz Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ public FullHumanoidRobotModel getFullRobotModel()
return estimatorFullRobotModel;
}

/**
* @return the main state estimator controller driving the root joint (e.g. the DRC estimator, or
* {@code InvariantMainStateEstimator} when the invariant InEKF has been promoted to main).
* Exposed so external comparators (e.g. against simulation ground truth) can reach the
* estimator regardless of which implementation owns the root. May be {@code null}.
*/
public StateEstimatorController getMainStateEstimator()
{
return mainStateEstimator;
}

@Override
public YoRegistry getYoRegistry()
{
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
import us.ihmc.simulationToolkit.RobotDefinitionTools;
import us.ihmc.simulationconstructionset.dataBuffer.MirroredYoVariableRegistry;
import us.ihmc.stateEstimation.humanoid.StateEstimatorControllerFactory;
import us.ihmc.stateEstimation.invariant_estimator.InvariantContactSource;
import us.ihmc.tools.factories.FactoryFieldNotSetException;
import us.ihmc.tools.factories.FactoryTools;
import us.ihmc.tools.factories.OptionalFactoryField;
Expand Down Expand Up @@ -201,6 +202,11 @@ public class SCS2AvatarSimulationFactory
"headingAndVelocityEvaluationScriptParameters");
private final OptionalFactoryField<StateEstimatorControllerFactory> secondaryStateEstimatorFactory = new OptionalFactoryField<>(
"SecondaryStateEstimatorFactory");
/** When true, the invariant InEKF replaces the DRC estimator as the main floating-base estimator. */
private boolean useInvariantMainStateEstimator = false;
private boolean invariantMainEstimatorYawSeeding = true;
/** Contact source for the invariant main estimator; forwarded to the estimator thread factory (shared by sim and hardware). */
private InvariantContactSource invariantMainEstimatorContactSource = InvariantContactSource.FOOT_SWITCHES;
private final OptionalFactoryField<Boolean> createIKStreamingRealTimeController = new OptionalFactoryField<>(
"createIKStreamingRealTimeController",
false);
Expand Down Expand Up @@ -546,6 +552,12 @@ private void setupStateEstimationThread()
avatarEstimatorThreadFactory.setGravity(gravity.get());
if (secondaryStateEstimatorFactory.hasBeenSet())
avatarEstimatorThreadFactory.addSecondaryStateEstimatorFactory(secondaryStateEstimatorFactory.get());
if (useInvariantMainStateEstimator)
{
avatarEstimatorThreadFactory.setUseInvariantStateEstimator(true);
avatarEstimatorThreadFactory.setInvariantEstimatorYawSeeding(invariantMainEstimatorYawSeeding);
avatarEstimatorThreadFactory.setInvariantContactSource(invariantMainEstimatorContactSource);
}
estimatorThread = avatarEstimatorThreadFactory.createAvatarEstimatorThread();
}

Expand Down Expand Up @@ -1220,6 +1232,33 @@ public void setSecondaryStateEstimatorFactory(StateEstimatorControllerFactory se
this.secondaryStateEstimatorFactory.set(secondaryStateEstimatorFactory);
}

/**
* Replaces the DRC main state estimator with the contact-aided right-invariant InEKF. Joints are still
* read from the processed sensor output (good-enough FK); the InEKF drives the floating base.
*/
public void setUseInvariantMainStateEstimator(boolean useInvariantMainStateEstimator)
{
this.useInvariantMainStateEstimator = useInvariantMainStateEstimator;
}

/** Enables/disables foot-referenced yaw seeding when the invariant InEKF is the main estimator (default true). */
public void setInvariantMainEstimatorYawSeeding(boolean invariantMainEstimatorYawSeeding)
{
this.invariantMainEstimatorYawSeeding = invariantMainEstimatorYawSeeding;
}

/**
* Selects the invariant main estimator's contact-probability source: production foot switches
* ({@link InvariantContactSource#FOOT_SWITCHES}, default; joint-torque based on Alex, independent of the
* filter's own base estimate) or the built-in kinematic height detector
* ({@link InvariantContactSource#KINEMATIC_DETECTOR}, circular when the filter is main; A/B only). This is
* forwarded to the shared estimator thread factory, so the same source runs in sim and on hardware.
*/
public void setInvariantMainEstimatorContactSource(InvariantContactSource invariantMainEstimatorContactSource)
{
this.invariantMainEstimatorContactSource = invariantMainEstimatorContactSource;
}

public void setComponentFootstepGeneratorParameters(boolean useHeadingAndVelocityScript,
HeightMap heightMapForFootstepZ,
HeadingAndVelocityEvaluationScriptParameters headingAndVelocityEvaluationScriptParameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import us.ihmc.sensorProcessing.sensorProcessors.SensorProcessing;
import us.ihmc.sensorProcessing.simulatedSensors.SensorReaderFactory;
import us.ihmc.stateEstimation.humanoid.StateEstimatorController;
import us.ihmc.stateEstimation.invariant_estimator.InvariantContactSource;
import us.ihmc.tools.TimestampProvider;
import us.ihmc.tools.factories.OptionalFactoryField;
import us.ihmc.tools.factories.RequiredFactoryField;
Expand Down Expand Up @@ -109,6 +110,8 @@ public class AvatarMultiThreadingFactory
private final OptionalFactoryField<Map<HighLevelControllerName, StateEstimatorMode>> estimatorModeMapReference = new OptionalFactoryField<>("estimatorModeMapReference");
private final List<Runnable> preEstimatorRunnables = new ArrayList<>();
private final List<Runnable> postEstimatorRunnables = new ArrayList<>();
private final boolean useInvariantMainEstimator;
private final InvariantContactSource invariantContactSource;

// Controller
private final HighLevelHumanoidControllerFactory avatarControllerFactory;
Expand Down Expand Up @@ -158,7 +161,9 @@ public AvatarMultiThreadingFactory(DRCRobotModel robotModel,
double masterThreadDt,
TimestampProvider monotonicTimeProvider,
YoRegistry registry,
YoVariableServer yoVariableServer)
YoVariableServer yoVariableServer,
boolean useInvariantMainEstimator,
InvariantContactSource invariantContactSource)
{
this.masterRobotModel = robotModel;
this.masterFullRobotModel = fullRobotModel;
Expand All @@ -172,6 +177,8 @@ public AvatarMultiThreadingFactory(DRCRobotModel robotModel,
this.useMultiThreading = useMultiThreading;
this.rootRegistry = registry;
this.yoVariableServer = yoVariableServer;
this.useInvariantMainEstimator = useInvariantMainEstimator;
this.invariantContactSource = invariantContactSource;

masterContext = new HumanoidRobotContextData(masterFullRobotModel);

Expand Down Expand Up @@ -258,6 +265,8 @@ private AvatarEstimatorThread createAndAddEstimatorThread(DRCRobotModel robotMod
avatarEstimatorThreadFactory.setSensorReaderFactory(sensorReaderFactory);
avatarEstimatorThreadFactory.setHumanoidRobotContextDataFactory(estimatorContextDataFactory);
avatarEstimatorThreadFactory.setGravity(GRAVITY);
avatarEstimatorThreadFactory.setUseInvariantStateEstimator(useInvariantMainEstimator);
avatarEstimatorThreadFactory.setInvariantContactSource(invariantContactSource);
// if (secondaryEstimatorFactory != null)
// avatarEstimatorThreadFactory.addSecondaryStateEstimatorFactory(secondaryEstimatorFactory);
StateEstimatorController stateEstimator = avatarEstimatorThreadFactory.getMainStateEstimator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ public List<IMUBasedJointStateEstimatorParameters> getIMUBasedJointStateEstimato
return Collections.emptyList();
}

/**
* Which joint-level pre-filter implementation the estimator should construct.
* {@code ALPHA_COMPLEMENTARY} is the historical behavior (per-IMU-pair complementary joint fusion
* plus alpha-filtered IMU bias rejection); {@code JOINT_KF} selects the joint-level Kalman filter;
* {@code NONE} is an explicit pass-through (raw sensor values, zero biases) — the pre-seam
* behavior of the invariant pipeline, useful as a control condition. Note that on the DRC
* (kinematics-based) pipeline, {@code NONE} disables IMU-pair joint fusion AND IMU bias
* compensation, which is NOT that pipeline's historical behavior.
*/
public enum JointLevelEstimatorType
{
NONE, ALPHA_COMPLEMENTARY, JOINT_KF
}

/** Selected once at construction time; the default preserves the historical behavior for all robots. */
public JointLevelEstimatorType getJointLevelEstimatorType()
{
return JointLevelEstimatorType.JOINT_KF;
}

public boolean requestWristForceSensorCalibrationAtStart()
{
return false;
Expand Down Expand Up @@ -103,6 +123,51 @@ public double getIMUYawDriftRateFilterFreqInHertz()
return 1.5e-3;
}

/**
* Per-joint encoder position measurement-noise standard deviation (rad), by joint name, consumed by the
* {@code JOINT_KF} joint-level pre-filter for its direct encoder q update's measurement covariance.
* Return {@code Double.NaN} (the default) to use the filter's built-in scalar fallback for that joint.
*/
public double getEncoderPositionMeasurementStandardDeviation(String jointName)
{
return Double.NaN;
}

/**
* Per-joint encoder velocity measurement-noise standard deviation (rad/s), by joint name. Consumed by the
* {@code JOINT_KF} pre-filter's stance anchor for base->foot chain joints that are NOT filter states (their
* measured velocity enters the anchor as a known input, so its noise is propagated into the anchor's
* measurement covariance). Return {@code Double.NaN} (the default) to use the filter's built-in fallback.
*/
public double getEncoderVelocityMeasurementStandardDeviation(String jointName)
{
return Double.NaN;
}

/**
* Whether the {@code JOINT_KF} pre-filter should consume the sensed joint velocity as a direct measurement
* of its q̇ states (in addition to the pair-gyro and stance-anchor observations). Enable only when the
* velocity signal's low-pass corner is known — see
* {@link #getJointVelocityMeasurementBreakFrequency(String)} — or verified to sit far above the motion band.
*/
public boolean useDirectJointVelocityMeasurementInJointKF()
{
return false;
}

/**
* Effective first-order break frequency (Hz) of the low-pass cascade the sensed joint velocity passed
* through before reaching the estimator (e.g. drive-firmware LPF then the sensor-processing alpha filter;
* corners compose as {@code 1/f_eff = sum of 1/f_stage}). The {@code JOINT_KF} direct-velocity channel uses
* it to inflate that joint's measurement covariance by the instantaneous lag error. Return {@code NaN} (the
* default) to treat the measurement as instantaneous — correct when there is no filtering (sim) and honest
* on hardware only when the corner sits far above the motion band.
*/
public double getJointVelocityMeasurementBreakFrequency(String jointName)
{
return Double.NaN;
}

public abstract boolean enableIMUBiasCompensation();

public abstract double getIMUBiasFilterFreqInHertz();
Expand Down
Binary file added ihmc-state-estimation/scs2/EKF_config.scs2
Binary file not shown.
Binary file added ihmc-state-estimation/scs2/EKF_sim_config.scs2
Binary file not shown.
86 changes: 86 additions & 0 deletions ihmc-state-estimation/scs2/invariantFilterEstimator.scs2.chart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
SCS2 chart-group layout for the InvariantEKFStateEstimator YoVariables.

Load it in the SCS2 visualizer: on a chart-panel tab, right-click (or use the chart
toolbar menu) -> "Load chart group..." and select this file. It also loads as part of a
full SCS2 GUI configuration.

Variable names are given as "<registrySimpleName>.<variableName>"; SCS2 resolves the
registry segment as a namespace ending, so the full path prefix is not required. Vector
and yaw-pitch-roll YoVariables are charted through their scalar components (suffixes
X/Y/Z and Yaw/Pitch/Roll). Position/velocity charts overlay the estimate with its
1-sigma covariance envelope (…UpperBound / …LowerBound).

Grid: 4 columns x 3 rows.
-->
<YoChartGroupConfiguration name="InvariantFilterEstimator">
<chartConfigurations>
<identifier column="0" row="0"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionUpperBoundX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionLowerBoundX</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="1" row="0"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionUpperBoundY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionLowerBoundY</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="2" row="0"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionZ</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionUpperBoundZ</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBasePositionLowerBoundZ</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="3" row="0"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationYaw</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationPitch</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationRoll</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="0" row="1"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityUpperBoundX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityLowerBoundX</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="1" row="1"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityUpperBoundY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityLowerBoundY</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="2" row="1"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityZ</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityUpperBoundZ</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityLowerBoundZ</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="3" row="1"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationStdDevX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationStdDevY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisOrientationStdDevZ</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="0" row="2"/>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityBodyX</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityBodyY</yoVariables>
<yoVariables>InvariantEKFStateEstimator.invariantFilterPelvisBaseVelocityBodyZ</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="1" row="2"/>
<yoVariables>InvariantEKFStateEstimator.invariantMinusMainOrientationErrorAngle</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="2" row="2"/>
<yoVariables>InvariantEKFStateEstimator.invariantMinusMainLinearVelocityErrorMagnitude</yoVariables>
</chartConfigurations>
<chartConfigurations>
<identifier column="3" row="2"/>
<yoVariables>InvariantEKFStateEstimator.invariantMinusMainAngularVelocityErrorMagnitude</yoVariables>
</chartConfigurations>
<numberOfColumns>4</numberOfColumns>
<numberOfRows>3</numberOfRows>
</YoChartGroupConfiguration>
Loading
Loading