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
00026
00027
00028 #include "frames.hpp"
00029
00030 namespace KDL {
00031
00032 #ifndef KDL_INLINE
00033 #include "frames.inl"
00034 #endif
00035
00036 void Frame::Make4x4(double * d)
00037 {
00038 int i;
00039 int j;
00040 for (i=0;i<3;i++) {
00041 for (j=0;j<3;j++)
00042 d[i*4+j]=M(i,j);
00043 d[i*4+3] = p(i)/1000;
00044 }
00045 for (j=0;j<3;j++)
00046 d[12+j] = 0.;
00047 d[15] = 1;
00048 }
00049
00050 Frame Frame::DH_Craig1989(double a,double alpha,double d,double theta)
00051
00052 {
00053 double ct,st,ca,sa;
00054 ct = cos(theta);
00055 st = sin(theta);
00056 sa = sin(alpha);
00057 ca = cos(alpha);
00058 return Frame(Rotation(
00059 ct, -st, 0,
00060 st*ca, ct*ca, -sa,
00061 st*sa, ct*sa, ca ),
00062 Vector(
00063 a, -sa*d, ca*d )
00064 );
00065 }
00066
00067 Frame Frame::DH(double a,double alpha,double d,double theta)
00068
00069 {
00070 double ct,st,ca,sa;
00071 ct = cos(theta);
00072 st = sin(theta);
00073 sa = sin(alpha);
00074 ca = cos(alpha);
00075 return Frame(Rotation(
00076 ct, -st*ca, st*sa,
00077 st, ct*ca, -ct*sa,
00078 0, sa, ca ),
00079 Vector(
00080 a*ct, a*st, d )
00081 );
00082 }
00083
00084 double Vector2::Norm() const
00085 {
00086 if (fabs(data[0]) > fabs(data[1]) ) {
00087 return data[0]*sqrt(1+sqr(data[1]/data[0]));
00088 } else {
00089 return data[1]*sqrt(1+sqr(data[0]/data[1]));
00090 }
00091 }
00092
00093
00094
00095 double Vector2::Normalize(double eps) {
00096 double v = this->Norm();
00097 if (v < eps) {
00098 *this = Vector2(1,0);
00099 return v;
00100 } else {
00101 *this = (*this)/v;
00102 return v;
00103 }
00104 }
00105
00106
00107
00108 double Vector::Norm() const
00109 {
00110 double tmp1;
00111 double tmp2;
00112 tmp1 = fabs(data[0]);
00113 tmp2 = fabs(data[1]);
00114 if (tmp1 >= tmp2) {
00115 tmp2=fabs(data[2]);
00116 if (tmp1 >= tmp2) {
00117 if (tmp1 == 0) {
00118
00119 return 0;
00120 }
00121 return tmp1*sqrt(1+sqr(data[1]/data[0])+sqr(data[2]/data[0]));
00122 } else {
00123 return tmp2*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
00124 }
00125 } else {
00126 tmp1=fabs(data[2]);
00127 if (tmp2 > tmp1) {
00128 return tmp2*sqrt(1+sqr(data[0]/data[1])+sqr(data[2]/data[1]));
00129 } else {
00130 return tmp1*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
00131 }
00132 }
00133 }
00134
00135
00136
00137
00138 double Vector::Normalize(double eps) {
00139 double v = this->Norm();
00140 if (v < eps) {
00141 *this = Vector(1,0,0);
00142 return v;
00143 } else {
00144 *this = (*this)/v;
00145 return v;
00146 }
00147 }
00148
00149
00150 bool Equal(const Rotation& a,const Rotation& b,double eps) {
00151 return (Equal(a.data[0],b.data[0],eps) &&
00152 Equal(a.data[1],b.data[1],eps) &&
00153 Equal(a.data[2],b.data[2],eps) &&
00154 Equal(a.data[3],b.data[3],eps) &&
00155 Equal(a.data[4],b.data[4],eps) &&
00156 Equal(a.data[5],b.data[5],eps) &&
00157 Equal(a.data[6],b.data[6],eps) &&
00158 Equal(a.data[7],b.data[7],eps) &&
00159 Equal(a.data[8],b.data[8],eps) );
00160 }
00161
00162
00163
00164 Rotation operator *(const Rotation& lhs,const Rotation& rhs)
00165
00166 {
00167 return Rotation(
00168 lhs.data[0]*rhs.data[0]+lhs.data[1]*rhs.data[3]+lhs.data[2]*rhs.data[6],
00169 lhs.data[0]*rhs.data[1]+lhs.data[1]*rhs.data[4]+lhs.data[2]*rhs.data[7],
00170 lhs.data[0]*rhs.data[2]+lhs.data[1]*rhs.data[5]+lhs.data[2]*rhs.data[8],
00171 lhs.data[3]*rhs.data[0]+lhs.data[4]*rhs.data[3]+lhs.data[5]*rhs.data[6],
00172 lhs.data[3]*rhs.data[1]+lhs.data[4]*rhs.data[4]+lhs.data[5]*rhs.data[7],
00173 lhs.data[3]*rhs.data[2]+lhs.data[4]*rhs.data[5]+lhs.data[5]*rhs.data[8],
00174 lhs.data[6]*rhs.data[0]+lhs.data[7]*rhs.data[3]+lhs.data[8]*rhs.data[6],
00175 lhs.data[6]*rhs.data[1]+lhs.data[7]*rhs.data[4]+lhs.data[8]*rhs.data[7],
00176 lhs.data[6]*rhs.data[2]+lhs.data[7]*rhs.data[5]+lhs.data[8]*rhs.data[8]
00177 );
00178
00179 }
00180
00181 Rotation Rotation::Quaternion(double x,double y,double z, double w)
00182 {
00183 double x2, y2, z2, w2;
00184 x2 = x*x; y2 = y*y; z2 = z*z; w2 = w*w;
00185 return Rotation(w2+x2-y2-z2, 2*x*y-2*w*z, 2*x*z+2*w*y,
00186 2*x*y+2*w*z, w2-x2+y2-z2, 2*y*z-2*w*x,
00187 2*x*z-2*w*y, 2*y*z+2*w*x, w2-x2-y2+z2);
00188 }
00189
00190
00191
00192
00193
00194
00195 void Rotation::GetQuaternion(double& x,double& y,double& z, double& w) const
00196 {
00197 double trace = (*this)(0,0) + (*this)(1,1) + (*this)(2,2) + 1.0f;
00198 if( trace > epsilon ){
00199 double s = 0.5f / sqrt(trace);
00200 w = 0.25f / s;
00201 x = ( (*this)(2,1) - (*this)(1,2) ) * s;
00202 y = ( (*this)(0,2) - (*this)(2,0) ) * s;
00203 z = ( (*this)(1,0) - (*this)(0,1) ) * s;
00204 }else{
00205 if ( (*this)(0,0) > (*this)(1,1) && (*this)(0,0) > (*this)(2,2) ){
00206 float s = 2.0f * sqrtf( 1.0f + (*this)(0,0) - (*this)(1,1) - (*this)(2,2));
00207 w = ((*this)(2,1) - (*this)(1,2) ) / s;
00208 x = 0.25f * s;
00209 y = ((*this)(0,1) + (*this)(1,0) ) / s;
00210 z = ((*this)(0,2) + (*this)(2,0) ) / s;
00211 } else if ((*this)(1,1) > (*this)(2,2)) {
00212 float s = 2.0f * sqrtf( 1.0f + (*this)(1,1) - (*this)(0,0) - (*this)(2,2));
00213 w = ((*this)(0,2) - (*this)(2,0) ) / s;
00214 x = ((*this)(0,1) + (*this)(1,0) ) / s;
00215 y = 0.25f * s;
00216 z = ((*this)(1,2) + (*this)(2,1) ) / s;
00217 }else {
00218 float s = 2.0f * sqrtf( 1.0f + (*this)(2,2) - (*this)(0,0) - (*this)(1,1) );
00219 w = ((*this)(1,0) - (*this)(0,1) ) / s;
00220 x = ((*this)(0,2) + (*this)(2,0) ) / s;
00221 y = ((*this)(1,2) + (*this)(2,1) ) / s;
00222 z = 0.25f * s;
00223 }
00224 }
00225 }
00226
00227 Rotation Rotation::RPY(double roll,double pitch,double yaw)
00228 {
00229 double ca1,cb1,cc1,sa1,sb1,sc1;
00230 ca1 = cos(yaw); sa1 = sin(yaw);
00231 cb1 = cos(pitch);sb1 = sin(pitch);
00232 cc1 = cos(roll);sc1 = sin(roll);
00233 return Rotation(ca1*cb1,ca1*sb1*sc1 - sa1*cc1,ca1*sb1*cc1 + sa1*sc1,
00234 sa1*cb1,sa1*sb1*sc1 + ca1*cc1,sa1*sb1*cc1 - ca1*sc1,
00235 -sb1,cb1*sc1,cb1*cc1);
00236 }
00237
00238
00239 void Rotation::GetRPY(double& roll,double& pitch,double& yaw) const
00240 {
00241 if (fabs(data[6]) > 1.0 - epsilon ) {
00242 roll = -sign(data[6]) * atan2(data[1], data[4]);
00243 pitch= -sign(data[6]) * PI / 2;
00244 yaw = 0.0 ;
00245 } else {
00246 roll = atan2(data[7], data[8]);
00247 pitch = atan2(-data[6], sqrt( sqr(data[0]) +sqr(data[3]) ) );
00248 yaw = atan2(data[3], data[0]);
00249 }
00250 }
00251
00252 Rotation Rotation::EulerZYZ(double Alfa,double Beta,double Gamma) {
00253 double sa,ca,sb,cb,sg,cg;
00254 sa = sin(Alfa);ca = cos(Alfa);
00255 sb = sin(Beta);cb = cos(Beta);
00256 sg = sin(Gamma);cg = cos(Gamma);
00257 return Rotation( ca*cb*cg-sa*sg, -ca*cb*sg-sa*cg, ca*sb,
00258 sa*cb*cg+ca*sg, -sa*cb*sg+ca*cg, sa*sb,
00259 -sb*cg , sb*sg, cb
00260 );
00261
00262 }
00263
00264
00265 void Rotation::GetEulerZYZ(double& alfa,double& beta,double& gamma) const {
00266 if (fabs(data[6]) < epsilon ) {
00267 alfa=0.0;
00268 if (data[8]>0) {
00269 beta = 0.0;
00270 gamma= atan2(-data[1],data[0]);
00271 } else {
00272 beta = PI;
00273 gamma= atan2(data[1],-data[0]);
00274 }
00275 } else {
00276 alfa=atan2(data[5], data[2]);
00277 beta=atan2(sqrt( sqr(data[6]) +sqr(data[7]) ),data[8]);
00278 gamma=atan2(data[7], -data[6]);
00279 }
00280 }
00281
00282 Rotation Rotation::Rot(const Vector& rotaxis,double angle) {
00283
00284
00285
00286
00287 Vector rotvec = rotaxis;
00288 rotvec.Normalize();
00289 return Rotation::Rot2(rotvec,angle);
00290 }
00291
00292 Rotation Rotation::Rot2(const Vector& rotvec,double angle) {
00293
00294
00295
00296
00297
00298 double ct = cos(angle);
00299 double st = sin(angle);
00300 double vt = 1-ct;
00301 double m_vt_0=vt*rotvec(0);
00302 double m_vt_1=vt*rotvec(1);
00303 double m_vt_2=vt*rotvec(2);
00304 double m_st_0=rotvec(0)*st;
00305 double m_st_1=rotvec(1)*st;
00306 double m_st_2=rotvec(2)*st;
00307 double m_vt_0_1=m_vt_0*rotvec(1);
00308 double m_vt_0_2=m_vt_0*rotvec(2);
00309 double m_vt_1_2=m_vt_1*rotvec(2);
00310 return Rotation(
00311 ct + m_vt_0*rotvec(0),
00312 -m_st_2 + m_vt_0_1,
00313 m_st_1 + m_vt_0_2,
00314 m_st_2 + m_vt_0_1,
00315 ct + m_vt_1*rotvec(1),
00316 -m_st_0 + m_vt_1_2,
00317 -m_st_1 + m_vt_0_2,
00318 m_st_0 + m_vt_1_2,
00319 ct + m_vt_2*rotvec(2)
00320 );
00321 }
00322
00323
00324
00325 Vector Rotation::GetRot() const
00326
00327
00328 {
00329 Vector axis = Vector((data[7]-data[5]),
00330 (data[2]-data[6]),
00331 (data[3]-data[1]) )/2;
00332
00333 double sa = axis.Norm();
00334 double ca = (data[0]+data[4]+data[8]-1)/2.0;
00335 double alfa;
00336 if (sa > epsilon)
00337 alfa = ::atan2(sa,ca)/sa;
00338 else
00339 alfa = 1;
00340 return axis * alfa;
00341 }
00342
00343
00344
00355 double Rotation::GetRotAngle(Vector& axis,double eps) const {
00356 double ca = (data[0]+data[4]+data[8]-1)/2.0;
00357 if (ca>1-eps) {
00358
00359 axis = Vector(0,0,1);
00360 return 0;
00361 }
00362 if (ca < -1+eps) {
00363
00364 double z = sqrt( (data[8]+1)/2 );
00365 double x = (data[2])/2/z;
00366 double y = (data[5])/2/z;
00367 axis = Vector( x,y,z );
00368 return PI;
00369 }
00370 double angle = acos(ca);
00371 double sa = sin(angle);
00372 axis = Vector((data[7]-data[5])/2/sa,
00373 (data[2]-data[6])/2/sa,
00374 (data[3]-data[1])/2/sa );
00375 return angle;
00376 }
00377
00378 bool operator==(const Rotation& a,const Rotation& b) {
00379 #ifdef KDL_USE_EQUAL
00380 return Equal(a,b);
00381 #else
00382 return ( a.data[0]==b.data[0] &&
00383 a.data[1]==b.data[1] &&
00384 a.data[2]==b.data[2] &&
00385 a.data[3]==b.data[3] &&
00386 a.data[4]==b.data[4] &&
00387 a.data[5]==b.data[5] &&
00388 a.data[6]==b.data[6] &&
00389 a.data[7]==b.data[7] &&
00390 a.data[8]==b.data[8] );
00391 #endif
00392 }
00393 }