Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Modules/WalkingEngine/InvKinWalkingEngine.cpp

Go to the documentation of this file.
00001 /**
00002 * @file InvKinWalkingEngine.cpp
00003 * 
00004 * Implementation of class InvKinWalkingEngine
00005 *
00006 * @author Max Risler
00007 */
00008 
00009 #include "InvKinWalkingEngine.h"
00010 #include "Tools/Player.h"
00011 #include "Tools/RobotConfiguration.h"
00012 #include "Tools/Streams/InStreams.h"
00013 #include "Tools/Actorics/RobotDimensions.h"
00014 #include "Platform/SystemCall.h"
00015 #include <string.h>
00016 
00017 InvKinWalkingEngine::InvKinWalkingEngine(const WalkingEngineInterfaces& interfaces)
00018 : WalkingEngine(interfaces),
00019 requestedParameters(0),paramInterpolCount(0),
00020 paramInterpolLength(0), positionInWalkCycle(0),
00021 lastParametersFromPackageTimeStamp(0)
00022 {
00023   for (int i=0;i<4;i++) {
00024     legSpeedX[i]=0;legSpeedY[i]=0;
00025     footOnGround[i]=true;
00026   }
00027   currentRequest = Pose2D(0,0,0);
00028 }
00029 
00030 InvKinWalkingEngine::~InvKinWalkingEngine()
00031 {
00032 }
00033 
00034 void InvKinWalkingEngine::setParameters(InvKinWalkingParameters* p, int changeSteps)
00035 {
00036   if (requestedParameters != p)
00037   {
00038     nextParameters = *p;
00039     if (requestedParameters == NULL)
00040     {
00041       positionInWalkCycle = (double)currentParameters.firstStep/(double) currentParameters.stepLen;
00042       initParametersInterpolation(0);
00043     }
00044     else
00045     {
00046       initParametersInterpolation(changeSteps);
00047     }
00048     requestedParameters = p;
00049   }
00050 }
00051 
00052 bool InvKinWalkingEngine::executeParameterized(JointData& jointData,
00053                                                const WalkRequest& walkRequest,
00054                                                double requestedPositionInWalkCycle)
00055 {
00056   //somebody put new invKinWalkingParameters into packageCognitionMotion, so lets use it:
00057   //(cloned from UDWalkingEngine.cpp)
00058   if (walkParameterTimeStamp>lastParametersFromPackageTimeStamp)
00059   {
00060     nextParameters.copyValuesFrom(invKinWalkingParameters);
00061     lastParametersFromPackageTimeStamp = walkParameterTimeStamp;
00062     initParametersInterpolation(32);
00063   }
00064   
00065   Pose2D request = walkRequest.walkParams;
00066   bool standingStill = false;
00067   
00068   // reset current request if entered from other motion module
00069   if (lastMotionType != MotionRequest::walk)
00070   {
00071     currentRequest = Pose2D(0,0,0);
00072     positionInWalkCycle = (double)currentParameters.firstStep/(double)currentParameters.stepLen;
00073   }
00074   else
00075   {
00076     positionInWalkCycle = requestedPositionInWalkCycle;
00077   }
00078   
00079   // calculate new speeds and current request
00080   if (request != currentRequest ||
00081     lastMotionType != MotionRequest::walk)
00082   {
00083     // prevent stumbling on quick motion request changes 
00084     smoothMotionRequest(request, currentRequest);
00085     calculateLegSpeeds();
00086   }
00087   
00088   // stand still if request is zero
00089   if (currentRequest.translation.x == 0 &&
00090     currentRequest.translation.y == 0 &&
00091     currentRequest.rotation == 0)
00092     standingStill = true;
00093   
00094   nextParametersInterpolation(!standingStill || !currentParameters.allFeetOnGround((int)positionInWalkCycle * currentParameters.stepLen));
00095   
00096   odometryData.conc(odometry);
00097   
00098   motionInfo.neckHeight = currentParameters.neckHeight;
00099   
00100   motionInfo.bodyTilt = currentParameters.bodyTilt + 
00101 #ifndef _WIN32
00102     currentParameters.bodyTiltOffset + 
00103 #endif
00104     getRobotConfiguration().getRobotCalibration().bodyTiltOffset;
00105   
00106   motionInfo.motionIsStable = true;
00107   motionInfo.executedMotionRequest.motionType = MotionRequest::walk;
00108   motionInfo.executedMotionRequest.walkRequest.walkType = walkRequest.walkType;
00109   motionInfo.executedMotionRequest.walkRequest.walkParams = currentRequest;
00110   motionInfo.positionInWalkCycle = positionInWalkCycle;
00111   
00112   calculateData(jointData);
00113   
00114   return (!currentParameters.leaveAnytime && !currentParameters.allFeetOnGround((int)positionInWalkCycle * currentParameters.stepLen));
00115 }
00116 
00117 void InvKinWalkingEngine::calculateLegSpeeds() 
00118 {
00119   double stepSizeX;
00120   double stepSizeY;
00121   double stepSizeR;
00122 
00123   odometry = currentRequest;
00124 
00125   // convert to internal leg speeds by multiplicating
00126   // with odometry correction values 
00127   if (currentRequest.translation.x > 0)
00128     stepSizeX = currentRequest.translation.x * currentParameters.correctionValues.forward;
00129   else
00130     stepSizeX = currentRequest.translation.x * currentParameters.correctionValues.backward;
00131   stepSizeY = currentRequest.translation.y * currentParameters.correctionValues.sideward;
00132   stepSizeR = currentRequest.rotation * currentParameters.correctionValues.turning;
00133 
00134   limitToMaxSpeed(stepSizeX,stepSizeY,stepSizeR);
00135 
00136   // correction for incorrect rotation center
00137   odometry.translation.y -= odometry.rotation * currentParameters.correctionValues.rotationCenter;
00138 
00139   // convert odometry from mm/s to mm/tick
00140   odometry.translation *= motionCycleTime;
00141   // convert odometry rad/s to rad/tick
00142   odometry.rotation *= motionCycleTime;
00143 
00144    // counterrotation to prevent unwanted rotation while walking sideways
00145   stepSizeR += stepSizeY * currentParameters.counterRotation;
00146 
00147   //linear movement
00148   legSpeedX[Kinematics::fl]=legSpeedX[Kinematics::fr]=legSpeedX[Kinematics::hl]=legSpeedX[Kinematics::hr]=
00149     stepSizeX;
00150   legSpeedY[Kinematics::fl]=legSpeedY[Kinematics::fr]=legSpeedY[Kinematics::hl]=legSpeedY[Kinematics::hr]=
00151     stepSizeY;
00152 
00153   //speed difference between fore and hind legs
00154   legSpeedX[Kinematics::fl]*=currentParameters.legSpeedFactorX;
00155   legSpeedX[Kinematics::fr]*=currentParameters.legSpeedFactorX;
00156 
00157   legSpeedY[Kinematics::fl]*=currentParameters.legSpeedFactorY;
00158   legSpeedY[Kinematics::fr]*=currentParameters.legSpeedFactorY;
00159 
00160   //turn movement
00161   legSpeedX[Kinematics::fl]-=stepSizeR*currentParameters.legSpeedFactorR;
00162   legSpeedX[Kinematics::fr]+=stepSizeR*currentParameters.legSpeedFactorR;
00163 
00164   legSpeedX[Kinematics::hl]-=stepSizeR;
00165   legSpeedX[Kinematics::hr]+=stepSizeR;
00166   
00167   legSpeedY[Kinematics::fl]+=stepSizeR*currentParameters.legSpeedFactorR;
00168   legSpeedY[Kinematics::fr]+=stepSizeR*currentParameters.legSpeedFactorR;
00169 
00170   legSpeedY[Kinematics::hr]-=stepSizeR;
00171   legSpeedY[Kinematics::hl]-=stepSizeR;
00172 }
00173 
00174 void InvKinWalkingEngine::smoothMotionRequest(const Pose2D& request, Pose2D& currentRequest)
00175 {
00176   if (request.translation.x - currentRequest.translation.x > currentParameters.maxSpeedXChange) 
00177     currentRequest.translation.x += currentParameters.maxSpeedXChange;
00178   else if (request.translation.x - currentRequest.translation.x < -currentParameters.maxSpeedXChange)
00179     currentRequest.translation.x -= currentParameters.maxSpeedXChange;
00180   else
00181     currentRequest.translation.x = request.translation.x;
00182 
00183   if (request.translation.y - currentRequest.translation.y > currentParameters.maxSpeedYChange) 
00184     currentRequest.translation.y += currentParameters.maxSpeedYChange;
00185   else if (request.translation.y - currentRequest.translation.y < -currentParameters.maxSpeedYChange)
00186     currentRequest.translation.y -= currentParameters.maxSpeedYChange;
00187   else
00188     currentRequest.translation.y = request.translation.y;
00189 
00190   if (request.getAngle() - currentRequest.getAngle() > currentParameters.maxRotationChange)
00191     currentRequest.rotation += currentParameters.maxRotationChange;
00192   else if (request.getAngle() - currentRequest.getAngle() < -currentParameters.maxRotationChange)
00193     currentRequest.rotation -= currentParameters.maxRotationChange;
00194   else
00195     currentRequest.rotation = request.rotation;
00196 }
00197 
00198 void InvKinWalkingEngine::limitToMaxSpeed(double& stepSizeX, double& stepSizeY, double& stepSizeR)
00199 {
00200   if (stepSizeR > currentParameters.maxStepSizeR) {
00201     stepSizeR = currentParameters.maxStepSizeR;
00202     odometry.rotation = currentParameters.maxStepSizeR / currentParameters.correctionValues.turning;
00203   } else if (stepSizeR < -currentParameters.maxStepSizeR) {
00204     stepSizeR = -currentParameters.maxStepSizeR;
00205     odometry.rotation = -currentParameters.maxStepSizeR / currentParameters.correctionValues.turning;
00206   }
00207 
00208   // Hier wird der Vektor (stepSizeX,stepSizeY) so innerhalb der Ellipse aus (maxStepSizeX,maxStepSizeY)
00209   // geklippt, dass danach jeder der Vektoren für die einzelnen Beine (stepSizeX+-stepSizeR,stepSizeY+-stepSizeR)
00210   // noch innerhalb der Ellipse liegt. Die Richtung von (stepSizeX,stepSizeY) wird dabei nicht verändert.
00211   // Wer dies ändern will möge das mit mir absprechen.
00212   // Das geht evtl auch einfacher aber die Funktionalität soll erhalten bleiben. MR
00213 
00214   double testX = stepSizeX;
00215   double testY = stepSizeY;
00216   double r = fabs(stepSizeR);
00217 
00218   // generate point for greatest step size including rotation
00219   if (testX>0) testX += r; else testX -= r;
00220   if (testY>0) testY += r; else testY -= r;
00221 
00222   // test if maxStepSize exceeded = check if (testX,testY) is inside ellipse described by maxStepSizeX,maxStepSizeY
00223   if ((testX*testX/(currentParameters.maxStepSizeX*currentParameters.maxStepSizeX) +
00224        testY*testY/(currentParameters.maxStepSizeY*currentParameters.maxStepSizeY)) > 1.0)
00225   {
00226     // step size outside of ellipse described by maxStepSizeX,maxStepSizeY
00227     // calculate point on ellipse with direction of testX,testY
00228     if (testX != 0)
00229     {
00230       double m = testY / testX;
00231       stepSizeX = 
00232         ((testX>0)?1.0:-1.0) *
00233         currentParameters.maxStepSizeX*currentParameters.maxStepSizeY / 
00234         sqrt(currentParameters.maxStepSizeY*currentParameters.maxStepSizeY + 
00235                      currentParameters.maxStepSizeX*currentParameters.maxStepSizeX*m*m);
00236       stepSizeY = m*stepSizeX;
00237     } else {
00238       stepSizeX = 0;
00239       stepSizeY = ((testY>0)?1.0:-1.0) * currentParameters.maxStepSizeY;
00240     }
00241     // subtract rotation
00242     if (stepSizeX>0) stepSizeX -= r; else stepSizeX += r;
00243     if (stepSizeY>0) stepSizeY -= r; else stepSizeY += r;
00244     
00245     if (stepSizeX > 0)
00246       odometry.translation.x = stepSizeX / currentParameters.correctionValues.forward;
00247     else
00248       odometry.translation.x = stepSizeX / currentParameters.correctionValues.backward;
00249     odometry.translation.y = stepSizeY / currentParameters.correctionValues.sideward;
00250   }
00251 }
00252 
00253 
00254 void InvKinWalkingEngine::calculateData(JointData &j) 
00255 {
00256   double j1,j2,j3;
00257 
00258   calculateFootPositions();
00259 
00260   //head, mouth
00261   j.data[JointData::neckTilt] = currentParameters.headTilt;
00262   j.data[JointData::headPan] = currentParameters.headPan;
00263   j.data[JointData::headTilt] = currentParameters.headRoll;
00264   j.data[JointData::mouth] = currentParameters.mouth;
00265 
00266   //ears, tail
00267   j.data[JointData::earL] = j.data[JointData::earR] =
00268     j.data[JointData::tailTilt] = j.data[JointData::tailPan] =
00269       jointDataInvalidValue;
00270 
00271   //legs
00272   
00273   for (int leg=0;leg<4;leg++)
00274   {
00275     if (Kinematics::jointsFromLegPosition((Kinematics::LegIndex)leg,x[leg],y[leg],z[leg],j1,j2,j3,currentParameters.bodyTilt))
00276     {
00277       j.data[JointData::legFR1+leg*3] = toMicroRad(j1);
00278       j.data[JointData::legFR2+leg*3] = toMicroRad(j2);
00279       j.data[JointData::legFR3+leg*3] = toMicroRad(j3);
00280     }
00281     else
00282     {
00283       j.data[JointData::tailTilt] = -300000;
00284     }
00285   }
00286 }
00287 
00288 double InvKinWalkingEngine::getLegPositionCurve(double& rz,double index)
00289 {
00290   const double xtab[22]={1.0, 1.05, 1.1,  1.155, 1.19, 1.185, 1.165, 1.125, 1.07, 1.01, 0.94, 0.86, 0.77, 0.683, 0.59, 0.5,  0.4,  0.3,   0.2, 0.1, 0.0, 0.0};
00291   const double ztab[22]={0.0, 0.03, 0.095, 0.18, 0.27, 0.37,  0.47,  0.565, 0.65, 0.74, 0.8,  0.85, 0.9,  0.935, 0.96, 0.98, 0.99, 0.995, 1.0, 1.0, 1.0, 1.0};
00292   double ind=4*20*index;
00293   if (ind>20) ind=20;
00294   if (ind<0) ind=0;
00295   int left=(int)ind;
00296   int right=left+1;
00297   double weightRight=ind-left;
00298   double weightLeft=1.0-weightRight;
00299   rz=weightLeft*ztab[left]+weightRight*ztab[right];
00300   return weightLeft*xtab[left]+weightRight*xtab[right];
00301 }
00302 
00303 void InvKinWalkingEngine::calculateRelativeFootPosition(int step, int leg, double &rx, double &ry, double &rz)
00304 {
00305   //calculate relative position in rectangle
00306   //rx = -1..1, rz = 0..1
00307   switch(currentParameters.footMode)
00308   {
00309   case InvKinWalkingParameters::rectangle:
00310     if (step<currentParameters.stepLift[FORELEG(leg)?0:1]) {
00311       //foot is on ground
00312       rx=2.0*step/currentParameters.groundTime[FORELEG(leg)?0:1]-1.0;
00313       rz=0;
00314     } else if (step<currentParameters.stepAir[FORELEG(leg)?0:1]) {
00315       //raising foot
00316       rx=1.0;
00317       if (currentParameters.liftTime[FORELEG(leg)?0:1] == 0)
00318         rz=0;
00319       else
00320         rz=((double)(step-currentParameters.stepLift[FORELEG(leg)?0:1]))/currentParameters.liftTime[FORELEG(leg)?0:1];
00321     } else if (step<currentParameters.stepLower[FORELEG(leg)?0:1]) {
00322       //foot in air;
00323       if (currentParameters.airTime[FORELEG(leg)?0:1] == 0)
00324         rx=0;
00325       else
00326         rx=-2.0*(step-currentParameters.stepAir[FORELEG(leg)?0:1])/currentParameters.airTime[FORELEG(leg)?0:1]+1.0;
00327       rz=1.0;
00328     } else {
00329       //lowering foot
00330       rx=-1.0;
00331       if (currentParameters.loweringTime[FORELEG(leg)?0:1] == 0)
00332         rz=0;
00333       else
00334         rz=1.0-((double)(step-currentParameters.stepLower[FORELEG(leg)?0:1]))/currentParameters.loweringTime[FORELEG(leg)?0:1];
00335     }
00336     ry = 0;
00337     break;
00338   case InvKinWalkingParameters::halfCircle:
00339     if (step<currentParameters.stepLift[FORELEG(leg)?0:1]) {
00340       //foot is on ground
00341       rx=2.0*step/currentParameters.groundTime[FORELEG(leg)?0:1]-1.0;
00342       rz=0;
00343     } else if (step<currentParameters.stepAir[FORELEG(leg)?0:1]) {
00344       rx=1.0;
00345       rz=0;
00346     } else if (step<currentParameters.stepLower[FORELEG(leg)?0:1]) {
00347       //foot in air;
00348       if (currentParameters.airTime[FORELEG(leg)?0:1] == 0) {
00349         rx=0;
00350         rz=1.0;
00351       } else {
00352         rx=cos(pi*(step-currentParameters.stepAir[FORELEG(leg)?0:1])/currentParameters.airTime[FORELEG(leg)?0:1]);
00353         rz=sin(pi*(step-currentParameters.stepAir[FORELEG(leg)?0:1])/currentParameters.airTime[FORELEG(leg)?0:1]);
00354       }
00355     } else {
00356       //lowering foot
00357       rx=-1.0;
00358       rz=0;
00359     }
00360     ry = 0;
00361     break;
00362   case InvKinWalkingParameters::circle:
00363     if (step<currentParameters.stepLift[FORELEG(leg)?0:1])
00364     {
00365       //halfcircle through ground
00366       rx=-cos(pi*step/currentParameters.stepLift[FORELEG(leg)?0:1]);
00367       rz=-sin(pi*step/currentParameters.stepLift[FORELEG(leg)?0:1]);
00368     }
00369     else
00370     {
00371       //halfcircle through air
00372       rx=cos(pi*(step-currentParameters.stepLift[FORELEG(leg)?0:1])/(currentParameters.stepLen-currentParameters.stepLift[FORELEG(leg)?0:1]));
00373       rz=sin(pi*(step-currentParameters.stepLift[FORELEG(leg)?0:1])/(currentParameters.stepLen-currentParameters.stepLift[FORELEG(leg)?0:1]));
00374     }
00375     ry = 0;
00376     break;
00377   case InvKinWalkingParameters::optimized:
00378     if (step<currentParameters.stepLift[FORELEG(leg)?0:1])
00379     {
00380       //foot is on ground
00381       rx=2.0*step/currentParameters.groundTime[FORELEG(leg)?0:1]-1.0;
00382       rz=0;
00383     }
00384     else
00385     {
00386       int x=step-currentParameters.stepLift[FORELEG(leg)?0:1];
00387       if (x < (currentParameters.stepLen-currentParameters.groundTime[FORELEG(leg)?0:1])/2)
00388       {
00389         rx=getLegPositionCurve(rz,((double)x)/currentParameters.stepLen);
00390       }
00391       else
00392       {
00393         rx=-getLegPositionCurve(rz,((double)(currentParameters.stepLen-currentParameters.groundTime[FORELEG(leg)?0:1])-x)/currentParameters.stepLen);
00394       }
00395     }
00396     ry = 0;
00397     break;
00398   case InvKinWalkingParameters::rounded:
00399     if (step<currentParameters.stepLift[FORELEG(leg)?0:1])
00400     {
00401       //foot is on ground
00402       rx=2.0*step/currentParameters.groundTime[FORELEG(leg)?0:1]-1.0;
00403       rz=0;
00404     }
00405     else if (step<currentParameters.stepAir[FORELEG(leg)?0:1])
00406     {
00407       //raising foot
00408       if (currentParameters.liftTime[FORELEG(leg)?0:1] == 0)
00409       {
00410         rx=1.0;
00411         rz=0;
00412       }
00413       else
00414       {
00415         rx=1.0+0.4*cos((((double)(step-currentParameters.stepLift[FORELEG(leg)?0:1]))/currentParameters.liftTime[FORELEG(leg)?0:1]-0.5)*pi);
00416         rz=0.5+0.5*sin((((double)(step-currentParameters.stepLift[FORELEG(leg)?0:1]))/currentParameters.liftTime[FORELEG(leg)?0:1]-0.5)*pi);
00417       }
00418     }
00419     else if (step<currentParameters.stepLower[FORELEG(leg)?0:1])
00420     {
00421       //foot in air;
00422       if (currentParameters.airTime[FORELEG(leg)?0:1] == 0)
00423         rx=0;
00424       else
00425         rx=-2.0*(step-currentParameters.stepAir[FORELEG(leg)?0:1])/currentParameters.airTime[FORELEG(leg)?0:1]+1.0;
00426       rz=1.0;
00427     }
00428     else
00429     {
00430       //lowering foot
00431       if (currentParameters.loweringTime[FORELEG(leg)?0:1] == 0)
00432       {
00433         rx=-1.0;
00434         rz=0;
00435       }
00436       else
00437       {
00438         rx=-1.0-0.4*cos((((double)(step-currentParameters.stepLower[FORELEG(leg)?0:1]))/currentParameters.loweringTime[FORELEG(leg)?0:1]-0.5)*pi);
00439         rz=0.5-0.5*sin((((double)(step-currentParameters.stepLower[FORELEG(leg)?0:1]))/currentParameters.loweringTime[FORELEG(leg)?0:1]-0.5)*pi);
00440       }
00441     }
00442     ry = 0;
00443     break;
00444   case InvKinWalkingParameters::freeFormQuad:
00445     double d;
00446     if (step<currentParameters.stepLift[FORELEG(leg)?0:1]) {
00447       //foot is on ground
00448       d = ((double)step)/currentParameters.groundTime[FORELEG(leg)?0:1];
00449       rx = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][0] * d +
00450            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][0] * (1.0 - d);
00451       ry = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][1] * d +
00452            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][1] * (1.0 - d);
00453       rz = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][2] * d +
00454            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][2] * (1.0 - d);
00455     } else if (step<currentParameters.stepAir[FORELEG(leg)?0:1]) {
00456       //raising foot
00457       d = ((double)(step-currentParameters.stepLift[FORELEG(leg)?0:1]))/currentParameters.liftTime[FORELEG(leg)?0:1];
00458       rx = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][0] * d +
00459            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][0] * (1.0 - d);
00460       ry = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][1] * d +
00461            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][1] * (1.0 - d);
00462       rz = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][2] * d +
00463            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][1][2] * (1.0 - d);
00464     } else if (step<currentParameters.stepLower[FORELEG(leg)?0:1]) {
00465       //foot in air;
00466       d = ((double)(step-currentParameters.stepAir[FORELEG(leg)?0:1]))/currentParameters.airTime[FORELEG(leg)?0:1];
00467       rx = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][0] * d +
00468            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][0] * (1.0 - d);
00469       ry = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][1] * d +
00470            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][1] * (1.0 - d);
00471       rz = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][2] * d +
00472            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][2][2] * (1.0 - d);
00473     } else {
00474       //lowering foot
00475       d = ((double)(step-currentParameters.stepLower[FORELEG(leg)?0:1]))/currentParameters.loweringTime[FORELEG(leg)?0:1];
00476       rx = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][0] * d +
00477            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][0] * (1.0 - d);
00478       ry = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][1] * d +
00479            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][1] * (1.0 - d);
00480       rz = currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][0][2] * d +
00481            currentParameters.freeFormQuadPos[FORELEG(leg)?0:1][3][2] * (1.0 - d);
00482     }
00483     break;
00484   }
00485 }
00486 
00487 void InvKinWalkingEngine::calculateFootPositions()
00488 {
00489   double rx,ry,rz;
00490   int step,leg;
00491   double bodyX = 0,bodyY = 0;
00492 
00493   for (leg=0;leg<4;leg++)
00494   {
00495     //leg center position on ground
00496     if (FORELEG(leg)) {
00497       x[leg]=currentParameters.foreCenterX;
00498       y[leg]=(LEFTLEG(leg))?currentParameters.foreWidth:-currentParameters.foreWidth;
00499       z[leg]=-currentParameters.foreHeight;
00500     } else {
00501       x[leg]=currentParameters.hindCenterX;
00502       y[leg]=(LEFTLEG(leg))?currentParameters.hindWidth:-currentParameters.hindWidth;
00503       z[leg]=-currentParameters.hindHeight;
00504     }
00505 
00506     //step for this leg
00507     step=(((int)(positionInWalkCycle * currentParameters.stepLen)) + currentParameters.legPhaseIndex[leg]);
00508     if (step>currentParameters.stepLen) step-=currentParameters.stepLen;
00509 
00510     calculateRelativeFootPosition(step, leg, rx, ry, rz);
00511 
00512     footOnGround[leg] = (rz == 0);
00513 
00514     //calculate absolute position (center position + relative position)
00515     if (FORELEG(leg))
00516     {
00517       z[leg]+=currentParameters.foreFootLift*rz;
00518       z[leg]+=currentParameters.foreFootTilt*rx*legSpeedX[leg];
00519     } else {
00520       z[leg]+=currentParameters.hindFootLift*rz;
00521       z[leg]+=currentParameters.hindFootTilt*rx*legSpeedX[leg];
00522     }
00523     x[leg]-=rx*legSpeedX[leg];
00524     y[leg]-=rx*legSpeedY[leg];
00525     if (LEFTLEG(leg))
00526       y[leg]+=ry;
00527     else
00528       y[leg]-=ry;
00529   }
00530 
00531   //calculate shifted body center (away from lifted legs)
00532   if (currentParameters.bodyShiftX != 0 || currentParameters.bodyShiftY != 0)
00533   {
00534     for (leg=0;leg<4;leg++)
00535     {
00536       step=((int)(positionInWalkCycle * currentParameters.stepLen)) + currentParameters.legPhaseIndex[leg]-(int)(currentParameters.bodyShiftOffset*currentParameters.stepLen);
00537       if (step>currentParameters.stepLen) step-=currentParameters.stepLen;
00538       calculateRelativeFootPosition(step, leg, rx, ry, rz);
00539 
00540       bodyY+=rz*currentParameters.bodyShiftY*((LEFTLEG(leg))?-1.0:1.0);
00541       bodyX+=rz*currentParameters.bodyShiftX*((FORELEG(leg))?-1.0:1.0);
00542     }
00543 
00544     for (leg=0;leg<4;leg++)
00545     {
00546       x[leg]-=bodyX;
00547       y[leg]-=bodyY;
00548     }
00549   }
00550 }
00551 
00552 bool InvKinWalkingEngine::handleMessage(InMessage& message)
00553 {
00554   switch(message.getMessageID())
00555   {
00556     case idInvKinWalkingParameters:
00557       message.bin >> nextParameters;
00558       initParametersInterpolation(32);
00559       return true;
00560   }
00561   return false;
00562 }
00563 
00564 void InvKinWalkingEngine::initParametersInterpolation(int changeSteps)
00565 {
00566   lastParameters=currentParameters;
00567   paramInterpolCount=0;
00568   paramInterpolLength=changeSteps;
00569   if (changeSteps==0)
00570   {
00571     currentParameters=nextParameters;
00572   }
00573 }
00574 
00575 void InvKinWalkingEngine::nextParametersInterpolation(bool walk)
00576 {
00577   if (paramInterpolCount<paramInterpolLength)
00578   {
00579     paramInterpolCount++;
00580     currentParameters.interpolate(lastParameters,nextParameters,(double)(paramInterpolLength-paramInterpolCount)/paramInterpolLength);
00581     currentParameters.init();
00582     calculateLegSpeeds();
00583     positionInWalkCycle += ((walk)?1:0) * 1/(double) currentParameters.stepLen;
00584   }
00585   else if (walk)
00586   {
00587     positionInWalkCycle += ((walk)?1:0) * 1/(double) currentParameters.stepLen;
00588   }
00589   if (positionInWalkCycle>=1) positionInWalkCycle-=1;
00590 }
00591 
00592 /*
00593  * Change log :
00594  * 
00595  * $Log: InvKinWalkingEngine.cpp,v $
00596  * Revision 1.9  2004/06/07 18:49:37  spranger
00597  * -extended interface of executeParametrized by positionInWalkCycle,
00598  * -removed currentStep and doubleStep
00599  * -all cycle determination relies on positionInWalkCycle
00600  *
00601  * Revision 1.8  2004/06/04 11:19:20  dueffert
00602  * switching between parameter sets with different steplen fixed
00603  *
00604  * Revision 1.7  2004/06/02 17:18:22  spranger
00605  * MotionRequest cleanup
00606  *
00607  * Revision 1.6  2004/05/27 17:13:37  jhoffman
00608  * - renaming: tilt1 -> neckTilt,  pan -> headPan,  tilt2 -> headTilt
00609  * - clipping included for setJoints
00610  * - removed some microrad/rad-bugs
00611  * - bodyPosture constructor and "=" operator fixed
00612  *
00613  * Revision 1.5  2004/05/26 20:17:47  juengel
00614  * Removed RobotVerticesBuffer.
00615  * Added "receivedNewSensorData".
00616  *
00617  * Revision 1.4  2004/05/26 17:37:30  dueffert
00618  * comments fixed
00619  *
00620  * Revision 1.3  2004/05/26 17:21:47  dueffert
00621  * better data types used
00622  *
00623  * Revision 1.2  2004/05/26 16:10:24  dueffert
00624  * better data types used
00625  *
00626  * Revision 1.1.1.1  2004/05/22 17:22:31  cvsadm
00627  * created new repository GT2004_WM
00628  *
00629  * Revision 1.20  2004/05/10 10:29:39  juengel
00630  * executedMotionRequest.positionInWalkCycle is set
00631  *
00632  * Revision 1.19  2004/04/07 12:29:00  risler
00633  * ddd checkin after go04 - first part
00634  *
00635  * Revision 1.2  2004/03/29 09:54:07  risler
00636  * reenabled bodyTilt calculation for ERS7
00637  *
00638  * Revision 1.1.1.1  2004/03/29 08:28:46  Administrator
00639  * initial transfer from tamara
00640  *
00641  * Revision 1.18  2004/03/27 10:31:58  dueffert
00642  * separation of engine and parameters completed
00643  *
00644  * Revision 1.17  2004/03/20 09:55:26  roefer
00645  * Preparation for improved odometry
00646  *
00647  * Revision 1.16  2004/03/12 11:35:37  kindler
00648  * - reenabled warning message for missing odometry data.
00649  * (this _is_ an important message.. who commented it out?!)
00650  *
00651  * Revision 1.15  2004/03/09 22:31:48  cesarz
00652  * added functionality to change invKinWalkingParameters through the behavior
00653  *
00654  * Revision 1.14  2004/03/08 02:11:54  roefer
00655  * Interfaces should be const
00656  *
00657  * Revision 1.13  2004/03/04 18:18:45  juengel
00658  * ERS7 bodyTilt is determined using acceleration sensors.
00659  *
00660  */

Generated on Thu Sep 23 19:57:33 2004 for GT2004 by doxygen 1.3.6