00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #include <math.h>
00031
00032 #include "dynJoint.h"
00033 #include "joint.h"
00034 #include "body.h"
00035 #include "matrix.h"
00036
00037
00038 #include "debug.h"
00039
00052 void
00053 DynJoint::buildConstraints(double *Nu,double *eps,int numBodies,
00054 std::map<Body*,int> &islandIndices,int &ncn)
00055 {
00056
00057
00058 transf prevTrans = getPrevTrans() * prevLink->getTran();
00059 transf nextTrans = getNextTrans() * nextLink->getTran();
00060
00061
00062 transf error = nextTrans.inverse() * prevTrans;
00063
00064
00065
00066 vec3 constrainedAxis[3];
00067 constrainedAxis[0] = prevTrans.affine().row(0);
00068 constrainedAxis[1] = prevTrans.affine().row(1);
00069 constrainedAxis[2] = prevTrans.affine().row(2);
00070
00071 DBGP("Constrained axes:\n " << constrainedAxis[0] <<
00072 "\n " << constrainedAxis[1] << "\n " << constrainedAxis[2]);
00073
00074
00075
00076 vec3 prevCOG = (prevLink->getCoG() * prevLink->getTran())-position::ORIGIN;
00077 vec3 nextCOG = (nextLink->getCoG() * nextLink->getTran())-position::ORIGIN;
00078
00079
00080
00081 mat3 prevCross;
00082 prevCross.setCrossProductMatrix( prevTrans.translation() - prevCOG );
00083 prevCross *= prevTrans.affine().transpose();
00084
00085 mat3 nextCross;
00086 nextCross.setCrossProductMatrix( nextTrans.translation() - nextCOG );
00087 nextCross *= prevTrans.affine().transpose();
00088
00089
00090 char constraints[6];
00091 getConstraints(constraints);
00092
00093
00094 assert(islandIndices[prevLink] >= 0);
00095 assert(islandIndices[nextLink] >= 0);
00096 int prevLinkRow = 6*islandIndices[prevLink];
00097 int nextLinkRow = 6*islandIndices[nextLink];
00098
00099
00100 vec3 errorVec = nextTrans.translation() - prevTrans.translation();
00101 DBGP("Translation error: " << errorVec);
00102
00103
00104 for (int c=0; c<3; c++) {
00105 if (!constraints[c]) continue;
00106
00107 Nu[(ncn)*6*numBodies + prevLinkRow] -= constrainedAxis[c][0];
00108 Nu[(ncn)*6*numBodies + prevLinkRow+1] -= constrainedAxis[c][1];
00109 Nu[(ncn)*6*numBodies + prevLinkRow+2] -= constrainedAxis[c][2];
00110 Nu[(ncn)*6*numBodies + prevLinkRow+3] -= prevCross[3*c];
00111 Nu[(ncn)*6*numBodies + prevLinkRow+4] -= prevCross[3*c+1];
00112 Nu[(ncn)*6*numBodies + prevLinkRow+5] -= prevCross[3*c+2];
00113
00114 Nu[(ncn)*6*numBodies + nextLinkRow] += constrainedAxis[c][0];
00115 Nu[(ncn)*6*numBodies + nextLinkRow+1] += constrainedAxis[c][1];
00116 Nu[(ncn)*6*numBodies + nextLinkRow+2] += constrainedAxis[c][2];
00117 Nu[(ncn)*6*numBodies + nextLinkRow+3] += nextCross[3*c];
00118 Nu[(ncn)*6*numBodies + nextLinkRow+4] += nextCross[3*c+1];
00119 Nu[(ncn)*6*numBodies + nextLinkRow+5] += nextCross[3*c+2];
00120
00121 eps[ncn] = -(errorVec % constrainedAxis[c]);
00122 ncn++;
00123
00124 }
00125
00126
00127 double alpha;
00128 error.rotation().ToAngleAxis(alpha, errorVec);
00129 errorVec = - errorVec * alpha;
00130 DBGP("Rotation error: " << errorVec);
00131
00132 for (int c=0; c<3; c++) {
00133 if (!constraints[3+c]) continue;
00134
00135 Nu[(ncn)*6*numBodies + prevLinkRow+3] -= constrainedAxis[c][0];
00136 Nu[(ncn)*6*numBodies + prevLinkRow+4] -= constrainedAxis[c][1];
00137 Nu[(ncn)*6*numBodies + prevLinkRow+5] -= constrainedAxis[c][2];
00138
00139 Nu[(ncn)*6*numBodies + nextLinkRow+3] += constrainedAxis[c][0];
00140 Nu[(ncn)*6*numBodies + nextLinkRow+4] += constrainedAxis[c][1];
00141 Nu[(ncn)*6*numBodies + nextLinkRow+5] += constrainedAxis[c][2];
00142
00143 eps[ncn] = -(errorVec % constrainedAxis[c]);
00144 ncn++;
00145 }
00146 }
00147
00152 void
00153 DynJoint::jacobian(transf toTarget, Matrix *J, bool worldCoords)
00154 {
00155 transf myTran = getPrevTrans() * getPrevLink()->getTran();
00156 transf T;
00157 if (worldCoords) {
00158
00159 T = transf(Quaternion::IDENTITY, toTarget.translation()) * myTran.inverse();
00160 } else {
00161 T = toTarget * myTran.inverse();
00162 }
00163 double M[36];
00164 T.jacobian(M);
00165 J->copyMatrix(Matrix(M,6,6,true));
00166 }
00167
00171 void
00172 FixedDynJoint::updateValues()
00173 {
00174 }
00175
00180 void
00181 FixedDynJoint::buildConstraints(double *Nu,double *eps,int numBodies,
00182 std::map<Body*,int> &islandIndices,int &ncn)
00183 {
00184 if (prevLink) {
00185 DynJoint::buildConstraints(Nu, eps, numBodies, islandIndices, ncn);
00186 return;
00187 }
00188
00189 assert(islandIndices[nextLink] >= 0);
00190 int nextLinkRow = 6*islandIndices[nextLink];
00191
00192 transf prevTrans = getPrevTrans();
00193 transf nextTrans = getNextTrans() * nextLink->getTran();
00194 transf error = nextTrans.inverse() * prevTrans;
00195
00196 vec3 errorVec = nextTrans.translation() - prevTrans.translation();
00197
00198 for (int c=0; c<3; c++) {
00199 Nu[(ncn)*6*numBodies + nextLinkRow+c] += 1.0;
00200 eps[ncn] = -errorVec[c];
00201 ncn++;
00202 }
00203
00204 double alpha;
00205 error.rotation().ToAngleAxis(alpha, errorVec);
00206 errorVec = - errorVec * alpha;
00207 DBGP("Rotation error: " << errorVec);
00208
00209 for (int c=3; c<6; c++) {
00210 Nu[(ncn)*6*numBodies + nextLinkRow+c] += 1.0;
00211 eps[ncn] = 2*errorVec[c-3];
00212 ncn++;
00213 }
00214 }
00215
00221 void
00222 RevoluteDynJoint::updateValues()
00223 {
00224 transf b1JointTran = prevFrame * prevLink->getTran();
00225
00226
00227 vec3 axis = b1JointTran.affine().row(2);
00228 joint->setWorldAxis(axis);
00229 double vel1 = vec3(prevLink->getVelocity()[3],
00230 prevLink->getVelocity()[4],
00231 prevLink->getVelocity()[5]) % axis;
00232 double vel2 = vec3(nextLink->getVelocity()[3],
00233 nextLink->getVelocity()[4],
00234 nextLink->getVelocity()[5]) % axis;
00235 joint->setVelocity(vel2-vel1);
00236
00237 transf diffTran = joint->getTran(0.0).inverse() * nextLink->getTran() * b1JointTran.inverse();
00238
00239 double val;
00240 diffTran.rotation().ToAngleAxis(val,axis);
00241 if (axis.z() < 0) val = -val;
00242
00243 DBGP("link "<< prevLink->getName().latin1() <<" - link "<<nextLink->getName().latin1());
00244 DBGP(" joint angle: "<<val*180.0/M_PI<<" radians: "<<val<< " velocity: "<<vel2-vel1);
00245
00246 joint->setDynamicsVal(val);
00247 }
00248
00249 transf
00250 RevoluteDynJoint::getPrevTrans()
00251 {
00252
00253
00254
00255
00256 return prevFrame;
00257 }
00258
00259 transf
00260 RevoluteDynJoint::getNextTrans()
00261 {
00262
00263 return joint->getDynamicsTran().inverse();
00264 }
00265
00271 void
00272 UniversalDynJoint::updateValues()
00273 {
00274 vec3 axis,ax0,ax1,ax2;
00275 double val,vel1,vel2;
00276
00277 transf b1JointTran = prevFrame * prevLink->getTran();
00278 transf b2JointTran = nextFrame * nextLink->getTran();
00279
00280
00281 ax0 = b1JointTran.affine().row(2);
00282 ax2 = b2JointTran.affine().row(2);
00283 ax1 = normalise(ax2*ax0);
00284
00285 DBGP("ax0: "<<ax0<<" len "<<ax0.len());
00286 DBGP("ax1: "<<ax1<<" len "<<ax1.len());
00287 DBGP("ax2: "<<ax2<<" len "<<ax2.len());
00288
00289 axis = ax1*ax2;
00290 joint1->setWorldAxis(axis);
00291 vel1 = vec3(prevLink->getVelocity()[3],
00292 prevLink->getVelocity()[4],
00293 prevLink->getVelocity()[5]) % axis;
00294 vel2 = vec3(nextLink->getVelocity()[3],
00295 nextLink->getVelocity()[4],
00296 nextLink->getVelocity()[5]) % axis;
00297 joint1->setVelocity(vel2-vel1);
00298
00299 vec3 ref1 = (joint2->getTran(0.0)*joint1->getTran(0.0)*b1JointTran).affine().row(2);
00300
00301 val = atan2 (ax2 % (ax0 * ref1), ax2 % ref1);
00302
00303 DBGP("link " << prevLink->getName().latin1() << " - link " << nextLink->getName().latin1() << ":");
00304 DBGP(" joint1 angle: " << val*180.0/M_PI << " " << val << " (rad)");
00305 joint1->setDynamicsVal(val);
00306
00307
00308 axis = b2JointTran.affine().row(2);
00309
00310 joint2->setWorldAxis(ax0*ax1);
00311
00312 vel1 = vec3(prevLink->getVelocity()[3],
00313 prevLink->getVelocity()[4],
00314 prevLink->getVelocity()[5]) % axis;
00315 vel2= vec3(nextLink->getVelocity()[3],
00316 nextLink->getVelocity()[4],
00317 nextLink->getVelocity()[5]) % axis;
00318
00319 joint2->setVelocity(vel2-vel1);
00320
00321 vec3 ref2 = (joint2->getTran(0.0)*joint1->getTran(0.0)).inverse().affine().row(2) * b2JointTran;
00322
00323 val = atan2 (ref2 % ax1, ref2 % (ax1*ax2));
00324
00325 joint2->setDynamicsVal(val);
00326 }
00327
00328 transf
00329 UniversalDynJoint::getPrevTrans()
00330 {
00331 return prevFrame;
00332 }
00333
00334 transf
00335 UniversalDynJoint::getNextTrans()
00336 {
00337 return joint1->getDynamicsTran().inverse() * joint2->getDynamicsTran().inverse();
00338 }
00339
00345 void
00346 BallDynJoint::updateValues()
00347 {
00348 transf b1JointTran,b2JointTran;
00349
00350 vec3 axis,ax0,ax1,ax2;
00351 double val,vel1,vel2;
00352
00353 b1JointTran = prevFrame * prevLink->getTran();
00354 b2JointTran = nextFrame * nextLink->getTran();
00355
00356 ax0 = b1JointTran.affine().row(2);
00357 ax2 = b2JointTran.affine().row(2);
00358 ax1 = normalise(ax2*ax0);
00359
00360 DBGP("ax0: "<<ax0<<" len "<<ax0.len());
00361 DBGP("ax1: "<<ax1<<" len "<<ax1.len());
00362 DBGP("ax2: "<<ax2<<" len "<<ax2.len());
00363
00364
00365 axis = ax1*ax2;
00366 joint1->setWorldAxis(axis);
00367 vel1 = vec3(prevLink->getVelocity()[3],
00368 prevLink->getVelocity()[4],
00369 prevLink->getVelocity()[5]) % axis;
00370 vel2= vec3(nextLink->getVelocity()[3],
00371 nextLink->getVelocity()[4],
00372 nextLink->getVelocity()[5]) % axis;
00373 joint1->setVelocity(vel2-vel1);
00374
00375 vec3 ref1 = (joint2->getTran(0.0)*joint1->getTran(0.0)*b1JointTran).affine().row(2);
00376 val = atan2 (ax2 % (ax0 * ref1), ax2 % ref1);
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 #ifdef GRASPITDBG
00390 printf("link %s - link %s joint1 angle: %le %le(rad)\n",prevLink->getName().latin1(),
00391 nextLink->getName().latin1(),val*180.0/M_PI,val);
00392
00393 #endif
00394
00395
00396 joint1->setDynamicsVal(val);
00397
00398 axis = ax1;
00399 joint2->setWorldAxis(axis);
00400 vel1 = vec3(prevLink->getVelocity()[3],
00401 prevLink->getVelocity()[4],
00402 prevLink->getVelocity()[5]) % axis;
00403 vel2= vec3(nextLink->getVelocity()[3],
00404 nextLink->getVelocity()[4],
00405 nextLink->getVelocity()[5]) % axis;
00406
00407 joint2->setVelocity(vel2-vel1);
00408
00409 val = atan2 (ax2 % ax0, ax2 % (ax0*ax1));
00410
00411 #ifdef GRASPITDBG
00412 printf("link %s - link %s joint2 angle: %le %le(rad)\n",prevLink->getName().latin1(),
00413 nextLink->getName().latin1(),val*180.0/M_PI,val);
00414
00415 #endif
00416
00417
00418 joint2->setDynamicsVal(val);
00419
00420 axis = ax0*ax1;
00421 joint3->setWorldAxis(axis);
00422 vel1 = vec3(prevLink->getVelocity()[3],
00423 prevLink->getVelocity()[4],
00424 prevLink->getVelocity()[5]) % axis;
00425 vel2= vec3(nextLink->getVelocity()[3],
00426 nextLink->getVelocity()[4],
00427 nextLink->getVelocity()[5]) % axis;
00428
00429 joint3->setVelocity(vel2-vel1);
00430
00431 vec3 ref2 = (joint2->getTran(0.0)*joint1->getTran(0.0)).inverse().affine().row(2) * b2JointTran;
00432 val = atan2 (ref2 % ax1, ref2 % (ax1*ax2));
00433
00434 #ifdef GRASPITDBG
00435 printf("link %s - link %s joint3 angle: %le %le(rad)\n",prevLink->getName().latin1(),
00436 nextLink->getName().latin1(),val*180.0/M_PI,val);
00437
00438 #endif
00439
00440
00441 joint3->setDynamicsVal(val);
00442 }
00443
00444 transf
00445 BallDynJoint::getPrevTrans()
00446 {
00447 return prevFrame;
00448 }
00449
00450 transf
00451 BallDynJoint::getNextTrans()
00452 {
00453 return joint1->getDynamicsTran().inverse() *
00454 joint2->getDynamicsTran().inverse() *
00455 joint3->getDynamicsTran().inverse();
00456 }