Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpPoseFeatures.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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
38
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
66
67#ifndef DOXYGEN_SHOULD_SKIP_THIS
68//#################################################
69//## Call a function with a tuple as parameters
70//#################################################
71template <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
81template <> 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
91template <> 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
101template <typename featureType, typename RetType, typename... Args, typename... ArgsFunc>
102void 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
112template <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
124template <> 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
136template <> 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
147template <typename objType, typename featureType, typename RetType, typename... Args, typename... ArgsFunc>
148void 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
160template <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
173template <> 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
184template <> 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
195template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsFunc>
196void 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
209template <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
224template <> 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
236template <> 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
249template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsFunc>
250void 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//#################################################
267class VISP_EXPORT vpPoseSpecificFeature
268{
269public:
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
289template <typename featureType, typename RetType, typename... Args>
290class vpPoseSpecificFeatureTemplate : public vpPoseSpecificFeature
291{
292private:
293 featureType m_desiredFeature;
294 featureType m_currentFeature;
295 std::tuple<Args...> *m_tuple;
296 RetType(*func_ptr)(Args...);
297
298public:
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
343template <typename ObjectType, typename featureType, typename RetType, typename... Args>
344class vpPoseSpecificFeatureTemplateObject : public vpPoseSpecificFeature
345{
346private:
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
353public:
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
398class VISP_EXPORT vpPoseFeatures
399{
400public:
404 typedef enum
405 {
408 } vpPoseFeaturesMethodType;
409
414
418 virtual ~vpPoseFeatures();
419
420#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
421 vpPoseFeatures(const vpPoseFeatures &) = default;
423#endif
424
431 void addFeaturePoint(const vpPoint &p);
432
439 void addFeaturePoint3D(const vpPoint &p);
440
447 void addFeatureVanishingPoint(const vpPoint &p);
448
456 void addFeatureVanishingPoint(const vpLine &l1, const vpLine &l2);
457
464 void addFeatureEllipse(const vpCircle &c);
465
472 void addFeatureEllipse(const vpSphere &s);
473
480 void addFeatureLine(const vpLine &l);
481
490 void addFeatureLine(const vpCylinder &c, const int &line);
491
499 void addFeatureSegment(vpPoint &P1, vpPoint &P2);
500
504 template <typename RetType, typename... ArgsFunc, typename... Args>
505 void addSpecificFeature(RetType(*fct_ptr)(ArgsFunc...), Args &&...args);
506
510 template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args>
511 void addSpecificFeature(ObjType *obj, RetType(ObjType:: *fct_ptr)(ArgsFunc...), Args &&...args);
512
516 void clear();
517
532
541 {
542 if (!m_computeCovariance)
543 vpTRACE("Warning : The covariance matrix has not been computed. See "
544 "setCovarianceComputation() to do it.");
545
546 return m_covarianceMatrix;
547 }
548
555 double getLambda() { return m_lambda; }
556
563 unsigned int getVVSIterMax() { return m_vvsIterMax; }
564
570 void setCovarianceComputation(const bool &flag) { m_computeCovariance = flag; }
571
578 void setLambda(const double &val) { m_lambda = val; }
579
585 void setVVSIterMax(const unsigned int &val) { m_vvsIterMax = val; }
586
592 void setVerbose(const bool &mode) { m_verbose = mode; }
593
594private:
595#ifndef DOXYGEN_SHOULD_SKIP_THIS
596 template <typename FeatureType, typename FirstParamType> struct vpDuo
597 {
598 FeatureType *desiredFeature;
599 FirstParamType firstParam;
600 vpDuo() : desiredFeature(nullptr), firstParam() { }
601 };
602
603 template <typename FeatureType, typename FirstParamType, typename SecondParamType> struct vpTrio
604 {
605 FeatureType *desiredFeature;
606 FirstParamType firstParam;
607 SecondParamType secondParam;
608
609 vpTrio() : desiredFeature(nullptr), firstParam(), secondParam() { }
610 };
611#endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
612
613 unsigned int m_maxSize;
614 unsigned int m_totalSize;
615 unsigned int m_vvsIterMax;
616 double m_lambda;
617
618 bool m_verbose;
619
620 bool m_computeCovariance;
621 vpMatrix m_covarianceMatrix;
622
623 // vpFeaturePoint
624 std::vector<vpDuo<vpFeaturePoint, vpPoint> > m_featurePoint_Point_list;
625 // vpFeaturePoint3D
626 std::vector<vpDuo<vpFeaturePoint3D, vpPoint> > m_featurePoint3D_Point_list;
627 // vpFeatureVanishingPoint
628 std::vector<vpDuo<vpFeatureVanishingPoint, vpPoint> > m_featureVanishingPoint_Point_list;
629 std::vector<vpTrio<vpFeatureVanishingPoint, vpLine, vpLine> > m_featureVanishingPoint_DuoLine_list;
630 // vpFeatureEllipse
631 std::vector<vpDuo<vpFeatureEllipse, vpSphere> > m_featureEllipse_Sphere_list;
632 std::vector<vpDuo<vpFeatureEllipse, vpCircle> > m_featureEllipse_Circle_list;
633 // vpFeatureLine
634 std::vector<vpDuo<vpFeatureLine, vpLine> > m_featureLine_Line_list;
635 std::vector<vpTrio<vpFeatureLine, vpCylinder, int> > m_featureLine_DuoLineInt_List;
636 // vpFeatureSegment
637 std::vector<vpTrio<vpFeatureSegment, vpPoint, vpPoint> > m_featureSegment_DuoPoints_list;
638
639#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
640 // Specific features
641 std::vector<vpPoseSpecificFeature *> m_featureSpecific_list;
642#endif
643
651 void error_and_interaction(vpHomogeneousMatrix &cMo, vpColVector &err, vpMatrix &L);
652
660 void computePoseVVS(vpHomogeneousMatrix &cMo);
661
668 void computePoseRobustVVS(vpHomogeneousMatrix &cMo);
669};
670
727template <typename RetType, typename... ArgsFunc, typename... Args>
728void vpPoseFeatures::addSpecificFeature(RetType(*fct_ptr)(ArgsFunc...), Args &&...args)
729{
730 typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference;
731 typedef typename std::remove_reference<featureTypeReference>::type featureType;
732 m_featureSpecific_list.push_back(
733 new vpPoseSpecificFeatureTemplate<featureType, RetType, ArgsFunc...>(fct_ptr, std::forward<ArgsFunc>(args)...));
734
735 m_featureSpecific_list.back()->createDesired();
736
737 m_totalSize++;
738 if (m_featureSpecific_list.size() > m_maxSize)
739 m_maxSize = static_cast<unsigned int>(m_featureSpecific_list.size());
740}
741
810template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args>
811void vpPoseFeatures::addSpecificFeature(ObjType *obj, RetType(ObjType:: *fct_ptr)(ArgsFunc...), Args &&...args)
812{
813 typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference;
814 typedef typename std::remove_reference<featureTypeReference>::type featureType;
815 m_featureSpecific_list.push_back(new vpPoseSpecificFeatureTemplateObject<ObjType, featureType, RetType, ArgsFunc...>(
816 obj, fct_ptr, std::forward<ArgsFunc>(args)...));
817
818 m_featureSpecific_list.back()->createDesired();
819
820 m_totalSize++;
821 if (m_featureSpecific_list.size() > m_maxSize)
822 m_maxSize = static_cast<unsigned int>(m_featureSpecific_list.size());
823}
824
825END_VISP_NAMESPACE
826#endif
827
828#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
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:175
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
Tools for pose computation from any feature.
void setVerbose(const bool &mode)
void addFeatureLine(const vpLine &l)
void addFeatureEllipse(const vpCircle &c)
void addFeaturePoint3D(const vpPoint &p)
void setVVSIterMax(const unsigned int &val)
void addFeaturePoint(const vpPoint &p)
vpPoseFeatures & operator=(const vpPoseFeatures &)=default
vpPoseFeatures(const vpPoseFeatures &)=default
void setCovarianceComputation(const bool &flag)
unsigned int getVVSIterMax()
void addSpecificFeature(RetType(*fct_ptr)(ArgsFunc...), Args &&...args)
void addFeatureVanishingPoint(const vpPoint &p)
void setLambda(const double &val)
void computePose(vpHomogeneousMatrix &cMo, const vpPoseFeaturesMethodType &type=VIRTUAL_VS)
void addFeatureSegment(vpPoint &P1, vpPoint &P2)
vpMatrix getCovarianceMatrix() const
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition vpSphere.h:80
#define vpTRACE
Definition vpDebug.h:450