1 /**************************************************************************** 2 * 3 * ViSP, open source Visual Servoing Platform software. 4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved. 5 * 6 * This software is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * See the file LICENSE.txt at the root directory of this source 11 * distribution for additional information about the GNU GPL. 12 * 13 * For using ViSP with software that can not be combined with the GNU 14 * GPL, please contact Inria about acquiring a ViSP Professional 15 * Edition License. 16 * 17 * See http://visp.inria.fr for more information. 18 * 19 * This software was developed at: 20 * Inria Rennes - Bretagne Atlantique 21 * Campus Universitaire de Beaulieu 22 * 35042 Rennes Cedex 23 * France 24 * 25 * If you have questions regarding the use of this file, please contact 26 * Inria at visp@inria.fr 27 * 28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 30 * 31 * Description: 32 * Pose computation from any features. 33 * 34 * Authors: 35 * Aurelien Yol 36 * 37 *****************************************************************************/ 38 39 /*! 40 \file vpPose.h 41 \brief Tools for pose computation from any feature. 42 43 \author Aurelien Yol 44 \date June, 5 2012 45 */ 46 47 #ifndef vpPoseFeatures_HH 48 #define vpPoseFeatures_HH 49 50 #include <visp3/core/vpConfig.h> 51 52 #ifdef VISP_HAVE_MODULE_VISUAL_FEATURES 53 54 #include <visp3/core/vpCircle.h> 55 #include <visp3/core/vpCylinder.h> 56 #include <visp3/core/vpDebug.h> 57 #include <visp3/core/vpException.h> 58 #include <visp3/core/vpExponentialMap.h> 59 #include <visp3/core/vpForwardProjection.h> 60 #include <visp3/core/vpLine.h> 61 #include <visp3/core/vpPoint.h> 62 #include <visp3/core/vpRobust.h> 63 #include <visp3/core/vpSphere.h> 64 #include <visp3/visual_features/vpBasicFeature.h> 65 #include <visp3/visual_features/vpFeatureBuilder.h> 66 #include <visp3/visual_features/vpFeatureEllipse.h> 67 #include <visp3/visual_features/vpFeaturePoint.h> 68 69 #include <iostream> 70 #include <vector> 71 72 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 73 #include <tuple> 74 75 #ifndef DOXYGEN_SHOULD_SKIP_THIS 76 //################################################# 77 //## Call a function with a tuple as parameters 78 //################################################# 79 template <unsigned int N> struct vpDesiredFeatureBuilderWithTuple { 80 template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args> buildDesiredFeatureWithTuplevpDesiredFeatureBuilderWithTuple81 static void buildDesiredFeatureWithTuple(featureType &feature, RetType (*f)(ArgsF...), const std::tuple<ArgsT...> &t, 82 Args &&... args) 83 { 84 vpDesiredFeatureBuilderWithTuple<N - 1>::buildDesiredFeatureWithTuple(feature, f, t, std::get<N - 1>(t), args...); 85 } 86 }; 87 88 template <> struct vpDesiredFeatureBuilderWithTuple<0> { 89 template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args> 90 static void buildDesiredFeatureWithTuple(featureType & /* feature */, RetType (*f)(ArgsF...), 91 const std::tuple<ArgsT...> & /* t */, Args &&... args) 92 { 93 f(args...); 94 } 95 }; 96 97 template <> struct vpDesiredFeatureBuilderWithTuple<1> { 98 template <typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, typename... Args> 99 static void buildDesiredFeatureWithTuple(featureType &feature, RetType (*f)(ArgsF...), const std::tuple<ArgsT...> &t, 100 Args &&... args) 101 { 102 vpDesiredFeatureBuilderWithTuple<0>::buildDesiredFeatureWithTuple(feature, f, t, feature, args...); 103 } 104 }; 105 106 template <typename featureType, typename RetType, typename... Args, typename... ArgsFunc> 107 void buildDesiredFeatureWithTuple(featureType &feature, RetType (*f)(ArgsFunc...), std::tuple<Args...> const &t) 108 { 109 vpDesiredFeatureBuilderWithTuple<sizeof...(Args)>::buildDesiredFeatureWithTuple(feature, f, t); 110 } 111 112 //################################################# 113 //## Call a function with a tuple as parameters 114 //## Object Mode 115 //################################################# 116 117 template <unsigned int N> struct vpDesiredFeatureBuilderObjectWithTuple { 118 template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, 119 typename... Args> 120 static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType (objType::*f)(ArgsF...), 121 const std::tuple<ArgsT...> &t, Args &&... args) 122 { 123 vpDesiredFeatureBuilderObjectWithTuple<N - 1>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t, 124 std::get<N - 1>(t), args...); 125 } 126 }; 127 128 template <> struct vpDesiredFeatureBuilderObjectWithTuple<0> { 129 template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, 130 typename... Args> 131 static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType & /*feature*/, 132 RetType (objType::*f)(ArgsF...), const std::tuple<ArgsT...> & /* t */, 133 Args &&... args) 134 { 135 (obj->*f)(args...); 136 } 137 }; 138 139 template <> struct vpDesiredFeatureBuilderObjectWithTuple<1> { 140 template <typename objType, typename featureType, typename RetType, typename... ArgsF, typename... ArgsT, 141 typename... Args> 142 static void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType (objType::*f)(ArgsF...), 143 const std::tuple<ArgsT...> &t, Args &&... args) 144 { 145 vpDesiredFeatureBuilderObjectWithTuple<0>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t, feature, args...); 146 } 147 }; 148 149 template <typename objType, typename featureType, typename RetType, typename... Args, typename... ArgsFunc> 150 void buildDesiredFeatureObjectWithTuple(objType *obj, featureType &feature, RetType (objType::*f)(ArgsFunc...), 151 std::tuple<Args...> const &t) 152 { 153 vpDesiredFeatureBuilderObjectWithTuple<sizeof...(Args)>::buildDesiredFeatureObjectWithTuple(obj, feature, f, t); 154 } 155 156 //##################################################### 157 //## Call un function with a tuple as parameters 158 //## Track all the parameters with the cMo 159 //## Except the first one (must be de "BasicFeature" 160 //##################################################### 161 162 template <unsigned int N> struct vpCurrentFeatureBuilderWithTuple { 163 template <typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed, 164 typename... ArgsF> 165 static void buildCurrentFeatureWithTuple(featureType &feature, const vpHomogeneousMatrix &cMo, RetType (*f)(ArgsF...), 166 std::tuple<ArgsTuple...> &t, ArgsDecomposed &&... args) 167 { 168 auto proj = std::get<N - 1>(t); 169 proj.track(cMo); 170 vpCurrentFeatureBuilderWithTuple<N - 1>::buildCurrentFeatureWithTuple(feature, cMo, f, t, proj, args...); 171 } 172 }; 173 174 template <> struct vpCurrentFeatureBuilderWithTuple<0> { 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...> &, 179 ArgsDecomposed &&... args) 180 { 181 f(args...); 182 } 183 }; 184 185 template <> struct vpCurrentFeatureBuilderWithTuple<1> { 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 template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed, 211 typename... ArgsF> 212 static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo, 213 RetType (objType::*f)(ArgsF...), std::tuple<ArgsTuple...> &t, 214 ArgsDecomposed &&... args) 215 { 216 auto proj = std::get<N - 1>(t); 217 proj.track(cMo); 218 vpCurrentFeatureBuilderObjectWithTuple<N - 1>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f, t, proj, 219 args...); 220 } 221 }; 222 223 template <> struct vpCurrentFeatureBuilderObjectWithTuple<0> { 224 template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed, 225 typename... ArgsF> 226 static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType & /*feature*/, 227 const vpHomogeneousMatrix & /*cMo*/, RetType (objType::*f)(ArgsF...), 228 std::tuple<ArgsTuple...> &, ArgsDecomposed &&... args) 229 { 230 (obj->*f)(args...); 231 } 232 }; 233 234 template <> struct vpCurrentFeatureBuilderObjectWithTuple<1> { 235 template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsDecomposed, 236 typename... ArgsF> 237 static void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo, 238 RetType (objType::*f)(ArgsF...), std::tuple<ArgsTuple...> &t, 239 ArgsDecomposed &&... args) 240 { 241 vpCurrentFeatureBuilderObjectWithTuple<0>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f, t, feature, 242 args...); 243 } 244 }; 245 246 template <typename objType, typename featureType, typename RetType, typename... ArgsTuple, typename... ArgsFunc> 247 void buildCurrentFeatureObjectWithTuple(objType *obj, featureType &feature, const vpHomogeneousMatrix &cMo, 248 RetType (objType::*f)(ArgsFunc...), std::tuple<ArgsTuple...> &t) 249 { 250 vpCurrentFeatureBuilderObjectWithTuple<sizeof...(ArgsTuple)>::buildCurrentFeatureObjectWithTuple(obj, feature, cMo, f, 251 t); 252 } 253 254 //################################################# 255 //## Call that will be used in our vpPoseFeatures 256 //## to store the specific features. 257 //################################################# 258 /*! 259 \class vpPoseSpecificFeature 260 \ingroup group_vision_pose 261 \brief Class used to define specific features that could be considered in 262 pose estimation from visual features implemented in vpPoseFeatures. 263 */ 264 class VISP_EXPORT vpPoseSpecificFeature 265 { 266 public: 267 vpPoseSpecificFeature() {} 268 virtual ~vpPoseSpecificFeature() {} 269 270 virtual vpColVector error() = 0; 271 virtual vpMatrix currentInteraction() = 0; 272 virtual void createDesired() = 0; 273 virtual void createCurrent(const vpHomogeneousMatrix &cMo) = 0; 274 }; 275 276 //################################################# 277 //## Template for all kind of specific features 278 //################################################# 279 280 /*! 281 \class vpPoseSpecificFeatureTemplate 282 \ingroup group_vision_pose 283 \brief Template class that allows to estimate a pose from all kind of 284 specific features if the compiler support C++ 11. 285 */ 286 template <typename featureType, typename RetType, typename... Args> 287 class vpPoseSpecificFeatureTemplate : public vpPoseSpecificFeature 288 { 289 private: 290 featureType desiredFeature; 291 featureType currentFeature; 292 std::tuple<Args...> *tuple; 293 RetType (*func_ptr)(Args...); 294 295 public: 296 vpPoseSpecificFeatureTemplate(RetType (*f_ptr)(Args...), Args &&... args) 297 { 298 func_ptr = f_ptr; // std::move(f_ptr); 299 tuple = new std::tuple<Args...>(args...); 300 } 301 302 virtual ~vpPoseSpecificFeatureTemplate() { delete tuple; } 303 304 virtual void createDesired() { buildDesiredFeatureWithTuple(desiredFeature, func_ptr, *tuple); } 305 306 virtual vpColVector error() 307 { 308 // std::cout << "Getting S... : " << std::get<0>(*tuple).get_s() << 309 // std::endl; 310 return currentFeature.error(desiredFeature); 311 } 312 313 virtual vpMatrix currentInteraction() { return currentFeature.interaction(); } 314 315 virtual void createCurrent(const vpHomogeneousMatrix &cMo) 316 { 317 buildCurrentFeatureWithTuple(currentFeature, cMo, func_ptr, *tuple); 318 } 319 }; 320 321 //################################################# 322 //## Template for all kind of specific features 323 //## Object Mode 324 //################################################# 325 326 /*! 327 \class vpPoseSpecificFeatureTemplateObject 328 \ingroup group_vision_pose 329 \brief Template class that allows to estimate a pose from all kind of 330 specific features if the compiler support C++ 11. 331 */ 332 template <typename ObjectType, typename featureType, typename RetType, typename... Args> 333 class vpPoseSpecificFeatureTemplateObject : public vpPoseSpecificFeature 334 { 335 private: 336 featureType desiredFeature; 337 featureType currentFeature; 338 std::tuple<Args...> *tuple; 339 RetType (ObjectType::*func_ptr)(Args...); 340 ObjectType *obj; 341 342 public: 343 vpPoseSpecificFeatureTemplateObject(ObjectType *o, RetType (ObjectType::*f_ptr)(Args...), Args &&... args) 344 { 345 func_ptr = f_ptr; // std::move(f_ptr); 346 tuple = new std::tuple<Args...>(args...); 347 obj = o; 348 } 349 350 virtual ~vpPoseSpecificFeatureTemplateObject() { delete tuple; } 351 352 virtual void createDesired() { buildDesiredFeatureObjectWithTuple(obj, desiredFeature, func_ptr, *tuple); } 353 354 virtual vpColVector error() { return currentFeature.error(desiredFeature); } 355 356 virtual vpMatrix currentInteraction() { return currentFeature.interaction(); } 357 358 virtual void createCurrent(const vpHomogeneousMatrix &cMo) 359 { 360 buildCurrentFeatureObjectWithTuple(obj, currentFeature, cMo, func_ptr, *tuple); 361 } 362 }; 363 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS 364 #endif // (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 365 366 /*! 367 \class vpPoseFeatures 368 \brief Tools for pose computation from any feature. 369 \ingroup group_vision_pose 370 371 This class allows to estimate a pose by virtual visual servoing from visual 372 features. The features that are considered are points, segments, lines, 373 ellipses. If the compiler is compatible with C++ 11, it is possible to 374 introduce specific features that are not directly implemented in ViSP. 375 */ 376 class VISP_EXPORT vpPoseFeatures 377 { 378 public: 379 /*! 380 Method that will be used to estimate the pose from visual features. 381 */ 382 typedef enum { 383 VIRTUAL_VS, /*!< Virtual visual servoing approach. */ 384 ROBUST_VIRTUAL_VS /*!< Robust virtual visual servoing approach. */ 385 } vpPoseFeaturesMethodType; 386 387 private: 388 #ifndef DOXYGEN_SHOULD_SKIP_THIS 389 template <typename FeatureType, typename FirstParamType> struct vpDuo { 390 FeatureType *desiredFeature; 391 FirstParamType firstParam; 392 vpDuo() : desiredFeature(NULL), firstParam() {} 393 }; 394 395 template <typename FeatureType, typename FirstParamType, typename SecondParamType> struct vpTrio { 396 FeatureType *desiredFeature; 397 FirstParamType firstParam; 398 SecondParamType secondParam; 399 400 vpTrio() : desiredFeature(NULL), firstParam(), secondParam() {} 401 }; 402 #endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS 403 404 unsigned int maxSize; 405 unsigned int totalSize; 406 unsigned int vvsIterMax; 407 double lambda; 408 409 bool verbose; 410 411 bool computeCovariance; 412 vpMatrix covarianceMatrix; 413 414 // vpFeaturePoint 415 std::vector<vpDuo<vpFeaturePoint, vpPoint> > featurePoint_Point_list; 416 // vpFeaturePoint3D 417 std::vector<vpDuo<vpFeaturePoint3D, vpPoint> > featurePoint3D_Point_list; 418 // vpFeatureVanishingPoint 419 std::vector<vpDuo<vpFeatureVanishingPoint, vpPoint> > featureVanishingPoint_Point_list; 420 std::vector<vpTrio<vpFeatureVanishingPoint, vpLine, vpLine> > featureVanishingPoint_DuoLine_list; 421 // vpFeatureEllipse 422 std::vector<vpDuo<vpFeatureEllipse, vpSphere> > featureEllipse_Sphere_list; 423 std::vector<vpDuo<vpFeatureEllipse, vpCircle> > featureEllipse_Circle_list; 424 // vpFeatureLine 425 std::vector<vpDuo<vpFeatureLine, vpLine> > featureLine_Line_list; 426 std::vector<vpTrio<vpFeatureLine, vpCylinder, int> > featureLine_DuoLineInt_List; 427 // vpFeatureSegment 428 std::vector<vpTrio<vpFeatureSegment, vpPoint, vpPoint> > featureSegment_DuoPoints_list; 429 430 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 431 // Specific features 432 std::vector<vpPoseSpecificFeature *> featureSpecific_list; 433 #endif 434 435 public: 436 vpPoseFeatures(); 437 virtual ~vpPoseFeatures(); 438 439 // ! Features addition 440 void addFeaturePoint(const vpPoint &); 441 442 void addFeaturePoint3D(const vpPoint &); 443 444 void addFeatureVanishingPoint(const vpPoint &); 445 void addFeatureVanishingPoint(const vpLine &, const vpLine &); 446 447 void addFeatureEllipse(const vpCircle &); 448 void addFeatureEllipse(const vpSphere &); 449 450 void addFeatureLine(const vpLine &); 451 void addFeatureLine(const vpCylinder &, const int &line); 452 453 void addFeatureSegment(vpPoint &, vpPoint &); 454 455 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 456 template <typename RetType, typename... ArgsFunc, typename... Args> 457 void addSpecificFeature(RetType (*fct_ptr)(ArgsFunc...), Args &&... args); 458 459 template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args> 460 void addSpecificFeature(ObjType *obj, RetType (ObjType::*fct_ptr)(ArgsFunc...), Args &&... args); 461 #endif 462 463 void clear(); 464 465 // ! Pose computation 466 void computePose(vpHomogeneousMatrix &cMo, const vpPoseFeaturesMethodType &type = VIRTUAL_VS); 467 468 /*! 469 Get the covariance matrix of the pose parameters computed by virtual 470 visual servoing. 471 472 \warning By default, the covariance matrix is not computed. To enable the 473 computation, use setCovarianceComputation(). 474 */ 475 vpMatrix getCovarianceMatrix() const 476 { 477 if (!computeCovariance) 478 vpTRACE("Warning : The covariance matrix has not been computed. See " 479 "setCovarianceComputation() to do it."); 480 481 return covarianceMatrix; 482 } 483 484 /*! 485 Get the gain that is used to compute the pose with the control law \f${\bf 486 v} = -\lambda {\bf L}^+ ({\bf s} - {\bf s}^*)\f$. 487 488 \return Value of \f$\lambda\f$, the gain of the control law. 489 */ 490 double getLambda() { return lambda; } 491 492 /*! 493 Get the maximum number of iterations of the virtual visual servoing (VVS) 494 scheme implemented in computePose(). 495 496 \return Maximum number of iterations used during VVS minimization. 497 */ 498 unsigned int getVVSIterMax() { return vvsIterMax; } 499 500 /*! 501 Enable or disable covariance computation of the pose parameters. 502 503 \param flag : True if the covariance has to be computed, false otherwise. 504 */ 505 void setCovarianceComputation(const bool &flag) { computeCovariance = flag; } 506 507 /*! 508 Set the gain used in the virtual visual servoing scheme : \f${\bf v} = 509 -\lambda {\bf L}^+ ({\bf s} - {\bf s}^*)\f$. 510 511 \param val : Value of the gain \f$\lambda\f$. 512 */ 513 void setLambda(const double &val) { lambda = val; } 514 515 /*! 516 Set the maximum number of iterations used in computePose(). 517 518 \param val : Maximum number of iteration used in the VVS scheme. 519 */ 520 void setVVSIterMax(const unsigned int &val) { vvsIterMax = val; } 521 522 /*! 523 Turn the verbose mode ON / OFF. 524 525 \param mode : new verbose state. True to turn ON, false otherwise. 526 */ 527 void setVerbose(const bool &mode) { verbose = mode; } 528 529 private: 530 void error_and_interaction(vpHomogeneousMatrix &cMo, vpColVector &err, vpMatrix &L); 531 532 void computePoseVVS(vpHomogeneousMatrix &cMo); 533 void computePoseRobustVVS(vpHomogeneousMatrix &cMo); 534 }; 535 536 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 537 /*! 538 Add a specific feature for the pose computation. 539 540 \param fct_ptr : pointer on the function used to create the feature. 541 \param args : List of function parameters; 542 First argument supposed to be derived from vpBasicFeature 543 (redefine interaction() and error() functions), others are supposed to be 544 derived from vpForwardProjection (redefine track() function) 545 546 \warning This function is only available with C++11. It has to be activated 547 with USE_CPP11 option from CMake. 548 549 \code 550 #include <visp3/vision/vpPoseFeatures.h> 551 552 void vp_createPoint(vpFeaturePoint &fp,const vpPoint &p){ 553 vpFeatureBuilder::create(fp,p); 554 } 555 556 void vp_createTwoPoint(vpFeaturePoint &fp,const vpPoint &p, const vpPoint&p2){ 557 vpFeatureBuilder::create(fp,p); 558 vpFeatureBuilder::create(fp,p2); 559 } 560 561 void vp_createLine(vpFeatureLine &fp,const vpLine &l){ 562 vpFeatureBuilder::create(fp,l); 563 } 564 565 int main() 566 { 567 vpPoseFeatures pose; 568 569 vpPoint pts[4]; 570 vpLine line; 571 572 //... Projection of the points and line 573 574 vpFeaturePoint fp; 575 vpFeatureLine fl; 576 void (*ptr)(vpFeaturePoint&, const vpPoint&) = &vpFeatureBuilder::create; 577 578 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 579 pose.addSpecificFeature(ptr, fp, pts[0]); 580 pose.addSpecificFeature(&vp_createPoint, fp, pts[1]); 581 pose.addSpecificFeature(&vp_createTwoPoint, fp, pts[2], pts[3]); 582 pose.addSpecificFeature(&vp_createLine, fl, line); 583 #endif 584 585 //... Pose Computation 586 587 return 0; 588 } 589 \endcode 590 */ 591 template <typename RetType, typename... ArgsFunc, typename... Args> 592 void vpPoseFeatures::addSpecificFeature(RetType (*fct_ptr)(ArgsFunc...), Args &&... args) 593 { 594 typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference; 595 typedef typename std::remove_reference<featureTypeReference>::type featureType; 596 featureSpecific_list.push_back( 597 new vpPoseSpecificFeatureTemplate<featureType, RetType, ArgsFunc...>(fct_ptr, std::forward<ArgsFunc>(args)...)); 598 599 featureSpecific_list.back()->createDesired(); 600 601 totalSize++; 602 if (featureSpecific_list.size() > maxSize) 603 maxSize = static_cast<unsigned int>(featureSpecific_list.size()); 604 } 605 606 /*! 607 Add a specific feature for the pose computation. 608 609 \param obj : object used to call the function defined by fct_ptr. 610 \param fct_ptr : pointer on the function used to create the feature. 611 \param args : List of function parameters; 612 First argument supposed to be derived from vpBasicFeature 613 (redefine interaction() and error() functions), others are supposed to be 614 derived from vpForwardProjection (redefine track() function) 615 616 \warning This function is only available with C++11. It has to be activated 617 with USE_CPP11 option from CMake. 618 619 \code 620 #include <visp3/vision/vpPoseFeatures.h> 621 622 class vp_createClass{ 623 public: 624 vp_createClass(){} 625 626 int vp_createPoint(vpFeaturePoint &fp,const vpPoint &p) { 627 vpFeatureBuilder::create(fp,p); 628 return 2; 629 } 630 631 void vp_createTwoPoint(vpFeaturePoint &fp,const vpPoint &p, const vpPoint &p2) { 632 vpFeatureBuilder::create(fp,p); vpFeatureBuilder::create(fp,p2); 633 } 634 635 void vp_createLine(vpFeatureLine &fp,const vpLine &l) { 636 vpFeatureBuilder::create(fp,l); 637 } 638 }; 639 640 int main() 641 { 642 vpPoseFeatures pose; 643 644 vpPoint pts[3]; 645 vpLine line; 646 647 //... Projection of the points and line 648 649 vpFeaturePoint fp; 650 vpFeatureLine fl; 651 652 vp_createClass cpClass; 653 int (vp_createClass::*ptrClassPoint)(vpFeaturePoint&, const vpPoint&) 654 = &vp_createClass::vp_createPoint; 655 void (vp_createClass::*ptrClassTwoPoint)(vpFeaturePoint&, const vpPoint&, const vpPoint&) 656 = &vp_createClass::vp_createTwoPoint; 657 void (vp_createClass::*ptrClassLine)(vpFeatureLine &, const vpLine &) 658 = &vp_createClass::vp_createLine; 659 660 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 661 pose.addSpecificFeature(&cpClass, ptrClassPoint, fp, pts[0]); 662 pose.addSpecificFeature(&cpClass, ptrClassTwoPoint, fp, pts[1], pts[2]); 663 pose.addSpecificFeature(&cpClass, ptrClassLine, fl, line); 664 #endif 665 666 //... Pose Computation 667 668 return 0; 669 } 670 \endcode 671 */ 672 template <typename ObjType, typename RetType, typename... ArgsFunc, typename... Args> 673 void vpPoseFeatures::addSpecificFeature(ObjType *obj, RetType (ObjType::*fct_ptr)(ArgsFunc...), Args &&... args) 674 { 675 typedef typename std::tuple_element<0, std::tuple<Args...> >::type featureTypeReference; 676 typedef typename std::remove_reference<featureTypeReference>::type featureType; 677 featureSpecific_list.push_back(new vpPoseSpecificFeatureTemplateObject<ObjType, featureType, RetType, ArgsFunc...>( 678 obj, fct_ptr, std::forward<ArgsFunc>(args)...)); 679 680 featureSpecific_list.back()->createDesired(); 681 682 totalSize++; 683 if (featureSpecific_list.size() > maxSize) 684 maxSize = static_cast<unsigned int>(featureSpecific_list.size()); 685 } 686 #endif 687 688 #endif //#ifdef VISP_HAVE_MODULE_VISUAL_FEATURES 689 690 #endif 691