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 #ifndef SOFA_COMPONENT_FORCEFIELD_JOINTSPRINGFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_JOINTSPRINGFORCEFIELD_INL
00027
00028 #include <sofa/component/forcefield/JointSpringForceField.h>
00029 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00030 #include <sofa/helper/io/MassSpringLoader.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <sofa/helper/gl/Cylinder.h>
00033 #include <sofa/helper/gl/Axis.h>
00034 #include <sofa/helper/system/config.h>
00035 #include <assert.h>
00036 #include <iostream>
00037 using std::cerr;
00038 using std::endl;
00039
00040 namespace sofa
00041 {
00042
00043 namespace component
00044 {
00045
00046 namespace forcefield
00047 {
00048
00049
00050 template<class DataTypes>
00051 JointSpringForceField<DataTypes>::JointSpringForceField(MechanicalState* object1, MechanicalState* object2)
00052 : Inherit(object1, object2)
00053 , springs(initData(&springs,"spring","pairs of indices, stiffness, damping, rest length"))
00054 , showLawfulTorsion(initData(&showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation"))
00055 , showExtraTorsion(initData(&showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation"))
00056 {
00057 }
00058
00059 template<class DataTypes>
00060 JointSpringForceField<DataTypes>::JointSpringForceField()
00061 : springs(initData(&springs,"spring","pairs of indices, stiffness, damping, rest length"))
00062 , showLawfulTorsion(initData(&showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation"))
00063 , showExtraTorsion(initData(&showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation"))
00064 {
00065 }
00066
00067
00068 template <class DataTypes>
00069 void JointSpringForceField<DataTypes>::init()
00070 {
00071 this->Inherit::init();
00072 }
00073
00074 template<class DataTypes>
00075 void JointSpringForceField<DataTypes>::addSpringForce( double& , VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int , Spring& spring)
00076 {
00077 int a = spring.m1;
00078 int b = spring.m2;
00079
00080 Mat Mr01, Mr10;
00081 p1[a].writeRotationMatrix(Mr01);
00082 invertMatrix(Mr10, Mr01);
00083
00084 Vector damping(spring.kd, spring.kd, spring.kd);
00085
00086
00087 springRef[a] = p1[a];
00088
00089
00090 Coord Mp1p2 = p2[b] - p1[a];
00091 Deriv Vp1p2 = v2[b] - v1[a];
00092
00093
00094 Mp1p2.getCenter() -= spring.initTrans;
00095
00096 Mp1p2.getOrientation() = Mp1p2.getOrientation() * spring.initRot.inverse();
00097
00098
00099 Vector dRangles = Mp1p2.getOrientation().toEulerVector();
00100
00101 Vector lawfulRots( (Real)spring.freeMovements[3], (Real)spring.freeMovements[4], (Real)spring.freeMovements[5] );
00102 spring.lawfulTorsion = Quat::createFromRotationVector(dRangles.linearProduct(lawfulRots));
00103 Mat MRLT;
00104 spring.lawfulTorsion.toMatrix(MRLT);
00105
00106
00107 spring.extraTorsion = spring.lawfulTorsion.inverse()*Mp1p2.getOrientation();
00108
00109
00110
00111 Vector dTorsion = spring.lawfulTorsion.toEulerVector();
00112 bool bloc=false;
00113 for (unsigned int i=0; i<3; i++){
00114 if (spring.freeMovements[3+i] && dRangles[i] < spring.limitAngles[i*2]){
00115 spring.bloquage[i] = spring.blocStiffnessRot;
00116 dTorsion[i] -= spring.limitAngles[i*2];
00117 bloc=true;
00118 }
00119 else if (spring.freeMovements[3+i] && dRangles[i] > spring.limitAngles[i*2+1]){
00120 spring.bloquage[i] = spring.blocStiffnessRot;
00121 dTorsion[i] -= spring.limitAngles[i*2+1];
00122 bloc=true;
00123 }
00124 }
00125
00126
00127
00128 Vector kst( spring.freeMovements[0]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans, spring.freeMovements[1]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans, spring.freeMovements[2]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans);
00129 Vector ksrH( spring.freeMovements[3]!=0?(Real)0.0:spring.hardStiffnessRot, spring.freeMovements[4]!=0?(Real)0.0:spring.hardStiffnessRot, spring.freeMovements[5]!=0?(Real)0.0:spring.hardStiffnessRot);
00130 Vector ksrS( spring.freeMovements[3]==0?(Real)0.0:spring.softStiffnessRot, spring.freeMovements[4]==0?(Real)0.0:spring.softStiffnessRot, spring.freeMovements[5]==0?(Real)0.0:spring.softStiffnessRot);
00131
00132
00133 Vector fT0 = Mr01 * (kst.linearProduct(Mr10 * Mp1p2.getCenter())) + damping.linearProduct(Vp1p2.getVCenter());
00134
00135 Vector fR0 = Mr01 * MRLT * ( ksrH.linearProduct(spring.extraTorsion.toEulerVector())) + damping.linearProduct(Vp1p2.getVOrientation());
00136 fR0 += Mr01 * ( ksrS.linearProduct(spring.lawfulTorsion.toEulerVector())) + damping.linearProduct(Vp1p2.getVOrientation());
00137
00138 if(bloc)
00139 fR0 += Mr01 * ( spring.bloquage.linearProduct( dTorsion)) + damping.linearProduct(Vp1p2.getVOrientation());
00140
00141 const Deriv force(fT0, fR0 );
00142
00143 f1[a] += force;
00144 f2[b] -= force;
00145
00146 }
00147
00148 template<class DataTypes>
00149 void JointSpringForceField<DataTypes>::addSpringDForce(VecDeriv& f1, const VecDeriv& dx1, VecDeriv& f2, const VecDeriv& dx2, int , Spring& spring)
00150 {
00151 const int a = spring.m1;
00152 const int b = spring.m2;
00153 const Deriv Mdx1dx2 = dx2[b]-dx1[a];
00154
00155 Mat Mr01, Mr10;
00156 springRef[a].writeRotationMatrix(Mr01);
00157 invertMatrix(Mr10, Mr01);
00158
00159 Vector kst( spring.freeMovements[0]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans, spring.freeMovements[1]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans, spring.freeMovements[2]==0?spring.hardStiffnessTrans:spring.softStiffnessTrans);
00160 Vector ksr( spring.freeMovements[3]==0?spring.hardStiffnessRot:spring.softStiffnessRot+spring.bloquage[0], spring.freeMovements[4]==0?spring.hardStiffnessRot:spring.softStiffnessRot+spring.bloquage[1], spring.freeMovements[5]==0?spring.hardStiffnessRot:spring.softStiffnessRot+spring.bloquage[2]);
00161
00162
00163 Vector df0 = Mr01 * (kst.linearProduct(Mr10*Mdx1dx2.getVCenter() ));
00164
00165 Vector dR0 = Mr01 * (ksr.linearProduct(Mr10* Mdx1dx2.getVOrientation()));
00166
00167 const Deriv dforce(df0,dR0);
00168
00169 f1[a]+=dforce;
00170 f2[b]-=dforce;
00171
00172
00173 spring.bloquage=Vector();
00174 }
00175
00176 template<class DataTypes>
00177 void JointSpringForceField<DataTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2)
00178 {
00179 helper::vector<Spring>& springs = *this->springs.beginEdit();
00180
00181 springRef.resize(x1.size());
00182
00183 f1.resize(x1.size());
00184 f2.resize(x2.size());
00185 m_potentialEnergy = 0;
00186 for (unsigned int i=0; i<springs.size(); i++)
00187 {
00188 this->addSpringForce(m_potentialEnergy,f1,x1,v1,f2,x2,v2, i, springs[i]);
00189 }
00190 this->springs.endEdit();
00191 }
00192
00193 template<class DataTypes>
00194 void JointSpringForceField<DataTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2)
00195 {
00196 df1.resize(dx1.size());
00197 df2.resize(dx2.size());
00198
00199
00200 helper::vector<Spring>& springs = *this->springs.beginEdit();
00201 for (unsigned int i=0; i<springs.size(); i++) {
00202 this->addSpringDForce(df1,dx1,df2,dx2, i, springs[i]);
00203 }
00204 this->springs.endEdit();
00205 }
00206
00207 template<class DataTypes>
00208 void JointSpringForceField<DataTypes>::draw()
00209 {
00210 if (!((this->mstate1 == this->mstate2)?getContext()->getShowForceFields():getContext()->getShowInteractionForceFields())) return;
00211 const VecCoord& p1 = *this->mstate1->getX();
00212 const VecCoord& p2 = *this->mstate2->getX();
00213
00214 glDisable(GL_LIGHTING);
00215 bool external = (this->mstate1!=this->mstate2);
00216 const helper::vector<Spring>& springs = this->springs.getValue();
00217
00218 for (unsigned int i=0; i<springs.size(); i++)
00219 {
00220 Real d = (p2[springs[i].m2]-p1[springs[i].m1]).getCenter().norm();
00221 if (external)
00222 {
00223 if (d<springs[i].initTrans.norm()*0.9999)
00224 glColor4f(1,0,0,1);
00225 else
00226 glColor4f(0,1,0,1);
00227 }
00228 else
00229 {
00230 if (d<springs[i].initTrans.norm()*0.9999)
00231 glColor4f(1,0.5f,0,1);
00232 else
00233 glColor4f(0,1,0.5f,1);
00234 }
00235 glBegin(GL_LINES);
00236 helper::gl::glVertexT(p1[springs[i].m1].getCenter());
00237 helper::gl::glVertexT(p2[springs[i].m2].getCenter());
00238 glEnd();
00239
00240 if(springs[i].freeMovements[3] == 1){
00241 helper::gl::Cylinder::draw(p1[springs[i].m1].getCenter(), p1[springs[i].m1].getOrientation(), Vector(1,0,0));
00242 }
00243 if(springs[i].freeMovements[4] == 1){
00244 helper::gl::Cylinder::draw(p1[springs[i].m1].getCenter(), p1[springs[i].m1].getOrientation(), Vector(0,1,0));
00245 }
00246 if(springs[i].freeMovements[5] == 1){
00247 helper::gl::Cylinder::draw(p1[springs[i].m1].getCenter(), p1[springs[i].m1].getOrientation(), Vector(0,0,1));
00248 }
00249
00250
00251 if (showLawfulTorsion.getValue())
00252 helper::gl::Axis::draw(p1[springs[i].m1].getCenter(), p1[springs[i].m1].getOrientation()*springs[i].lawfulTorsion, 0.5);
00253 if (showExtraTorsion.getValue())
00254 helper::gl::Axis::draw(p1[springs[i].m1].getCenter(), p1[springs[i].m1].getOrientation()*springs[i].extraTorsion, 0.5);
00255 }
00256
00257 }
00258
00259 }
00260
00261 }
00262
00263 }
00264
00265 #endif
00266