Skip to content

Commit 151a297

Browse files
committed
add subsampling of targettrajectory to work better with inverse kinematic adaptation
1 parent e244a21 commit 151a297

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

ocs2_robotic_examples/ocs2_perceptive_anymal/ocs2_switched_model_interface/include/ocs2_switched_model_interface/foot_planner/SwingTrajectoryPlanner.h

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct SwingTrajectoryPlannerSettings {
3838
scalar_t legOverExtensionPenalty = 5.0; // Weight of the leg overextension penalty
3939

4040
scalar_t referenceExtensionAfterHorizon = 1.0; // base and foot references generated for this amount of seconds after the horizon ends.
41+
scalar_t maximumReferenceSampleTime = 0.05; // if the reference trajectory has samples with longer intervals, it will be subsampled.
4142

4243
bool swingTrajectoryFromReference = false; // Flag to take the swing trajectory from the reference trajectory
4344
};
@@ -98,6 +99,8 @@ class SwingTrajectoryPlanner {
9899
void applySwingMotionScaling(SwingPhase::SwingEvent& liftOff, SwingPhase::SwingEvent& touchDown,
99100
SwingPhase::SwingProfile& swingProfile) const;
100101

102+
void subsampleReferenceTrajectory(const ocs2::TargetTrajectories& targetTrajectories, scalar_t initTime, scalar_t finalTime);
103+
101104
// Apply IK to cartesian swing motion to update joint references
102105
void adaptJointReferencesWithInverseKinematics(scalar_t finalTime);
103106

ocs2_robotic_examples/ocs2_perceptive_anymal/ocs2_switched_model_interface/src/foot_planner/SwingTrajectoryPlanner.cpp

+56-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ void SwingTrajectoryPlanner::updateSwingMotions(scalar_t initTime, scalar_t fina
4444
throw std::runtime_error("[SwingTrajectoryPlanner] terrain cannot be null. Update the terrain before planning swing motions");
4545
}
4646

47-
// Need a copy to provide joint references later (possibly adapted with inverse kinematics)
48-
targetTrajectories_ = targetTrajectories;
47+
// Need a copy to
48+
// 1. possibly overwrite joint references later (adapted with inverse kinematics)
49+
// 2. ensure a maximum interval between references points.
50+
// 3. unsure we have samples at start and end of the MPC horizon.
51+
subsampleReferenceTrajectory(targetTrajectories, initTime, finalTime);
4952

5053
const feet_array_t<std::vector<ContactTiming>> contactTimingsPerLeg = extractContactTimingsPerLeg(modeSchedule);
5154

@@ -429,6 +432,56 @@ std::vector<ConvexTerrain> SwingTrajectoryPlanner::selectNominalFootholdTerrain(
429432
return nominalFootholdTerrain;
430433
}
431434

435+
void SwingTrajectoryPlanner::subsampleReferenceTrajectory(const ocs2::TargetTrajectories& targetTrajectories, scalar_t initTime,
436+
scalar_t finalTime) {
437+
if (targetTrajectories.empty()) {
438+
throw std::runtime_error("[SwingTrajectoryPlanner] provided target trajectory cannot be empty.");
439+
}
440+
441+
targetTrajectories_.clear();
442+
443+
// Add first reference
444+
{
445+
const auto initInterpIndex = ocs2::LinearInterpolation::timeSegment(initTime, targetTrajectories.timeTrajectory);
446+
targetTrajectories_.timeTrajectory.push_back(initTime);
447+
targetTrajectories_.stateTrajectory.push_back(
448+
ocs2::LinearInterpolation::interpolate(initInterpIndex, targetTrajectories.stateTrajectory));
449+
targetTrajectories_.inputTrajectory.push_back(
450+
ocs2::LinearInterpolation::interpolate(initInterpIndex, targetTrajectories.inputTrajectory));
451+
}
452+
453+
for (int k = 0; k < targetTrajectories.timeTrajectory.size(); ++k) {
454+
if (targetTrajectories.timeTrajectory[k] < initTime) {
455+
continue; // Drop all samples before init time
456+
} else if (targetTrajectories.timeTrajectory[k] > finalTime) {
457+
// Add final time sample. Samples after final time are also kept for touchdowns after the horizon.
458+
const auto finalInterpIndex = ocs2::LinearInterpolation::timeSegment(finalTime, targetTrajectories.timeTrajectory);
459+
targetTrajectories_.timeTrajectory.push_back(finalTime);
460+
targetTrajectories_.stateTrajectory.push_back(
461+
ocs2::LinearInterpolation::interpolate(finalInterpIndex, targetTrajectories.stateTrajectory));
462+
targetTrajectories_.inputTrajectory.push_back(
463+
ocs2::LinearInterpolation::interpolate(finalInterpIndex, targetTrajectories.inputTrajectory));
464+
}
465+
466+
// Check if we need to add extra intermediate samples
467+
while (targetTrajectories_.timeTrajectory.back() + settings_.maximumReferenceSampleTime < targetTrajectories.timeTrajectory[k]) {
468+
const scalar_t t = targetTrajectories_.timeTrajectory.back() + settings_.maximumReferenceSampleTime;
469+
const auto interpIndex = ocs2::LinearInterpolation::timeSegment(t, targetTrajectories.timeTrajectory);
470+
471+
targetTrajectories_.timeTrajectory.push_back(t);
472+
targetTrajectories_.stateTrajectory.push_back(
473+
ocs2::LinearInterpolation::interpolate(interpIndex, targetTrajectories.stateTrajectory));
474+
targetTrajectories_.inputTrajectory.push_back(
475+
ocs2::LinearInterpolation::interpolate(interpIndex, targetTrajectories.inputTrajectory));
476+
}
477+
478+
// Add the original reference sample
479+
targetTrajectories_.timeTrajectory.push_back(targetTrajectories.timeTrajectory[k]);
480+
targetTrajectories_.stateTrajectory.push_back(targetTrajectories.stateTrajectory[k]);
481+
targetTrajectories_.inputTrajectory.push_back(targetTrajectories.inputTrajectory[k]);
482+
}
483+
}
484+
432485
void SwingTrajectoryPlanner::adaptJointReferencesWithInverseKinematics(scalar_t finalTime) {
433486
const scalar_t damping = 0.01; // Quite some damping on the IK to get well conditions references.
434487

@@ -548,6 +601,7 @@ SwingTrajectoryPlannerSettings loadSwingTrajectorySettings(const std::string& fi
548601
ocs2::loadData::loadPtreeValue(pt, settings.nominalLegExtension, prefix + "nominalLegExtension", verbose);
549602
ocs2::loadData::loadPtreeValue(pt, settings.legOverExtensionPenalty, prefix + "legOverExtensionPenalty", verbose);
550603
ocs2::loadData::loadPtreeValue(pt, settings.referenceExtensionAfterHorizon, prefix + "referenceExtensionAfterHorizon", verbose);
604+
ocs2::loadData::loadPtreeValue(pt, settings.maximumReferenceSampleTime, prefix + "maximumReferenceSampleTime", verbose);
551605
ocs2::loadData::loadPtreeValue(pt, settings.swingTrajectoryFromReference, prefix + "swingTrajectoryFromReference", verbose);
552606

553607
if (verbose) {

0 commit comments

Comments
 (0)