00001
00002
00003
00004
00005
00006
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
00057
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
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
00080 if (request != currentRequest ||
00081 lastMotionType != MotionRequest::walk)
00082 {
00083
00084 smoothMotionRequest(request, currentRequest);
00085 calculateLegSpeeds();
00086 }
00087
00088
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
00126
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
00137 odometry.translation.y -= odometry.rotation * currentParameters.correctionValues.rotationCenter;
00138
00139
00140 odometry.translation *= motionCycleTime;
00141
00142 odometry.rotation *= motionCycleTime;
00143
00144
00145 stepSizeR += stepSizeY * currentParameters.counterRotation;
00146
00147
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
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
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
00209
00210
00211
00212
00213
00214 double testX = stepSizeX;
00215 double testY = stepSizeY;
00216 double r = fabs(stepSizeR);
00217
00218
00219 if (testX>0) testX += r; else testX -= r;
00220 if (testY>0) testY += r; else testY -= r;
00221
00222
00223 if ((testX*testX/(currentParameters.maxStepSizeX*currentParameters.maxStepSizeX) +
00224 testY*testY/(currentParameters.maxStepSizeY*currentParameters.maxStepSizeY)) > 1.0)
00225 {
00226
00227
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
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
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
00267 j.data[JointData::earL] = j.data[JointData::earR] =
00268 j.data[JointData::tailTilt] = j.data[JointData::tailPan] =
00269 jointDataInvalidValue;
00270
00271
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
00306
00307 switch(currentParameters.footMode)
00308 {
00309 case InvKinWalkingParameters::rectangle:
00310 if (step<currentParameters.stepLift[FORELEG(leg)?0:1]) {
00311
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660