Blender V2.61 - r43446
|
00001 /*************************************************************************** 00002 frames.inl - description 00003 ------------------------- 00004 begin : June 2006 00005 copyright : (C) 2006 Erwin Aertbelien 00006 email : firstname.lastname@mech.kuleuven.ac.be 00007 00008 History (only major changes)( AUTHOR-Description ) : 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 51 Franklin Street, * 00024 * Fifth Floor, Boston, MA 02110-1301, USA. * 00025 * * 00026 ***************************************************************************/ 00027 00028 00029 IMETHOD Vector::Vector(const Vector & arg) 00030 { 00031 data[0] = arg.data[0]; 00032 data[1] = arg.data[1]; 00033 data[2] = arg.data[2]; 00034 } 00035 00036 IMETHOD Vector::Vector(double x,double y, double z) 00037 { 00038 data[0]=x;data[1]=y;data[2]=z; 00039 } 00040 00041 IMETHOD Vector::Vector(double* xyz) 00042 { 00043 data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2]; 00044 } 00045 00046 IMETHOD Vector::Vector(float* xyz) 00047 { 00048 data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2]; 00049 } 00050 00051 IMETHOD void Vector::GetValue(double* xyz) const 00052 { 00053 xyz[0]=data[0];xyz[1]=data[1];xyz[2]=data[2]; 00054 } 00055 00056 00057 IMETHOD Vector& Vector::operator =(const Vector & arg) 00058 { 00059 data[0] = arg.data[0]; 00060 data[1] = arg.data[1]; 00061 data[2] = arg.data[2]; 00062 return *this; 00063 } 00064 00065 IMETHOD Vector operator +(const Vector & lhs,const Vector& rhs) 00066 { 00067 Vector tmp; 00068 tmp.data[0] = lhs.data[0]+rhs.data[0]; 00069 tmp.data[1] = lhs.data[1]+rhs.data[1]; 00070 tmp.data[2] = lhs.data[2]+rhs.data[2]; 00071 return tmp; 00072 } 00073 00074 IMETHOD Vector operator -(const Vector & lhs,const Vector& rhs) 00075 { 00076 Vector tmp; 00077 tmp.data[0] = lhs.data[0]-rhs.data[0]; 00078 tmp.data[1] = lhs.data[1]-rhs.data[1]; 00079 tmp.data[2] = lhs.data[2]-rhs.data[2]; 00080 return tmp; 00081 } 00082 00083 IMETHOD double Vector::x() const { return data[0]; } 00084 IMETHOD double Vector::y() const { return data[1]; } 00085 IMETHOD double Vector::z() const { return data[2]; } 00086 00087 IMETHOD void Vector::x( double _x ) { data[0] = _x; } 00088 IMETHOD void Vector::y( double _y ) { data[1] = _y; } 00089 IMETHOD void Vector::z( double _z ) { data[2] = _z; } 00090 00091 Vector operator *(const Vector& lhs,double rhs) 00092 { 00093 Vector tmp; 00094 tmp.data[0] = lhs.data[0]*rhs; 00095 tmp.data[1] = lhs.data[1]*rhs; 00096 tmp.data[2] = lhs.data[2]*rhs; 00097 return tmp; 00098 } 00099 00100 Vector operator *(double lhs,const Vector& rhs) 00101 { 00102 Vector tmp; 00103 tmp.data[0] = lhs*rhs.data[0]; 00104 tmp.data[1] = lhs*rhs.data[1]; 00105 tmp.data[2] = lhs*rhs.data[2]; 00106 return tmp; 00107 } 00108 00109 Vector operator /(const Vector& lhs,double rhs) 00110 { 00111 Vector tmp; 00112 tmp.data[0] = lhs.data[0]/rhs; 00113 tmp.data[1] = lhs.data[1]/rhs; 00114 tmp.data[2] = lhs.data[2]/rhs; 00115 return tmp; 00116 } 00117 00118 Vector operator *(const Vector & lhs,const Vector& rhs) 00119 // Complexity : 6M+3A 00120 { 00121 Vector tmp; 00122 tmp.data[0] = lhs.data[1]*rhs.data[2]-lhs.data[2]*rhs.data[1]; 00123 tmp.data[1] = lhs.data[2]*rhs.data[0]-lhs.data[0]*rhs.data[2]; 00124 tmp.data[2] = lhs.data[0]*rhs.data[1]-lhs.data[1]*rhs.data[0]; 00125 return tmp; 00126 } 00127 00128 Vector& Vector::operator +=(const Vector & arg) 00129 // Complexity : 3A 00130 { 00131 data[0]+=arg.data[0]; 00132 data[1]+=arg.data[1]; 00133 data[2]+=arg.data[2]; 00134 return *this; 00135 } 00136 00137 Vector& Vector::operator -=(const Vector & arg) 00138 // Complexity : 3A 00139 { 00140 data[0]-=arg.data[0]; 00141 data[1]-=arg.data[1]; 00142 data[2]-=arg.data[2]; 00143 return *this; 00144 } 00145 00146 Vector Vector::Zero() 00147 { 00148 return Vector(0,0,0); 00149 } 00150 00151 double Vector::operator()(int index) const { 00152 FRAMES_CHECKI((0<=index)&&(index<=2)); 00153 return data[index]; 00154 } 00155 00156 double& Vector::operator () (int index) 00157 { 00158 FRAMES_CHECKI((0<=index)&&(index<=2)); 00159 return data[index]; 00160 } 00161 00162 IMETHOD Vector Normalize(const Vector& a, double eps) 00163 { 00164 double l=a.Norm(); 00165 return (l<eps) ? Vector(0.0,0.0,0.0) : a/l; 00166 } 00167 00168 Wrench Frame::operator * (const Wrench& arg) const 00169 // Complexity : 24M+18A 00170 { 00171 Wrench tmp; 00172 tmp.force = M*arg.force; 00173 tmp.torque = M*arg.torque + p*tmp.force; 00174 return tmp; 00175 } 00176 00177 Wrench Frame::Inverse(const Wrench& arg) const 00178 { 00179 Wrench tmp; 00180 tmp.force = M.Inverse(arg.force); 00181 tmp.torque = M.Inverse(arg.torque-p*arg.force); 00182 return tmp; 00183 } 00184 00185 00186 00187 Wrench Rotation::Inverse(const Wrench& arg) const 00188 { 00189 return Wrench(Inverse(arg.force),Inverse(arg.torque)); 00190 } 00191 00192 Twist Rotation::Inverse(const Twist& arg) const 00193 { 00194 return Twist(Inverse(arg.vel),Inverse(arg.rot)); 00195 } 00196 00197 Wrench Wrench::Zero() 00198 { 00199 return Wrench(Vector::Zero(),Vector::Zero()); 00200 } 00201 00202 00203 void Wrench::ReverseSign() 00204 { 00205 torque.ReverseSign(); 00206 force.ReverseSign(); 00207 } 00208 00209 Wrench Wrench::RefPoint(const Vector& v_base_AB) const 00210 // Changes the reference point of the Wrench. 00211 // The vector v_base_AB is expressed in the same base as the twist 00212 // The vector v_base_AB is a vector from the old point to 00213 // the new point. 00214 { 00215 return Wrench(this->force, 00216 this->torque+this->force*v_base_AB 00217 ); 00218 } 00219 00220 00221 Wrench& Wrench::operator-=(const Wrench& arg) 00222 { 00223 torque-=arg.torque; 00224 force -=arg.force; 00225 return *this; 00226 } 00227 00228 Wrench& Wrench::operator+=(const Wrench& arg) 00229 { 00230 torque+=arg.torque; 00231 force +=arg.force; 00232 return *this; 00233 } 00234 00235 double& Wrench::operator()(int i) 00236 { 00237 // assert((0<=i)&&(i<6)); done by underlying routines 00238 if (i<3) 00239 return force(i); 00240 else 00241 return torque(i-3); 00242 } 00243 00244 double Wrench::operator()(int i) const 00245 { 00246 // assert((0<=i)&&(i<6)); done by underlying routines 00247 if (i<3) 00248 return force(i); 00249 else 00250 return torque(i-3); 00251 } 00252 00253 00254 Wrench operator*(const Wrench& lhs,double rhs) 00255 { 00256 return Wrench(lhs.force*rhs,lhs.torque*rhs); 00257 } 00258 00259 Wrench operator*(double lhs,const Wrench& rhs) 00260 { 00261 return Wrench(lhs*rhs.force,lhs*rhs.torque); 00262 } 00263 00264 Wrench operator/(const Wrench& lhs,double rhs) 00265 { 00266 return Wrench(lhs.force/rhs,lhs.torque/rhs); 00267 } 00268 00269 // addition of Wrench's 00270 Wrench operator+(const Wrench& lhs,const Wrench& rhs) 00271 { 00272 return Wrench(lhs.force+rhs.force,lhs.torque+rhs.torque); 00273 } 00274 00275 Wrench operator-(const Wrench& lhs,const Wrench& rhs) 00276 { 00277 return Wrench(lhs.force-rhs.force,lhs.torque-rhs.torque); 00278 } 00279 00280 // unary - 00281 Wrench operator-(const Wrench& arg) 00282 { 00283 return Wrench(-arg.force,-arg.torque); 00284 } 00285 00286 Twist Frame::operator * (const Twist& arg) const 00287 // Complexity : 24M+18A 00288 { 00289 Twist tmp; 00290 tmp.rot = M*arg.rot; 00291 tmp.vel = M*arg.vel+p*tmp.rot; 00292 return tmp; 00293 } 00294 Twist Frame::Inverse(const Twist& arg) const 00295 { 00296 Twist tmp; 00297 tmp.rot = M.Inverse(arg.rot); 00298 tmp.vel = M.Inverse(arg.vel-p*arg.rot); 00299 return tmp; 00300 } 00301 00302 Twist Twist::Zero() 00303 { 00304 return Twist(Vector::Zero(),Vector::Zero()); 00305 } 00306 00307 00308 void Twist::ReverseSign() 00309 { 00310 vel.ReverseSign(); 00311 rot.ReverseSign(); 00312 } 00313 00314 Twist Twist::RefPoint(const Vector& v_base_AB) const 00315 // Changes the reference point of the twist. 00316 // The vector v_base_AB is expressed in the same base as the twist 00317 // The vector v_base_AB is a vector from the old point to 00318 // the new point. 00319 // Complexity : 6M+6A 00320 { 00321 return Twist(this->vel+this->rot*v_base_AB,this->rot); 00322 } 00323 00324 Twist& Twist::operator-=(const Twist& arg) 00325 { 00326 vel-=arg.vel; 00327 rot -=arg.rot; 00328 return *this; 00329 } 00330 00331 Twist& Twist::operator+=(const Twist& arg) 00332 { 00333 vel+=arg.vel; 00334 rot +=arg.rot; 00335 return *this; 00336 } 00337 00338 double& Twist::operator()(int i) 00339 { 00340 // assert((0<=i)&&(i<6)); done by underlying routines 00341 if (i<3) 00342 return vel(i); 00343 else 00344 return rot(i-3); 00345 } 00346 00347 double Twist::operator()(int i) const 00348 { 00349 // assert((0<=i)&&(i<6)); done by underlying routines 00350 if (i<3) 00351 return vel(i); 00352 else 00353 return rot(i-3); 00354 } 00355 00356 00357 Twist operator*(const Twist& lhs,double rhs) 00358 { 00359 return Twist(lhs.vel*rhs,lhs.rot*rhs); 00360 } 00361 00362 Twist operator*(double lhs,const Twist& rhs) 00363 { 00364 return Twist(lhs*rhs.vel,lhs*rhs.rot); 00365 } 00366 00367 Twist operator/(const Twist& lhs,double rhs) 00368 { 00369 return Twist(lhs.vel/rhs,lhs.rot/rhs); 00370 } 00371 00372 // addition of Twist's 00373 Twist operator+(const Twist& lhs,const Twist& rhs) 00374 { 00375 return Twist(lhs.vel+rhs.vel,lhs.rot+rhs.rot); 00376 } 00377 00378 Twist operator-(const Twist& lhs,const Twist& rhs) 00379 { 00380 return Twist(lhs.vel-rhs.vel,lhs.rot-rhs.rot); 00381 } 00382 00383 // unary - 00384 Twist operator-(const Twist& arg) 00385 { 00386 return Twist(-arg.vel,-arg.rot); 00387 } 00388 00389 Frame::Frame(const Rotation & R) 00390 { 00391 M=R; 00392 p=Vector::Zero(); 00393 } 00394 00395 Frame::Frame(const Vector & V) 00396 { 00397 M = Rotation::Identity(); 00398 p = V; 00399 } 00400 00401 Frame::Frame(const Rotation & R, const Vector & V) 00402 { 00403 M = R; 00404 p = V; 00405 } 00406 00407 Frame operator *(const Frame& lhs,const Frame& rhs) 00408 // Complexity : 36M+36A 00409 { 00410 return Frame(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p); 00411 } 00412 00413 Vector Frame::operator *(const Vector & arg) const 00414 { 00415 return M*arg+p; 00416 } 00417 00418 Vector Frame::Inverse(const Vector& arg) const 00419 { 00420 return M.Inverse(arg-p); 00421 } 00422 00423 Frame Frame::Inverse() const 00424 { 00425 return Frame(M.Inverse(),-M.Inverse(p)); 00426 } 00427 00428 00429 Frame& Frame::operator =(const Frame & arg) 00430 { 00431 M = arg.M; 00432 p = arg.p; 00433 return *this; 00434 } 00435 00436 Frame::Frame(const Frame & arg) : 00437 p(arg.p),M(arg.M) 00438 {} 00439 00440 00441 void Vector::ReverseSign() 00442 { 00443 data[0] = -data[0]; 00444 data[1] = -data[1]; 00445 data[2] = -data[2]; 00446 } 00447 00448 00449 00450 Vector operator-(const Vector & arg) 00451 { 00452 Vector tmp; 00453 tmp.data[0]=-arg.data[0]; 00454 tmp.data[1]=-arg.data[1]; 00455 tmp.data[2]=-arg.data[2]; 00456 return tmp; 00457 } 00458 00459 void Vector::Set2DXY(const Vector2& v) 00460 // a 3D vector where the 2D vector v is put in the XY plane 00461 { 00462 data[0]=v(0); 00463 data[1]=v(1); 00464 data[2]=0; 00465 00466 } 00467 void Vector::Set2DYZ(const Vector2& v) 00468 // a 3D vector where the 2D vector v is put in the YZ plane 00469 { 00470 data[1]=v(0); 00471 data[2]=v(1); 00472 data[0]=0; 00473 00474 } 00475 00476 void Vector::Set2DZX(const Vector2& v) 00477 // a 3D vector where the 2D vector v is put in the ZX plane 00478 { 00479 data[2]=v(0); 00480 data[0]=v(1); 00481 data[1]=0; 00482 00483 } 00484 00485 00486 00487 00488 00489 double& Rotation::operator()(int i,int j) { 00490 FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); 00491 return data[i*3+j]; 00492 } 00493 00494 double Rotation::operator()(int i,int j) const { 00495 FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); 00496 return data[i*3+j]; 00497 } 00498 00499 Rotation::Rotation( double Xx,double Yx,double Zx, 00500 double Xy,double Yy,double Zy, 00501 double Xz,double Yz,double Zz) 00502 { 00503 data[0] = Xx;data[1]=Yx;data[2]=Zx; 00504 data[3] = Xy;data[4]=Yy;data[5]=Zy; 00505 data[6] = Xz;data[7]=Yz;data[8]=Zz; 00506 } 00507 00508 00509 Rotation::Rotation(const Vector& x,const Vector& y,const Vector& z) 00510 { 00511 data[0] = x.data[0];data[3] = x.data[1];data[6] = x.data[2]; 00512 data[1] = y.data[0];data[4] = y.data[1];data[7] = y.data[2]; 00513 data[2] = z.data[0];data[5] = z.data[1];data[8] = z.data[2]; 00514 } 00515 00516 Rotation& Rotation::operator=(const Rotation& arg) { 00517 int count=9; 00518 while (count--) data[count] = arg.data[count]; 00519 return *this; 00520 } 00521 00522 Vector Rotation::operator*(const Vector& v) const { 00523 // Complexity : 9M+6A 00524 return Vector( 00525 data[0]*v.data[0] + data[1]*v.data[1] + data[2]*v.data[2], 00526 data[3]*v.data[0] + data[4]*v.data[1] + data[5]*v.data[2], 00527 data[6]*v.data[0] + data[7]*v.data[1] + data[8]*v.data[2] 00528 ); 00529 } 00530 00531 Twist Rotation::operator * (const Twist& arg) const 00532 // Transformation of the base to which the twist is expressed. 00533 // look at Frame*Twist for a transformation that also transforms 00534 // the velocity reference point. 00535 // Complexity : 18M+12A 00536 { 00537 return Twist((*this)*arg.vel,(*this)*arg.rot); 00538 } 00539 00540 Wrench Rotation::operator * (const Wrench& arg) const 00541 // Transformation of the base to which the wrench is expressed. 00542 // look at Frame*Twist for a transformation that also transforms 00543 // the force reference point. 00544 { 00545 return Wrench((*this)*arg.force,(*this)*arg.torque); 00546 } 00547 00548 Rotation Rotation::Identity() { 00549 return Rotation(1,0,0,0,1,0,0,0,1); 00550 } 00551 // *this = *this * ROT(X,angle) 00552 void Rotation::DoRotX(double angle) 00553 { 00554 double cs = cos(angle); 00555 double sn = sin(angle); 00556 double x1,x2,x3; 00557 x1 = cs* (*this)(0,1) + sn* (*this)(0,2); 00558 x2 = cs* (*this)(1,1) + sn* (*this)(1,2); 00559 x3 = cs* (*this)(2,1) + sn* (*this)(2,2); 00560 (*this)(0,2) = -sn* (*this)(0,1) + cs* (*this)(0,2); 00561 (*this)(1,2) = -sn* (*this)(1,1) + cs* (*this)(1,2); 00562 (*this)(2,2) = -sn* (*this)(2,1) + cs* (*this)(2,2); 00563 (*this)(0,1) = x1; 00564 (*this)(1,1) = x2; 00565 (*this)(2,1) = x3; 00566 } 00567 00568 void Rotation::DoRotY(double angle) 00569 { 00570 double cs = cos(angle); 00571 double sn = sin(angle); 00572 double x1,x2,x3; 00573 x1 = cs* (*this)(0,0) - sn* (*this)(0,2); 00574 x2 = cs* (*this)(1,0) - sn* (*this)(1,2); 00575 x3 = cs* (*this)(2,0) - sn* (*this)(2,2); 00576 (*this)(0,2) = sn* (*this)(0,0) + cs* (*this)(0,2); 00577 (*this)(1,2) = sn* (*this)(1,0) + cs* (*this)(1,2); 00578 (*this)(2,2) = sn* (*this)(2,0) + cs* (*this)(2,2); 00579 (*this)(0,0) = x1; 00580 (*this)(1,0) = x2; 00581 (*this)(2,0) = x3; 00582 } 00583 00584 void Rotation::DoRotZ(double angle) 00585 { 00586 double cs = cos(angle); 00587 double sn = sin(angle); 00588 double x1,x2,x3; 00589 x1 = cs* (*this)(0,0) + sn* (*this)(0,1); 00590 x2 = cs* (*this)(1,0) + sn* (*this)(1,1); 00591 x3 = cs* (*this)(2,0) + sn* (*this)(2,1); 00592 (*this)(0,1) = -sn* (*this)(0,0) + cs* (*this)(0,1); 00593 (*this)(1,1) = -sn* (*this)(1,0) + cs* (*this)(1,1); 00594 (*this)(2,1) = -sn* (*this)(2,0) + cs* (*this)(2,1); 00595 (*this)(0,0) = x1; 00596 (*this)(1,0) = x2; 00597 (*this)(2,0) = x3; 00598 } 00599 00600 00601 Rotation Rotation::RotX(double angle) { 00602 double cs=cos(angle); 00603 double sn=sin(angle); 00604 return Rotation(1,0,0,0,cs,-sn,0,sn,cs); 00605 } 00606 Rotation Rotation::RotY(double angle) { 00607 double cs=cos(angle); 00608 double sn=sin(angle); 00609 return Rotation(cs,0,sn,0,1,0,-sn,0,cs); 00610 } 00611 Rotation Rotation::RotZ(double angle) { 00612 double cs=cos(angle); 00613 double sn=sin(angle); 00614 return Rotation(cs,-sn,0,sn,cs,0,0,0,1); 00615 } 00616 00617 00618 00619 00620 void Frame::Integrate(const Twist& t_this,double samplefrequency) 00621 { 00622 double n = t_this.rot.Norm()/samplefrequency; 00623 if (n<epsilon) { 00624 p += M*(t_this.vel/samplefrequency); 00625 } else { 00626 (*this) = (*this) * 00627 Frame ( Rotation::Rot( t_this.rot, n ), 00628 t_this.vel/samplefrequency 00629 ); 00630 } 00631 } 00632 00633 Rotation Rotation::Inverse() const 00634 { 00635 Rotation tmp(*this); 00636 tmp.SetInverse(); 00637 return tmp; 00638 } 00639 00640 Vector Rotation::Inverse(const Vector& v) const { 00641 return Vector( 00642 data[0]*v.data[0] + data[3]*v.data[1] + data[6]*v.data[2], 00643 data[1]*v.data[0] + data[4]*v.data[1] + data[7]*v.data[2], 00644 data[2]*v.data[0] + data[5]*v.data[1] + data[8]*v.data[2] 00645 ); 00646 } 00647 00648 void Rotation::setValue(float* oglmat) 00649 { 00650 data[0] = *oglmat++; data[3] = *oglmat++; data[6] = *oglmat++; oglmat++; 00651 data[1] = *oglmat++; data[4] = *oglmat++; data[7] = *oglmat++; oglmat++; 00652 data[2] = *oglmat++; data[5] = *oglmat++; data[8] = *oglmat; 00653 Ortho(); 00654 } 00655 00656 void Rotation::getValue(float* oglmat) const 00657 { 00658 *oglmat++ = (float)data[0]; *oglmat++ = (float)data[3]; *oglmat++ = (float)data[6]; *oglmat++ = 0.f; 00659 *oglmat++ = (float)data[1]; *oglmat++ = (float)data[4]; *oglmat++ = (float)data[7]; *oglmat++ = 0.f; 00660 *oglmat++ = (float)data[2]; *oglmat++ = (float)data[5]; *oglmat++ = (float)data[8]; *oglmat++ = 0.f; 00661 *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat = 1.f; 00662 } 00663 00664 void Rotation::SetInverse() 00665 { 00666 double tmp; 00667 tmp = data[1];data[1]=data[3];data[3]=tmp; 00668 tmp = data[2];data[2]=data[6];data[6]=tmp; 00669 tmp = data[5];data[5]=data[7];data[7]=tmp; 00670 } 00671 00672 00673 00674 00675 00676 00677 00678 double Frame::operator()(int i,int j) { 00679 FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3)); 00680 if (i==3) { 00681 if (j==3) 00682 return 1.0; 00683 else 00684 return 0.0; 00685 } else { 00686 if (j==3) 00687 return p(i); 00688 else 00689 return M(i,j); 00690 00691 } 00692 } 00693 00694 double Frame::operator()(int i,int j) const { 00695 FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3)); 00696 if (i==3) { 00697 if (j==3) 00698 return 1; 00699 else 00700 return 0; 00701 } else { 00702 if (j==3) 00703 return p(i); 00704 else 00705 return M(i,j); 00706 00707 } 00708 } 00709 00710 00711 Frame Frame::Identity() { 00712 return Frame(Rotation::Identity(),Vector::Zero()); 00713 } 00714 00715 00716 void Frame::setValue(float* oglmat) 00717 { 00718 M.setValue(oglmat); 00719 p.data[0] = oglmat[12]; 00720 p.data[1] = oglmat[13]; 00721 p.data[2] = oglmat[14]; 00722 } 00723 00724 void Frame::getValue(float* oglmat) const 00725 { 00726 M.getValue(oglmat); 00727 oglmat[12] = (float)p.data[0]; 00728 oglmat[13] = (float)p.data[1]; 00729 oglmat[14] = (float)p.data[2]; 00730 } 00731 00732 void Vector::Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY) 00733 // a 3D vector where the 2D vector v is put in the XY plane of the frame 00734 // F_someframe_XY. 00735 { 00736 Vector tmp_XY; 00737 tmp_XY.Set2DXY(v_XY); 00738 tmp_XY = F_someframe_XY*(tmp_XY); 00739 } 00740 00741 00742 00743 00744 00745 00746 00747 00748 00749 //============ 2 dimensional version of the frames objects ============= 00750 IMETHOD Vector2::Vector2(const Vector2 & arg) 00751 { 00752 data[0] = arg.data[0]; 00753 data[1] = arg.data[1]; 00754 } 00755 00756 IMETHOD Vector2::Vector2(double x,double y) 00757 { 00758 data[0]=x;data[1]=y; 00759 } 00760 00761 IMETHOD Vector2::Vector2(double* xy) 00762 { 00763 data[0]=xy[0];data[1]=xy[1]; 00764 } 00765 00766 IMETHOD Vector2::Vector2(float* xy) 00767 { 00768 data[0]=xy[0];data[1]=xy[1]; 00769 } 00770 00771 IMETHOD Vector2& Vector2::operator =(const Vector2 & arg) 00772 { 00773 data[0] = arg.data[0]; 00774 data[1] = arg.data[1]; 00775 return *this; 00776 } 00777 00778 IMETHOD void Vector2::GetValue(double* xy) const 00779 { 00780 xy[0]=data[0];xy[1]=data[1]; 00781 } 00782 00783 IMETHOD Vector2 operator +(const Vector2 & lhs,const Vector2& rhs) 00784 { 00785 return Vector2(lhs.data[0]+rhs.data[0],lhs.data[1]+rhs.data[1]); 00786 } 00787 00788 IMETHOD Vector2 operator -(const Vector2 & lhs,const Vector2& rhs) 00789 { 00790 return Vector2(lhs.data[0]-rhs.data[0],lhs.data[1]-rhs.data[1]); 00791 } 00792 00793 IMETHOD Vector2 operator *(const Vector2& lhs,double rhs) 00794 { 00795 return Vector2(lhs.data[0]*rhs,lhs.data[1]*rhs); 00796 } 00797 00798 IMETHOD Vector2 operator *(double lhs,const Vector2& rhs) 00799 { 00800 return Vector2(lhs*rhs.data[0],lhs*rhs.data[1]); 00801 } 00802 00803 IMETHOD Vector2 operator /(const Vector2& lhs,double rhs) 00804 { 00805 return Vector2(lhs.data[0]/rhs,lhs.data[1]/rhs); 00806 } 00807 00808 IMETHOD Vector2& Vector2::operator +=(const Vector2 & arg) 00809 { 00810 data[0]+=arg.data[0]; 00811 data[1]+=arg.data[1]; 00812 return *this; 00813 } 00814 00815 IMETHOD Vector2& Vector2::operator -=(const Vector2 & arg) 00816 { 00817 data[0]-=arg.data[0]; 00818 data[1]-=arg.data[1]; 00819 return *this; 00820 } 00821 00822 IMETHOD Vector2 Vector2::Zero() { 00823 return Vector2(0,0); 00824 } 00825 00826 IMETHOD double Vector2::operator()(int index) const { 00827 FRAMES_CHECKI((0<=index)&&(index<=1)); 00828 return data[index]; 00829 } 00830 00831 IMETHOD double& Vector2::operator () (int index) 00832 { 00833 FRAMES_CHECKI((0<=index)&&(index<=1)); 00834 return data[index]; 00835 } 00836 IMETHOD void Vector2::ReverseSign() 00837 { 00838 data[0] = -data[0]; 00839 data[1] = -data[1]; 00840 } 00841 00842 00843 IMETHOD Vector2 operator-(const Vector2 & arg) 00844 { 00845 return Vector2(-arg.data[0],-arg.data[1]); 00846 } 00847 00848 00849 IMETHOD void Vector2::Set3DXY(const Vector& v) 00850 // projects v in its XY plane, and sets *this to these values 00851 { 00852 data[0]=v(0); 00853 data[1]=v(1); 00854 } 00855 IMETHOD void Vector2::Set3DYZ(const Vector& v) 00856 // projects v in its XY plane, and sets *this to these values 00857 { 00858 data[0]=v(1); 00859 data[1]=v(2); 00860 } 00861 IMETHOD void Vector2::Set3DZX(const Vector& v) 00862 // projects v in its XY plane, and and sets *this to these values 00863 { 00864 data[0]=v(2); 00865 data[1]=v(0); 00866 } 00867 00868 IMETHOD void Vector2::Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe) 00869 // projects v in the XY plane of F_someframe_XY, and sets *this to these values 00870 // expressed wrt someframe. 00871 { 00872 Vector tmp = F_someframe_XY.Inverse(v_someframe); 00873 data[0]=tmp(0); 00874 data[1]=tmp(1); 00875 } 00876 00877 00878 00879 IMETHOD Rotation2& Rotation2::operator=(const Rotation2& arg) { 00880 c=arg.c;s=arg.s; 00881 return *this; 00882 } 00883 00884 IMETHOD Vector2 Rotation2::operator*(const Vector2& v) const { 00885 return Vector2(v.data[0]*c-v.data[1]*s,v.data[0]*s+v.data[1]*c); 00886 } 00887 00888 IMETHOD double Rotation2::operator()(int i,int j) const { 00889 FRAMES_CHECKI((0<=i)&&(i<=1)&&(0<=j)&&(j<=1)); 00890 if (i==j) return c; 00891 if (i==0) 00892 return s; 00893 else 00894 return -s; 00895 } 00896 00897 00898 IMETHOD Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs) { 00899 return Rotation2(lhs.c*rhs.c-lhs.s*rhs.s,lhs.s*rhs.c+lhs.c*rhs.s); 00900 } 00901 00902 IMETHOD void Rotation2::SetInverse() { 00903 s=-s; 00904 } 00905 00906 IMETHOD Rotation2 Rotation2::Inverse() const { 00907 return Rotation2(c,-s); 00908 } 00909 00910 IMETHOD Vector2 Rotation2::Inverse(const Vector2& v) const { 00911 return Vector2(v.data[0]*c+v.data[1]*s,-v.data[0]*s+v.data[1]*c); 00912 } 00913 00914 IMETHOD Rotation2 Rotation2::Identity() { 00915 return Rotation2(1,0); 00916 } 00917 00918 IMETHOD void Rotation2::SetIdentity() 00919 { 00920 c = 1; 00921 s = 0; 00922 } 00923 00924 IMETHOD void Rotation2::SetRot(double angle) { 00925 c=cos(angle);s=sin(angle); 00926 } 00927 00928 IMETHOD Rotation2 Rotation2::Rot(double angle) { 00929 return Rotation2(cos(angle),sin(angle)); 00930 } 00931 00932 IMETHOD double Rotation2::GetRot() const { 00933 return atan2(s,c); 00934 } 00935 00936 00937 IMETHOD Frame2::Frame2() { 00938 } 00939 00940 IMETHOD Frame2::Frame2(const Rotation2 & R) 00941 { 00942 M=R; 00943 p=Vector2::Zero(); 00944 } 00945 00946 IMETHOD Frame2::Frame2(const Vector2 & V) 00947 { 00948 M = Rotation2::Identity(); 00949 p = V; 00950 } 00951 00952 IMETHOD Frame2::Frame2(const Rotation2 & R, const Vector2 & V) 00953 { 00954 M = R; 00955 p = V; 00956 } 00957 00958 IMETHOD Frame2 operator *(const Frame2& lhs,const Frame2& rhs) 00959 { 00960 return Frame2(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p); 00961 } 00962 00963 IMETHOD Vector2 Frame2::operator *(const Vector2 & arg) 00964 { 00965 return M*arg+p; 00966 } 00967 00968 IMETHOD Vector2 Frame2::Inverse(const Vector2& arg) const 00969 { 00970 return M.Inverse(arg-p); 00971 } 00972 00973 IMETHOD void Frame2::SetIdentity() 00974 { 00975 M.SetIdentity(); 00976 p = Vector2::Zero(); 00977 } 00978 00979 IMETHOD void Frame2::SetInverse() 00980 { 00981 M.SetInverse(); 00982 p = M*p; 00983 p.ReverseSign(); 00984 } 00985 00986 00987 IMETHOD Frame2 Frame2::Inverse() const 00988 { 00989 Frame2 tmp(*this); 00990 tmp.SetInverse(); 00991 return tmp; 00992 } 00993 00994 IMETHOD Frame2& Frame2::operator =(const Frame2 & arg) 00995 { 00996 M = arg.M; 00997 p = arg.p; 00998 return *this; 00999 } 01000 01001 IMETHOD Frame2::Frame2(const Frame2 & arg) : 01002 p(arg.p), M(arg.M) 01003 {} 01004 01005 01006 IMETHOD double Frame2::operator()(int i,int j) { 01007 FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); 01008 if (i==2) { 01009 if (j==2) 01010 return 1; 01011 else 01012 return 0; 01013 } else { 01014 if (j==2) 01015 return p(i); 01016 else 01017 return M(i,j); 01018 01019 } 01020 } 01021 01022 IMETHOD double Frame2::operator()(int i,int j) const { 01023 FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); 01024 if (i==2) { 01025 if (j==2) 01026 return 1; 01027 else 01028 return 0; 01029 } else { 01030 if (j==2) 01031 return p(i); 01032 else 01033 return M(i,j); 01034 01035 } 01036 } 01037 01038 // Scalar products. 01039 01040 IMETHOD double dot(const Vector& lhs,const Vector& rhs) { 01041 return rhs(0)*lhs(0)+rhs(1)*lhs(1)+rhs(2)*lhs(2); 01042 } 01043 01044 IMETHOD double dot(const Twist& lhs,const Wrench& rhs) { 01045 return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque); 01046 } 01047 01048 IMETHOD double dot(const Wrench& rhs,const Twist& lhs) { 01049 return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque); 01050 } 01051 01052 01053 01054 01055 01056 // Equality operators 01057 01058 01059 01060 IMETHOD bool Equal(const Vector& a,const Vector& b,double eps) { 01061 return (Equal(a.data[0],b.data[0],eps)&& 01062 Equal(a.data[1],b.data[1],eps)&& 01063 Equal(a.data[2],b.data[2],eps) ); 01064 } 01065 01066 01067 IMETHOD bool Equal(const Frame& a,const Frame& b,double eps) { 01068 return (Equal(a.p,b.p,eps)&& 01069 Equal(a.M,b.M,eps) ); 01070 } 01071 01072 IMETHOD bool Equal(const Wrench& a,const Wrench& b,double eps) { 01073 return (Equal(a.force,b.force,eps)&& 01074 Equal(a.torque,b.torque,eps) ); 01075 } 01076 01077 IMETHOD bool Equal(const Twist& a,const Twist& b,double eps) { 01078 return (Equal(a.rot,b.rot,eps)&& 01079 Equal(a.vel,b.vel,eps) ); 01080 } 01081 01082 IMETHOD bool Equal(const Vector2& a,const Vector2& b,double eps) { 01083 return (Equal(a.data[0],b.data[0],eps)&& 01084 Equal(a.data[1],b.data[1],eps) ); 01085 } 01086 01087 IMETHOD bool Equal(const Rotation2& a,const Rotation2& b,double eps) { 01088 return ( Equal(a.c,b.c,eps) && Equal(a.s,b.s,eps) ); 01089 } 01090 01091 IMETHOD bool Equal(const Frame2& a,const Frame2& b,double eps) { 01092 return (Equal(a.p,b.p,eps)&& 01093 Equal(a.M,b.M,eps) ); 01094 } 01095 01096 IMETHOD void SetToZero(Vector& v) { 01097 v=Vector::Zero(); 01098 } 01099 IMETHOD void SetToZero(Twist& v) { 01100 SetToZero(v.rot); 01101 SetToZero(v.vel); 01102 } 01103 IMETHOD void SetToZero(Wrench& v) { 01104 SetToZero(v.force); 01105 SetToZero(v.torque); 01106 } 01107 01108 IMETHOD void SetToZero(Vector2& v) { 01109 v = Vector2::Zero(); 01110 } 01111 01112 01114 // The following defines the operations 01115 // diff 01116 // addDelta 01117 // random 01118 // posrandom 01119 // on all the types defined in this library. 01120 // (mostly for uniform integration, differentiation and testing). 01121 // Defined as functions because double is not a class and a method 01122 // would brake uniformity when defined for a double. 01124 01125 01126 01127 01128 01129 01135 IMETHOD Rotation Rot(const Vector& axis_a_b) { 01136 // The formula is 01137 // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr)) 01138 // can be found by multiplying it with an arbitrary vector p 01139 // and noting that this vector is rotated. 01140 Vector rotvec = axis_a_b; 01141 double angle = rotvec.Normalize(1E-10); 01142 double ct = ::cos(angle); 01143 double st = ::sin(angle); 01144 double vt = 1-ct; 01145 return Rotation( 01146 ct + vt*rotvec(0)*rotvec(0), 01147 -rotvec(2)*st + vt*rotvec(0)*rotvec(1), 01148 rotvec(1)*st + vt*rotvec(0)*rotvec(2), 01149 rotvec(2)*st + vt*rotvec(1)*rotvec(0), 01150 ct + vt*rotvec(1)*rotvec(1), 01151 -rotvec(0)*st + vt*rotvec(1)*rotvec(2), 01152 -rotvec(1)*st + vt*rotvec(2)*rotvec(0), 01153 rotvec(0)*st + vt*rotvec(2)*rotvec(1), 01154 ct + vt*rotvec(2)*rotvec(2) 01155 ); 01156 } 01157 01158 IMETHOD Vector diff(const Vector& a,const Vector& b,double dt) { 01159 return (b-a)/dt; 01160 } 01161 01194 IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt) { 01195 Rotation R_b1_b2(R_a_b1.Inverse()*R_a_b2); 01196 return R_a_b1 * R_b1_b2.GetRot() / dt; 01197 } 01198 IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt) { 01199 return Twist( 01200 diff(F_a_b1.p,F_a_b2.p,dt), 01201 diff(F_a_b1.M,F_a_b2.M,dt) 01202 ); 01203 } 01204 IMETHOD Twist diff(const Twist& a,const Twist& b,double dt) { 01205 return Twist(diff(a.vel,b.vel,dt),diff(a.rot,b.rot,dt)); 01206 } 01207 01208 IMETHOD Wrench diff(const Wrench& a,const Wrench& b,double dt) { 01209 return Wrench( 01210 diff(a.force,b.force,dt), 01211 diff(a.torque,b.torque,dt) 01212 ); 01213 } 01214 01215 01216 IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt) { 01217 return a+da*dt; 01218 } 01219 01220 IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt) { 01221 return a*Rot(a.Inverse(da)*dt); 01222 } 01223 IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt) { 01224 return Frame( 01225 addDelta(a.M,da.rot,dt), 01226 addDelta(a.p,da.vel,dt) 01227 ); 01228 } 01229 IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt) { 01230 return Twist(addDelta(a.vel,da.vel,dt),addDelta(a.rot,da.rot,dt)); 01231 } 01232 IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt) { 01233 return Wrench(addDelta(a.force,da.force,dt),addDelta(a.torque,da.torque,dt)); 01234 } 01235 01236 01274 IMETHOD void random(Vector& a) { 01275 random(a[0]); 01276 random(a[1]); 01277 random(a[2]); 01278 } 01279 IMETHOD void random(Twist& a) { 01280 random(a.rot); 01281 random(a.vel); 01282 } 01283 IMETHOD void random(Wrench& a) { 01284 random(a.torque); 01285 random(a.force); 01286 } 01287 01288 IMETHOD void random(Rotation& R) { 01289 double alfa; 01290 double beta; 01291 double gamma; 01292 random(alfa); 01293 random(beta); 01294 random(gamma); 01295 R = Rotation::EulerZYX(alfa,beta,gamma); 01296 } 01297 01298 IMETHOD void random(Frame& F) { 01299 random(F.M); 01300 random(F.p); 01301 } 01302 01303 IMETHOD void posrandom(Vector& a) { 01304 posrandom(a[0]); 01305 posrandom(a[1]); 01306 posrandom(a[2]); 01307 } 01308 IMETHOD void posrandom(Twist& a) { 01309 posrandom(a.rot); 01310 posrandom(a.vel); 01311 } 01312 IMETHOD void posrandom(Wrench& a) { 01313 posrandom(a.torque); 01314 posrandom(a.force); 01315 } 01316 01317 IMETHOD void posrandom(Rotation& R) { 01318 double alfa; 01319 double beta; 01320 double gamma; 01321 posrandom(alfa); 01322 posrandom(beta); 01323 posrandom(gamma); 01324 R = Rotation::EulerZYX(alfa,beta,gamma); 01325 } 01326 01327 IMETHOD void posrandom(Frame& F) { 01328 random(F.M); 01329 random(F.p); 01330 } 01331 01332 01333 01334 01335 IMETHOD bool operator==(const Frame& a,const Frame& b ) { 01336 #ifdef KDL_USE_EQUAL 01337 return Equal(a,b); 01338 #else 01339 return (a.p == b.p && 01340 a.M == b.M ); 01341 #endif 01342 } 01343 01344 IMETHOD bool operator!=(const Frame& a,const Frame& b) { 01345 return !operator==(a,b); 01346 } 01347 01348 IMETHOD bool operator==(const Vector& a,const Vector& b) { 01349 #ifdef KDL_USE_EQUAL 01350 return Equal(a,b); 01351 #else 01352 return (a.data[0]==b.data[0]&& 01353 a.data[1]==b.data[1]&& 01354 a.data[2]==b.data[2] ); 01355 #endif 01356 } 01357 01358 IMETHOD bool operator!=(const Vector& a,const Vector& b) { 01359 return !operator==(a,b); 01360 } 01361 01362 IMETHOD bool operator==(const Twist& a,const Twist& b) { 01363 #ifdef KDL_USE_EQUAL 01364 return Equal(a,b); 01365 #else 01366 return (a.rot==b.rot && 01367 a.vel==b.vel ); 01368 #endif 01369 } 01370 01371 IMETHOD bool operator!=(const Twist& a,const Twist& b) { 01372 return !operator==(a,b); 01373 } 01374 01375 IMETHOD bool operator==(const Wrench& a,const Wrench& b ) { 01376 #ifdef KDL_USE_EQUAL 01377 return Equal(a,b); 01378 #else 01379 return (a.force==b.force && 01380 a.torque==b.torque ); 01381 #endif 01382 } 01383 01384 IMETHOD bool operator!=(const Wrench& a,const Wrench& b) { 01385 return !operator==(a,b); 01386 } 01387 IMETHOD bool operator!=(const Rotation& a,const Rotation& b) { 01388 return !operator==(a,b); 01389 } 01390