root / AFM / AFM.cpp @ 1
Historique | Voir | Annoter | Télécharger (10,4 ko)
1 |
#include <sofa/simulation/graph/DAGSimulation.h> |
---|---|
2 |
#include <plugins/SofaPython/SceneLoaderPY.h> |
3 |
#include <sofa/helper/system/PluginManager.h> |
4 |
#include <sofa/defaulttype/Mat.h> |
5 |
#include <SofaBaseLinearSolver/FullVector.h> |
6 |
#include <sofa/simulation/common/MechanicalVisitor.h> |
7 |
#include <SofaComponentMain/init.h> |
8 |
#include <../MyDefaultContactManager.h> |
9 |
#include <sofa/core/objectmodel/BaseObject.h> |
10 |
#include <SofaBoundaryCondition/ConstantForceField.h> |
11 |
#include <sofa/simulation/common/FindByTypeVisitor.h> |
12 |
#include <SofaBaseMechanics/MechanicalObject.h> |
13 |
#include <sofa/helper/accessor.h> |
14 |
#include <sofa/defaulttype/DataTypeInfo.h> |
15 |
#include <SofaBoundaryCondition/ProjectToLineConstraint.h> |
16 |
#include <cmath> |
17 |
#include <cstdlib> |
18 |
#include <fstream> |
19 |
#include <vector> |
20 |
|
21 |
using namespace sofa; |
22 |
using namespace simulation; |
23 |
|
24 |
typedef sofa::component::linearsolver::FullVector<double> FullVector; |
25 |
typedef defaulttype::Vec3dTypes::Deriv Deriv;
|
26 |
typedef defaulttype::Vec3d myVec3d;
|
27 |
|
28 |
/// return the maximum difference between corresponding entries, or the infinity if the vectors have different sizes
|
29 |
template< typename Vector1, typename Vector2> |
30 |
static double vectorCompare( const Vector1& m1, const Vector2& m2 ) |
31 |
{ |
32 |
if( m1.size()!=m2.size() ) {
|
33 |
printf("Comparison between vectors of different sizes\n");
|
34 |
std::fflush(stdout); |
35 |
return std::numeric_limits<double>::infinity(); |
36 |
} |
37 |
double result = 0; |
38 |
for( unsigned i=0; i<m1.size(); i++ ){ |
39 |
double diff = fabs(m1.element(i)-m2.element(i));
|
40 |
if( diff>result ) result=diff;
|
41 |
} |
42 |
return result;
|
43 |
} |
44 |
|
45 |
/** fill the vector with the positions.
|
46 |
@param x the position vector
|
47 |
*/
|
48 |
void getAssembledPositionVector( FullVector* x, unsigned xSize, |
49 |
std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs ) |
50 |
{ |
51 |
x->resize(xSize); |
52 |
unsigned offset = 0; |
53 |
|
54 |
for (unsigned i = 0; i < DOFs.size(); i++){ |
55 |
helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecCoord> > vSrc = DOFs[i]->readPositions(); |
56 |
|
57 |
for (unsigned j=0; j < vSrc.size(); j++){ |
58 |
double tmp = 0.0; |
59 |
tmp = vSrc[j][0];
|
60 |
// defaulttype::Vec3dTypes::Coord getValue(vSrc[j], 0, tmp);
|
61 |
x->set(offset + 3*j,tmp);
|
62 |
// DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 1, tmp);
|
63 |
tmp = vSrc[j][1];
|
64 |
x->set(offset + 3*j+1,tmp); |
65 |
//DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 2, tmp);
|
66 |
tmp = vSrc[j][2];
|
67 |
x->set(offset + 3*j+2,tmp); |
68 |
} |
69 |
offset += DOFs[i]->getSize() * 3;
|
70 |
} |
71 |
} |
72 |
|
73 |
/** fill the vector with the velocities.
|
74 |
@param v the velocity vector
|
75 |
*/
|
76 |
void getAssembledVelocityVector( FullVector* v, unsigned vSize, |
77 |
std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs ) |
78 |
{ |
79 |
v->resize(vSize); |
80 |
unsigned offset = 0; |
81 |
|
82 |
for (unsigned i = 0; i < DOFs.size(); i++){ |
83 |
helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecDeriv> > vSrc = DOFs[i]->readVelocities(); |
84 |
for (unsigned j=0; j < vSrc.size(); j++){ |
85 |
double tmp = 0.0; |
86 |
//DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 0, tmp);
|
87 |
tmp = vSrc[j][0];
|
88 |
v->set(offset + 3*j,tmp);
|
89 |
//DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 1, tmp);
|
90 |
tmp = vSrc[j][1];
|
91 |
v->set(offset + 3*j+1,tmp); |
92 |
//DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 2, tmp);
|
93 |
tmp = vSrc[j][2];
|
94 |
v->set(offset + 3*j+2,tmp); |
95 |
} |
96 |
offset += DOFs[i]->getSize() * 3;
|
97 |
} |
98 |
|
99 |
} |
100 |
|
101 |
|
102 |
int main()
|
103 |
{ |
104 |
//the file in which the resulting curve will be put
|
105 |
std::ofstream fileResult("./AFM-results.txt");
|
106 |
fileResult << "### first the force then the depth ###\n\n" ;
|
107 |
|
108 |
//load the required plugins
|
109 |
std::string pluginPath = "Flexible"; |
110 |
std::string pluginPath1 = "AFM_plane"; |
111 |
|
112 |
sofa::helper::system::PluginRepository.addLastPath("../../../../build_release/lib/");
|
113 |
if (sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath) &&
|
114 |
sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath1)) |
115 |
sofa::helper::system::PluginManager::getInstance().init(); |
116 |
|
117 |
|
118 |
|
119 |
unsigned xsize; ///< size of assembled position vector, |
120 |
unsigned vsize; ///< size of assembled velocity vector, |
121 |
|
122 |
|
123 |
// loading the scene which is in the file examples/AFM-plane.py
|
124 |
setSimulation(new simulation::graph::DAGSimulation());
|
125 |
sofa::component::init(); |
126 |
Node::SPtr root = getSimulation()->createNewGraph("root");
|
127 |
|
128 |
SceneLoaderPY LoaderPy; |
129 |
root = LoaderPy.load("./AFM-plane.py");
|
130 |
getSimulation()->init(root.get()); |
131 |
|
132 |
//we take the direction of the force
|
133 |
sofa::component::forcefield::ConstantForceField<defaulttype::Vec3dTypes>::SPtr CFF; |
134 |
root->getContext()->get(CFF, sofa::core::objectmodel::BaseContext::SearchRoot); |
135 |
|
136 |
Deriv forceInit = CFF->force.getValue(); |
137 |
|
138 |
Deriv forceActu; |
139 |
forceActu[0] = 0; |
140 |
forceActu[1] = 0; |
141 |
forceActu[2] = 0; |
142 |
CFF->force = forceActu; |
143 |
|
144 |
|
145 |
// first find the size of the DOFs
|
146 |
core::ExecParams* params = core::ExecParams::defaultInstance(); |
147 |
FindByTypeVisitor<component::container::MechanicalObject<defaulttype::Vec3dTypes> > FBTVisitor(params); |
148 |
root->execute(FBTVisitor); |
149 |
|
150 |
std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> allPoints; |
151 |
allPoints = FBTVisitor.found; |
152 |
|
153 |
std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs, mObject; |
154 |
for (unsigned i=0; i<allPoints.size();i++) |
155 |
if (allPoints[i]->getName() == "DOFs" || allPoints[i]->getName() == "indentor" ) |
156 |
DOFs.push_back(allPoints[i]); |
157 |
|
158 |
for (unsigned i=0; i<allPoints.size();i++) |
159 |
if (allPoints[i]->getName() == "DOFs") |
160 |
mObject.push_back(allPoints[i]); |
161 |
|
162 |
unsigned xInitSize = mObject[0]->getSize(); |
163 |
|
164 |
xsize = DOFs[0]->getSize() * DOFs[0]->getCoordDimension() + DOFs[1]->getSize() * DOFs[1]->getCoordDimension(); |
165 |
vsize = DOFs[0]->getMatrixSize() + DOFs[1]->getMatrixSize(); |
166 |
|
167 |
FullVector x0, x1, v0, v1, xinit, xend; |
168 |
getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
|
169 |
getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
|
170 |
|
171 |
double dx, dv;
|
172 |
unsigned n=0; |
173 |
const double precision = 1.e-4; |
174 |
unsigned const nmax = 1000; |
175 |
// first loop to stabilize the plane growth under pressure
|
176 |
|
177 |
do {
|
178 |
getSimulation()->animate(root.get(),0.01); |
179 |
|
180 |
getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
|
181 |
getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
|
182 |
|
183 |
dx = vectorCompare(x0,x1); |
184 |
dv = vectorCompare(v0,v1); |
185 |
x0 = x1; |
186 |
v0 = v1; |
187 |
n++; |
188 |
|
189 |
} while((dx>precision || dv>precision) && n < nmax); // |
190 |
|
191 |
printf("\n %i iterations to stabilize the plane \n",n);
|
192 |
std::fflush(stdout); |
193 |
|
194 |
getAssembledPositionVector(&xinit, xInitSize*3, mObject);
|
195 |
|
196 |
//second loop : to detect a collision
|
197 |
|
198 |
//we place the indentor first and calculate the force
|
199 |
forceInit[0] = 0; |
200 |
forceInit[1] = 0; |
201 |
forceInit[2] = -0.1; |
202 |
|
203 |
|
204 |
|
205 |
//we put the position of indentor
|
206 |
component::container::MechanicalObject<defaulttype::Vec3dTypes> *indentor = NULL ;
|
207 |
if (DOFs[0]->getName()=="DOFs") |
208 |
indentor = DOFs[1];
|
209 |
else indentor = DOFs[0]; |
210 |
|
211 |
helper::vector<double> centerPos;
|
212 |
|
213 |
centerPos.push_back(0.5); |
214 |
centerPos.push_back(0.5); |
215 |
centerPos.push_back(2);
|
216 |
|
217 |
indentor->forcePointPosition(0,centerPos);
|
218 |
|
219 |
myVec3d indentPos; |
220 |
myVec3d indentForce; |
221 |
indentPos.set(0.5 ,0.5, 2); |
222 |
indentForce.set(0,0,1); |
223 |
|
224 |
component::projectiveconstraintset::ProjectToLineConstraint<defaulttype::Vec3dTypes>::SPtr constraint; |
225 |
root->getContext()->get(constraint, sofa::core::objectmodel::BaseContext::SearchRoot); |
226 |
constraint->f_origin.setValue(indentPos); |
227 |
constraint->f_direction.setValue(indentForce); |
228 |
|
229 |
forceActu[2] = -0.1; |
230 |
|
231 |
CFF->force = forceActu; |
232 |
|
233 |
component::collision::MyDefaultContactManager::SPtr MDCM; |
234 |
root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot); |
235 |
while (!MDCM->CollisionDetected())
|
236 |
{ |
237 |
getSimulation()->animate(root.get(),0.01); |
238 |
root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot); |
239 |
} |
240 |
|
241 |
|
242 |
//third loop : until the end we increment the force
|
243 |
n = 0;
|
244 |
unsigned compteur = 0; |
245 |
|
246 |
getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
|
247 |
getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
|
248 |
|
249 |
|
250 |
while (forceActu.norm() < 150 && MDCM->getDepth() < 0.15 ){ |
251 |
n = 0;
|
252 |
fileResult << forceActu.norm() <<" " ;
|
253 |
printf("new force %f : ",forceActu.norm());
|
254 |
std::fflush(stdout); |
255 |
|
256 |
do {
|
257 |
getSimulation()->animate(root.get(),0.01); |
258 |
|
259 |
getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
|
260 |
getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
|
261 |
|
262 |
dx = vectorCompare(x0,x1); |
263 |
dv = vectorCompare(v0,v1); |
264 |
x0 = x1; |
265 |
v0 = v1; |
266 |
n++; |
267 |
|
268 |
} while((dx>precision || dv>precision) && n < nmax); // |
269 |
|
270 |
printf("%i iterations, depth: %f \n",n,MDCM->getDepth());
|
271 |
std::fflush(stdout); |
272 |
|
273 |
compteur++; |
274 |
fileResult << MDCM->getDepth() << std::endl; |
275 |
forceActu += forceInit; |
276 |
CFF->force = forceActu; |
277 |
} |
278 |
|
279 |
|
280 |
|
281 |
//forth loop to decrement the force
|
282 |
|
283 |
/*while (forceActu.norm() > 0.1){
|
284 |
n = 0;
|
285 |
fileResult << forceActu.norm() <<" " ;
|
286 |
printf("new force %f : ",forceActu.norm());
|
287 |
std::fflush(stdout);
|
288 |
|
289 |
do {
|
290 |
getSimulation()->animate(root.get(),0.01);
|
291 |
|
292 |
getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
|
293 |
getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
|
294 |
|
295 |
dx = vectorCompare(x0,x1);
|
296 |
dv = vectorCompare(v0,v1);
|
297 |
x0 = x1;
|
298 |
v0 = v1;
|
299 |
n++;
|
300 |
|
301 |
} while((dx>precision || dv>precision) && n < nmax); //
|
302 |
|
303 |
printf("%i iterations, depth : %f \n",n,MDCM->getDepth() );
|
304 |
std::fflush(stdout);
|
305 |
|
306 |
compteur++;
|
307 |
fileResult << MDCM->getDepth() << std::endl;
|
308 |
forceActu -= forceInit;
|
309 |
CFF->force = forceActu;
|
310 |
}
|
311 |
*/
|
312 |
|
313 |
return 0; |
314 |
} |
315 |
|