LaparoscopicRigidTypes.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #ifndef SOFA_DEFAULTTYPE_LAPAROSCOPICRIGIDTYPES_H
00028 #define SOFA_DEFAULTTYPE_LAPAROSCOPICRIGIDTYPES_H
00029 
00030 
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <sofa/defaulttype/DataTypeInfo.h>
00033 #include <sofa/defaulttype/Vec.h>
00034 #include <sofa/core/objectmodel/BaseContext.h>
00035 #include <sofa/core/componentmodel/behavior/Mass.h>
00036 #include <sofa/helper/vector.h>
00037 #include <iostream>
00038 
00039 namespace sofa
00040 {
00041 
00042 namespace defaulttype
00043 {
00044 
00045 using sofa::helper::vector;
00046 
00047 class LaparoscopicRigid3Types
00048 {
00049 public:
00050     
00051     typedef SReal Real;
00052     
00053     class Deriv
00054     {
00055     private:
00056         Real vTranslation;
00057         Vector3 vOrientation;
00058       public:
00059         typedef Real value_type;
00060         friend class Coord;
00061         
00062         Deriv (const Real &velTranslation, const Vector3 &velOrient)
00063         : vTranslation(velTranslation), vOrientation(velOrient) {}
00064         Deriv () { clear(); }
00065         
00066         void clear() { vTranslation = 0; vOrientation.clear(); }
00067         
00068         void operator +=(const Deriv& a)
00069         {
00070             vTranslation += a.vTranslation;
00071             vOrientation += a.vOrientation;
00072         }
00073         
00074         Deriv operator + (const Deriv& a) const
00075         {
00076             Deriv d;
00077             d.vTranslation = vTranslation + a.vTranslation;
00078             d.vOrientation = vOrientation + a.vOrientation;
00079             return d;
00080         }
00081         
00082         void operator*=(Real a)
00083         {
00084             vTranslation *= a;
00085             vOrientation *= a;
00086         }
00087         
00088         Deriv operator*(Real a) const
00089         {
00090             Deriv r = *this;
00091             r*=a;
00092             return r;
00093         }
00094         
00095         Deriv operator - () const 
00096         {
00097             return Deriv(-vTranslation, -vOrientation);
00098         }
00099         
00101         Real operator*(const Deriv& a) const
00102         {
00103             return vTranslation*a.vTranslation
00104                     +vOrientation[0]*a.vOrientation[0]+vOrientation[1]*a.vOrientation[1]
00105                     +vOrientation[2]*a.vOrientation[2];
00106         }
00107         
00108         Real& getVTranslation (void) { return vTranslation; }
00109         Vector3& getVOrientation (void) { return vOrientation; }
00110         const Real& getVTranslation (void) const { return vTranslation; }
00111         const Vector3& getVOrientation (void) const { return vOrientation; }
00112         inline friend std::ostream& operator << (std::ostream& out, const Deriv& v ){
00113             out<<v.getVTranslation();
00114             out<<" "<<v.getVOrientation();
00115             return out;
00116         }
00117                 inline friend std::istream& operator >> (std::istream& in, Deriv& v ){
00118                     in>>v.vTranslation;
00119                     in>>v.vOrientation;
00120                     return in;
00121                 }
00122         };
00123     
00124     class Coord
00125     {
00126       
00127     private:
00128         Real translation;
00129         Quat orientation;
00130     public:
00131         typedef Real value_type;
00132         Coord (const Real &posTranslation, const Quat &orient)
00133         : translation(posTranslation), orientation(orient) {}
00134         Coord () { clear(); }
00135         
00136         void clear() { translation = 0; orientation.clear(); }
00137     
00138         void operator +=(const Deriv& a)
00139         {
00140             translation += a.getVTranslation();
00141             orientation.normalize();
00142             Quat qDot = orientation.vectQuatMult(a.getVOrientation());
00143             for (int i = 0; i < 4; i++)
00144                 orientation[i] += qDot[i] * (SReal)0.5;
00145             orientation.normalize();
00146         }
00147         
00148         Coord operator + (const Deriv& a) const
00149         {
00150             Coord c = *this;
00151             c.translation += a.getVTranslation();
00152             c.orientation.normalize();
00153             Quat qDot = c.orientation.vectQuatMult(a.getVOrientation());
00154             for (int i = 0; i < 4; i++)
00155                 c.orientation[i] += qDot[i] * (SReal)0.5;
00156             c.orientation.normalize();
00157             return c;
00158         }
00159         
00160         void operator +=(const Coord& a)
00161         {
00162 //          std::cout << "+="<<std::endl;
00163             translation += a.getTranslation();
00164             //orientation += a.getOrientation();
00165             //orientation.normalize();
00166         }
00167         
00168         void operator*=(Real a)
00169         {
00170 //          std::cout << "*="<<std::endl;
00171             translation *= a;
00172             //orientation *= a;
00173         }
00174         
00175         Coord operator*(Real a) const
00176         {
00177             Coord r = *this;
00178             r*=a;
00179             return r;
00180         }
00181         
00183         Real operator*(const Coord& a) const
00184         {
00185             return translation*a.translation
00186                 +orientation[0]*a.orientation[0]+orientation[1]*a.orientation[1]
00187                 +orientation[2]*a.orientation[2]+orientation[3]*a.orientation[3];
00188         }
00189         
00190         Real& getTranslation () { return translation; }
00191         Quat& getOrientation () { return orientation; }
00192         const Real& getTranslation () const { return translation; }
00193         const Quat& getOrientation () const { return orientation; }
00194         inline friend std::ostream& operator << (std::ostream& out, const Coord& c ){
00195             out<<c.getTranslation();
00196             out<<" "<<c.getOrientation();
00197             return out;
00198         }
00199                 inline friend std::istream& operator >> (std::istream& in, Coord& c ){
00200                     in>>c.translation;
00201                     in>>c.orientation;
00202                     return in;
00203                 }
00204         
00205         static Coord identity() {
00206             Coord c;
00207             return c;
00208         }
00209         
00211         void multRight( const Coord& c )
00212         {
00213             translation += c.getTranslation();
00214             orientation = orientation * c.getOrientation();
00215         }
00216         
00218         Coord mult( const Coord& c ) const {
00219             Coord r;
00220             r.translation = translation + c.translation; //orientation.rotate( c.translation );
00221             r.orientation = orientation * c.getOrientation();
00222             return r;
00223         }
00225         Vector3 vectorToChild( const Vector3& v ) const {
00226             return orientation.inverseRotate(v);
00227         }
00228     };
00229     
00230     template <class T>
00231     class SparseData
00232     {
00233     public:
00234         SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
00235         unsigned int index;
00236         T data;
00237     };
00238 
00239     typedef SparseData<Coord> SparseCoord;
00240     typedef SparseData<Deriv> SparseDeriv;
00241 
00242     typedef vector<SparseCoord> SparseVecCoord;
00243     typedef vector<SparseDeriv> SparseVecDeriv;
00244 
00246     typedef vector<SparseVecDeriv> VecConst;
00247 
00248     typedef vector<Coord> VecCoord;
00249     typedef vector<Deriv> VecDeriv;
00250     typedef vector<Real> VecReal;
00251 
00252     template<typename T>
00253     static void set(Coord& c, T x, T, T)
00254     {
00255         c.getTranslation() = (Real)x;
00256     }
00257     
00258     template<typename T>
00259     static void get(T& x, T&, T&, const Coord& c)
00260     {
00261         x = (T)c.getTranslation();
00262     }
00263     
00264     template<typename T>
00265     static void add(Coord& c, T x, T, T)
00266     {
00267         c.getTranslation() += (Real)x;
00268     }
00269     
00270     template<typename T>
00271     static void set(Deriv& c, T x, T, T)
00272     {
00273         c.getVTranslation() = (Real)x;
00274     }
00275     
00276     template<typename T>
00277     static void get(T& x, T& y, T& z, const Deriv& c)
00278     {
00279         x = (T)c.getVTranslation();
00280         y = (T)0;
00281         z = (T)0;
00282     }
00283     
00284     template<typename T>
00285     static void add(Deriv& c, T x, T, T)
00286     {
00287         c.getVTranslation() += (T)x;
00288     }
00289     static const char* Name()
00290     {
00291        return "LaparoscopicRigid3";
00292     }
00293 
00294     static Coord interpolate(const helper::vector< Coord > &ancestors, const helper::vector< Real > &coefs)
00295     {
00296         assert(ancestors.size() == coefs.size());
00297             
00298         Coord c;
00299         
00300         for (unsigned int i = 0; i < ancestors.size(); i++)
00301         {
00302             c += ancestors[i] * coefs[i];
00303         }
00304 
00305         return c;
00306     }
00307 
00308     static Deriv interpolate(const helper::vector< Deriv > &ancestors, const helper::vector< Real > &coefs)
00309     {
00310         assert(ancestors.size() == coefs.size());
00311             
00312         Deriv d;
00313         
00314         for (unsigned int i = 0; i < ancestors.size(); i++)
00315         {
00316             d += ancestors[i] * coefs[i];
00317         }
00318 
00319         return d;
00320     }
00321 };
00322 
00323 inline LaparoscopicRigid3Types::Deriv operator*(const LaparoscopicRigid3Types::Deriv& d, const Rigid3Mass& m)
00324 {
00325     LaparoscopicRigid3Types::Deriv res;
00326     res.getVTranslation() = d.getVTranslation() * m.mass;
00327     res.getVOrientation() = m.inertiaMassMatrix * d.getVOrientation();
00328     return res;
00329 }
00330 
00331 inline LaparoscopicRigid3Types::Deriv operator/(const LaparoscopicRigid3Types::Deriv& d, const Rigid3Mass& m)
00332 {
00333     LaparoscopicRigid3Types::Deriv res;
00334     res.getVTranslation() = d.getVTranslation() / m.mass;
00335     res.getVOrientation() = m.invInertiaMassMatrix * d.getVOrientation();
00336     return res;
00337 }
00338 
00339 typedef LaparoscopicRigid3Types LaparoscopicRigidTypes; 
00340 
00341 template<>
00342 class DataTypeInfo<LaparoscopicRigidTypes::Coord>
00343 {
00344 public:
00345     static unsigned int size() { return 5; }
00346 
00347     template <typename T>
00348     static void getValue(const LaparoscopicRigidTypes::Coord &type, unsigned int index, T& value) 
00349     { 
00350         if (index < 1)
00351             value = static_cast<T>(type.getTranslation()); 
00352         else
00353             value = static_cast<T>(type.getOrientation()[index-1]);
00354     }
00355     
00356     template<typename T>
00357     static void setValue(LaparoscopicRigidTypes::Coord &type, unsigned int index, const T& value ) 
00358     { 
00359         if (index < 1)
00360           type.getTranslation() = static_cast<LaparoscopicRigidTypes::Coord::value_type>(value);
00361         else
00362           type.getOrientation()[index-1] = static_cast<LaparoscopicRigidTypes::Coord::value_type>(value);
00363     }
00364 };
00365 
00366 template<>
00367 class DataTypeInfo<LaparoscopicRigidTypes::Deriv>
00368 {
00369 public:
00370     static unsigned int size() { return 4; }
00371     
00372     template <typename T>
00373     static void getValue(const LaparoscopicRigidTypes::Deriv &type, unsigned int index, T& value) 
00374     { 
00375         if (index < 1)
00376             value = static_cast<T>(type.getVTranslation()); 
00377         else
00378             value = static_cast<T>(type.getVOrientation()[index-1]);
00379     }
00380     
00381     template<typename T>
00382     static void setValue(LaparoscopicRigidTypes::Deriv &type, unsigned int index, const T& value ) 
00383     { 
00384         if (index < 1)
00385           type.getVTranslation() = static_cast<LaparoscopicRigidTypes::Deriv::value_type>(value);
00386         else
00387           type.getVOrientation()[index-1] = static_cast<LaparoscopicRigidTypes::Deriv::value_type>(value);
00388     }
00389 };
00390 
00391 } // namespace defaulttype
00392 
00393 
00394 //================================================================================================================
00395 // This is probably useless because the RigidObject actually contains its mass and computes its inertia forces itself:
00396 //================================================================================================================
00397 
00398 namespace core {
00399 namespace componentmodel {
00400 namespace behavior {
00402     template <>
00403     inline defaulttype::LaparoscopicRigid3Types::Deriv inertiaForce<
00404     defaulttype::LaparoscopicRigid3Types::Coord,
00405     defaulttype::LaparoscopicRigid3Types::Deriv,
00406     defaulttype::Vector3,
00407     defaulttype::Rigid3Mass,
00408     objectmodel::BaseContext::SpatialVector
00409     >
00410     (
00411     const objectmodel::BaseContext::SpatialVector& vframe,
00412     const defaulttype::Vector3& aframe,
00413     const defaulttype::Rigid3Mass& mass,
00414     const defaulttype::LaparoscopicRigid3Types::Coord& x,
00415     const defaulttype::LaparoscopicRigid3Types::Deriv& v )
00416     {
00417         defaulttype::Vector3 omega( vframe.lineVec[0], vframe.lineVec[1], vframe.lineVec[2] );
00418         defaulttype::Vector3 origin, finertia, zero(0,0,0);
00419         origin[0] = x.getTranslation();
00420         
00421         finertia = -( aframe + omega.cross( omega.cross(origin) + defaulttype::Vector3(v.getVTranslation()*2,0,0) ))*mass.mass;
00422         return defaulttype::LaparoscopicRigid3Types::Deriv( finertia[0], zero );
00424     }
00425 
00426 } // namespace behavoir
00427 
00428 } // namespace componentmodel
00429 
00430 } // namespace core
00431 
00432 } // namespace sofa
00433 
00434 #endif

Generated on Sun Nov 23 02:29:28 2008 for Sofa by  doxygen 1.5.7.1