LCPForceFeedback.cpp

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 #include <sofa/component/controller/LCPForceFeedback.h>
00026 #include <sofa/core/ObjectFactory.h>
00027 
00028 using namespace std;
00029 
00030 namespace sofa
00031 {
00032 namespace component
00033 {
00034 namespace controller
00035 {
00036     
00037 
00038 void LCPForceFeedback::init()
00039 {
00040     this->ForceFeedback::init();
00041     OmniDriver* driver = context->get<OmniDriver>(); 
00042 
00043 //  BaseObject* object2 = static_cast<BaseObject*>(context->getObject(classid(sofa::component::odesolver::MasterContactSolver)));
00044 
00045     mastersolver = context->get<sofa::component::odesolver::MasterContactSolver>();
00046 
00047     driver->setForceFeedback(this);
00048 
00049     mState = dynamic_cast<MechanicalState<Rigid3dTypes> *> (this->getContext()->getMechanicalState());
00050     if (!mState)
00051         std::cerr << "WARNING - LCPForceFeedback has no binding MechanicalState\n";
00052 
00053 
00054     if (!mastersolver)
00055         std::cerr << "WARNING - LCPForceFeedback has no binding MasterContactSolver\n" ;
00056 
00057     lcp = mastersolver->getLCP();
00058 
00059     cout << "init LCPForceFeedback " << driver << " done " << std::endl;
00060 };
00061 
00062 void LCPForceFeedback::computeForce(double x, double y, double z, double /*u*/, double /*v*/, double /*w*/, double /*q*/, double& fx, double& fy, double& fz)
00063 {
00064     if (!f_activate.getValue())
00065     {
00066         return;
00067     }
00068     static double mx = (*mState->getX())[0].getCenter()[0];
00069     static double my = (*mState->getX())[0].getCenter()[1];
00070     static double mz = (*mState->getX())[0].getCenter()[2];
00071 
00072     static component::odesolver::LCP* lcp_buf = NULL;
00073     
00074     static RigidTypes::VecConst c;
00075     static std::vector<int> id_buf;
00076     
00077     if (lcp_buf == NULL)
00078     {
00079         lcp_buf = mastersolver->getLCP();
00080         mx = (*mState->getX())[0].getCenter()[0];
00081         my = (*mState->getX())[0].getCenter()[1];
00082         mz = (*mState->getX())[0].getCenter()[2];       
00083     }
00084 
00085     lcp = mastersolver->getLCP();
00086     
00087     if (lcp_buf!=lcp)
00088     {
00090         //std::cout<<"new LCP detected"<<std::endl;
00091         
00092         mx = (*mState->getX())[0].getCenter()[0];
00093         my = (*mState->getX())[0].getCenter()[1];
00094         mz = (*mState->getX())[0].getCenter()[2];   
00095         
00096         // copy of the constraints that correspond to the lcp in vecConst c
00097         c.clear();
00098         id_buf.clear();
00099         for(unsigned int c1 = 0; c1 < mState->getC()->size(); c1++)
00100         {
00101             int indexC1 = mState->getConstraintId()[c1];
00102             id_buf.push_back(indexC1);
00103             int sizeC1 = (*mState->getC())[c1].size();
00104             RigidTypes::SparseVecDeriv v;
00105             for(int i = 0; i < sizeC1; i++)
00106             {
00107                 RigidTypes::SparseDeriv d((*mState->getC())[c1][i].index, (*mState->getC())[c1][i].data);
00108                 v.push_back(d);
00109             }
00110             c.push_back(v);
00111         } 
00112                 
00113     }
00114     else
00115     {
00116         //std::cout<<"old LCP "<<std::endl;
00117     }
00118     lcp_buf = lcp;  
00119     //lcp->wait();
00120     //lcp->lock();
00121 
00122     
00123 
00124 
00126     RigidTypes::VecConst* constraints = &c; 
00128     
00130 //  if(lcp)
00131 //      std::cout<<"numConst" <<constraints->size()<<std::endl;
00132 //  else
00133 //      std::cout<<"WARNING : LCP is null"<<std::endl;
00135 
00136 //  std::cout << "LCPForceFeedback::computeForce " << constraints->size() << std::endl;
00137 
00138     if(lcp)
00139     {
00140         if ((lcp)->getMu() > 0.0 && constraints->size())
00141         {
00142             
00143             //RigidTypes::VecDeriv DX;
00144             //DX.resize(3);
00145             const unsigned int numConstraints = constraints->size();
00146             RigidTypes::VecDeriv force;
00147 
00148             if(!force.size())
00149                 force.resize((*mState->getX()).size());
00150 
00151 
00152             //DX[0][0] = x - mx;
00153             //DX[1][0] = y - my;
00154             //DX[2][0] = z - mz;
00155 
00156             double dx = (x - mx);
00157             double dy = (y - my);
00158             double dz = (z - mz);
00159 
00160             //cout << "two !" << endl;
00161 
00162             for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00163             {
00164                 int indexC1 = id_buf[c1];
00165                 int sizeC1 = (*constraints)[c1].size();
00166                 for(int i = 0; i < sizeC1; i++)
00167                 {
00168                     //cout << "constraint ID :  " << indexC1 << endl;
00169                     (lcp)->getDfree()[indexC1] += (*constraints)[c1][i].data[0] * dx;
00170                     (lcp)->getDfree()[indexC1] += (*constraints)[c1][i].data[1] * dy;
00171                     (lcp)->getDfree()[indexC1] += (*constraints)[c1][i].data[2] * dz;
00172                     //cout << "data : " << constraints[c1][i].data[0] << " " << constraints[c1][i].data[1] << " " << constraints[c1][i].data[2] << endl;
00173                 }
00174             }
00175 
00176             //cout << "three !" << endl;
00177 
00178             double tol = lcp->getTolerance();
00179             int max = 100;
00180             
00181             tol *= 0.001;
00182             //helper::nlcp_gaussseidel((lcp)->getNbConst(), (lcp)->getDfree(), (lcp)->getW(), (lcp)->getF(), (lcp)->getMu(), tol, max, true);
00183             helper::nlcp_gaussseidelTimed((lcp)->getNbConst(), (lcp)->getDfree(), (lcp)->getW(), (lcp)->getF(), (lcp)->getMu(), tol, max, true, 0.0008);
00184             //helper::afficheLCP((lcp)->getDfree(), (lcp)->getW(), (lcp)->getF(),(lcp)->getNbConst());
00185 
00186 
00187             //cout << "four !" << endl;
00188 
00189             for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00190             {
00191                 int indexC1 = id_buf[c1];
00192                 int sizeC1 = (*constraints)[c1].size();
00193                 for(int i = 0; i < sizeC1; i++)
00194                 {
00195                     (lcp)->getDfree()[indexC1] -= (*constraints)[c1][i].data[0] * dx;
00196                     (lcp)->getDfree()[indexC1] -= (*constraints)[c1][i].data[1] * dy;
00197                     (lcp)->getDfree()[indexC1] -= (*constraints)[c1][i].data[2] * dz;
00198                 }
00199             }
00200 
00201             //cout << "five !" << endl;
00202 
00203             for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00204             {
00205                 int indexC1 = id_buf[c1];
00206                 if ((lcp)->getF()[indexC1] != 0.0)
00207                 {
00208                     int sizeC1 = (*constraints)[c1].size();
00209 
00210                     for(int i = 0; i < sizeC1; i++)
00211                     {
00212                         force[0] += (*constraints)[c1][i].data * (lcp)->getF()[indexC1];
00213                     }
00214                 }
00215             }
00216 
00217             //cout << "six !" << endl;
00218 
00219             fx = force[0][0]*forceCoef.getValue() ;//0.0003;
00220             fy = force[0][1]*forceCoef.getValue() ;//0.0003;
00221             fz = force[0][2]*forceCoef.getValue();//0.0003;
00222 
00223             //cout << "seven !" << endl;
00224 
00225             //cout << "haptic forces : " << fx << " " << fy << " " << fz << endl;
00226             //cout << "forces : " << force << end;
00227             //cout << "haptic diff : " << DX[0][0] << " " << DX[1][0] << " " << DX[2][0]  << endl;
00228         }
00229         //cout << "eight" << endl;
00230 
00231     }
00232 
00233     //cout << "nine !" << endl;
00234     //lcp->unlock();
00235 
00236 };
00237 
00238 
00239 
00240 int lCPForceFeedbackClass = sofa::core::RegisterObject("LCP force feedback for the omni")
00241     .add< LCPForceFeedback >();
00242 
00243 SOFA_DECL_CLASS(LCPForceFeedback)
00244 
00245 } // namespace controller
00246 } // namespace component
00247 } // namespace sofa

Generated on Sun Nov 23 02:50:16 2008 for Sofa by  doxygen 1.5.7.1