35 using Foot = mc_plugin::ExternalFootstepPlanner::Foot;
38 double allowedTime = ctl.externalFootstepPlanner.allowedTimeSingleSupport();
39 if(allowedTime >= duration_)
41 mc_rtc::log::error_and_throw<std::runtime_error>(
"[{}] Maximum allowed time ({:.3f}) for the external planner "
42 "cannot be greater than the single support duration ({:.3f})",
43 name(), allowedTime, duration_);
46 if(ctl.externalFootstepPlanner.planningRequested())
48 if(remTime_ > allowedTime)
51 if(ctl.supportContact().surfaceName ==
"LeftFootCenter")
53 const auto lf_start =
utils::SE2d{ctl.supportContact().pose};
54 const auto rf_start =
utils::SE2d{ctl.targetContact().pose};
55 Foot supportFoot = Foot::Right;
61 const auto rf_start =
utils::SE2d{ctl.supportContact().pose};
62 const auto lf_start =
utils::SE2d{ctl.targetContact().pose};
63 Foot supportFoot = Foot::Left;
73 auto & ctl = controller();
75 auto & supportContact = ctl.supportContact();
76 auto & targetContact = ctl.targetContact();
78 duration_ = ctl.singleSupportDuration();
79 hasUpdatedMPCOnce_ =
false;
80 remTime_ = ctl.singleSupportDuration();
82 timeSinceLastPreviewUpdate_ = 0.;
84 if(supportContact.surfaceName ==
"LeftFootCenter")
86 ctl.leftFootRatio(1.);
87 ctl.setContacts({{ContactState::Left, supportContact.pose}});
88 swingFootTask = ctl.swingFootTaskRight_;
92 ctl.leftFootRatio(0.);
93 ctl.setContacts({{ContactState::Right, supportContact.pose}});
94 swingFootTask = ctl.swingFootTaskLeft_;
96 swingFootTask->reset();
97 ctl.solver().addTask(swingFootTask);
99 swingFoot_.landingDuration(ctl.plan.landingDuration());
100 swingFoot_.landingPitch(ctl.plan.landingPitch());
101 swingFoot_.takeoffDuration(ctl.plan.takeoffDuration());
102 swingFoot_.takeoffOffset(ctl.plan.takeoffOffset());
103 swingFoot_.takeoffPitch(ctl.plan.takeoffPitch());
104 swingFoot_.reset(swingFootTask->surfacePose(), targetContact.pose, duration_, ctl.plan.swingHeight());
106 logger().addLogEntry(
"rem_phase_time", [
this]() {
return remTime_; });
107 logger().addLogEntry(
"walking_phase", []() {
return 1.; });
108 swingFoot_.addLogEntries(logger());
115 controller().solver().removeTask(swingFootTask);
117 logger().removeLogEntry(
"contact_impulse");
118 logger().removeLogEntry(
"rem_phase_time");
119 logger().removeLogEntry(
"walking_phase");
120 swingFoot_.removeLogEntries(logger());
127 output(
"DoubleSupport");
135 auto & ctl = controller();
136 double dt = ctl.timeStep;
138 if(ctl.plan.name ==
"external")
140 handleExternalPlan();
149 ctl.preview->integrate(pendulum(), dt);
150 if(hasUpdatedMPCOnce_)
152 pendulum().resetCoMHeight(ctl.plan.comHeight(), ctl.supportContact().p(), ctl.supportContact().normal());
153 pendulum().completeIPM(ctl.supportContact().p(), ctl.supportContact().normal());
157 pendulum().completeIPM(ctl.prevContact().p(), ctl.prevContact().normal());
160 stabilizer()->target(pendulum().com(), pendulum().comd(), pendulum().comdd(), pendulum().zmp());
164 timeSinceLastPreviewUpdate_ += dt;
169 auto & ctl = controller();
170 auto & targetContact = ctl.targetContact();
171 auto & supportContact = ctl.supportContact();
172 double dt = ctl.timeStep;
174 if(!stabilizer()->inDoubleSupport())
176 bool liftPhase = (remTime_ > duration_ / 3.);
177 bool touchdownDetected = detectTouchdown(swingFootTask, targetContact.pose);
178 if(liftPhase || !touchdownDetected)
180 swingFoot_.integrate(dt);
181 swingFootTask->target(swingFoot_.pose());
183 sva::PTransformd T_0_s(swingFootTask->surfacePose().rotation());
184 swingFootTask->refVelB(T_0_s * swingFoot_.vel());
185 swingFootTask->refAccel(T_0_s * swingFoot_.accel());
189 if(supportContact.surfaceName ==
"LeftFootCenter")
191 stabilizer()->setContacts(
192 {{ContactState::Left, supportContact.pose}, {ContactState::Right, targetContact.pose}});
196 stabilizer()->setContacts(
197 {{ContactState::Left, targetContact.pose}, {ContactState::Right, supportContact.pose}});
204 const sva::PTransformd & contactPose)
206 const sva::PTransformd X_0_s = footTask->surfacePose();
207 const sva::PTransformd & X_0_c = contactPose;
208 sva::PTransformd X_c_s = X_0_s * X_0_c.inv();
209 double xDist = std::abs(X_c_s.translation().x());
210 double yDist = std::abs(X_c_s.translation().y());
211 double zDist = std::abs(X_c_s.translation().z());
212 double Fz = controller().robot().surfaceWrench(footTask->surface()).force().z();
213 return (xDist < 0.01 && yDist < 0.01 && zDist < 0.01 && Fz > 50.);
218 auto & ctl = controller();
219 ctl.mpc().contacts(ctl.supportContact(), ctl.targetContact(), ctl.nextContact());
220 if(ctl.isLastSSP() || ctl.pauseWalking)
222 ctl.nextDoubleSupportDuration(ctl.plan.finalDSPDuration());
223 ctl.mpc().phaseDurations(remTime_, ctl.plan.finalDSPDuration(), 0.);
227 ctl.mpc().phaseDurations(remTime_, ctl.doubleSupportDuration(), ctl.singleSupportDuration());
229 if(ctl.updatePreview())
231 timeSinceLastPreviewUpdate_ = 0.;
232 hasUpdatedMPCOnce_ =
true;
constexpr double PREVIEW_UPDATE_PERIOD
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Controller & controller()
void handleExternalPlan()
bool checkTransitions() override
bool detectTouchdown(const std::shared_ptr< mc_tasks::SurfaceTransformTask > footTask, const sva::PTransformd &contactPose)