UsTK : Ultrasound ToolKit  version 2.0.1 under development (2024-11-24)
usNeedleJacobians.h
1 /****************************************************************************
2  *
3  * This file is part of the ustk software.
4  * Copyright (C) 2016 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ustk with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * This software was developed at:
17  * Inria Rennes - Bretagne Atlantique
18  * Campus Universitaire de Beaulieu
19  * 35042 Rennes Cedex
20  * France
21  *
22  * If you have questions regarding the use of this file, please contact
23  * Inria at ustk@inria.fr
24  *
25  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  *
28  * Author:
29  * Jason Chevrie
30  *
31  *****************************************************************************/
32 
33 #ifndef __usNeedleJacobians_h_
34 #define __usNeedleJacobians_h_
35 
36 #include <functional>
37 #include <vector>
38 
39 #include <visp3/core/vpColVector.h>
40 #include <visp3/core/vpExponentialMap.h>
41 #include <visp3/core/vpMatrix.h>
42 #include <visp3/core/vpPoseVector.h>
43 #include <visp3/core/vpRotationMatrix.h>
44 
45 
47 {
49 
50  template<class NeedleInsertionModel>
51  bool getJacobian(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true);
52 
53  template<class NeedleInsertionModel>
54  bool getJacobianScalarToScalar(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, double)> InputScalarMethod, std::function<double(const NeedleInsertionModel&)> OutputScalarMethod, vpMatrix &J, double discretizationStep = 1e-5, bool centeredDifference=true);
55 
56  template<class NeedleInsertionModel>
57  bool getJacobianScalarToVector(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, double)> InputScalarMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, double discretizationStep = 1e-5, bool centeredDifference=true);
58 
59  template<class NeedleInsertionModel>
60  bool getJacobianVectorToScalar(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<double(const NeedleInsertionModel&)> OutputScalarMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true);
61 
62  template<class NeedleInsertionModel>
63  bool getJacobianVectorToVector(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true);
64 
65  template<class NeedleInsertionModel>
66  bool getJacobianVectorToPose(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpHomogeneousMatrix(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true);
67 
69 
70  template<class NeedleInsertionModel>
71  bool getJacobianWorldBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J);
72 
73  template<class NeedleInsertionModel>
74  bool getJacobianBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J);
75 
76  template<class NeedleInsertionModel>
77  bool getJacobianWorldBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J);
78 
79  template<class NeedleInsertionModel>
80  bool getJacobianBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J);
81 
83 
84  template<class NeedleInsertionModel>
85  bool getJacobianBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J);
86 
87  template<class NeedleInsertionModel>
88  bool getJacobianWorldBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J);
89 
91 
92  template<class NeedleInsertionModel>
93  bool getJacobianBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J);
94 
95  template<class NeedleInsertionModel>
96  bool getJacobianWorldBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J);
97 
98  template<class NeedleInsertionModel>
99  bool getJacobianBaseVelocityToNeedleInsertionPointVelocity(const NeedleInsertionModel &model, vpMatrix &J);
100 
101  template<class NeedleInsertionModel>
102  bool getJacobianBaseVelocityToSurfaceTissueStretch(const NeedleInsertionModel &model, vpMatrix &J);
103 
104  template<class NeedleInsertionModel>
105  bool getJacobianBaseVelocityToMaxTissueStretch(const NeedleInsertionModel &model, vpMatrix &J);
106 
107  template<class NeedleInsertionModel>
108  bool getJacobianBaseVelocityToMeanTissueStretch(const NeedleInsertionModel &model, vpMatrix &J);
109 
111 
112  template<class NeedleInsertionModel>
113  bool getJacobianBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l);
114 
115  template<class NeedleInsertionModel>
116  bool getJacobianWorldBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l);
117 
119 
120  template<class NeedleInsertionModel>
121  bool getJacobianBaseVelocityToTransversalTargetDistance(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target);
122 
123  template<class NeedleInsertionModel>
124  bool getJacobianBaseVelocityToTargetAngle(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target);
125 
127 
128  template<class NeedleInsertionModel>
129  bool getJacobianSpringVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, int spring, double l);
130 
132 
133  template<class NeedleInsertionModel>
134  bool getJacobianSpringVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int spring, const std::vector<vpColVector> &points);
135 
137 
138  template<class NeedleInsertionModel>
139  bool getJacobianRestPathPointVelocityToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector<double> &l);
140 
142 
143  template<class NeedleInsertionModel>
144  bool getJacobianRestPathPointVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector<vpColVector> &points);
145 
147 
148  template<class NeedleInsertionModel>
149  bool getJacobianStiffnessPerUnitLengthToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, const std::vector<vpColVector> &points);
150 
152 
153  template<class NeedleInsertionModel>
154  bool getJacobianStiffnessPerUnitLengthToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, const std::vector<double> &l);
155 
161 
162  template<class NeedleInsertionModel>
163  bool getJacobian(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, std::function<vpColVector( const vpColVector&, const vpColVector&, const double step)> DifferenceMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference)
164  {
165  // dVectorOut = J * dVectorIn
166 
167  double stepFactor = (centeredDifference?2:1);
168  NeedleInsertionModel SimulationNeedle(model);
169 
170  int dim = discretizationStep.size();
171  vpColVector test(OutputVectorMethod(SimulationNeedle));
172  vpMatrix M(test.size(), dim);
173 
174  vpColVector v2;
175  if(!centeredDifference) v2 = OutputVectorMethod(model);
176  for(int i=0 ; i<dim ; i++)
177  {
178  vpColVector input(dim,0);
179 
180  input[i] = discretizationStep[i];
181 
182  SimulationNeedle = model;
183  if(!InputVectorMethod(SimulationNeedle, input)) return false;
184 
185  vpColVector v1 = OutputVectorMethod(SimulationNeedle);
186 
187  if(centeredDifference)
188  {
189  input[i] = -discretizationStep[i];
190 
191  SimulationNeedle = model;
192  if(!InputVectorMethod(SimulationNeedle, input)) return false;
193 
194  v2 = OutputVectorMethod(SimulationNeedle);
195  }
196 
197  M.insert(DifferenceMethod(v1,v2,stepFactor*discretizationStep[i]), 0,i);
198  }
199 
200  J = M;
201 
202  return true;
203  }
204 
205  template<class NeedleInsertionModel>
206  bool getJacobianScalarToScalar(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, double)> InputScalarMethod, std::function<double(const NeedleInsertionModel&)> OutputScalarMethod, vpMatrix &J, double discretizationStep, bool centeredDifference)
207  {
208  // dScalarOut = J * dScalarIn
209 
210  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod = [&InputScalarMethod](NeedleInsertionModel& m, const vpColVector& v)
211  {
212  return InputScalarMethod(m, v[0]);
213  };
214 
215  std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod = [&OutputScalarMethod](const NeedleInsertionModel& m)
216  {
217  return vpColVector(1,OutputScalarMethod(m));
218  };
219 
220  std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod = [](const vpColVector& v1, const vpColVector& v2, const double step)
221  {
222  return 1./step*(v1-v2);
223  };
224  vpColVector vectorDiscretizationStep(1,discretizationStep);
225 
226  return getJacobian(model, InputVectorMethod, OutputVectorMethod, DifferenceMethod, J, vectorDiscretizationStep, centeredDifference);
227  }
228 
229  template<class NeedleInsertionModel>
230  bool getJacobianScalarToVector(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, double)> InputScalarMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, double discretizationStep, bool centeredDifference)
231  {
232  // dVectorOut = J * dScalarIn
233 
234  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod = [&InputScalarMethod](NeedleInsertionModel& m, const vpColVector& v)
235  {
236  return InputScalarMethod(m, v[0]);
237  };
238 
239  std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod = [](const vpColVector& v1, const vpColVector& v2, const double step)
240  {
241  return 1./step*(v1-v2);
242  };
243  vpColVector vectorDiscretizationStep(1,discretizationStep);
244 
245  return getJacobian(model, InputVectorMethod, OutputVectorMethod, DifferenceMethod, J, vectorDiscretizationStep, centeredDifference);
246  }
247 
248  template<class NeedleInsertionModel>
249  bool getJacobianVectorToScalar(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<double(const NeedleInsertionModel&)> OutputScalarMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference)
250  {
251  // dScalarOut = J * dVectorIn
252 
253  std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod = [&OutputScalarMethod](const NeedleInsertionModel& m)
254  {
255  return vpColVector(1,OutputScalarMethod(m));
256  };
257 
258  std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod = [](const vpColVector& v1, const vpColVector& v2, const double step)
259  {
260  return 1./step*(v1-v2);
261  };
262 
263  return getJacobian(model, InputVectorMethod, OutputVectorMethod, DifferenceMethod, J, discretizationStep, centeredDifference);
264  }
265 
266  template<class NeedleInsertionModel>
267  bool getJacobianVectorToVector(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpColVector(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference)
268  {
269  // dVectorOut = J * dVectorIn
270 
271  std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod = [](const vpColVector& v1, const vpColVector& v2, const double step)
272  {
273  return 1./step*(v1-v2);
274  };
275 
276  return getJacobian(model, InputVectorMethod, OutputVectorMethod, DifferenceMethod, J, discretizationStep, centeredDifference);
277  }
278 
279  template<class NeedleInsertionModel>
280  bool getJacobianVectorToPose(NeedleInsertionModel model, std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputVectorMethod, std::function<vpHomogeneousMatrix(const NeedleInsertionModel&)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference)
281  {
282  // dPose/dt= J * dVectorIn/dt (use exponential map instead of difference)
283 
284  std::function<vpColVector(const NeedleInsertionModel&)> trueOutputVectorMethod = [&OutputVectorMethod](const NeedleInsertionModel& m)
285  {
286  return vpColVector(vpPoseVector(OutputVectorMethod(m)));
287  };
288 
289  std::function<vpColVector(const vpColVector&, const vpColVector&, const double step)> DifferenceMethod = [](const vpColVector& v1, const vpColVector& v2, const double step)
290  {
291  vpHomogeneousMatrix H1(v1[0], v1[1], v1[2], v1[3], v1[4], v1[5]);
292  vpHomogeneousMatrix H2(v2[0], v2[1], v2[2], v2[3], v2[4], v2[5]);
293  return vpExponentialMap::inverse(H2.inverse()*H1, step);
294  };
295 
296  return getJacobian(model, InputVectorMethod, trueOutputVectorMethod, DifferenceMethod, J, discretizationStep, centeredDifference);
297  }
298 
300 
301  template<class NeedleInsertionModel>
302  bool getJacobianWorldBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
303  {
304  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
305  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
306  {
307  n.accessNeedle().moveBaseWorldFrame(v);
308  return n.updateState();
309  };
310  std::function<vpHomogeneousMatrix(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n)
311  {
312  return n.accessNeedle().getWorldMtip();
313  };
314 
315  bool success = getJacobianVectorToPose(model, InputFunction, OutputFunction, J, discretStep);
316 
317  return success;
318  }
319 
320  template<class NeedleInsertionModel>
321  bool getJacobianBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
322  {
323  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
324  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
325  {
326  n.accessNeedle().moveBase(v);
327  return n.updateState();
328  };
329  std::function<vpHomogeneousMatrix(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n)
330  {
331  return n.accessNeedle().getWorldMtip();
332  };
333 
334  bool success = getJacobianVectorToPose(model, InputFunction, OutputFunction, J, discretStep);
335 
336  return success;
337  }
338 
339  template<class NeedleInsertionModel>
340  bool getJacobianWorldBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
341  {
342  vpMatrix M;
343  bool success = getJacobianWorldBaseVelocityToTipVelocity(model,M);
344 
345  if(success)
346  {
347  // Vtip_tip = J * Vbase_world
348  // (worldRtip 0 )
349  // => Vtip_world = ( 0 worldRtip) * J * Vbase_world
350 
351  vpRotationMatrix worldRtip(model.accessNeedle().getWorldMtip());
352 
353  vpMatrix Jtranslation(M, 0,0, 3,6);
354  vpMatrix Jrotation(M, 3,0, 3,6);
355 
356  Jtranslation = static_cast<vpMatrix>(worldRtip) * Jtranslation;
357  Jrotation = static_cast<vpMatrix>(worldRtip) * Jrotation;
358 
359  J.resize(6,6);
360  J.insert(Jtranslation, 0,0);
361  J.insert(Jrotation, 3,0);
362  }
363 
364  return success;
365  }
366 
367  template<class NeedleInsertionModel>
368  bool getJacobianBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
369  {
370  vpMatrix M;
371  bool success = getJacobianBaseVelocityToTipVelocity(model,M);
372 
373  if(success)
374  {
375  // Vtip_tip = J * Vbase_base
376  // (worldRtip 0 )
377  // => Vtip_world = ( 0 worldRtip) * J * Vbase_base
378 
379  vpRotationMatrix worldRtip(model.accessNeedle().getWorldMtip());
380 
381  vpMatrix Jtranslation(M, 0,0, 3,6);
382  vpMatrix Jrotation(M, 3,0, 3,6);
383 
384  Jtranslation = static_cast<vpMatrix>(worldRtip) * Jtranslation;
385  Jrotation = static_cast<vpMatrix>(worldRtip) * Jrotation;
386 
387  J.resize(6,6);
388  J.insert(Jtranslation, 0,0);
389  J.insert(Jrotation, 3,0);
390  }
391 
392  return success;
393  }
394 
396 
397  template<class NeedleInsertionModel>
398  bool getJacobianBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J)
399  {
400  vpColVector discretStep(6, 1e-5*model.accessNeedle().getParametricLength());
401  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
402  {
403  n.accessNeedle().moveBase(v);
404  return n.updateState();
405  };
406  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.accessNeedle().getBendingEnergy();};
407  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
408  }
409 
410  template<class NeedleInsertionModel>
411  bool getJacobianWorldBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J)
412  {
413  vpColVector discretStep(6, 1e-5*model.accessNeedle().getParametricLength());
414  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
415  {
416  n.accessNeedle().moveBaseWorldFrame(v);
417  return n.updateState();
418  };
419  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.accessNeedle().getBendingEnergy();};
420  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
421  }
422 
424 
425  template<class NeedleInsertionModel>
426  bool getJacobianBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J)
427  {
428  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
429  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
430  {
431  n.accessNeedle().moveBase(v);
432  return n.updateState();
433  };
434  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getTissueDeformationEnergy();};
435  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
436  }
437 
438  template<class NeedleInsertionModel>
439  bool getJacobianWorldBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J)
440  {
441  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
442  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
443  {
444  n.accessNeedle().moveBase(v);
445  return n.updateState();
446  };
447  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getTissueDeformationEnergy();};
448  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
449  }
450 
451  template<class NeedleInsertionModel>
452  bool getJacobianBaseVelocityToNeedleInsertionPointVelocity(const NeedleInsertionModel &model, vpMatrix &J)
453  {
454  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
455  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
456  {
457  n.accessNeedle().moveBase(v);
458  return n.updateState();
459  };
460  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getNeedleInsertionPoint();};
461  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
462  }
463 
464  template<class NeedleInsertionModel>
465  bool getJacobianBaseVelocityToBaseForceTorque(const NeedleInsertionModel &model, vpMatrix &J)
466  {
467  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
468  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
469  {
470  n.accessNeedle().moveBase(v);
471  return n.updateState();
472  };
473  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n)
474  {
475  vpColVector baseForceTorque = n.accessNeedle().getBaseStaticTorsor();
476  vpRotationMatrix bRw = n.accessNeedle().getWorldMbase().getRotationMatrix().inverse();
477  baseForceTorque.insert(0, bRw * vpColVector(baseForceTorque, 0,3));
478  baseForceTorque.insert(3, bRw * vpColVector(baseForceTorque, 3,3));
479  return baseForceTorque;
480  };
481  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
482  }
483 
484  template<class NeedleInsertionModel>
485  bool getJacobianBaseVelocityToInsertionLength(const NeedleInsertionModel &model, vpMatrix &J)
486  {
487  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
488  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
489  {
490  n.accessNeedle().moveBase(v);
491  return n.updateState();
492  };
493  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getInsertionDepth();};
494  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
495  }
496 
497  template<class NeedleInsertionModel>
498  bool getJacobianBaseVelocityToSurfaceTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
499  {
500  vpColVector e = model.getNeedleInsertionPoint() - model.getTissueInsertionPoint();
501  double norm = e.frobeniusNorm();
502  if(norm <= std::numeric_limits<double>::epsilon()) return false;
503  else e /= norm;
504 
505  vpMatrix M(6,3,0);
507  {
508  J = e.t() * M;
509  return true;
510  }
511  else return false;
512  }
513 
514  template<class NeedleInsertionModel>
515  bool getJacobianBaseVelocityToMaxTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
516  {
517  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
518  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
519  {
520  n.accessNeedle().moveBase(v);
521  return n.updateState();
522  };
523  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getMaxTissueStretch();};
524  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
525  }
526 
527  template<class NeedleInsertionModel>
528  bool getJacobianBaseVelocityToMeanTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
529  {
530  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
531  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
532  {
533  n.accessNeedle().moveBase(v);
534  return n.updateState();
535  };
536  std::function<double(const NeedleInsertionModel&)> OutputFunction = [](const NeedleInsertionModel& n){return n.getMeanTissueStretch();};
537  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
538  }
539 
541 
542  template<class NeedleInsertionModel>
543  bool getJacobianBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l)
544  {
545  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
546  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
547  {
548  n.accessNeedle().moveBase(v);
549  return n.updateState();
550  };
551  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n){return n.accessNeedle().getPoint(l);};
552  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
553  }
554 
555  template<class NeedleInsertionModel>
556  bool getJacobianWorldBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l)
557  {
558  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
559  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
560  {
561  n.accessNeedle().moveBaseWorldFrame(v);
562  return n.updateState();
563  };
564  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n){return n.accessNeedle().getPoint(l);};
565  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
566  }
567 
569 
570  template<class NeedleInsertionModel>
571  bool getJacobianBaseVelocityToTransversalTargetDistance(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target)
572  {
573  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
574  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
575  {
576  n.accessNeedle().moveBase(v);
577  return n.updateState();
578  };
579  std::function<double(const NeedleInsertionModel&)> OutputFunction = [target](const NeedleInsertionModel& n)
580  {
581  vpColVector v(4,1);
582  v.insert(0,target);
583  v = n.accessNeedle().getWorldMtip().inverse()*v;
584  return sqrt(v[0]*v[0]+v[1]*v[1]);
585  };
586  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
587  }
588 
589  template<class NeedleInsertionModel>
590  bool getJacobianBaseVelocityToTargetAngle(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target)
591  {
592  vpColVector discretStep(6, 0.01*model.accessNeedle().getParametricLength());
593  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [](NeedleInsertionModel& n, const vpColVector& v)
594  {
595  n.accessNeedle().moveBase(v);
596  return n.updateState();
597  };
598  std::function<double(const NeedleInsertionModel&)> OutputFunction = [target](const NeedleInsertionModel& n)
599  {
600  vpColVector v(4,1);
601  v.insert(0,target);
602  v = n.accessNeedle().getWorldMtip().inverse()*v;
603  return atan2(sqrt(v[0]*v[0]+v[1]*v[1]),v[2]);
604  };
605  return getJacobianVectorToScalar(model, InputFunction, OutputFunction, J, discretStep);
606  }
607 
609 
610  template<class NeedleInsertionModel>
611  bool getJacobianSpringVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, int spring, double l)
612  {
613  vpColVector discretStep(3, 1e-6);
614  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [spring](NeedleInsertionModel& n, const vpColVector& v){return n.moveSpringPosition(spring, v, true);};
615  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n){return n.accessNeedle().getPoint(l);};
616  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
617  }
618 
620 
621  template<class NeedleInsertionModel>
622  bool getJacobianSpringVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int spring, const std::vector<vpColVector> &points)
623  {
624  vpColVector discretStep(3, 1e-6);
625  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [spring](NeedleInsertionModel& n, const vpColVector& v){return n.moveSpringPosition(spring, v, true);};
626  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [points](const NeedleInsertionModel& n)
627  {
628  int m = points.size();
629  vpColVector P(m,1);
630  for(int i=0 ; i<m ; i++)
631  {
632  P[i] = n.accessNeedle().getDistanceFromPoint(points.at(i));
633  }
634  return P;
635  };
636  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
637  }
638 
640 
641  template<class NeedleInsertionModel>
642  bool getJacobianRestPathPointVelocityToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector<double> &l)
643  {
644  vpColVector discretStep(3, 1e-6);
645  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [restPoint](NeedleInsertionModel& n, const vpColVector& v)
646  {
647  int m = n.accessTissue().accessPath().getNbSegments()+1;
648  if(restPoint<0 || restPoint>=m || v.size()!=3) return false;
649  std::vector<vpColVector> P(m);
650  std::vector<double> lengths(m-1);
651  for(int i=0 ; i<m-1 ; i++)
652  {
653  P.at(i) = n.accessTissue().accessPath().accessSegment(i).getStartPoint();
654  lengths.at(i) = n.accessTissue().accessPath().accessSegment(i).getParametricLength();
655  }
656  P.back() = n.accessTissue().accessPath().accessLastSegment().getEndPoint();
657 
658  P.at(restPoint) += v;
659  n.accessTissue().accessPath().defineFromPoints(P,lengths,1);
660  n.updateState();
661  return true;
662  };
663  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n)
664  {
665  int m = l.size();
666  vpColVector P(3*m,1);
667  for(int i=0 ; i<m ; i++)
668  {
669  P.insert(3*i, n.accessNeedle().getPoint(l.at(i)));
670  }
671  return P;
672  };
673  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
674  }
675 
677 
678  template<class NeedleInsertionModel>
679  bool getJacobianRestPathPointVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector<vpColVector> &points)
680  {
681  vpColVector discretStep(3, 1e-6);
682  std::function<bool(NeedleInsertionModel&, const vpColVector&)> InputFunction = [restPoint](NeedleInsertionModel& n, const vpColVector& v)
683  {
684  int m = n.accessTissue().accessPath().getNbSegments()+1;
685  if(restPoint<0 || restPoint>=m || v.size()!=3) return false;
686  std::vector<vpColVector> P(m);
687  std::vector<double> lengths(m-1);
688  for(int i=0 ; i<m-1 ; i++)
689  {
690  P.at(i) = n.accessTissue().accessPath().accessSegment(i).getStartPoint();
691  lengths.at(i) = n.accessTissue().accessPath().accessSegment(i).getParametricLength();
692  }
693  P.back() = n.accessTissue().accessPath().accessLastSegment().getEndPoint();
694 
695  P.at(restPoint) += v;
696  n.updateState();
697  return true;
698  };
699  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [points](const NeedleInsertionModel& n)
700  {
701  int m = points.size();
702  vpColVector P(m,1);
703  for(int i=0 ; i<m ; i++)
704  {
705  P[i] = n.accessNeedle().getDistanceFromPoint(points.at(i));
706  }
707  return P;
708  };
709  return getJacobianVectorToVector(model, InputFunction, OutputFunction, J, discretStep);
710  }
711 
713 
714  template<class NeedleInsertionModel>
715  bool getJacobianStiffnessPerUnitLengthToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, const std::vector<vpColVector> &points)
716  {
717  double discretStep = 0.01*model.getStiffnessPerUnitLength();
718  std::function<bool(NeedleInsertionModel&, double)> InputFunction = [](NeedleInsertionModel& n, double dK)
719  {
720  n.setStiffnessPerUnitLength(n.getStiffnessPerUnitLength()+dK);
721  return n.updateState();
722  };
723  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [points](const NeedleInsertionModel& n)
724  {
725  vpColVector d(points.size());
726  for(unsigned int i=0 ; i<points.size() ; i++) d[i] = n.accessNeedle().getDistanceFromPoint(points.at(i));
727  return d;
728  };
729  return getJacobianScalarToVector(model, InputFunction, OutputFunction, J, discretStep);
730  }
731 
733 
734  template<class NeedleInsertionModel>
735  bool getJacobianStiffnessPerUnitLengthToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, const std::vector<double> &l)
736  {
737  double discretStep = 0.01*model.getStiffnessPerUnitLength();
738  std::function<bool(NeedleInsertionModel&, double)> InputFunction = [](NeedleInsertionModel& n, double dK)
739  {
740  n.setStiffnessPerUnitLength(n.getStiffnessPerUnitLength()+dK);
741  return n.updateState();
742  };
743  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n)
744  {
745  int m = l.size();
746  vpColVector P(3*m,1);
747  for(int i=0 ; i<m ; i++)
748  {
749  P.insert(3*i, n.accessNeedle().getPoint(l.at(i)));
750  }
751  return P;
752  };
753  return getJacobianScalarToVector(model, InputFunction, OutputFunction, J, discretStep);
754  }
755 
757 
758  template<class NeedleInsertionModel>
759  bool getJacobianStiffnessPerUnitLengthToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, int i, const std::vector<double> &l)
760  {
761  double discretStep = 0.01*model.getStiffnessPerUnitLength(i);
762  std::function<bool(NeedleInsertionModel&, double)> InputFunction = [i](NeedleInsertionModel& n, double dK)
763  {
764  n.setStiffnessPerUnitLength(i, n.getStiffnessPerUnitLength(i)+dK);
765  return n.updateState();
766  };
767  std::function<vpColVector(const NeedleInsertionModel&)> OutputFunction = [l](const NeedleInsertionModel& n)
768  {
769  int m = l.size();
770  vpColVector P(3*m,1);
771  for(int i=0 ; i<m ; i++)
772  {
773  P.insert(3*i, n.accessNeedle().getPoint(l.at(i)));
774  }
775  return P;
776  };
777  return getJacobianScalarToVector(model, InputFunction, OutputFunction, J, discretStep);
778  }
779 
780 } //namespace usNeedleJacobians
781 
782 #endif // __usNeedleJacobians_h_
bool getJacobianSpringVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int spring, const std::vector< vpColVector > &points)
Springs to distance from points (nbPointsx6)
bool getJacobianBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J)
Base to tissue deformation energy (1x6)
bool getJacobianBaseVelocityToTransversalTargetDistance(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target)
Base to features (1x6)
bool getJacobianBaseVelocityToInsertionLength(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianWorldBaseVelocityToTissueEnergy(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l)
Base to needle point (3x6)
bool getJacobianScalarToVector(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, double)> InputScalarMethod, std::function< vpColVector(const NeedleInsertionModel &)> OutputVectorMethod, vpMatrix &J, double discretizationStep=1e-5, bool centeredDifference=true)
bool getJacobianBaseVelocityToSurfaceTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianRestPathPointVelocityToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector< double > &l)
Rest path points to model point (3x3)
bool getJacobianVectorToVector(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, const vpColVector &)> InputVectorMethod, std::function< vpColVector(const NeedleInsertionModel &)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true)
bool getJacobianScalarToScalar(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, double)> InputScalarMethod, std::function< double(const NeedleInsertionModel &)> OutputScalarMethod, vpMatrix &J, double discretizationStep=1e-5, bool centeredDifference=true)
bool getJacobianWorldBaseVelocityToTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
Base to tip.
bool getJacobianVectorToScalar(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, const vpColVector &)> InputVectorMethod, std::function< double(const NeedleInsertionModel &)> OutputScalarMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true)
bool getJacobianRestPathPointVelocityToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, int restPoint, const std::vector< vpColVector > &points)
Rest path points distance from points (nbPointsx3)
bool getJacobianBaseVelocityToNeedleInsertionPointVelocity(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J)
Base to bending energy (1x6)
bool getJacobianSpringVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, int spring, double l)
Springs to needle point (3x6)
bool getJacobian(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, const vpColVector &)> InputVectorMethod, std::function< vpColVector(const NeedleInsertionModel &)> OutputVectorMethod, std::function< vpColVector(const vpColVector &, const vpColVector &, const double step)> DifferenceMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true)
Generic Jacobians.
bool getJacobianWorldBaseVelocityToBendingEnergy(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToTargetAngle(const NeedleInsertionModel &model, vpMatrix &J, const vpColVector &target)
bool getJacobianWorldBaseVelocityToPointVelocity(const NeedleInsertionModel &model, vpMatrix &J, double l)
bool getJacobianBaseVelocityToBaseForceTorque(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToMaxTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianWorldBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
Base to tip (manipulation Jacobian) (6x6)
bool getJacobianStiffnessPerUnitLengthToPointsVelocity(const NeedleInsertionModel &model, vpMatrix &J, const std::vector< double > &l)
Stiffness per unit length to needle point ( (3*nbPoints)x1 matrix)
bool getJacobianStiffnessPerUnitLengthToPointsDistance(const NeedleInsertionModel &model, vpMatrix &J, const std::vector< vpColVector > &points)
Stiffness per unit length to distance from points (nbPointsx1)
bool getJacobianBaseVelocityToWorldTipVelocity(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianBaseVelocityToMeanTissueStretch(const NeedleInsertionModel &model, vpMatrix &J)
bool getJacobianVectorToPose(NeedleInsertionModel model, std::function< bool(NeedleInsertionModel &, const vpColVector &)> InputVectorMethod, std::function< vpHomogeneousMatrix(const NeedleInsertionModel &)> OutputVectorMethod, vpMatrix &J, const vpColVector &discretizationStep, bool centeredDifference=true)