Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

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; // time within step
00018   if(t > stepDuration) {
00019     t += stepStartTime;
00020     if(!advanceStep()) {
00021       // reached destination, set legs to final values
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; // delay message to sync with corresponding joint angles
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       // currently in contact with ground, just track body motion
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       // need to lift leg and place at next contact point
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         // rising leg - track old contact, increase height
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         // flying leg - move to new contact
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         // lowering leg - track new contact, decrease height
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         // step completed - continue support
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     // send driver message reporting leg contacts
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; // delay message to sync with corresponding joint angles
00097       postMessage(contactMsg);
00098     }
00099   }
00100   
00101   newStep=false;
00102   return NumLegs * NumLegJoints;
00103 }
00104 
00105 /*! internal function, assumes #curStep is at most next-to-last */
00106 fmat::Column<2> GaitedFootstepMC::curBodyOffset(double t) {
00107   fmat::Column<2> d = steps[curStep+1].pos - steps[curStep].pos; // step displacement
00108   fmat::fmatReal s = static_cast<fmat::fmatReal>(t / stepDuration); // percentage of step
00109   return d * s;
00110 }
00111 
00112 /*! internal function, assumes #curStep is at most next-to-last */
00113 bool GaitedFootstepMC::advanceStep() {
00114   newStep=true;
00115   ++curStep;
00116   stepStartTime+=stepDuration;
00117   if(curStep+1 >= steps.size())
00118     return false;
00119   
00120   // which legs are in flight?
00121   //std::cout << "Step " << curStep << ": " << std::endl;
00122   for(unsigned int i=0; i<NumLegs; ++i) {
00123     support[i] = (steps[curStep].footPos[i] == steps[curStep+1].footPos[i]);
00124     //std::cout << "  leg " << i << " in support? " << support[i] << ' ' << steps[curStep].footPos[i] << ' ' << steps[curStep+1].footPos[i] << std::endl;
00125   }
00126   
00127   // calculate nominal step duration
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; // divide by dist to norm d
00131   stepDuration = dist / speed;
00132   
00133   // limit duration to flight time
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       /*if(leg==1)
00149        std::cout << eff->outputOffset.get() << " set to " << eff->getQ() << std::endl;*/
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 /*! @file
00164  * @brief Implements GaitedFootstepMC, which executes a series of footsteps, probably generated by applying astar() to a GaitedFootsteps domain
00165  * @author Ethan Tira-Thompson (ejt) (Creator)
00166  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:40 2016 by Doxygen 1.6.3