Skip to content

Commit a76a67f

Browse files
committed
got the IMU based locomotion working better
1 parent 25d65d7 commit a76a67f

File tree

3 files changed

+106
-24
lines changed

3 files changed

+106
-24
lines changed

ihmc-state-estimation/src/main/java/us/ihmc/stateEstimation/humanoid/kinematicsBasedStateEstimation/PelvisKinematicsBasedLinearStateCalculator.java

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package us.ihmc.stateEstimation.humanoid.kinematicsBasedStateEstimation;
22

3+
import java.util.ArrayList;
34
import java.util.HashMap;
45
import java.util.List;
56
import java.util.Map;
@@ -109,7 +110,7 @@ public PelvisKinematicsBasedLinearStateCalculator(FullInverseDynamicsStructure i
109110
YoDouble footAlphaLeakIMUOnly = new YoDouble("footIMUOnlyAlphaLeak", registry);
110111
YoDouble imuAgainstKinematicsForVelocityBreakFrequency = new YoDouble("footIMUAgainstKinematicsForVelocityBreakFrequency", registry);
111112
YoDouble imuAgainstKinematicsForPositionBreakFrequency = new YoDouble("footIMUAgainstKinematicsForPositionBreakFrequency", registry);
112-
imuAgainstKinematicsForPositionBreakFrequency.set(200.0);
113+
imuAgainstKinematicsForPositionBreakFrequency.set(0.0);
113114
imuAgainstKinematicsForVelocityBreakFrequency.set(2.0);
114115
footAlphaLeakIMUOnly.set(0.999);
115116

@@ -234,14 +235,28 @@ public void updateNoTrustedFeet(FramePoint3DReadOnly pelvisPosition, FrameVector
234235
rootJointLinearVelocity.setToZero();
235236
}
236237

237-
public void estimatePelvisLinearState(List<RigidBodyBasics> trustedFeet, List<RigidBodyBasics> unTrustedFeet, FramePoint3DReadOnly pelvisPosition)
238+
private final List<RigidBodyBasics> trustedFeetLocal = new ArrayList<>();
239+
private final List<RigidBodyBasics> unTrustedFeetLocal = new ArrayList<>();
240+
241+
public void estimatePelvisLinearState(List<RigidBodyBasics> trustedFeet,
242+
List<RigidBodyBasics> unTrustedFeet,
243+
FramePoint3DReadOnly pelvisPosition,
244+
FrameVector3DReadOnly pelvisLinearVelocity)
238245
{
239246
if (!kinematicsIsUpToDate.getBooleanValue())
240247
throw new RuntimeException("Leg kinematics needs to be updated before trying to estimate the pelvis position/linear velocity.");
241248

249+
trustedFeetLocal.clear();
250+
unTrustedFeetLocal.clear();
251+
242252
for (int i = 0; i < trustedFeet.size(); i++)
253+
trustedFeetLocal.add(trustedFeet.get(i));
254+
for (int i = 0; i < unTrustedFeet.size(); i++)
255+
unTrustedFeetLocal.add(unTrustedFeet.get(i));
256+
257+
for (int i = 0; i < trustedFeetLocal.size(); i++)
243258
{
244-
SingleFootEstimator footEstimator = footEstimatorMap.get(trustedFeet.get(i));
259+
SingleFootEstimator footEstimator = footEstimatorMap.get(trustedFeetLocal.get(i));
245260
if (assumeTrustedFootAtZeroHeight.getValue())
246261
{
247262
if (trustCoPAsNonSlippingContactPoint.getValue())
@@ -257,23 +272,52 @@ public void estimatePelvisLinearState(List<RigidBodyBasics> trustedFeet, List<Ri
257272
{
258273
footEstimator.updateCoPAndFootPosition(trustCoPAsNonSlippingContactPoint.getValue(), useControllerDesiredCoP.getValue());
259274
}
260-
footEstimator.correctPelvisFromKinematics(trustedFeet.size(), alphaRootJointLinearVelocity.getValue(), rootJointPosition, rootJointLinearVelocity);
275+
}
276+
277+
int trustIdx = 0;
278+
while (trustIdx < trustedFeetLocal.size())
279+
{
280+
if (footEstimatorMap.get(trustedFeetLocal.get(trustIdx)).isFootMoving())
281+
unTrustedFeetLocal.add(trustedFeetLocal.remove(trustIdx));
282+
else
283+
trustIdx++;
284+
}
285+
286+
if (trustedFeetLocal.isEmpty())
287+
{
288+
rootJointPosition.set(pelvisPosition);
289+
if (pelvisLinearVelocity != null)
290+
rootJointLinearVelocity.set(pelvisLinearVelocity);
291+
else
292+
rootJointLinearVelocity.setToZero();
293+
}
294+
else
295+
{
296+
for (int i = 0; i < trustedFeetLocal.size(); i++)
297+
{
298+
SingleFootEstimator footEstimator = footEstimatorMap.get(trustedFeetLocal.get(i));
299+
footEstimator.correctPelvisFromKinematics(trustedFeetLocal.size(),
300+
alphaRootJointLinearVelocity.getValue(),
301+
rootJointPosition,
302+
rootJointLinearVelocity);
303+
}
261304
}
262305

263306
rootJointLinearVelocityFDDebug.update();
264307

308+
// TODO should this use the local copies?
265309
if (correctTrustedFeetPositions.getValue())
266310
{
267-
for (int i = 0; i < trustedFeet.size(); i++)
311+
for (int i = 0; i < trustedFeetLocal.size(); i++)
268312
{
269-
SingleFootEstimator footEstimator = footEstimatorMap.get(trustedFeet.get(i));
313+
SingleFootEstimator footEstimator = footEstimatorMap.get(trustedFeetLocal.get(i));
270314
footEstimator.correctFootPositionFromRootJoint(true, trustCoPAsNonSlippingContactPoint.getValue(), rootJointPosition);
271315
}
272316
}
273317

274-
for (int i = 0; i < unTrustedFeet.size(); i++)
318+
for (int i = 0; i < unTrustedFeetLocal.size(); i++)
275319
{
276-
SingleFootEstimator footEstimator = footEstimatorMap.get(unTrustedFeet.get(i));
320+
SingleFootEstimator footEstimator = footEstimatorMap.get(unTrustedFeetLocal.get(i));
277321
footEstimator.correctFootPositionFromRootJoint(false, false, pelvisPosition);
278322
}
279323

ihmc-state-estimation/src/main/java/us/ihmc/stateEstimation/humanoid/kinematicsBasedStateEstimation/PelvisLinearStateUpdater.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,11 @@ public void updateForFrozenState()
364364

365365
public void updateRootJointPositionAndLinearVelocity()
366366
{
367+
kinematicsBasedLinearStateCalculator.updateKinematics();
368+
367369
if (requestStopEstimationOfPelvisLinearState.getBooleanValue())
368370
return;
369371

370-
kinematicsBasedLinearStateCalculator.updateKinematics();
371-
372372
numberOfEndEffectorsTrusted.set(setTrustedFeetUsingFootSwitches());
373373
numberOfEndEffectorsFilteredByLoad.set(0);
374374

@@ -413,7 +413,7 @@ public void updateRootJointPositionAndLinearVelocity()
413413
else if (numberOfEndEffectorsTrusted.getIntegerValue() > 0)
414414
{
415415
updateTrustedFeetLists();
416-
kinematicsBasedLinearStateCalculator.estimatePelvisLinearState(listOfTrustedFeet, listOfUnTrustedFeet, rootJointPosition);
416+
kinematicsBasedLinearStateCalculator.estimatePelvisLinearState(listOfTrustedFeet, listOfUnTrustedFeet, rootJointPosition, rootJointVelocity);
417417

418418
if (imuBasedLinearStateCalculator.isEstimationEnabled())
419419
{

ihmc-state-estimation/src/main/java/us/ihmc/stateEstimation/humanoid/kinematicsBasedStateEstimation/SingleFootEstimator.java

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import us.ihmc.euclid.referenceFrame.interfaces.FixedFramePoint3DBasics;
1010
import us.ihmc.euclid.referenceFrame.interfaces.FixedFrameVector3DBasics;
1111
import us.ihmc.euclid.referenceFrame.interfaces.FramePoint2DBasics;
12+
import us.ihmc.euclid.referenceFrame.interfaces.FramePoint2DReadOnly;
1213
import us.ihmc.euclid.referenceFrame.interfaces.FramePoint3DReadOnly;
1314
import us.ihmc.euclid.referenceFrame.interfaces.FrameVector3DReadOnly;
1415
import us.ihmc.euclid.referenceFrame.interfaces.FrameVertex2DSupplier;
@@ -39,6 +40,7 @@
3940
import us.ihmc.yoVariables.providers.BooleanProvider;
4041
import us.ihmc.yoVariables.providers.DoubleProvider;
4142
import us.ihmc.yoVariables.registry.YoRegistry;
43+
import us.ihmc.yoVariables.variable.YoBoolean;
4244

4345
class SingleFootEstimator implements SCS2YoGraphicHolder
4446
{
@@ -57,13 +59,17 @@ class SingleFootEstimator implements SCS2YoGraphicHolder
5759
private final YoFrameVector3D footFusedLinearVelocityInWorld;
5860
private final YoFrameVector3D footFusedAngularVelocityInWorld;
5961

62+
private final YoBoolean footIsMoving;
63+
6064
private final YoFrameVector3D copVelocityInWorld;
6165
private final AlphaFilteredYoFrameVector3D footToRootJointPosition;
6266
private final YoFramePoint3D footPositionInWorld;
6367
/** Debug variable */
6468
private final YoFramePoint3D rootJointPositionPerFoot;
6569

66-
private final YoFramePoint3D copPositionInWorld;
70+
private final YoFramePoint3D copIKPositionInWorld;
71+
private final YoFramePoint3D copIMUPositionInWorld;
72+
private final YoFramePoint3D copFusedPositionInWorld;
6773
private final YoFramePoint2D previousCoPInFootFrame;
6874

6975
private final AlphaFilteredYoFramePoint2D copFilteredInFootFrame;
@@ -124,6 +130,8 @@ public SingleFootEstimator(FloatingJointBasics rootJoint,
124130
copRawInFootFrame = new YoFramePoint2D(namePrefix + "CoPRawInFootFrame", soleFrame, registry);
125131
previousCoPInFootFrame = new YoFramePoint2D(namePrefix + "PreviousCoPInFootFrame", soleFrame, registry);
126132

133+
footIsMoving = new YoBoolean(namePrefix + "IsMoving", registry);
134+
127135
footIKLinearVelocityInWorld = new YoFrameVector3D(namePrefix + "IKLinearVelocityInWorld", worldFrame, registry);
128136
footIKAngularVelocityInWorld = new YoFrameVector3D(namePrefix + "IKAngularVelocityInWorld", worldFrame, registry);
129137
footIMULinearVelocityInWorld = new YoFrameVector3D(namePrefix + "IMULinearVelocityInWorld", worldFrame, registry);
@@ -134,7 +142,9 @@ public SingleFootEstimator(FloatingJointBasics rootJoint,
134142
DoubleProvider alphaCop = () -> AlphaFilterTools.computeAlphaGivenBreakFrequencyProperly(copFilterBreakFrequency.getValue(), estimatorDT);
135143
copFilteredInFootFrame = new AlphaFilteredYoFramePoint2D(namePrefix + "CoPFilteredInFootFrame", "", registry, alphaCop, copRawInFootFrame);
136144
copFilteredInFootFrame.update(0.0, 0.0);
137-
copPositionInWorld = new YoFramePoint3D(namePrefix + "CoPPositionInWorld", worldFrame, registry);
145+
copIKPositionInWorld = new YoFramePoint3D(namePrefix + "CoPIKPositionInWorld", worldFrame, registry);
146+
copIMUPositionInWorld = new YoFramePoint3D(namePrefix + "CoPIMUPositionInWorld", worldFrame, registry);
147+
copFusedPositionInWorld = new YoFramePoint3D(namePrefix + "CoPFusedPositionInWorld", worldFrame, registry);
138148
copVelocityInWorld = new YoFrameVector3D(namePrefix + "CoPVelocityInWorld", worldFrame, registry);
139149
}
140150

@@ -144,7 +154,7 @@ public void createVisualization(YoGraphicsListRegistry yoGraphicsListRegistry)
144154
return;
145155

146156
String sidePrefix = foot.getName();
147-
YoGraphicPosition copInWorld = new YoGraphicPosition(sidePrefix + "StateEstimatorCoP", copPositionInWorld, 0.005, YoAppearance.DeepPink());
157+
YoGraphicPosition copInWorld = new YoGraphicPosition(sidePrefix + "StateEstimatorCoP", copFusedPositionInWorld, 0.005, YoAppearance.DeepPink());
148158
YoArtifactPosition artifact = copInWorld.createArtifact();
149159
artifact.setVisible(false);
150160
yoGraphicsListRegistry.registerArtifact("StateEstimator", artifact);
@@ -153,7 +163,7 @@ public void createVisualization(YoGraphicsListRegistry yoGraphicsListRegistry)
153163
@Override
154164
public YoGraphicDefinition getSCS2YoGraphics()
155165
{
156-
return YoGraphicDefinitionFactory.newYoGraphicPoint2D(foot.getName() + "StateEstimatorCoP", copPositionInWorld,
166+
return YoGraphicDefinitionFactory.newYoGraphicPoint2D(foot.getName() + "StateEstimatorCoP", copFusedPositionInWorld,
157167
0.01,
158168
ColorDefinitions.DeepPink(),
159169
DefaultPoint2DGraphic.CIRCLE);
@@ -192,6 +202,12 @@ public void updateKinematics(TwistReadOnly rootBodyTwist)
192202
tempFrameVector.changeFrame(worldFrame);
193203

194204
footToRootJointPosition.update(tempFrameVector);
205+
206+
// FIXME remove magic parameters
207+
if (USE_IMU_DATA)
208+
footIsMoving.set(getFootLinearVelocityInWorld().norm() > 0.5 || getFootAngularVelocityInWorld().norm() > 1.0);
209+
else
210+
footIsMoving.set(false);
195211
}
196212

197213
/**
@@ -202,7 +218,7 @@ public void updateKinematics(TwistReadOnly rootBodyTwist)
202218
public void updateCoPAndFootSettingZ(boolean trustCoPAsNonSlippingContactPoint, boolean useControllerDesiredCoP, double zPosition)
203219
{
204220
updateCoPPosition(trustCoPAsNonSlippingContactPoint, useControllerDesiredCoP);
205-
copPositionInWorld.setZ(zPosition);
221+
copFusedPositionInWorld.setZ(zPosition);
206222
correctFootPositionsUsingCoP(trustCoPAsNonSlippingContactPoint);
207223
}
208224

@@ -257,14 +273,14 @@ public void correctFootPositionFromRootJoint(boolean isTrusted, boolean trustCoP
257273

258274
if (!isTrusted)
259275
{
260-
copPositionInWorld.set(footPositionInWorld);
276+
copFusedPositionInWorld.set(footPositionInWorld);
261277
copRawInFootFrame.setToZero();
262278
copFilteredInFootFrame.setToZero();
263279
}
264280
else if (trustCoPAsNonSlippingContactPoint)
265281
{
266282
tempFrameVector.sub(footPositionInWorld, tempPoint); // Delta from previous to new foot position
267-
copPositionInWorld.add(tempFrameVector); // New CoP position
283+
copFusedPositionInWorld.add(tempFrameVector); // New CoP position
268284
}
269285
}
270286

@@ -288,6 +304,11 @@ public FrameVector3DReadOnly getFootAngularVelocityInWorld()
288304
return footFusedAngularVelocityInWorld;
289305
}
290306

307+
public boolean isFootMoving()
308+
{
309+
return footIsMoving.getBooleanValue();
310+
}
311+
291312
private final FramePoint2D tempCoP2d = new FramePoint2D();
292313
private final FrameVector3D tempCoPOffset = new FrameVector3D();
293314

@@ -340,23 +361,35 @@ private void updateCoPPosition(boolean trustCoPAsNonSlippingContactPoint, boolea
340361
copRawInFootFrame.set(tempCoP2d);
341362
copFilteredInFootFrame.update();
342363

364+
// Update the CoP value from kinematics. This treats it as non-stationary.
365+
copIKPositionInWorld.setMatchingFrame(soleFrame, copFilteredInFootFrame.getX(), copFilteredInFootFrame.getY(), 0.0);
366+
343367
// Update the change in the CoP from the previous tick.
344368
tempCoPOffset.setIncludingFrame(soleFrame,
345369
copFilteredInFootFrame.getX() - previousCoPInFootFrame.getX(),
346370
copFilteredInFootFrame.getY() - previousCoPInFootFrame.getY(),
347371
0.0);
348372
tempCoPOffset.changeFrame(worldFrame);
349373
// Apply this same change to the CoP in world.
350-
copPositionInWorld.add(tempCoPOffset);
374+
copFusedPositionInWorld.add(tempCoPOffset);
351375
}
352376
else
353377
{
354378
tempCoP2d.setToZero(soleFrame);
355-
copRawInFootFrame.setToZero();
356-
copFilteredInFootFrame.setToZero();
357-
copPositionInWorld.setFromReferenceFrame(soleFrame);
379+
// Update the CoP value to match the center of the foot.
380+
copIKPositionInWorld.setFromReferenceFrame(soleFrame);
358381
}
359382

383+
if (USE_IMU_DATA)
384+
{
385+
// Integrate the fused position using the velocity, which is from the kinematics and the IMU.
386+
computeLinearVelocityAtPointInWorld(copFusedPositionInWorld, tempFrameVector);
387+
copIMUPositionInWorld.scaleAdd(footAlphaLeakIMUOnly.getValue() * estimatorDT, tempFrameVector, copFusedPositionInWorld);
388+
389+
// Fuse the kinematic data with the IMU data
390+
double alpha = AlphaFilterTools.computeAlphaGivenBreakFrequencyProperly(imuAgainstKinematicsForPositionBreakFrequency.getValue(), estimatorDT);
391+
copFusedPositionInWorld.interpolate(copIKPositionInWorld, copIMUPositionInWorld, alpha);
392+
}
360393
}
361394

362395
private void correctFootPositionsUsingCoP(boolean trustCoPAsNonSlippingContactPoint)
@@ -368,7 +401,7 @@ private void correctFootPositionsUsingCoP(boolean trustCoPAsNonSlippingContactPo
368401
tempCoPOffset.setIncludingFrame(copFilteredInFootFrame, 0.0);
369402
tempCoPOffset.changeFrame(worldFrame);
370403
// Update where the foot must be, according to this CoP location
371-
footPositionInWorld.sub(copPositionInWorld, tempCoPOffset);
404+
footPositionInWorld.sub(copFusedPositionInWorld, tempCoPOffset);
372405
}
373406

374407
private final FrameVector3D linearAcceleration = new FrameVector3D();
@@ -445,10 +478,15 @@ private void computeFootTwistInWorld(TwistReadOnly rootBodyTwist)
445478
}
446479

447480
private void computeCoPLinearVelocityInWorld(FixedFrameVector3DBasics footLinearVelocityToPack)
481+
{
482+
computeLinearVelocityAtPointInWorld(copFusedPositionInWorld, footLinearVelocityToPack);
483+
}
484+
485+
private void computeLinearVelocityAtPointInWorld(FramePoint3DReadOnly point, FixedFrameVector3DBasics footLinearVelocityToPack)
448486
{
449487
footTwistInWorld.getLinearPart().set(footFusedLinearVelocityInWorld);
450488
footTwistInWorld.getAngularPart().set(footFusedAngularVelocityInWorld);
451489

452-
footTwistInWorld.getLinearVelocityAt(copPositionInWorld, footLinearVelocityToPack);
490+
footTwistInWorld.getLinearVelocityAt(point, footLinearVelocityToPack);
453491
}
454492
}

0 commit comments

Comments
 (0)