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 #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
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
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
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
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
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
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
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;
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
00217 if(s.blocStiffnessRot == 0.0)
00218 s.blocStiffnessRot = s.hardStiffnessRot/100;
00219
00220
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
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, Spring& spring);
00280 void addSpringDForce(VecDeriv& df1, const VecDeriv& dx1, VecDeriv& df2, const VecDeriv& dx2, int i, 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
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 }
00333
00334 }
00335
00336 }
00337
00338 #endif