Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/quickster footstep provider #527

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5d0dccc
added necessary classes for QFP
stefanfasano Dec 5, 2024
ef60a8d
added QFP to CSG
stefanfasano Dec 5, 2024
340f1ab
QFP steps added to CSG FootstepDataList
stefanfasano Dec 5, 2024
92955ed
footsteps now continuously update throughout swing
stefanfasano Dec 5, 2024
33793fc
fixed stageable yovariable params. Did some tuning of double support …
stefanfasano Dec 5, 2024
8341322
added ICP param to disable feedback CoP control
stefanfasano Dec 6, 2024
2b83ce2
fixed turn walking bug by setting QFP footstep position and orientation
stefanfasano Dec 9, 2024
e89e446
added support for joystick control in QFP Sim
stefanfasano Dec 9, 2024
a09a8ae
fixed csg wrong support side bug
stefanfasano Dec 10, 2024
022c0e7
added boolean to not continously update touchdown location throughout…
stefanfasano Dec 12, 2024
4b5cc4c
yovariableized StepGeneratorCommandInputManager desired input variables
stefanfasano Dec 12, 2024
3532006
fixed bug in which footsteps weren't polled at right time causing sta…
stefanfasano Dec 13, 2024
a846e1b
added visualizer of desired touchdown position from QFP
stefanfasano Dec 13, 2024
d1c11a7
Merge branch 'develop' into feature/quickster-footstep-provider
stefanfasano Dec 13, 2024
5a0ee77
switched to ALIP+DS model
stefanfasano Dec 16, 2024
c5bcb14
disabled continouous touchdown position update by default
stefanfasano Dec 17, 2024
ad74d77
Merge branch 'develop' into feature/quickster-footstep-provider
stefanfasano Dec 17, 2024
c0e9d4e
fixed control frame yaw discontinuity bug
stefanfasano Dec 18, 2024
b7dc596
some parameter tuning for hardware
stefanfasano Dec 18, 2024
e9f6dec
Merge branch 'develop' into feature/quickster-footstep-provider
stefanfasano Dec 18, 2024
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 @@ -78,6 +78,7 @@ public AvatarStepGeneratorThread(HumanoidSteppingPluginFactory pluginFactory,
humanoidRobotContextData = contextDataFactory.createHumanoidRobotContextData();

csgCommandInputManager = pluginFactory.getStepGeneratorCommandInputManager();
csgRegistry.addChild(csgCommandInputManager.getRegistry());

if (environmentalConstraints != null)
{
Expand All @@ -98,12 +99,13 @@ public AvatarStepGeneratorThread(HumanoidSteppingPluginFactory pluginFactory,
pluginFactory.createStepGeneratorNetworkSubscriber(drcRobotModel.getSimpleRobotName(), ros2Node);

humanoidReferenceFrames = new HumanoidReferenceFrames(fullRobotModel);
continuousStepGeneratorPlugin = pluginFactory.buildPlugin(humanoidReferenceFrames,
continuousStepGeneratorPlugin = pluginFactory.buildPlugin(fullRobotModel,
humanoidReferenceFrames,
drcRobotModel.getStepGeneratorDT(),
drcRobotModel.getWalkingControllerParameters(),
walkingOutputManager,
walkingCommandInputManager,
null,
csgGraphics,
null,
csgTime);
csgRegistry.addChild(continuousStepGeneratorPlugin.getRegistry());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ private void setupStepGeneratorThread()
else
{
JoystickBasedSteppingPluginFactory joystickPluginFactory = new JoystickBasedSteppingPluginFactory();
if (heightMapForFootstepZ.hasValue())
if (heightMapForFootstepZ.hasValue() && heightMapForFootstepZ.get() != null)
joystickPluginFactory.setFootStepAdjustment(new HeightMapBasedFootstepAdjustment(heightMapForFootstepZ.get()));
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class ICPController implements ICPControllerInterface
private final YoRegistry registry = new YoRegistry(getClass().getSimpleName());

private final BooleanProvider useCMPFeedback;
private final BooleanProvider useCoPFeedback;
private final BooleanProvider useAngularMomentum;

private final BooleanProvider scaleFeedbackWeightWithGain;
Expand Down Expand Up @@ -160,6 +161,7 @@ public ICPController(WalkingControllerParameters walkingControllerParameters,
this.controlDTSquare = controlDT * controlDT;

useCMPFeedback = new BooleanParameter(yoNamePrefix + "UseCMPFeedback", registry, icpOptimizationParameters.useCMPFeedback());
useCoPFeedback = new BooleanParameter(yoNamePrefix + "UseCoPFeedback", registry, icpOptimizationParameters.useCoPFeedback());
useAngularMomentum = new BooleanParameter(yoNamePrefix + "UseAngularMomentum", registry, icpOptimizationParameters.useAngularMomentum());

scaleFeedbackWeightWithGain = new BooleanParameter(yoNamePrefix + "ScaleFeedbackWeightWithGain",
Expand Down Expand Up @@ -449,7 +451,9 @@ private void extractSolutionsFromSolver(boolean converged)

private void computeFeedForwardAndFeedBackAlphas()
{
if (parameters.getFeedbackAlphaCalculator() != null)
if (!useCoPFeedback.getValue())
feedbackAlpha.set(1.0);
else if (parameters.getFeedbackAlphaCalculator() != null)
feedbackAlpha.set(parameters.getFeedbackAlphaCalculator().computeAlpha(currentICP, copConstraintHandler.getCoPConstraint()));
else
feedbackAlpha.set(0.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ public boolean useCMPFeedback()
return true;
}

/**
* Enabling this boolean allows feedback control of CoP (feedback alpha < 1).
*/
public boolean useCoPFeedback()
{
return true;
}

/**
* Enabling this boolean allows the CMP to exit the support polygon. The CoP will still be
* constrained to lie inside the support polygon, however.
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package us.ihmc.commonWalkingControlModules.desiredFootStep.footstepGenerator.quicksterFootstepProvider;

import us.ihmc.euclid.referenceFrame.ReferenceFrame;
import us.ihmc.euclid.referenceFrame.interfaces.FramePoint3DReadOnly;
import us.ihmc.euclid.referenceFrame.interfaces.FrameQuaternionReadOnly;
import us.ihmc.euclid.referenceFrame.interfaces.FrameVector3DReadOnly;
import us.ihmc.euclid.transform.RigidBodyTransform;
import us.ihmc.graphicsDescription.yoGraphics.YoGraphicReferenceFrame;
import us.ihmc.graphicsDescription.yoGraphics.YoGraphicsListRegistry;
import us.ihmc.mecano.frames.MovingReferenceFrame;
import us.ihmc.mecano.spatial.Twist;
import us.ihmc.robotModels.FullHumanoidRobotModel;
import us.ihmc.robotics.screwTheory.AngularExcursionCalculator;
import us.ihmc.robotics.screwTheory.MovingZUpFrame;
import us.ihmc.sensorProcessing.frames.CommonHumanoidReferenceFrames;
import us.ihmc.yoVariables.euclid.referenceFrame.YoFramePoint3D;
import us.ihmc.yoVariables.euclid.referenceFrame.YoFrameVector3D;
import us.ihmc.yoVariables.registry.YoRegistry;

public class QuicksterFootstepProviderEstimates
{
// CoM State Estimates
private final YoFramePoint3D currentCoMPosition;
private final YoFrameVector3D currentCoMVelocity;
private final YoFrameVector3D currentCoMLinearMomentum;
private final YoFrameVector3D currentCoMAngularMomentum;

// CoM Frames
private final MovingReferenceFrame centerOfMassFrame;
private final MovingReferenceFrame centerOfMassControlFrame;
private final MovingZUpFrame centerOfMassControlZUpFrame;
private final YoGraphicReferenceFrame centerOfMassControlZUpFrameGraphic;

// Calculator for CoM momentum info
private final AngularExcursionCalculator angularExcursionCalculator;

public QuicksterFootstepProviderEstimates(FullHumanoidRobotModel robotModel,
CommonHumanoidReferenceFrames referenceFrames,
FrameQuaternionReadOnly desiredPelvisOrientation,
double updateDT,
String variableNameSuffix,
YoRegistry registry,
YoGraphicsListRegistry yoGraphicsListRegistry)
{
currentCoMPosition = new YoFramePoint3D("currentCoMPosition" + variableNameSuffix, ReferenceFrame.getWorldFrame(), registry);
currentCoMVelocity = new YoFrameVector3D("currentCoMVelocity" + variableNameSuffix, ReferenceFrame.getWorldFrame(), registry);
currentCoMLinearMomentum = new YoFrameVector3D("currentCoMLinearMomentum" + variableNameSuffix, ReferenceFrame.getWorldFrame(), registry);
currentCoMAngularMomentum = new YoFrameVector3D("currentCoMAngularMomentum" + variableNameSuffix, ReferenceFrame.getWorldFrame(), registry);

centerOfMassFrame = (MovingReferenceFrame) referenceFrames.getCenterOfMassFrame();

centerOfMassControlFrame = new MovingReferenceFrame("centerOfMassControlFrame" + variableNameSuffix, ReferenceFrame.getWorldFrame())
{
@Override
protected void updateTwistRelativeToParent(Twist twistRelativeToParentToPack)
{
// pelvisFrame.getTwistRelativeToOther(ReferenceFrame.getWorldFrame(), pelvisTwist);
// pelvisTwist.changeFrame(centerOfMassFrame); // FIXME we really want the rotation about the center of mass, relative to the world.

twistRelativeToParentToPack.getLinearPart().setMatchingFrame(getCenterOfMassVelocity());
// twistRelativeToParentToPack.getAngularPart().setMatchingFrame(pelvisTwist.getAngularPart());
}

@Override
protected void updateTransformToParent(RigidBodyTransform transformToParent)
{
transformToParent.getTranslation().set(currentCoMPosition);
transformToParent.getRotation().set(desiredPelvisOrientation);
}
};

centerOfMassControlZUpFrame = new MovingZUpFrame(centerOfMassControlFrame, "centerOfMassControlZUpFrame" + variableNameSuffix);

centerOfMassControlZUpFrameGraphic = new YoGraphicReferenceFrame(centerOfMassControlZUpFrame, registry, false, 1.25);
yoGraphicsListRegistry.registerYoGraphic("QFP", centerOfMassControlZUpFrameGraphic);

angularExcursionCalculator = new AngularExcursionCalculator(centerOfMassFrame, robotModel.getElevator(), updateDT, registry, null);
}

public void update()
{
// Update CoM position and velocity from CoM frame
currentCoMPosition.setFromReferenceFrame(centerOfMassFrame);
currentCoMVelocity.setMatchingFrame(centerOfMassFrame.getTwistOfFrame().getLinearPart());

// Update CoM momentum info
angularExcursionCalculator.compute();
currentCoMLinearMomentum.setMatchingFrame(angularExcursionCalculator.getLinearMomentum());
currentCoMAngularMomentum.setMatchingFrame(angularExcursionCalculator.getAngularMomentum());

// Update CoM control frames
centerOfMassControlFrame.update();
centerOfMassControlZUpFrame.update();
centerOfMassControlZUpFrameGraphic.update();
}

public FramePoint3DReadOnly getCenterOfMassPosition()
{
return currentCoMPosition;
}

public FrameVector3DReadOnly getCenterOfMassVelocity()
{
return currentCoMVelocity;
}

public FrameVector3DReadOnly getCenterOfMassLinearMomentum()
{
return currentCoMLinearMomentum;
}

public FrameVector3DReadOnly getCenterOfMassAngularMomentum()
{
return currentCoMAngularMomentum;
}

public MovingZUpFrame getCenterOfMassControlZUpFrame()
{
return centerOfMassControlZUpFrame;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package us.ihmc.commonWalkingControlModules.desiredFootStep.footstepGenerator.quicksterFootstepProvider;

import us.ihmc.commons.MathTools;
import us.ihmc.robotics.robotSide.RobotSide;
import us.ihmc.robotics.robotSide.SideDependentList;
import us.ihmc.yoVariables.registry.YoRegistry;
import us.ihmc.yoVariables.variable.YoDouble;
import java.util.ArrayList;
import java.util.List;

public class QuicksterFootstepProviderParameters
{
// Static variables
private static final double SWING_DURATION = 0.7;//0.55;
private static final double DOUBLE_SUPPORT_FRACTION = 0.1;//0.05;
private static final double STANCE_WIDTH = 0.275;
private static final double SWING_HEIGHT = 0.09;
private static final double COM_HEIGHT = 0.95;
private static final double POLE = 0.0;
private static final double MAX_ACCELERATION_PER_STEP = 0.075;
private static final double MAX_DECELERATION_PER_STEP = -0.2;

// YoVariables
private final YoDouble swingDuration;
private final YoDouble doubleSupportFraction;
private final YoDouble stanceWidth;
private final YoDouble swingHeight;
private final YoDouble comHeight;
private final YoDouble pole;
private final YoDouble maxAccelerationPerStep;
private final YoDouble maxDecelerationPerStep;
private final YoDouble omega;

// Stageable YoVariables
private final SideDependentList<StageableYoDouble> swingDurationCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> doubleSupportFractionCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> stanceWidthCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> swingHeightCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> comHeightCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> poleCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> maxAccelerationPerStepCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> maxDecelerationPerStepCurrentStep = new SideDependentList<>();
private final SideDependentList<StageableYoDouble> omegaCurrentStep = new SideDependentList<>();

private final SideDependentList<List<StageableYoDouble>> stageableYoDoubles = new SideDependentList<>();

public QuicksterFootstepProviderParameters(double gravityZ, YoRegistry parentRegistry)
{
YoRegistry registry = new YoRegistry(getClass().getSimpleName());
String suffix2 = "QFP";

swingDuration = new YoDouble("swingDuration" + suffix2, registry);
doubleSupportFraction = new YoDouble("doubleSupportFraction" + suffix2, registry);
stanceWidth = new YoDouble("stanceWidth" + suffix2, registry);
swingHeight = new YoDouble("desiredSwingHeight" + suffix2, registry);
comHeight = new YoDouble("desiredComHeight" + suffix2, registry);
pole = new YoDouble("pole" + suffix2, registry);
maxAccelerationPerStep = new YoDouble("maxAccelerationPerStep" + suffix2, registry);
maxDecelerationPerStep = new YoDouble("maxDecelerationPerStep" + suffix2, registry);
omega = new YoDouble("omega" + suffix2, registry);

swingDuration.set(SWING_DURATION);
doubleSupportFraction.set(DOUBLE_SUPPORT_FRACTION);
stanceWidth.set(STANCE_WIDTH);
swingHeight.set(SWING_HEIGHT);
comHeight.set(COM_HEIGHT);
pole.set(POLE);
maxAccelerationPerStep.set(MAX_ACCELERATION_PER_STEP);
maxDecelerationPerStep.set(MAX_DECELERATION_PER_STEP);
omega.set(Math.sqrt(Math.abs(gravityZ / comHeight.getDoubleValue())));

for (RobotSide robotSide : RobotSide.values)
{
String suffix = robotSide.getPascalCaseName() + "CurrentStep";
stageableYoDoubles.put(robotSide, new ArrayList<>());

swingDurationCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "swingDuration", suffix + suffix2, swingDuration, registry));
doubleSupportFractionCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "doubleSupportFraction", suffix + suffix2, doubleSupportFraction, registry));
stanceWidthCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "stanceWidthCurrentStep", suffix + suffix2, stanceWidth, registry));
swingHeightCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "desiredSwingHeight", suffix + suffix2, swingHeight, registry));
comHeightCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "desiredComHeight", suffix + suffix2, comHeight, registry));
poleCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "pole", suffix + suffix2, pole, registry));
maxAccelerationPerStepCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "maxAccelerationPerStep", suffix + suffix2, maxAccelerationPerStep, registry));
maxDecelerationPerStepCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "maxDecelerationPerStep", suffix + suffix2, maxDecelerationPerStep, registry));
omegaCurrentStep.put(robotSide, createStageableYoDouble(robotSide, "omega", suffix + suffix2, omega, registry));

}

comHeight.addListener(change -> omega.set(Math.sqrt(Math.abs(gravityZ / comHeight.getDoubleValue()))));

parentRegistry.addChild(registry);
}

private StageableYoDouble createStageableYoDouble(RobotSide robotSide, String prefix, String suffix, YoDouble valueToWatch, YoRegistry registry)
{
StageableYoDouble stageableYoDouble = new StageableYoDouble(prefix, suffix, valueToWatch, registry);
stageableYoDoubles.get(robotSide).add(stageableYoDouble);

return stageableYoDouble;
}

public void setParametersForUpcomingSwing(RobotSide swingSide)
{
for (int i = 0; i < stageableYoDoubles.get(swingSide).size(); i++)
stageableYoDoubles.get(swingSide).get(i).loadFromStage();
}

public void setParametersForUpcomingSwing(RobotSide swingSide, double swingHeight, double swingDuration, double doubleSupportFraction)
{
for (int i = 0; i < stageableYoDoubles.get(swingSide).size(); i++)
stageableYoDoubles.get(swingSide).get(i).loadFromStage();

if (!Double.isNaN(swingHeight) && swingHeight >= 0.02)
this.swingHeightCurrentStep.get(swingSide).set(swingHeight);
if (!Double.isNaN(swingDuration) && MathTools.intervalContains(swingDuration, 0.2, 1.0))
this.swingDurationCurrentStep.get(swingSide).set(swingDuration);
if (!Double.isNaN(doubleSupportFraction) && MathTools.intervalContains(doubleSupportFraction, 0.0, 0.5))
this.doubleSupportFractionCurrentStep.get(swingSide).set(doubleSupportFraction);
}

public YoDouble getSwingDuration(RobotSide robotSide)
{
return swingDurationCurrentStep.get(robotSide);
}

public YoDouble getDoubleSupportFraction(RobotSide robotSide)
{
return doubleSupportFractionCurrentStep.get(robotSide);
}

public YoDouble getStanceWidth(RobotSide robotSide)
{
return stanceWidthCurrentStep.get(robotSide);
}

public YoDouble getSwingHeight(RobotSide robotSide)
{
return swingHeightCurrentStep.get(robotSide);
}

public YoDouble getDesiredCoMHeight(RobotSide robotSide)
{
return comHeightCurrentStep.get(robotSide);
}

public YoDouble getPole(RobotSide robotSide)
{
return poleCurrentStep.get(robotSide);
}

public YoDouble getMaxAccelerationPerStepCurrentStep(RobotSide robotSide)
{
return maxAccelerationPerStepCurrentStep.get(robotSide);
}

public YoDouble getMaxDecelerationPerStepCurrentStep(RobotSide robotSide)
{
return maxDecelerationPerStepCurrentStep.get(robotSide);
}

public YoDouble getOmega(RobotSide robotSide)
{
return omegaCurrentStep.get(robotSide);
}

private static class StageableYoDouble extends YoDouble
{
private double stagedValue;
private final YoDouble valueToWatch;

public StageableYoDouble(String prefix, String suffix, YoDouble valueToWatch, YoRegistry registry)
{
super(prefix + suffix, registry);
this.valueToWatch = valueToWatch;
stagedValue = valueToWatch.getDoubleValue();
loadFromStage();
valueToWatch.addListener((v) -> stageValue());
}

private void stageValue()
{
if (stagedValue != valueToWatch.getDoubleValue())
stagedValue = valueToWatch.getDoubleValue();
}

public void loadFromStage()
{
if (getDoubleValue() != stagedValue)
set(stagedValue);
}
}
}
Loading
Loading