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 }