/*************************************************************************** frames.inl - description ------------------------- begin : June 2006 copyright : (C) 2006 Erwin Aertbelien email : firstname.lastname@mech.kuleuven.ac.be History (only major changes)( AUTHOR-Description ) : *************************************************************************** * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307 USA * * * ***************************************************************************/ IMETHOD Vector::Vector(const Vector & arg) { data[0] = arg.data[0]; data[1] = arg.data[1]; data[2] = arg.data[2]; } IMETHOD Vector::Vector(double x,double y, double z) { data[0]=x;data[1]=y;data[2]=z; } IMETHOD Vector::Vector(double* xyz) { data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2]; } IMETHOD Vector::Vector(float* xyz) { data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2]; } IMETHOD void Vector::GetValue(double* xyz) const { xyz[0]=data[0];xyz[1]=data[1];xyz[2]=data[2]; } IMETHOD Vector& Vector::operator =(const Vector & arg) { data[0] = arg.data[0]; data[1] = arg.data[1]; data[2] = arg.data[2]; return *this; } IMETHOD Vector operator +(const Vector & lhs,const Vector& rhs) { Vector tmp; tmp.data[0] = lhs.data[0]+rhs.data[0]; tmp.data[1] = lhs.data[1]+rhs.data[1]; tmp.data[2] = lhs.data[2]+rhs.data[2]; return tmp; } IMETHOD Vector operator -(const Vector & lhs,const Vector& rhs) { Vector tmp; tmp.data[0] = lhs.data[0]-rhs.data[0]; tmp.data[1] = lhs.data[1]-rhs.data[1]; tmp.data[2] = lhs.data[2]-rhs.data[2]; return tmp; } IMETHOD double Vector::x() const { return data[0]; } IMETHOD double Vector::y() const { return data[1]; } IMETHOD double Vector::z() const { return data[2]; } IMETHOD void Vector::x( double _x ) { data[0] = _x; } IMETHOD void Vector::y( double _y ) { data[1] = _y; } IMETHOD void Vector::z( double _z ) { data[2] = _z; } Vector operator *(const Vector& lhs,double rhs) { Vector tmp; tmp.data[0] = lhs.data[0]*rhs; tmp.data[1] = lhs.data[1]*rhs; tmp.data[2] = lhs.data[2]*rhs; return tmp; } Vector operator *(double lhs,const Vector& rhs) { Vector tmp; tmp.data[0] = lhs*rhs.data[0]; tmp.data[1] = lhs*rhs.data[1]; tmp.data[2] = lhs*rhs.data[2]; return tmp; } Vector operator /(const Vector& lhs,double rhs) { Vector tmp; tmp.data[0] = lhs.data[0]/rhs; tmp.data[1] = lhs.data[1]/rhs; tmp.data[2] = lhs.data[2]/rhs; return tmp; } Vector operator *(const Vector & lhs,const Vector& rhs) // Complexity : 6M+3A { Vector tmp; tmp.data[0] = lhs.data[1]*rhs.data[2]-lhs.data[2]*rhs.data[1]; tmp.data[1] = lhs.data[2]*rhs.data[0]-lhs.data[0]*rhs.data[2]; tmp.data[2] = lhs.data[0]*rhs.data[1]-lhs.data[1]*rhs.data[0]; return tmp; } Vector& Vector::operator +=(const Vector & arg) // Complexity : 3A { data[0]+=arg.data[0]; data[1]+=arg.data[1]; data[2]+=arg.data[2]; return *this; } Vector& Vector::operator -=(const Vector & arg) // Complexity : 3A { data[0]-=arg.data[0]; data[1]-=arg.data[1]; data[2]-=arg.data[2]; return *this; } Vector Vector::Zero() { return Vector(0,0,0); } double Vector::operator()(int index) const { FRAMES_CHECKI((0<=index)&&(index<=2)); return data[index]; } double& Vector::operator () (int index) { FRAMES_CHECKI((0<=index)&&(index<=2)); return data[index]; } IMETHOD Vector Normalize(const Vector& a, double eps) { double l=a.Norm(); return (lforce, this->torque+this->force*v_base_AB ); } Wrench& Wrench::operator-=(const Wrench& arg) { torque-=arg.torque; force -=arg.force; return *this; } Wrench& Wrench::operator+=(const Wrench& arg) { torque+=arg.torque; force +=arg.force; return *this; } double& Wrench::operator()(int i) { // assert((0<=i)&&(i<6)); done by underlying routines if (i<3) return force(i); else return torque(i-3); } double Wrench::operator()(int i) const { // assert((0<=i)&&(i<6)); done by underlying routines if (i<3) return force(i); else return torque(i-3); } Wrench operator*(const Wrench& lhs,double rhs) { return Wrench(lhs.force*rhs,lhs.torque*rhs); } Wrench operator*(double lhs,const Wrench& rhs) { return Wrench(lhs*rhs.force,lhs*rhs.torque); } Wrench operator/(const Wrench& lhs,double rhs) { return Wrench(lhs.force/rhs,lhs.torque/rhs); } // addition of Wrench's Wrench operator+(const Wrench& lhs,const Wrench& rhs) { return Wrench(lhs.force+rhs.force,lhs.torque+rhs.torque); } Wrench operator-(const Wrench& lhs,const Wrench& rhs) { return Wrench(lhs.force-rhs.force,lhs.torque-rhs.torque); } // unary - Wrench operator-(const Wrench& arg) { return Wrench(-arg.force,-arg.torque); } Twist Frame::operator * (const Twist& arg) const // Complexity : 24M+18A { Twist tmp; tmp.rot = M*arg.rot; tmp.vel = M*arg.vel+p*tmp.rot; return tmp; } Twist Frame::Inverse(const Twist& arg) const { Twist tmp; tmp.rot = M.Inverse(arg.rot); tmp.vel = M.Inverse(arg.vel-p*arg.rot); return tmp; } Twist Twist::Zero() { return Twist(Vector::Zero(),Vector::Zero()); } void Twist::ReverseSign() { vel.ReverseSign(); rot.ReverseSign(); } Twist Twist::RefPoint(const Vector& v_base_AB) const // Changes the reference point of the twist. // The vector v_base_AB is expressed in the same base as the twist // The vector v_base_AB is a vector from the old point to // the new point. // Complexity : 6M+6A { return Twist(this->vel+this->rot*v_base_AB,this->rot); } Twist& Twist::operator-=(const Twist& arg) { vel-=arg.vel; rot -=arg.rot; return *this; } Twist& Twist::operator+=(const Twist& arg) { vel+=arg.vel; rot +=arg.rot; return *this; } double& Twist::operator()(int i) { // assert((0<=i)&&(i<6)); done by underlying routines if (i<3) return vel(i); else return rot(i-3); } double Twist::operator()(int i) const { // assert((0<=i)&&(i<6)); done by underlying routines if (i<3) return vel(i); else return rot(i-3); } Twist operator*(const Twist& lhs,double rhs) { return Twist(lhs.vel*rhs,lhs.rot*rhs); } Twist operator*(double lhs,const Twist& rhs) { return Twist(lhs*rhs.vel,lhs*rhs.rot); } Twist operator/(const Twist& lhs,double rhs) { return Twist(lhs.vel/rhs,lhs.rot/rhs); } // addition of Twist's Twist operator+(const Twist& lhs,const Twist& rhs) { return Twist(lhs.vel+rhs.vel,lhs.rot+rhs.rot); } Twist operator-(const Twist& lhs,const Twist& rhs) { return Twist(lhs.vel-rhs.vel,lhs.rot-rhs.rot); } // unary - Twist operator-(const Twist& arg) { return Twist(-arg.vel,-arg.rot); } Frame::Frame(const Rotation & R) { M=R; p=Vector::Zero(); } Frame::Frame(const Vector & V) { M = Rotation::Identity(); p = V; } Frame::Frame(const Rotation & R, const Vector & V) { M = R; p = V; } Frame operator *(const Frame& lhs,const Frame& rhs) // Complexity : 36M+36A { return Frame(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p); } Vector Frame::operator *(const Vector & arg) const { return M*arg+p; } Vector Frame::Inverse(const Vector& arg) const { return M.Inverse(arg-p); } Frame Frame::Inverse() const { return Frame(M.Inverse(),-M.Inverse(p)); } Frame& Frame::operator =(const Frame & arg) { M = arg.M; p = arg.p; return *this; } Frame::Frame(const Frame & arg) : p(arg.p),M(arg.M) {} void Vector::ReverseSign() { data[0] = -data[0]; data[1] = -data[1]; data[2] = -data[2]; } Vector operator-(const Vector & arg) { Vector tmp; tmp.data[0]=-arg.data[0]; tmp.data[1]=-arg.data[1]; tmp.data[2]=-arg.data[2]; return tmp; } void Vector::Set2DXY(const Vector2& v) // a 3D vector where the 2D vector v is put in the XY plane { data[0]=v(0); data[1]=v(1); data[2]=0; } void Vector::Set2DYZ(const Vector2& v) // a 3D vector where the 2D vector v is put in the YZ plane { data[1]=v(0); data[2]=v(1); data[0]=0; } void Vector::Set2DZX(const Vector2& v) // a 3D vector where the 2D vector v is put in the ZX plane { data[2]=v(0); data[0]=v(1); data[1]=0; } double& Rotation::operator()(int i,int j) { FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); return data[i*3+j]; } double Rotation::operator()(int i,int j) const { FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2)); return data[i*3+j]; } Rotation::Rotation( double Xx,double Yx,double Zx, double Xy,double Yy,double Zy, double Xz,double Yz,double Zz) { data[0] = Xx;data[1]=Yx;data[2]=Zx; data[3] = Xy;data[4]=Yy;data[5]=Zy; data[6] = Xz;data[7]=Yz;data[8]=Zz; } Rotation::Rotation(const Vector& x,const Vector& y,const Vector& z) { data[0] = x.data[0];data[3] = x.data[1];data[6] = x.data[2]; data[1] = y.data[0];data[4] = y.data[1];data[7] = y.data[2]; data[2] = z.data[0];data[5] = z.data[1];data[8] = z.data[2]; } Rotation& Rotation::operator=(const Rotation& arg) { int count=9; while (count--) data[count] = arg.data[count]; return *this; } Vector Rotation::operator*(const Vector& v) const { // Complexity : 9M+6A return Vector( data[0]*v.data[0] + data[1]*v.data[1] + data[2]*v.data[2], data[3]*v.data[0] + data[4]*v.data[1] + data[5]*v.data[2], data[6]*v.data[0] + data[7]*v.data[1] + data[8]*v.data[2] ); } Twist Rotation::operator * (const Twist& arg) const // Transformation of the base to which the twist is expressed. // look at Frame*Twist for a transformation that also transforms // the velocity reference point. // Complexity : 18M+12A { return Twist((*this)*arg.vel,(*this)*arg.rot); } Wrench Rotation::operator * (const Wrench& arg) const // Transformation of the base to which the wrench is expressed. // look at Frame*Twist for a transformation that also transforms // the force reference point. { return Wrench((*this)*arg.force,(*this)*arg.torque); } Rotation Rotation::Identity() { return Rotation(1,0,0,0,1,0,0,0,1); } // *this = *this * ROT(X,angle) void Rotation::DoRotX(double angle) { double cs = cos(angle); double sn = sin(angle); double x1,x2,x3; x1 = cs* (*this)(0,1) + sn* (*this)(0,2); x2 = cs* (*this)(1,1) + sn* (*this)(1,2); x3 = cs* (*this)(2,1) + sn* (*this)(2,2); (*this)(0,2) = -sn* (*this)(0,1) + cs* (*this)(0,2); (*this)(1,2) = -sn* (*this)(1,1) + cs* (*this)(1,2); (*this)(2,2) = -sn* (*this)(2,1) + cs* (*this)(2,2); (*this)(0,1) = x1; (*this)(1,1) = x2; (*this)(2,1) = x3; } void Rotation::DoRotY(double angle) { double cs = cos(angle); double sn = sin(angle); double x1,x2,x3; x1 = cs* (*this)(0,0) - sn* (*this)(0,2); x2 = cs* (*this)(1,0) - sn* (*this)(1,2); x3 = cs* (*this)(2,0) - sn* (*this)(2,2); (*this)(0,2) = sn* (*this)(0,0) + cs* (*this)(0,2); (*this)(1,2) = sn* (*this)(1,0) + cs* (*this)(1,2); (*this)(2,2) = sn* (*this)(2,0) + cs* (*this)(2,2); (*this)(0,0) = x1; (*this)(1,0) = x2; (*this)(2,0) = x3; } void Rotation::DoRotZ(double angle) { double cs = cos(angle); double sn = sin(angle); double x1,x2,x3; x1 = cs* (*this)(0,0) + sn* (*this)(0,1); x2 = cs* (*this)(1,0) + sn* (*this)(1,1); x3 = cs* (*this)(2,0) + sn* (*this)(2,1); (*this)(0,1) = -sn* (*this)(0,0) + cs* (*this)(0,1); (*this)(1,1) = -sn* (*this)(1,0) + cs* (*this)(1,1); (*this)(2,1) = -sn* (*this)(2,0) + cs* (*this)(2,1); (*this)(0,0) = x1; (*this)(1,0) = x2; (*this)(2,0) = x3; } Rotation Rotation::RotX(double angle) { double cs=cos(angle); double sn=sin(angle); return Rotation(1,0,0,0,cs,-sn,0,sn,cs); } Rotation Rotation::RotY(double angle) { double cs=cos(angle); double sn=sin(angle); return Rotation(cs,0,sn,0,1,0,-sn,0,cs); } Rotation Rotation::RotZ(double angle) { double cs=cos(angle); double sn=sin(angle); return Rotation(cs,-sn,0,sn,cs,0,0,0,1); } void Frame::Integrate(const Twist& t_this,double samplefrequency) { double n = t_this.rot.Norm()/samplefrequency; if (n