JointSpringForceField.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 :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 
00026 #ifndef SOFA_COMPONENT_FORCEFIELD_JOINTSPRINGFORCEFIELD_H
00027 #define SOFA_COMPONENT_FORCEFIELD_JOINTSPRINGFORCEFIELD_H
00028 
00029 #include <sofa/core/componentmodel/behavior/PairInteractionForceField.h>
00030 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00031 #include <sofa/defaulttype/Vec.h>
00032 #include <vector>
00033 #include <sofa/defaulttype/Mat.h>
00034 using namespace sofa::defaulttype;
00035 
00036 
00037 namespace sofa
00038 {
00039 
00040 namespace component
00041 {
00042 
00043 namespace forcefield
00044 {
00045 
00046 template<class DataTypes>
00047 class JointSpringForceFieldInternalData
00048 {
00049 public:
00050 };
00051 
00056 template<class DataTypes>
00057 class JointSpringForceField : public core::componentmodel::behavior::PairInteractionForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00058 {
00059 public:
00060     typedef typename core::componentmodel::behavior::PairInteractionForceField<DataTypes> Inherit;
00061     typedef typename DataTypes::VecCoord VecCoord;
00062     typedef typename DataTypes::VecDeriv VecDeriv;
00063     typedef typename DataTypes::Coord Coord;
00064     typedef typename DataTypes::Deriv Deriv;
00065     typedef typename Coord::value_type Real;
00066     typedef core::componentmodel::behavior::MechanicalState<DataTypes> MechanicalState;
00067     enum { N=Coord::static_size };
00068     typedef defaulttype::Mat<N,N,Real> Mat;
00069     typedef Vec<N,Real> Vector;
00070 
00071 
00072   class Spring
00073   {
00074     public:
00075       int  m1, m2;          
00076       Real kd;              
00077       Vector  initTrans;        
00078       Quat initRot;         
00079       Quat lawfulTorsion;   
00080       Quat extraTorsion;    
00081 
00082       sofa::defaulttype::Vec<6,bool> freeMovements; 
00083       Real softStiffnessTrans;  
00084       Real hardStiffnessTrans;  
00085       Real softStiffnessRot;    
00086       Real hardStiffnessRot;    
00087       Real blocStiffnessRot;    
00088 
00089       sofa::defaulttype::Vec<6,Real> limitAngles; 
00090 
00091       Vector bloquage;
00092 
00093 
00095       Spring()
00096       : m1(0), m2(0), kd(0), lawfulTorsion(0,0,0,1), extraTorsion(0,0,0,1)
00097       , softStiffnessTrans(0), hardStiffnessTrans(10000), softStiffnessRot(0), hardStiffnessRot(10000), blocStiffnessRot(100)
00098       //, freeMovements(0,0,0,1,1,1), limitAngles(-100000, 100000, -100000, 100000, -100000, 100000)
00099       {
00100           freeMovements = sofa::defaulttype::Vec<6,bool>(0,0,0,1,1,1);
00101           limitAngles = sofa::defaulttype::Vec<6,Real>(-100000, 100000, -100000, 100000, -100000, 100000);
00102           initTrans = Vector(0,0,0);
00103           initRot = Quat(0,0,0,1);
00104       }
00105 
00106       Spring(int m1, int m2)
00107       : m1(m1), m2(m2), kd(0), lawfulTorsion(0,0,0,1), extraTorsion(0,0,0,1)
00108       , softStiffnessTrans(0), hardStiffnessTrans(10000), softStiffnessRot(0), hardStiffnessRot(10000), blocStiffnessRot(100)
00109       //, freeMovements(0,0,0,1,1,1), limitAngles(-100000, 100000, -100000, 100000, -100000, 100000)
00110       {
00111           freeMovements = sofa::defaulttype::Vec<6,bool>(0,0,0,1,1,1);
00112           limitAngles = sofa::defaulttype::Vec<6,Real>(-100000, 100000, -100000, 100000, -100000, 100000);
00113           initTrans = Vector(0,0,0);
00114           initRot = Quat(0,0,0,1);
00115       }
00116 
00117       Spring(int m1, int m2, Real softKst, Real hardKst, Real softKsr, Real hardKsr, Real blocKsr, Real axmin, Real axmax, Real aymin, Real aymax, Real azmin, Real azmax, Real kd)
00118       : m1(m1), m2(m2), kd(kd), lawfulTorsion(0,0,0,1), extraTorsion(0,0,0,1)
00119       //,limitAngles(axmin,axmax,aymin,aymax,azmin,azmax)
00120       , softStiffnessTrans(softKst), hardStiffnessTrans(hardKst), softStiffnessRot(softKsr), hardStiffnessRot(hardKsr), blocStiffnessRot(blocKsr)
00121       {
00122           limitAngles = sofa::defaulttype::Vec<6,Real>(axmin,axmax,aymin,aymax,azmin,azmax);
00123           freeMovements = sofa::defaulttype::Vec<6,bool>(false, false, false, true, true, true);
00124           for (unsigned int i=0; i<3; i++){
00125             if(limitAngles[2*i]==limitAngles[2*i+1])
00126                 freeMovements[3+i] = false;
00127           }
00128           initTrans = Vector(0,0,0);
00129           initRot = Quat(0,0,0,1);
00130       }
00131       
00132       //accessors
00133       Real getHardStiffnessRotation() {return hardStiffnessRot;}
00134       Real getSoftStiffnessRotation() {return softStiffnessRot;}
00135       Real getHardStiffnessTranslation() {return hardStiffnessTrans;}
00136       Real getSoftStiffnessTranslation() {return softStiffnessTrans;}
00137       Real getBlocStiffnessRotation() { return blocStiffnessRot; }
00138       sofa::defaulttype::Vec<6,Real> getLimitAngles() { return limitAngles;}
00139       sofa::defaulttype::Vec<6,bool> getFreeAxis() { return freeMovements;}
00140       Vector getInitLength() { return initTrans; }
00141       Quat getInitOrientation() { return initRot; }
00142 
00143       //affectors
00144       void setHardStiffnessRotation(Real ksr){    hardStiffnessRot = ksr;  }
00145       void setSoftStiffnessRotation(Real ksr){    softStiffnessRot = ksr;  }
00146       void setHardStiffnessTranslation(Real kst){ hardStiffnessTrans = kst;  }
00147       void setSoftStiffnessTranslation(Real kst){ softStiffnessTrans = kst;  }
00148       void setBlocStiffnessRotation(Real ksb){    blocStiffnessRot = ksb;  }
00149       void setLimitAngles(const sofa::defaulttype::Vec<6,Real>& lims) { 
00150           limitAngles = lims; 
00151             if(lims[0]==lims[1]) freeMovements[3]=false;
00152             if(lims[2]==lims[3]) freeMovements[4]=false;
00153             if(lims[4]==lims[5]) freeMovements[5]=false;
00154       }
00155       void setLimitAngles(Real minx, Real maxx, Real miny, Real maxy, Real minz, Real maxz) {
00156           limitAngles = sofa::defaulttype::Vec<6,Real>(minx, maxx, miny, maxy, minz, maxz);
00157           if(minx==maxx) freeMovements[3]=false;
00158           if(miny==maxy) freeMovements[4]=false;
00159           if(minz==maxz) freeMovements[5]=false;
00160       }
00161       void setInitLength( const Vector& l) { initTrans=l; }
00162       void setInitOrientation( const Quat& o) { initRot=o; }
00163       void setInitOrientation( const Vector& o) { initRot=Quat::createFromRotationVector(o); }
00164       void setFreeAxis(const sofa::defaulttype::Vec<6,bool>& axis) { freeMovements = axis; }
00165       void setFreeAxis(bool isFreeTx, bool isFreeTy, bool isFreeTz, bool isFreeRx, bool isFreeRy, bool isFreeRz)  {
00166          freeMovements = sofa::defaulttype::Vec<6,bool>(isFreeTx, isFreeTy, isFreeTz, isFreeRx, isFreeRy, isFreeRz);
00167       }
00168       void setDamping(Real _kd){  kd = _kd;   }
00169 
00170 
00171       inline friend std::istream& operator >> ( std::istream& in, Spring& s )
00172       {
00173         //default joint is a free rotation joint --> translation is bloqued, rotation is free
00174         s.freeMovements = sofa::defaulttype::Vec<6,bool>(false, false, false, true, true, true);
00175         s.initTrans = Vector(0,0,0);
00176         s.initRot = Quat(0,0,0,1);
00177         s.blocStiffnessRot = 0.0;
00178         //by default no angle limitation is set (bi values for initialisation)
00179         s.limitAngles = sofa::defaulttype::Vec<6,Real>(-100000., 100000., -100000., 100000., -100000., 100000.);
00180 
00181         std::string str;
00182         in>>str;
00183         if(str == "BEGIN_SPRING"){
00184             in>>s.m1>>s.m2; //read references
00185             in>>str;
00186             while(str != "END_SPRING"){
00187                 if(str == "FREE_AXIS")
00188                       in>>s.freeMovements;
00189                 else if(str == "KS_T")
00190                       in>>s.softStiffnessTrans>>s.hardStiffnessTrans;
00191                 else if(str == "KS_R")
00192                       in>>s.softStiffnessRot>>s.hardStiffnessRot;
00193                 else if(str == "KS_B")
00194                       in>>s.blocStiffnessRot;
00195                 else if(str == "KD")
00196                       in>>s.kd;
00197                 else if(str == "R_LIM_X")
00198                       in>>s.limitAngles[0]>>s.limitAngles[1];
00199                 else if(str == "R_LIM_Y")
00200                       in>>s.limitAngles[2]>>s.limitAngles[3];
00201                 else if(str == "R_LIM_Z")
00202                       in>>s.limitAngles[4]>>s.limitAngles[5];
00203                 else if(str == "REST_T")
00204                       in>>s.initTrans;
00205                 else if(str == "REST_R")
00206                       in>>s.initRot;
00207                 else{
00208                     std::cerr<<"Error parsing Spring : Unknown Attribute "<<str<<std::endl;
00209                       return in;
00210                 }
00211 
00212                 in>>str;
00213             }
00214         }
00215 
00216         //if no blocStiffnessRot was specified (typically 0), we use hardStiffnessRot/100
00217         if(s.blocStiffnessRot == 0.0)
00218             s.blocStiffnessRot = s.hardStiffnessRot/100;
00219 
00220         //if limit angle were specified, free rotation axis are set from them
00221         for (unsigned int i=0; i<3; i++){
00222             if(s.limitAngles[2*i]==s.limitAngles[2*i+1])
00223                 s.freeMovements[3+i] = false;
00224         }
00225       
00226         return in;
00227       }
00228       
00229       friend std::ostream& operator << ( std::ostream& out, const Spring& s )
00230       {
00231           out<<"BEGIN_SPRING  "<<s.m1<<" "<<s.m2<<"  ";
00232 
00233           if (s.freeMovements[0]!=false || s.freeMovements[1]!=false || s.freeMovements[2]!=false || s.freeMovements[3]!=true || s.freeMovements[4]!=true || s.freeMovements[5]!=true)
00234               out<<"FREE_AXIS "<<s.freeMovements<<"  ";
00235           if (s.softStiffnessTrans != 0.0 || s.hardStiffnessTrans != 10000.0)
00236               out<<"KS_T "<<s.softStiffnessTrans<<" "<<s.hardStiffnessTrans<<"  ";
00237           if (s.softStiffnessRot != 0.0 || s.hardStiffnessRot != 10000.0)
00238               out<<"KS_R "<<s.softStiffnessRot<<" "<<s.hardStiffnessRot<<"  ";
00239           if (s.blocStiffnessRot != s.hardStiffnessRot/100)
00240               out<<"KS_B "<<s.blocStiffnessRot<<"  ";
00241           if (s.kd != 0.0)
00242               out<<"KD "<<s.kd<<"  ";
00243           if (s.limitAngles[0]!=-100000 || s.limitAngles[1] != 100000)
00244               out<<"R_LIM_X "<<s.limitAngles[0]<<" "<<s.limitAngles[1]<<"  ";
00245           if (s.limitAngles[2]!=-100000 || s.limitAngles[3] != 100000)
00246               out<<"R_LIM_Y "<<s.limitAngles[2]<<" "<<s.limitAngles[3]<<"  ";
00247           if (s.limitAngles[4]!=-100000 || s.limitAngles[5] != 100000)
00248               out<<"R_LIM_Z "<<s.limitAngles[4]<<" "<<s.limitAngles[5]<<"  ";
00249           if (s.initTrans!= Vector())
00250               out<<"REST_T "<<s.initTrans<<"  ";
00251           if (s.initRot[3]!= 1)
00252               out<<"REST_R "<<s.initRot<<"  ";
00253 
00254           out<<"END_SPRING"<<std::endl;
00255           return out;
00256       }
00257       
00258   };
00259 // end inner class spring
00260 
00261 
00262 
00263 protected:
00264 
00265     double m_potentialEnergy;
00267     Data<sofa::helper::vector<Spring> > springs;
00269     VecCoord springRef;
00271     Data<bool> showLawfulTorsion;
00272     Data<bool> showExtraTorsion;
00273     
00274     JointSpringForceFieldInternalData<DataTypes> data;
00275 
00276     
00278     void addSpringForce(double& potentialEnergy, VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int i, /*const*/ Spring& spring);
00280     void addSpringDForce(VecDeriv& df1, const VecDeriv& dx1, VecDeriv& df2, const VecDeriv& dx2, int i, /*const*/ Spring& spring);
00281     
00282 
00283 
00284 public:
00285     JointSpringForceField(MechanicalState* object1, MechanicalState* object2);  
00286     JointSpringForceField();
00287     
00288     core::componentmodel::behavior::MechanicalState<DataTypes>* getObject1() { return this->mstate1; }
00289     core::componentmodel::behavior::MechanicalState<DataTypes>* getObject2() { return this->mstate2; }
00290 
00291     virtual void init();
00292 
00293     virtual void addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2);
00294     
00295     virtual void addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2);
00296         
00297     virtual double getPotentialEnergy(const VecCoord&, const VecCoord&) { return m_potentialEnergy; }
00298 
00299     sofa::helper::vector<Spring> * getSprings() { return springs.beginEdit(); }
00300     
00301     void draw();
00302     
00303     // -- Modifiers
00304     
00305     void clear(int reserve=0)
00306     {
00307         helper::vector<Spring>& springs = *this->springs.beginEdit();
00308         springs.clear();
00309         if (reserve) springs.reserve(reserve);
00310         this->springs.endEdit();
00311     }
00312 
00313     void addSpring(const Spring& s)
00314     {
00315         springs.beginEdit()->push_back(s);
00316         springs.endEdit();
00317     }
00318 
00319 
00320     void addSpring(int m1, int m2, Real softKst, Real hardKst, Real softKsr, Real hardKsr, Real blocKsr, Real axmin, Real axmax, Real aymin, Real aymax, Real azmin, Real azmax, Real kd)
00321     {
00322         Spring s(m1,m2,softKst,hardKst,softKsr,hardKsr, blocKsr, axmin, axmax, aymin, aymax, azmin, azmax, kd);
00323         s.initTrans = Vector(0,0,0);
00324         s.initRot = Quat(0,0,0,1);
00325 
00326         springs.beginEdit()->push_back(s);
00327         springs.endEdit();
00328     }
00329 
00330 };
00331 
00332 } // namespace forcefield
00333 
00334 } // namespace component
00335 
00336 } // namespace sofa
00337 
00338 #endif

Generated on Sun Nov 23 02:59:05 2008 for Sofa by  doxygen 1.5.7.1