Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpPoseFeatures.h
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 ViSP 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  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Pose computation from any features.
32  */
33 
39 #ifndef vpPoseFeatures_HH
40 #define vpPoseFeatures_HH
41 
42 #include <visp3/core/vpConfig.h>
43 
44 #if defined(VISP_HAVE_MODULE_VISUAL_FEATURES) && (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
45 
46 #include <visp3/core/vpCircle.h>
47 #include <visp3/core/vpCylinder.h>
48 #include <visp3/core/vpDebug.h>
49 #include <visp3/core/vpException.h>
50 #include <visp3/core/vpExponentialMap.h>
51 #include <visp3/core/vpForwardProjection.h>
52 #include <visp3/core/vpLine.h>
53 #include <visp3/core/vpPoint.h>
54 #include <visp3/core/vpRobust.h>
55 #include <visp3/core/vpSphere.h>
56 #include <visp3/visual_features/vpBasicFeature.h>
57 #include <visp3/visual_features/vpFeatureBuilder.h>
58 #include <visp3/visual_features/vpFeatureEllipse.h>
59 #include <visp3/visual_features/vpFeaturePoint.h>
60 
61 #include <iostream>
62 #include <vector>
63 #include <tuple>
64 
65 BEGIN_VISP_NAMESPACE
66 
67 #ifndef DOXYGEN_SHOULD_SKIP_THIS
68 //#################################################
69 //## Call a function with a tuple as parameters
70 //#################################################
71 template <unsigned int N> struct vpDesiredFeatureBuilderWithTuple
72 {
73  template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args>
74  static void buildDesiredFeatureWithTuple(featureType &feature, RetType(*f)(ArgsF...), const std::tuple<ArgsT...> &t,
75  Args &&...args)
76  {
77  vpDesiredFeatureBuilderWithTuple<N - 1>::buildDesiredFeatureWithTuple(feature, f, t, std::get<N - 1>(t), args...);
78  }
79 };
80 
81 template <> struct vpDesiredFeatureBuilderWithTuple<0>
82 {
83  template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args>
84  static void buildDesiredFeatureWithTuple(featureType & /* feature */, RetType(*f)(ArgsF...),
85  const std::tuple<ArgsT...> & /* t */, Args &&...args)
86  {
87  f(args...);
88  }
89 };
90 
91 template <> struct vpDesiredFeatureBuilderWithTuple<1>
92 {
93  template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args>
94  static void buildDesiredFeatureWithTuple(featureType &feature, RetType(*f)(ArgsF...), const std::tuple<ArgsT...> &t,
95  Args &&...args)
96  {
97  vpDesiredFeatureBuilderWithTuple<0>::buildDesiredFeatureWithTuple(feature, f, t, feature, args...);
98  }
99 };
100 
101 template <typename featureType, typename RetType, typename... Args, typename... ArgsFunc>
102 void buildDesiredFeatureWithTuple(featureType &feature, RetType(*f)(ArgsFunc...), std::tuple<Args...> const &t)
103 {
104  vpDesiredFeatureBuilderWithTuple<sizeof...(Args)>::buildDesiredFeatureWithTuple(feature, f, t);
105 }
106 
107 //#################################################
108 //## Call a function with a tuple as parameters
109 //## Object Mode
110 //#################################################
111 
112 template <unsigned int N> struct vpDesiredFeatureBuilderObjectWithTuple
113 {
114  template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT,
115  typename... Args>
116  static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType(objType:: *f)(ArgsF...),
117  const std::tuple<ArgsT...> &t, Args &&...args)
118  {
119  vpDesiredFeatureBuilderObjectWithTuple<N - 1>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t,
120  std::get<N - 1>(t), args...);
121  }
122 };
123 
124 template <> struct vpDesiredFeatureBuilderObjectWithTuple<0>
125 {
126  template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT,
127  typename... Args>
128  static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType & /*feature*/,
129  RetType(objType:: *f)(ArgsF...), const std::tuple<ArgsT...> & /* t */,
130  Args &&...args)
131  {
132  (obj->*f)(args...);
133  }
134 };
135 
136 template <> struct vpDesiredFeatureBuilderObjectWithTuple<1>
137 {
138  template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT,
139  typename... Args>
140  static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType(objType:: *f)(ArgsF...),
141  const std::tuple<ArgsT...> &t, Args &&...args)
142  {
143  vpDesiredFeatureBuilderObjectWithTuple<0>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t, feature, args...);
144  }
145 };
146 
147 template <typename objType, typename featureType, typename RetType, typename... Args, typename... ArgsFunc>
148 void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType(objType:: *f)(ArgsFunc...),
149  std::tuple<Args...> const &t)
150 {
151  vpDesiredFeatureBuilderObjectWithTuple<sizeof...(Args)>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t);
152 }
153 
154 //#####################################################
155 //## Call un function with a tuple as parameters
156 //## Track all the parameters with the cMo
157 //## Except the first one (must be de "BasicFeature"
158 //#####################################################
159 
160 template <unsigned int N> struct vpCurrentFeatureBuilderWithTuple
161 {
162  template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
163  typename... ArgsF>
164  static void buildCurrentFeatureWithTuple(featureType &feature, const vpHomogeneousMatrix &cMo, RetType(*f)(ArgsF...),
165  std::tuple<ArgsTuple...> &t, ArgsDecomposed &&...args)
166  {
167  auto proj = std::get<N - 1>(t);
168  proj.track(cMo);
169  vpCurrentFeatureBuilderWithTuple<N - 1>::buildCurrentFeatureWithTuple(feature, cMo, f, t, proj, args...);
170  }
171 };
172 
173 template <> struct vpCurrentFeatureBuilderWithTuple<0>
174 {
175  template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
176  typename... ArgsF>
177  static void buildCurrentFeatureWithTuple(featureType & /*feature*/, const vpHomogeneousMatrix & /*cMo*/,
178  RetType(*f)(ArgsF...), std::tuple<ArgsTuple...> &, ArgsDecomposed &&...args)
179  {
180  f(args...);
181  }
182 };
183 
184 template <> struct vpCurrentFeatureBuilderWithTuple<1>
185 {
186  template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
187  typename... ArgsF>
188  static void buildCurrentFeatureWithTuple(featureType &feature, const vpHomogeneousMatrix &cMo, RetType(*f)(ArgsF...),
189  std::tuple<ArgsTuple...> &t, ArgsDecomposed &&...args)
190  {
191  vpCurrentFeatureBuilderWithTuple<0>::buildCurrentFeatureWithTuple(feature, cMo, f, t, feature, args...);
192  }
193 };
194 
195 template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsFunc>
196 void buildCurrentFeatureWithTuple(featureType &feature, const vpHomogeneousMatrix &cMo, RetType(*f)(ArgsFunc...),
197  std::tuple<ArgsTuple...> &t)
198 {
199  vpCurrentFeatureBuilderWithTuple<sizeof...(ArgsTuple)>::buildCurrentFeatureWithTuple(feature, cMo, f, t);
200 }
201 
202 //#####################################################
203 //## Call un function with a tuple as parameters
204 //## Track all the parameters with the cMo
205 //## Except the first one (must be de "BasicFeature"
206 //## Object Mode
207 //#####################################################
208 
209 template <unsigned int N> struct vpCurrentFeatureBuilderObjectWithTuple
210 {
211  template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
212  typename... ArgsF>
213  static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo,
214  RetType(objType:: *f)(ArgsF...), std::tuple<ArgsTuple...> &t,
215  ArgsDecomposed &&...args)
216  {
217  auto proj = std::get<N - 1>(t);
218  proj.track(cMo);
219  vpCurrentFeatureBuilderObjectWithTuple<N - 1>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f, t, proj,
220  args...);
221  }
222 };
223 
224 template <> struct vpCurrentFeatureBuilderObjectWithTuple<0>
225 {
226  template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
227  typename... ArgsF>
228  static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType & /*feature*/,
229  const vpHomogeneousMatrix & /*cMo*/, RetType(objType:: *f)(ArgsF...),
230  std::tuple<ArgsTuple...> &, ArgsDecomposed &&...args)
231  {
232  (obj->*f)(args...);
233  }
234 };
235 
236 template <> struct vpCurrentFeatureBuilderObjectWithTuple<1>
237 {
238  template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed,
239  typename... ArgsF>
240  static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo,
241  RetType(objType:: *f)(ArgsF...), std::tuple<ArgsTuple...> &t,
242  ArgsDecomposed &&...args)
243  {
244  vpCurrentFeatureBuilderObjectWithTuple<0>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f, t, feature,
245  args...);
246  }
247 };
248 
249 template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsFunc>
250 void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo,
251  RetType(objType:: *f)(ArgsFunc...), std::tuple<ArgsTuple...> &t)
252 {
253  vpCurrentFeatureBuilderObjectWithTuple<sizeof...(ArgsTuple)>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f,
254  t);
255 }
256 
257 //#################################################
258 //## Call that will be used in our vpPoseFeatures
259 //## to store the specific features.
260 //#################################################
267 class VISP_EXPORT vpPoseSpecificFeature
268 {
269 public:
270  vpPoseSpecificFeature() { }
271  virtual ~vpPoseSpecificFeature() { }
272 
273  virtual vpColVector error() = 0;
274  virtual vpMatrix currentInteraction() = 0;
275  virtual void createDesired() = 0;
276  virtual void createCurrent(const vpHomogeneousMatrix &cMo) = 0;
277 };
278 
279 //#################################################
280 //## Template for all kind of specific features
281 //#################################################
282 
289 template <typename featureType, typename RetType, typename... Args>
290 class vpPoseSpecificFeatureTemplate : public vpPoseSpecificFeature
291 {
292 private:
293  featureType m_desiredFeature;
294  featureType m_currentFeature;
295  std::tuple<Args...> *m_tuple;
296  RetType(*func_ptr)(Args...);
297 
298 public:
299  vpPoseSpecificFeatureTemplate(RetType(*f_ptr)(Args...), Args &&...args)
300  {
301  func_ptr = f_ptr; // std::move(f_ptr);
302  m_tuple = new std::tuple<Args...>(args...);
303  }
304  virtual ~vpPoseSpecificFeatureTemplate() VP_OVERRIDE
305  {
306  delete m_tuple;
307  }
308 
309  virtual void createDesired() VP_OVERRIDE
310  {
311  buildDesiredFeatureWithTuple(m_desiredFeature, func_ptr, *m_tuple);
312  }
313 
314  virtual vpColVector error() VP_OVERRIDE
315  {
316  // std::cout << "Getting S... : " << std::get<0>(*tuple).get_s() <<
317  // std::endl;
318  return m_currentFeature.error(m_desiredFeature);
319  }
320 
321  virtual vpMatrix currentInteraction() VP_OVERRIDE
322  {
323  return m_currentFeature.interaction();
324  }
325 
326  virtual void createCurrent(const vpHomogeneousMatrix &cMo) VP_OVERRIDE
327  {
328  buildCurrentFeatureWithTuple(m_currentFeature, cMo, func_ptr, *m_tuple);
329  }
330 };
331 
332 //#################################################
333 //## Template for all kind of specific features
334 //## Object Mode
335 //#################################################
336 
343 template <typename ObjectType, typename featureType, typename RetType, typename... Args>
344 class vpPoseSpecificFeatureTemplateObject : public vpPoseSpecificFeature
345 {
346 private:
347  featureType m_desiredFeature;
348  featureType m_currentFeature;
349  std::tuple<Args...> *m_tuple;
350  RetType(ObjectType:: *func_ptr)(Args...);
351  ObjectType *m_obj;
352 
353 public:
354  vpPoseSpecificFeatureTemplateObject(ObjectType *o, RetType(ObjectType:: *f_ptr)(Args...), Args &&...args)
355  {
356  func_ptr = f_ptr; // std::move(f_ptr);
357  m_tuple = new std::tuple<Args...>(args...);
358  m_obj = o;
359  }
360 
361  virtual ~vpPoseSpecificFeatureTemplateObject() VP_OVERRIDE
362  {
363  delete m_tuple;
364  }
365 
366  virtual void createDesired() VP_OVERRIDE
367  {
368  buildDesiredFeatureObjectWithTuple(m_obj, m_desiredFeature, func_ptr, *m_tuple);
369  }
370 
371  virtual vpColVector error() VP_OVERRIDE
372  {
373  return m_currentFeature.error(m_desiredFeature);
374  }
375 
376  virtual vpMatrix currentInteraction() VP_OVERRIDE
377  {
378  return m_currentFeature.interaction();
379  }
380 
381  virtual void createCurrent(const vpHomogeneousMatrix &cMo) VP_OVERRIDE
382  {
383  buildCurrentFeatureObjectWithTuple(m_obj, m_currentFeature, cMo, func_ptr, *m_tuple);
384  }
385 };
386 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
387 
398 class VISP_EXPORT vpPoseFeatures
399 {
400 public:
404  typedef enum
405  {
406  VIRTUAL_VS,
407  ROBUST_VIRTUAL_VS
408  } vpPoseFeaturesMethodType;
409 
413  vpPoseFeatures();
414 
418  virtual ~vpPoseFeatures();
419 
426  void addFeaturePoint(const vpPoint &p);
427 
434  void addFeaturePoint3D(const vpPoint &p);
435 
442  void addFeatureVanishingPoint(const vpPoint &p);
443 
451  void addFeatureVanishingPoint(const vpLine &l1, const vpLine &l2);
452 
459  void addFeatureEllipse(const vpCircle &);
460 
467  void addFeatureEllipse(const vpSphere &);
468 
475  void addFeatureLine(const vpLine &);
476 
485  void addFeatureLine(const vpCylinder &, const int &line);
486 
494  void addFeatureSegment(vpPoint &, vpPoint &);
495 
499  template <typename RetType, typename... ArgsFunc, typename... Args>
500  void addSpecificFeature(RetType(*fct_ptr)(ArgsFunc...), Args &&...args);
501 
505  template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args>
506  void addSpecificFeature(ObjType *obj, RetType(ObjType:: *fct_ptr)(ArgsFunc...), Args &&...args);
507 
511  void clear();
512 
526  void computePose(vpHomogeneousMatrix &cMo, const vpPoseFeaturesMethodType &type = VIRTUAL_VS);
527 
535  vpMatrix getCovarianceMatrix() const
536  {
537  if (!m_computeCovariance)
538  vpTRACE("Warning : The covariance matrix has not been computed. See "
539  "setCovarianceComputation() to do it.");
540 
541  return m_covarianceMatrix;
542  }
543 
550  double getLambda() { return m_lambda; }
551 
558  unsigned int getVVSIterMax() { return m_vvsIterMax; }
559 
565  void setCovarianceComputation(const bool &flag) { m_computeCovariance = flag; }
566 
573  void setLambda(const double &val) { m_lambda = val; }
574 
580  void setVVSIterMax(const unsigned int &val) { m_vvsIterMax = val; }
581 
587  void setVerbose(const bool &mode) { m_verbose = mode; }
588 
589 private:
590 #ifndef DOXYGEN_SHOULD_SKIP_THIS
591  template <typename FeatureType, typename FirstParamType> struct vpDuo
592  {
593  FeatureType *desiredFeature;
594  FirstParamType firstParam;
595  vpDuo() : desiredFeature(nullptr), firstParam() { }
596  };
597 
598  template <typename FeatureType, typename FirstParamType, typename SecondParamType> struct vpTrio
599  {
600  FeatureType *desiredFeature;
601  FirstParamType firstParam;
602  SecondParamType secondParam;
603 
604  vpTrio() : desiredFeature(nullptr), firstParam(), secondParam() { }
605  };
606 #endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
607 
608  unsigned int m_maxSize;
609  unsigned int m_totalSize;
610  unsigned int m_vvsIterMax;
611  double m_lambda;
612 
613  bool m_verbose;
614 
615  bool m_computeCovariance;
616  vpMatrix m_covarianceMatrix;
617 
618  // vpFeaturePoint
619  std::vector<vpDuo<vpFeaturePoint, vpPoint> > m_featurePoint_Point_list;
620  // vpFeaturePoint3D
621  std::vector<vpDuo<vpFeaturePoint3D, vpPoint> > m_featurePoint3D_Point_list;
622  // vpFeatureVanishingPoint
623  std::vector<vpDuo<vpFeatureVanishingPoint, vpPoint> > m_featureVanishingPoint_Point_list;
624  std::vector<vpTrio<vpFeatureVanishingPoint, vpLine, vpLine> > m_featureVanishingPoint_DuoLine_list;
625  // vpFeatureEllipse
626  std::vector<vpDuo<vpFeatureEllipse, vpSphere> > m_featureEllipse_Sphere_list;
627  std::vector<vpDuo<vpFeatureEllipse, vpCircle> > m_featureEllipse_Circle_list;
628  // vpFeatureLine
629  std::vector<vpDuo<vpFeatureLine, vpLine> > m_featureLine_Line_list;
630  std::vector<vpTrio<vpFeatureLine, vpCylinder, int> > m_featureLine_DuoLineInt_List;
631  // vpFeatureSegment
632  std::vector<vpTrio<vpFeatureSegment, vpPoint, vpPoint> > m_featureSegment_DuoPoints_list;
633 
634 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
635  // Specific features
636  std::vector<vpPoseSpecificFeature *> m_featureSpecific_list;
637 #endif
638 
646  void error_and_interaction(vpHomogeneousMatrix &cMo, vpColVector &err, vpMatrix &L);
647 
655  void computePoseVVS(vpHomogeneousMatrix &cMo);
656 
663  void computePoseRobustVVS(vpHomogeneousMatrix &cMo);
664 };
665 
722 template <typename RetType, typename... ArgsFunc, typename... Args>
723 void vpPoseFeatures::addSpecificFeature(RetType(*fct_ptr)(ArgsFunc...), Args &&...args)
724 {
725  typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference;
726  typedef typename std::remove_reference<featureTypeReference>::type featureType;
727  m_featureSpecific_list.push_back(
728  new vpPoseSpecificFeatureTemplate<featureType, RetType, ArgsFunc...>(fct_ptr, std::forward<ArgsFunc>(args)...));
729 
730  m_featureSpecific_list.back()->createDesired();
731 
732  m_totalSize++;
733  if (m_featureSpecific_list.size() > m_maxSize)
734  m_maxSize = static_cast<unsigned int>(m_featureSpecific_list.size());
735 }
736 
805 template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args>
806 void vpPoseFeatures::addSpecificFeature(ObjType *obj, RetType(ObjType:: *fct_ptr)(ArgsFunc...), Args &&...args)
807 {
808  typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference;
809  typedef typename std::remove_reference<featureTypeReference>::type featureType;
810  m_featureSpecific_list.push_back(new vpPoseSpecificFeatureTemplateObject<ObjType, featureType, RetType, ArgsFunc...>(
811  obj, fct_ptr, std::forward<ArgsFunc>(args)...));
812 
813  m_featureSpecific_list.back()->createDesired();
814 
815  m_totalSize++;
816  if (m_featureSpecific_list.size() > m_maxSize)
817  m_maxSize = static_cast<unsigned int>(m_featureSpecific_list.size());
818 }
819 
820 END_VISP_NAMESPACE
821 #endif
822 
823 #endif
Class that defines a 3D circle in the object frame and allows forward projection of a 3D circle in th...
Definition: vpCircle.h:87
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
Class that defines a 3D cylinder in the object frame and allows forward projection of a 3D cylinder i...
Definition: vpCylinder.h:101
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines a 3D line in the object frame and allows forward projection of the line in the cam...
Definition: vpLine.h:103
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition: vpSphere.h:80