GaitedFootstepMC.cc
Go to the documentation of this file.00001 #include "Shared/RobotInfo.h"
00002 #if defined(TGT_HAS_LEGS) && !defined(TGT_IS_AIBO) && (!defined(__GNUC__) || __GNUC__>=4)
00003
00004 #include "GaitedFootstepMC.h"
00005
00006 using namespace std;
00007
00008 KinematicJoint* GaitedFootstepMC::kine=NULL;
00009 KinematicJoint* GaitedFootstepMC::childMap[NumReferenceFrames];
00010
00011 int GaitedFootstepMC::updateOutputs() {
00012 if(curStep+1 >= steps.size()) {
00013 newStep=false;
00014 return 0;
00015 }
00016
00017 double t = (get_time() / 1000.0) - stepStartTime;
00018 if(t > stepDuration) {
00019 t += stepStartTime;
00020 if(!advanceStep()) {
00021
00022 for(unsigned int i=0; i<NumLegs; ++i) {
00023 if(!xp.legParams[i].usable)
00024 continue;
00025 fmat::Column<3> tgt;
00026 (fmat::SubVector<2>)tgt = steps[curStep].footPos[i];
00027 xp.projectToGround(ground, xp.groundPlane[3], gravity, tgt);
00028 solveIK(i,tgt);
00029 if(DriverMessaging::hasListener(DriverMessaging::FixedPoints::NAME)) {
00030 contactMsg.clear();
00031 contactMsg.flushOnMotionUpdate=true;
00032 postMessage(contactMsg);
00033 }
00034 newStep=false;
00035 return NumLegs * NumLegJoints;
00036 }
00037 }
00038 t -= stepStartTime;
00039 }
00040
00041 fmat::Column<2> p = curBodyOffset(t);
00042 for(unsigned int i=0; i<NumLegs; ++i) {
00043 if(!xp.legParams[i].usable)
00044 continue;
00045
00046 fmat::Column<3> tgt;
00047 if(support[i]) {
00048
00049 (fmat::SubVector<2>)tgt = steps[curStep].footPos[i] - steps[curStep].pos - p;
00050 xp.projectToGround(ground, xp.groundPlane[3], gravity, tgt);
00051
00052 } else {
00053
00054 double raiseDur = xp.legParams[i].raiseDuration / 1000.0;
00055 double flightDur = xp.legParams[i].flightDuration / 1000.0;
00056 double lowerDur = xp.legParams[i].lowerDuration / 1000.0;
00057
00058 if(t < raiseDur) {
00059
00060 fmat::fmatReal s = static_cast<fmat::fmatReal>(t / raiseDur);
00061 (fmat::SubVector<2>)tgt = steps[curStep].footPos[i] - steps[curStep].pos - p;
00062 xp.projectToGround(ground, xp.groundPlane[3], gravity, tgt);
00063 tgt[2] += xp.legParams[i].flightHeight * s;
00064
00065 } else if(t < raiseDur + flightDur) {
00066
00067 fmat::fmatReal s = static_cast<fmat::fmatReal>( (t - raiseDur) / flightDur );
00068 fmat::Column<2> d = steps[curStep+1].footPos[i] - steps[curStep].footPos[i];
00069 (fmat::SubVector<2>)tgt = steps[curStep].footPos[i] - steps[curStep].pos - p + d*s;
00070 tgt[2] = xp.legParams[i].flightHeight;
00071
00072 } else if(t < raiseDur + flightDur + lowerDur) {
00073
00074 fmat::fmatReal s = static_cast<fmat::fmatReal>( (t - raiseDur - flightDur) / lowerDur );
00075 (fmat::SubVector<2>)tgt = steps[curStep+1].footPos[i] - steps[curStep].pos - p;
00076 xp.projectToGround(ground, xp.groundPlane[3], gravity, tgt);
00077 tgt[2] += xp.legParams[i].flightHeight * (1-s);
00078
00079 } else {
00080
00081 (fmat::SubVector<2>)tgt = steps[curStep+1].footPos[i] - steps[curStep].pos - p;
00082 xp.projectToGround(ground, xp.groundPlane[3], gravity, tgt);
00083 }
00084 }
00085 solveIK(i,tgt);
00086 }
00087
00088 if(newStep) {
00089
00090 if(DriverMessaging::hasListener(DriverMessaging::FixedPoints::NAME)) {
00091 contactMsg.clear();
00092 for(unsigned int leg=0; leg<NumLegs; ++leg) {
00093 if(support[leg] && xp.legParams[leg].usable)
00094 contactMsg.addEntry(FootFrameOffset+leg, fmat::Column<3>());
00095 }
00096 contactMsg.flushOnMotionUpdate=true;
00097 postMessage(contactMsg);
00098 }
00099 }
00100
00101 newStep=false;
00102 return NumLegs * NumLegJoints;
00103 }
00104
00105
00106 fmat::Column<2> GaitedFootstepMC::curBodyOffset(double t) {
00107 fmat::Column<2> d = steps[curStep+1].pos - steps[curStep].pos;
00108 fmat::fmatReal s = static_cast<fmat::fmatReal>(t / stepDuration);
00109 return d * s;
00110 }
00111
00112
00113 bool GaitedFootstepMC::advanceStep() {
00114 newStep=true;
00115 ++curStep;
00116 stepStartTime+=stepDuration;
00117 if(curStep+1 >= steps.size())
00118 return false;
00119
00120
00121
00122 for(unsigned int i=0; i<NumLegs; ++i) {
00123 support[i] = (steps[curStep].footPos[i] == steps[curStep+1].footPos[i]);
00124
00125 }
00126
00127
00128 fmat::Column<2> d = steps[curStep+1].pos - steps[curStep].pos;
00129 fmat::fmatReal dist = d.norm();
00130 fmat::fmatReal speed = fmat::dotProduct( xySpeed, d ) / dist;
00131 stepDuration = dist / speed;
00132
00133
00134 for(unsigned int i=0; i<NumLegs; ++i) {
00135 double legDuration = xp.legParams[i].totalDuration() / 1000.0;
00136 if(legDuration > stepDuration)
00137 stepDuration = legDuration;
00138 }
00139
00140 return true;
00141 }
00142
00143 void GaitedFootstepMC::solveIK(unsigned int leg, const IKSolver::Point& tgt) {
00144 KinematicJoint * eff = childMap[FootFrameOffset+leg];
00145 eff->getIK().solve(IKSolver::Point(), *eff, tgt);
00146 for(; eff!=NULL; eff=eff->getParent()) {
00147 if(eff->outputOffset!=plist::OutputSelector::UNUSED && eff->outputOffset<NumOutputs) {
00148
00149
00150 #ifndef PLATFORM_APERIOS
00151 if(!std::isnan(eff->getQ()))
00152 #endif
00153 {
00154 motman->setOutput(this, eff->outputOffset, eff->getQ());
00155 }
00156 }
00157 }
00158 }
00159
00160
00161 #endif
00162
00163
00164
00165
00166