28 #include <mc_rbdyn/rpy_utils.h> 43 sva::PTransformd makeHorizontal(sva::PTransformd pose)
45 const Eigen::Matrix3d R = pose.rotation();
46 const Eigen::Vector3d p = pose.translation();
47 Eigen::Vector3d rpy = mc_rbdyn::rpyFromMat(R);
48 return {mc_rbdyn::rpyToMat(0., 0., rpy(2)), {p.x(), p.y(), 0.}};
55 config(
"com_height", comHeight_);
56 config(
"contacts", contacts_);
57 config(
"double_support_duration", doubleSupportDuration_);
58 config(
"final_dsp_duration", finalDSPDuration_);
59 config(
"init_dsp_duration", initDSPDuration_);
60 config(
"landing_duration", landingDuration_);
61 config(
"landing_pitch", landingPitch_);
62 config(
"single_support_duration", singleSupportDuration_);
63 config(
"swing_height", swingHeight_);
64 config(
"takeoff_duration", takeoffDuration_);
65 config(
"takeoff_pitch", takeoffPitch_);
66 config(
"torso_pitch", torsoPitch_);
75 config.add(
"com_height", comHeight_);
76 config.add(
"contacts", contacts_);
77 config.add(
"double_support_duration", doubleSupportDuration_);
78 config.add(
"final_dsp_duration", finalDSPDuration_);
79 config.add(
"init_dsp_duration", initDSPDuration_);
80 config.add(
"landing_duration", landingDuration_);
81 config.add(
"landing_pitch", landingPitch_);
82 config.add(
"single_support_duration", singleSupportDuration_);
83 config.add(
"swing_height", swingHeight_);
84 config.add(
"takeoff_duration", takeoffDuration_);
85 config.add(
"takeoff_pitch", takeoffPitch_);
88 config.add(
"torso_pitch", torsoPitch_);
98 for(
unsigned i = 0; i < contacts_.size(); i++)
100 auto & contact = contacts_[i];
102 if(contact.halfLength < 1e-4)
106 if(contact.halfWidth < 1e-4)
110 if(contact.surfaceName.length() < 1)
112 LOG_ERROR(
"Footstep plan has no surface name for contact " << i);
119 nextFootstep_ = startIndex + 1;
120 supportContact_ = contacts_[startIndex > 0 ? startIndex - 1 : 0];
121 targetContact_ = contacts_[startIndex];
127 prevContact_ = supportContact_;
128 supportContact_ = targetContact_;
129 unsigned targetFootstep = nextFootstep_++;
130 targetContact_ = (targetFootstep < contacts_.size()) ? contacts_[targetFootstep] : prevContact_;
131 nextContact_ = (nextFootstep_ < contacts_.size()) ? contacts_[nextFootstep_] : supportContact_;
136 assert(nextFootstep_ >= 1);
137 sva::PTransformd poseDrift = actualTargetPose * targetContact_.
pose.inv();
138 const Eigen::Vector3d & posDrift = poseDrift.translation();
139 sva::PTransformd xyDrift = Eigen::Vector3d{posDrift.x(), posDrift.y(), 0.};
140 for(
unsigned i = nextFootstep_ - 1; i < contacts_.size(); i++)
142 contacts_[i] = xyDrift * contacts_[i];
144 targetContact_.
pose = xyDrift * targetContact_.
pose;
150 nextContact_ = targetContact_;
151 targetContact_ = supportContact_;
152 supportContact_ = prevContact_;
154 if(nextFootstep_ >= contacts_.size())
157 prevContact_ = nextContact_;
163 sva::PTransformd X_0_c = contacts_[0].pose;
164 const std::string & surfaceName = contacts_[0].surfaceName;
165 const sva::PTransformd & X_0_fb = robot.posW();
166 sva::PTransformd X_s_0 = robot.surfacePose(surfaceName).inv();
167 sva::PTransformd X_s_fb = X_0_fb * X_s_0;
168 return X_s_fb * X_0_c;
172 const sva::PTransformd & X_0_rf,
175 sva::PTransformd X_0_mid = sva::interpolate(X_0_lf, X_0_rf, 0.5);
176 sva::PTransformd X_0_old = sva::interpolate(contacts_[0].pose, contacts_[1].pose, 0.5);
177 sva::PTransformd X_delta = makeHorizontal(X_0_old.inv() * X_0_mid);
178 for(
unsigned i = 2; i < contacts_.size(); i++)
181 const sva::PTransformd & X_0_c = contacts_[i].pose;
182 contacts_[i].pose = X_0_c * X_delta;
184 if(contacts_[0].surfaceName ==
"LeftFootCenter" && contacts_[1].surfaceName ==
"RightFootCenter")
186 contacts_[0].pose = makeHorizontal(X_0_lf);
187 contacts_[1].pose = makeHorizontal(X_0_rf);
189 else if(contacts_[0].surfaceName ==
"RightFootCenter" && contacts_[1].surfaceName ==
"LeftFootCenter")
191 contacts_[0].pose = makeHorizontal(X_0_rf);
192 contacts_[1].pose = makeHorizontal(X_0_lf);
196 LOG_ERROR(
"Invalid footstep plan: initial surfaces are \"" << contacts_[0].surfaceName <<
"\" and \"" 197 << contacts_[1].surfaceName <<
"\"");
199 sva::PTransformd X_0_rise = Eigen::Vector3d{0., 0., initHeight};
200 for(
unsigned i = 0; i < contacts_.size(); i++)
202 contacts_[i].pose = contacts_[i].pose * X_0_rise;
204 X_0_init_ = X_delta * X_0_rise;
double halfLength
Half-length of the sole in [m].
double halfWidth
Half-width of the sole in [m].
Main controller namespace.