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/alip calculator modifications #714

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
716b4a4
made ALIP tools class with static methods for ALIP calculations and c…
stefanfasano Feb 14, 2025
ed7e992
Merge branch 'develop' into feature/ALIP-calculator-modifications
stefanfasano Feb 18, 2025
47619a3
added raibert heuristic controller to ALIP tools
stefanfasano Feb 18, 2025
3fc6f1a
made full footstepDataList calculated using QFP, not fully working pr…
stefanfasano Feb 19, 2025
02bc312
removed reliance on reference frames in ALIP calculator tools class
stefanfasano Feb 19, 2025
d76bf05
can walk with all csg footsteps calculated via QFP, but turning is st…
stefanfasano Feb 19, 2025
cebff3c
turning in place and turning while walking now work
stefanfasano Feb 21, 2025
f05b474
Merge branch 'develop' into feature/ALIP-calculator-modifications
stefanfasano Mar 10, 2025
77021d1
fixed broken touchdown position visualizer
stefanfasano Mar 10, 2025
94446a7
Merge branch 'develop' into feature/ALIP-calculator-modifications
stefanfasano Mar 13, 2025
cf58f13
fixed some visualization stuff, made QFP state machine more synced wi…
stefanfasano Mar 17, 2025
e72af38
made ALIPCalculatorTools not completely static. Modified calculation …
stefanfasano Mar 19, 2025
6bba954
added documentation and Gong-based footstep control to ALIPCalculator…
stefanfasano Mar 20, 2025
f170671
Merge branch 'develop' into feature/ALIP-calculator-modifications
stefanfasano Mar 20, 2025
ff45efe
Merge branch 'develop' into feature/ALIP-calculator-modifications
stefanfasano Mar 25, 2025
8fe7701
first qfp step uses regular controller (longer) transfer duration to …
stefanfasano Mar 26, 2025
feaff72
added visualizers for future state. Added some double support conside…
stefanfasano Mar 28, 2025
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 @@ -350,7 +350,7 @@ public MomentumRateCommand getMomentumRateCommand()
*/
public CenterOfPressureCommand getCenterOfPressureCommand()
{
return centerOfPressureCommand;
return centerOfPressureCommandCalculator.getCenterOfPressureCommand();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import us.ihmc.commonWalkingControlModules.capturePoint.ICPControlPolygons;
import us.ihmc.commonWalkingControlModules.capturePoint.ParameterizedICPControlGains;
import us.ihmc.commonWalkingControlModules.configurations.WalkingControllerParameters;
import us.ihmc.commons.InterpolationTools;
import us.ihmc.commons.MathTools;
import us.ihmc.euclid.referenceFrame.FramePoint2D;
import us.ihmc.euclid.referenceFrame.FrameVector2D;
import us.ihmc.euclid.referenceFrame.ReferenceFrame;
Expand Down Expand Up @@ -108,6 +110,7 @@ public class ICPController implements ICPControllerInterface
private final YoBoolean hasNotConvergedInPast = new YoBoolean(yoNamePrefix + "HasNotConvergedInPast", registry);
private final YoBoolean previousTickFailed = new YoBoolean(yoNamePrefix + "PreviousTickFailed", registry);
private final YoInteger hasNotConvergedCounts = new YoInteger(yoNamePrefix + "HasNotConvergedCounts", registry);
private final YoInteger ticksToInterpolateAlpha = new YoInteger("ticksToInterpolateAlpha", registry);

private final IntegerProvider maxNumberOfIterations = new IntegerParameter(yoNamePrefix + "MaxNumberOfIterations", registry, 100);

Expand Down Expand Up @@ -212,6 +215,8 @@ public ICPController(WalkingControllerParameters walkingControllerParameters,
parameters.createFeedbackAlphaCalculator(registry, null);
parameters.createFeedbackProjectionOperator(registry, null);

ticksToInterpolateAlpha.set(75);

if (yoGraphicsListRegistry != null)
setupVisualizers(yoGraphicsListRegistry);

Expand Down Expand Up @@ -452,14 +457,31 @@ private void extractSolutionsFromSolver(boolean converged)
integrator.update(desiredICPVelocity, currentCoMVelocity, icpError);
}

private int alphaInterpolationTicks = 0;
private void computeFeedForwardAndFeedBackAlphas()
{
if (disableCoPFeedback.getValue() || !useCoPFeedbackByDefault.getValue())
feedbackAlpha.set(1.0);
{
double maxNumberOfAlphaInterpolationTicks = MathTools.clamp(ticksToInterpolateAlpha.getIntegerValue(), 1, Integer.MAX_VALUE);
double interpolationFactor = (double) alphaInterpolationTicks / maxNumberOfAlphaInterpolationTicks;
interpolationFactor = MathTools.clamp(interpolationFactor, 0.0, 1.0);
double startValue = 0.0; //parameters.getFeedbackAlphaCalculator() != null ? parameters.getFeedbackAlphaCalculator().computeAlpha(currentICP, copConstraintHandler.getCoPConstraint()) : 0.0;
double endValue = 1.0;
double valueToUse = InterpolationTools.linearInterpolate(startValue, endValue, interpolationFactor);
feedbackAlpha.set(valueToUse);
if (alphaInterpolationTicks < ticksToInterpolateAlpha.getValue())
alphaInterpolationTicks++;
}
else if (parameters.getFeedbackAlphaCalculator() != null)
{
feedbackAlpha.set(parameters.getFeedbackAlphaCalculator().computeAlpha(currentICP, copConstraintHandler.getCoPConstraint()));
alphaInterpolationTicks = 0;
}
else
{
feedbackAlpha.set(0.0);
alphaInterpolationTicks = 0;
}

if (parameters.getFeedForwardAlphaCalculator() != null)
feedForwardAlpha.set(parameters.getFeedForwardAlphaCalculator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public class ContinuousStepGenerator implements Updatable, SCS2YoGraphicHolder
private final YoEnum<ContinuousStepGeneratorMode> currentCSGMode = new YoEnum<>("currentCSGMode", registry, ContinuousStepGeneratorMode.class);
private final YoEnum<ContinuousStepGeneratorMode> requestedCSGMode = new YoEnum<>("requestedCSGMode", registry, ContinuousStepGeneratorMode.class);
private final OptionalFactoryField<QuicksterFootstepProvider> quicksterFootstepProvider = new OptionalFactoryField<>("QuicksterFootstepProviderField");
private boolean useQFPParameters = false;

/**
* Creates a new step generator, its {@code YoVariable}s will not be attached to any registry.
Expand All @@ -186,6 +187,12 @@ public ContinuousStepGenerator(YoRegistry parentRegistry)
numberOfTicksBeforeSubmittingFootsteps.set(0);
currentFootstepDataListCommandID.set(new Random().nextLong(0, Long.MAX_VALUE / 2)); // To make this command ID unique

requestedCSGMode.addListener(change ->
{
// if (requestedCSGMode.getEnumValue().equals(ContinuousStepGeneratorMode.STANDARD))
// useQFPParameters = false;
});

currentCSGMode.addListener(change ->
{
if (currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.QFP)
Expand Down Expand Up @@ -287,12 +294,33 @@ else if (statusToProcess == FootstepStatus.COMPLETED)
previousFootstepPose.set(previousFootstep.getLocation(), previousFootstep.getOrientation());
}

if (quicksterFootstepProvider.hasValue())
{
if (currentCSGMode.getEnumValue().equals(ContinuousStepGeneratorMode.QFP))
swingSide = quicksterFootstepProvider.get().getCurrentSwingSide();

if (useQFPParameters)
quicksterFootstepProvider.get().setUseAlternateTransferDuration(false);
else
{
quicksterFootstepProvider.get().setUseAlternateTransferDuration(true);
quicksterFootstepProvider.get().setAlternateTransferDuration(parameters.getTransferDuration());
}

// If in standard mode, keep initializing QFP so its control frame matches pelvis yaw
if (currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.STANDARD)
quicksterFootstepProvider.get().initialize();

// Continuously update QFP for data visualization purposes
quicksterFootstepProvider.get().update(parameters.getNumberOfFootstepsToPlan());
}

// Set footstep parameters
if (currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.QFP && quicksterFootstepProvider.hasValue())
{
footstepDataListMessage.setDefaultSwingDuration(quicksterFootstepProvider.get().getSwingDuration(swingSide));
footstepDataListMessage.setDefaultTransferDuration(quicksterFootstepProvider.get().getTransferDuration(swingSide));
footstepDataListMessage.setFinalTransferDuration(quicksterFootstepProvider.get().getTransferDuration(swingSide));
footstepDataListMessage.setDefaultSwingDuration(quicksterFootstepProvider.get().getSwingDuration(swingSide));
footstepDataListMessage.setAreFootstepsAdjustable(false);
footstepDataListMessage.setOffsetFootstepsWithExecutionError(false);
}
Expand Down Expand Up @@ -335,42 +363,16 @@ else if (statusToProcess == FootstepStatus.COMPLETED)
this.desiredTurningVelocity.set(turningVelocity);

int startingIndexToAdjust = footsteps.size();

// Continuously update QFP for data visualization purposes
if (quicksterFootstepProvider.hasValue())
{
// If in standard mode, keep initializing QFP so its control frame matches pelvis yaw
if (currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.STANDARD)
quicksterFootstepProvider.get().initialize();

quicksterFootstepProvider.get().update(time);
}
int perFootIndex = 0;

for (int i = startingIndexToAdjust; i < parameters.getNumberOfFootstepsToPlan(); i++)
{
if (currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.QFP && quicksterFootstepProvider.hasValue())
{
// FIXME we want all steps in plan to be QFP eventually
if (i == startingIndexToAdjust)
{
quicksterFootstepProvider.get().getDesiredTouchdownPose(swingSide, nextFootstepPose2D);
}
else
{
calculateNextFootstepPose2D(stepTime.getValue(),
desiredVelocityX,
desiredVelocityY,
desiredTurningVelocity.getDoubleValue(),
swingSide,
maxStepLength,
maxStepWidth,
defaultStepWidth,
minStepWidth,
turnMaxAngleInward,
turnMaxAngleOutward,
footstepPose2D,
nextFootstepPose2D);
}
if (i != 0 && i % 2 == 0)
perFootIndex++;

quicksterFootstepProvider.get().getDesiredTouchdownPose(perFootIndex, swingSide, nextFootstepPose2D);
}
else
{
Expand Down Expand Up @@ -407,7 +409,7 @@ else if (statusToProcess == FootstepStatus.COMPLETED)

if (swingHeightInputProvider == null && currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.STANDARD)
footstep.setSwingHeight(parameters.getSwingHeight());
else if (swingHeightInputProvider == null && currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.QFP)
else if (swingHeightInputProvider == null && currentCSGMode.getEnumValue() == ContinuousStepGeneratorMode.QFP && quicksterFootstepProvider.hasValue())
footstep.setSwingHeight(quicksterFootstepProvider.get().getSwingHeight(swingSide));
else
footstep.setSwingHeight(swingHeightInputProvider.getValue());
Expand Down Expand Up @@ -438,30 +440,30 @@ else if (swingHeightInputProvider == null && currentCSGMode.getEnumValue() == Co
}

// run through and make sure these adjusted steps are valid.
for (int i = startingIndexToAdjust; i < footstepDataListMessage.getFootstepDataList().size(); i++)
{
FootstepDataMessage footstepData = footstepDataListMessage.getFootstepDataList().get(i);
nextFootstepPose2D.getPosition().set(footstepData.getLocation());
nextFootstepPose2D.getOrientation().set(footstepData.getOrientation());
nextFootstepPose3D.getPosition().set(footstepData.getLocation());
nextFootstepPose3D.getOrientation().set(footstepData.getOrientation());
swingSide = RobotSide.fromByte(footstepData.getRobotSide());

if (!isStepValid(nextFootstepPose3D, previousFootstepPose, swingSide))
{
alternateStepChooser.computeStep(footstepPose2D, nextFootstepPose2D, swingSide, footstepData);

// remove all the other steps after the invalid one.
while (footstepDataListMessage.getFootstepDataList().size() > i + 1)
{
footstepDataListMessage.getFootstepDataList().remove(i + 1);
}
}

previousFootstepPose.getPosition().set(footstepData.getLocation());
previousFootstepPose.getOrientation().set(footstepData.getOrientation());
footstepPose2D.set(previousFootstepPose);
}
// for (int i = startingIndexToAdjust; i < footstepDataListMessage.getFootstepDataList().size(); i++)
// {
// FootstepDataMessage footstepData = footstepDataListMessage.getFootstepDataList().get(i);
// nextFootstepPose2D.getPosition().set(footstepData.getLocation());
// nextFootstepPose2D.getOrientation().set(footstepData.getOrientation());
// nextFootstepPose3D.getPosition().set(footstepData.getLocation());
// nextFootstepPose3D.getOrientation().set(footstepData.getOrientation());
// swingSide = RobotSide.fromByte(footstepData.getRobotSide());
//
// if (!isStepValid(nextFootstepPose3D, previousFootstepPose, swingSide))
// {
// alternateStepChooser.computeStep(footstepPose2D, nextFootstepPose2D, swingSide, footstepData);
//
// // remove all the other steps after the invalid one.
// while (footstepDataListMessage.getFootstepDataList().size() > i + 1)
// {
// footstepDataListMessage.getFootstepDataList().remove(i + 1);
// }
// }
//
// previousFootstepPose.getPosition().set(footstepData.getLocation());
// previousFootstepPose.getOrientation().set(footstepData.getOrientation());
// footstepPose2D.set(previousFootstepPose);
// }

// Update the visualizers
for (int i = startingIndexToAdjust; i < footstepDataListMessage.getFootstepDataList().size(); i++)
Expand Down Expand Up @@ -689,6 +691,8 @@ public void notifyFootstepStarted(RobotSide robotSide)
{
latestStatusReceived.setValue(FootstepStatus.STARTED);
currentSupportSide.set(robotSide.getOppositeSide());

useQFPParameters = currentCSGMode.getEnumValue().equals(ContinuousStepGeneratorMode.QFP);
}

/**
Expand Down
Loading
Loading