LCPForceFeedback.cpp
Go to the documentation of this file.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 #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
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 , double , double , double , 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
00091
00092 mx = (*mState->getX())[0].getCenter()[0];
00093 my = (*mState->getX())[0].getCenter()[1];
00094 mz = (*mState->getX())[0].getCenter()[2];
00095
00096
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
00117 }
00118 lcp_buf = lcp;
00119
00120
00121
00122
00123
00124
00126 RigidTypes::VecConst* constraints = &c;
00128
00130
00131
00132
00133
00135
00136
00137
00138 if(lcp)
00139 {
00140 if ((lcp)->getMu() > 0.0 && constraints->size())
00141 {
00142
00143
00144
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
00153
00154
00155
00156 double dx = (x - mx);
00157 double dy = (y - my);
00158 double dz = (z - mz);
00159
00160
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
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
00173 }
00174 }
00175
00176
00177
00178 double tol = lcp->getTolerance();
00179 int max = 100;
00180
00181 tol *= 0.001;
00182
00183 helper::nlcp_gaussseidelTimed((lcp)->getNbConst(), (lcp)->getDfree(), (lcp)->getW(), (lcp)->getF(), (lcp)->getMu(), tol, max, true, 0.0008);
00184
00185
00186
00187
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
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
00218
00219 fx = force[0][0]*forceCoef.getValue() ;
00220 fy = force[0][1]*forceCoef.getValue() ;
00221 fz = force[0][2]*forceCoef.getValue();
00222
00223
00224
00225
00226
00227
00228 }
00229
00230
00231 }
00232
00233
00234
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 }
00246 }
00247 }