15 _nextGait = _currentGait;
18 periodTimeNominal = 0.0;
20 switchingPhaseNominal = 0.0;
23 gaitEnabled = Eigen::Vector4i::Zero();
41 contactStateScheduled = Eigen::Vector4i::Zero();
43 Eigen::Vector4i::Zero();
44 touchdownScheduled = Eigen::Vector4i::Zero();
45 liftoffScheduled = Eigen::Vector4i::Zero();
48 posFootTouchdownWorld =
72 std::cout <<
"[GAIT] Initialize Gait Scheduler" << std::endl;
91 if (gaitData._currentGait != gaitData._nextGait) {
92 std::cout <<
"[GAIT] Transitioning gait from " << gaitData.gaitName
95 std::cout << gaitData.gaitName <<
"\n" << std::endl;
96 gaitData._currentGait = gaitData._nextGait;
100 for (
int foot = 0; foot < 4; foot++) {
101 if (gaitData.gaitEnabled(foot) == 1) {
107 dphase = gaitData.phaseScale(foot) * (dt / gaitData.periodTimeNominal);
111 gaitData.phaseVariable(foot) =
112 fmod((gaitData.phaseVariable(foot) + dphase), 1);
115 if (gaitData.phaseVariable(foot) <= gaitData.switchingPhase(foot)) {
117 gaitData.contactStateScheduled(foot) = 1;
120 gaitData.phaseStance(foot) =
121 gaitData.phaseVariable(foot) / gaitData.switchingPhase(foot);
124 gaitData.phaseSwing(foot) = 0.0;
127 gaitData.timeStanceRemaining(foot) =
128 gaitData.periodTime(foot) *
129 (gaitData.switchingPhase(foot) - gaitData.phaseVariable(foot));
132 gaitData.timeSwingRemaining(foot) = 0.0;
135 if (gaitData.contactStatePrev(foot) == 0) {
137 gaitData.touchdownScheduled(foot) = 1;
144 gaitData.touchdownScheduled(foot) = 0;
149 gaitData.contactStateScheduled(foot) = 0;
152 gaitData.phaseStance(foot) = 1.0;
155 gaitData.phaseSwing(foot) =
156 (gaitData.phaseVariable(foot) - gaitData.switchingPhase(foot)) /
157 (1.0 - gaitData.switchingPhase(foot));
160 gaitData.timeStanceRemaining(foot) = 0.0;
163 gaitData.timeSwingRemaining(foot) =
164 gaitData.periodTime(foot) * (1 - gaitData.phaseVariable(foot));
167 if (gaitData.contactStatePrev(foot) == 1) {
169 gaitData.liftoffScheduled(foot) = 1;
176 gaitData.liftoffScheduled(foot) = 0;
182 gaitData.phaseVariable(foot) = 0.0;
185 gaitData.contactStateScheduled(foot) = 0;
189 gaitData.contactStatePrev(foot) = gaitData.contactStateScheduled(foot);
211 template <
typename T>
214 switch (gaitData._nextGait) {
216 gaitData.gaitName =
"STAND";
217 gaitData.gaitEnabled << 1, 1, 1, 1;
218 gaitData.periodTimeNominal = 10.0;
219 gaitData.initialPhase = 0.0;
220 gaitData.switchingPhaseNominal = 1.0;
221 gaitData.phaseOffset << 0.5, 0.5, 0.5, 0.5;
222 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
226 gaitData.gaitName =
"STAND_CYCLE";
227 gaitData.gaitEnabled << 1, 1, 1, 1;
228 gaitData.periodTimeNominal = 1.0;
229 gaitData.initialPhase = 0.0;
230 gaitData.switchingPhaseNominal = 1.0;
231 gaitData.phaseOffset << 0.5, 0.5, 0.5, 0.5;
232 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
236 gaitData.gaitName =
"STATIC_WALK";
237 gaitData.gaitEnabled << 1, 1, 1, 1;
238 gaitData.periodTimeNominal = 1.25;
239 gaitData.initialPhase = 0.0;
240 gaitData.switchingPhaseNominal = 0.8;
241 gaitData.phaseOffset << 0.25, 0.0, 0.75, 0.5;
242 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
246 gaitData.gaitName =
"AMBLE";
247 gaitData.gaitEnabled << 1, 1, 1, 1;
248 gaitData.periodTimeNominal = 1.0;
249 gaitData.initialPhase = 0.0;
250 gaitData.switchingPhaseNominal = 0.8;
251 gaitData.phaseOffset << 0.0, 0.5, 0.25, 0.75;
252 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
256 gaitData.gaitName =
"TROT_WALK";
257 gaitData.gaitEnabled << 1, 1, 1, 1;
258 gaitData.periodTimeNominal = 0.5;
259 gaitData.initialPhase = 0.0;
260 gaitData.switchingPhaseNominal = 0.6;
261 gaitData.phaseOffset << 0.0, 0.5, 0.5, 0.0;
262 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
266 gaitData.gaitName =
"TROT";
267 gaitData.gaitEnabled << 1, 1, 1, 1;
268 gaitData.periodTimeNominal = 0.5;
269 gaitData.initialPhase = 0.0;
270 gaitData.switchingPhaseNominal = 0.5;
271 gaitData.phaseOffset << 0.0, 0.5, 0.5, 0.0;
272 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
276 gaitData.gaitName =
"TROT_RUN";
277 gaitData.gaitEnabled << 1, 1, 1, 1;
278 gaitData.periodTimeNominal = 0.5;
279 gaitData.initialPhase = 0.0;
280 gaitData.switchingPhaseNominal = 0.4;
281 gaitData.phaseOffset << 0.0, 0.5, 0.5, 0.0;
282 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
286 gaitData.gaitName =
"PACE";
287 gaitData.gaitEnabled << 1, 1, 1, 1;
288 gaitData.periodTimeNominal = 0.5;
289 gaitData.initialPhase = 0.0;
290 gaitData.switchingPhaseNominal = 0.5;
291 gaitData.phaseOffset << 0.0, 0.5, 0.0, 0.5;
292 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
296 gaitData.gaitName =
"BOUND";
297 gaitData.gaitEnabled << 1, 1, 1, 1;
298 gaitData.periodTimeNominal = 0.5;
299 gaitData.initialPhase = 0.0;
300 gaitData.switchingPhaseNominal = 0.5;
301 gaitData.phaseOffset << 0.0, 0.0, 0.5, 0.5;
302 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
306 gaitData.gaitName =
"ROTARY_GALLOP";
307 gaitData.gaitEnabled << 1, 1, 1, 1;
308 gaitData.periodTimeNominal = 0.4;
309 gaitData.initialPhase = 0.0;
310 gaitData.switchingPhaseNominal = 0.2;
311 gaitData.phaseOffset << 0.0, 0.8571, 0.3571, 0.5;
312 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
317 gaitData.gaitName =
"TRAVERSE_GALLOP";
318 gaitData.gaitEnabled << 1, 1, 1, 1;
319 gaitData.periodTimeNominal = 0.5;
320 gaitData.initialPhase = 0.0;
321 gaitData.switchingPhaseNominal = 0.2;
322 gaitData.phaseOffset << 0.0, 0.8571, 0.3571, 0.5;
323 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
327 gaitData.gaitName =
"PRONK";
328 gaitData.gaitEnabled << 1, 1, 1, 1;
329 gaitData.periodTimeNominal = 0.5;
330 gaitData.initialPhase = 0.0;
331 gaitData.switchingPhaseNominal = 0.5;
332 gaitData.phaseOffset << 0.0, 0.0, 0.0, 0.0;
333 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
337 gaitData.gaitName =
"THREE_FOOT";
338 gaitData.gaitEnabled << 0, 1, 1, 1;
339 gaitData.periodTimeNominal = 0.5;
340 gaitData.initialPhase = 0.0;
341 gaitData.switchingPhaseNominal = 0.5;
342 gaitData.phaseOffset << 0.0, 0.666, 0.0, 0.333;
343 gaitData.phaseScale << 0.0, 1.0, 1.0, 1.0;
347 gaitData.gaitName =
"CUSTOM";
352 gaitData.gaitName =
"TRANSITION_TO_STAND";
353 gaitData.gaitEnabled << 1, 1, 1, 1;
354 T oldGaitPeriodTimeNominal = gaitData.periodTimeNominal;
355 gaitData.periodTimeNominal = 3 * gaitData.periodTimeNominal;
356 gaitData.initialPhase = 0.0;
357 gaitData.switchingPhaseNominal =
358 (gaitData.periodTimeNominal +
359 oldGaitPeriodTimeNominal * (gaitData.switchingPhaseNominal - 1)) /
360 gaitData.periodTimeNominal;
361 gaitData.phaseOffset << (gaitData.periodTimeNominal +
362 oldGaitPeriodTimeNominal *
363 (gaitData.phaseVariable(0) - 1)) /
364 gaitData.periodTimeNominal,
365 (gaitData.periodTimeNominal +
366 oldGaitPeriodTimeNominal * (gaitData.phaseVariable(1) - 1)) /
367 gaitData.periodTimeNominal,
368 (gaitData.periodTimeNominal +
369 oldGaitPeriodTimeNominal * (gaitData.phaseVariable(2) - 1)) /
370 gaitData.periodTimeNominal,
371 (gaitData.periodTimeNominal +
372 oldGaitPeriodTimeNominal * (gaitData.phaseVariable(3) - 1)) /
373 gaitData.periodTimeNominal;
374 gaitData.phaseScale << 1.0, 1.0, 1.0, 1.0;
380 for (
int foot = 0; foot < 4; foot++) {
381 if (gaitData.gaitEnabled(foot) == 1) {
383 gaitData.periodTime(foot) =
384 gaitData.periodTimeNominal / gaitData.phaseScale(foot);
387 gaitData.switchingPhase(foot) = gaitData.switchingPhaseNominal;
390 gaitData.phaseVariable(foot) =
391 gaitData.initialPhase + gaitData.phaseOffset(foot);
394 gaitData.timeStance(foot) =
395 gaitData.periodTime(foot) * gaitData.switchingPhase(foot);
398 gaitData.timeSwing(foot) =
399 gaitData.periodTime(foot) * (1.0 - gaitData.switchingPhase(foot));
403 gaitData.periodTime(foot) = 0.0;
406 gaitData.switchingPhase(foot) = 0.0;
409 gaitData.phaseVariable(foot) = 0.0;
412 gaitData.timeStance(foot) = 0.0;
415 gaitData.timeSwing(foot) = 1.0 / gaitData.periodTime(foot);
423 template <
typename T>
429 if (printIter == printNum) {
430 std::cout <<
"[GAIT SCHEDULER] Printing Gait Info...\n";
431 std::cout <<
"Gait Type: " << gaitData.gaitName <<
"\n";
432 std::cout <<
"---------------------------------------------------------\n";
433 std::cout <<
"Enabled: " << gaitData.gaitEnabled(0) <<
" | " 434 << gaitData.gaitEnabled(1) <<
" | " << gaitData.gaitEnabled(2)
435 <<
" | " << gaitData.gaitEnabled(3) <<
"\n";
436 std::cout <<
"Period Time: " << gaitData.periodTime(0) <<
"s | " 437 << gaitData.periodTime(1) <<
"s | " << gaitData.periodTime(2)
438 <<
"s | " << gaitData.periodTime(3) <<
"s\n";
439 std::cout <<
"---------------------------------------------------------\n";
440 std::cout <<
"Contact State: " << gaitData.contactStateScheduled(0) <<
" | " 441 << gaitData.contactStateScheduled(1) <<
" | " 442 << gaitData.contactStateScheduled(2) <<
" | " 443 << gaitData.contactStateScheduled(3) <<
"\n";
444 std::cout <<
"Phase Variable: " << gaitData.phaseVariable(0) <<
" | " 445 << gaitData.phaseVariable(1) <<
" | " << gaitData.phaseVariable(2)
446 <<
" | " << gaitData.phaseVariable(3) <<
"\n";
447 std::cout <<
"Stance Time Remaining: " << gaitData.timeStanceRemaining(0)
448 <<
"s | " << gaitData.timeStanceRemaining(1) <<
"s | " 449 << gaitData.timeStanceRemaining(2) <<
"s | " 450 << gaitData.timeStanceRemaining(3) <<
"s\n";
451 std::cout <<
"Swing Time Remaining: " << gaitData.timeSwingRemaining(0)
452 <<
"s | " << gaitData.timeSwingRemaining(1) <<
"s | " 453 << gaitData.timeSwingRemaining(2) <<
"s | " 454 << gaitData.timeSwingRemaining(3) <<
"s\n";
455 std::cout << std::endl;
Eigen::Matrix< T, 3, 4 > Mat34
typename Eigen::Matrix< T, 4, 1 > Vec4