Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpParticleFilter.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 * Display a point cloud using PCL library.
32 */
33
34#ifndef VP_PARTICLE_FILTER_H
35#define VP_PARTICLE_FILTER_H
36
37#include <visp3/core/vpConfig.h>
38
39#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
40#include <visp3/core/vpColVector.h>
41#include <visp3/core/vpGaussRand.h>
42#include <visp3/core/vpMatrix.h>
43
44#include <functional> // std::function
45
46#ifdef VISP_HAVE_OPENMP
47#include <omp.h>
48#endif
49
50#if defined(__clang__)
51// Mute warning : '\tparam' command used in a comment that is not attached to a template declaration [-Wdocumentation]
52# pragma clang diagnostic push
53# pragma clang diagnostic ignored "-Wexit-time-destructors"
54#endif
55
109template <typename MeasurementsType>
111{
112public:
118 {
119 std::vector<vpColVector> m_particles;
120 std::vector<double> m_weights;
122
129 typedef std::function<vpColVector(const vpColVector &, const vpColVector &)> vpStateAddFunction;
130
136 typedef std::function<vpColVector(const vpColVector &, const double &)> vpProcessFunction;
137
144 typedef std::function<vpColVector(const vpColVector &, const vpColVector &, const double &)> vpCommandStateFunction;
145
153 typedef std::function<double(const vpColVector &, const MeasurementsType &)> vpLikelihoodFunction;
154
162 typedef std::function<vpColVector(const std::vector<vpColVector> &, const std::vector<double> &, const vpStateAddFunction &)> vpFilterFunction;
163
169 typedef std::function<bool(const unsigned int &, const std::vector<double> &)> vpResamplingConditionFunction;
170
175 typedef std::function<vpParticlesWithWeights(const std::vector<vpColVector> &, const std::vector<double> &)> vpResamplingFunction;
176
187 VP_EXPLICIT vpParticleFilter(const unsigned int &N, const std::vector<double> &stdev, const long &seed = -1, const int &nbThreads = -1);
188
189 inline virtual ~vpParticleFilter() { }
190
207 void init(const vpColVector &x0, const vpProcessFunction &f,
208 const vpLikelihoodFunction &l,
209 const vpResamplingConditionFunction &checkResamplingFunc, const vpResamplingFunction &resamplingFunc,
210 const vpFilterFunction &filterFunc = weightedMean,
211 const vpStateAddFunction &addFunc = simpleAdd);
212
229 void init(const vpColVector &x0, const vpCommandStateFunction &bx,
230 const vpLikelihoodFunction &l,
231 const vpResamplingConditionFunction &checkResamplingFunc, const vpResamplingFunction &resamplingFunc,
232 const vpFilterFunction &filterFunc = weightedMean,
233 const vpStateAddFunction &addFunc = simpleAdd);
234
247 void filter(const MeasurementsType &z, const double &dt, const vpColVector &u = vpColVector());
248
259 void predict(const double &dt, const vpColVector &u = vpColVector());
260
267 void update(const MeasurementsType &z);
268
275
284 {
285 m_f = f;
286 m_useCommandStateFunction = false;
287 m_useProcessFunction = true;
288 }
289
298 {
299 m_bx = bx;
300 m_useCommandStateFunction = true;
301 m_useProcessFunction = false;
302 }
303
310 inline void setLikelihoodFunction(const vpLikelihoodFunction &likelihood)
311 {
312 m_likelihood = likelihood;
313 }
314
321 inline void setFilterFunction(const vpFilterFunction &filterFunc)
322 {
323 m_stateFilterFunc = filterFunc;
324 }
325
332 inline void setCheckResamplingFunction(const vpResamplingConditionFunction &resamplingCondFunc)
333 {
334 m_checkIfResample = resamplingCondFunc;
335 }
336
343 inline void setResamplingFunction(const vpResamplingFunction &resamplingFunc)
344 {
345 m_resampling = resamplingFunc;
346 }
347
355 inline static vpColVector simpleAdd(const vpColVector &a, const vpColVector &toAdd)
356 {
357 vpColVector res = a + toAdd;
358 return res;
359 }
360
370 static vpColVector weightedMean(const std::vector<vpColVector> &particles, const std::vector<double> &weights, const vpStateAddFunction &addFunc);
371
381 static bool simpleResamplingCheck(const unsigned int &N, const std::vector<double> &weights);
382
391 static vpParticlesWithWeights simpleImportanceResampling(const std::vector<vpColVector> &particles, const std::vector<double> &weights);
392
393private:
394 void initParticles(const vpColVector &x0);
395#ifdef VISP_HAVE_OPENMP
396 void predictMultithread(const double &dt, const vpColVector &u);
397 void updateMultithread(const MeasurementsType &z);
398#endif
399
400 void predictMonothread(const double &dt, const vpColVector &u);
401 void updateMonothread(const MeasurementsType &z);
402
403 static vpUniRand sampler;
404 static vpUniRand samplerRandomIdx;
405
406 unsigned int m_N;
407 unsigned int m_nbMaxThreads;
408 std::vector<std::vector<vpGaussRand>> m_noiseGenerators;
409 std::vector<vpColVector> m_particles;
410 std::vector<double> m_w;
411
412 vpColVector m_Xest;
413
415 vpLikelihoodFunction m_likelihood;
417 vpFilterFunction m_stateFilterFunc;
418 vpResamplingConditionFunction m_checkIfResample;
419 vpResamplingFunction m_resampling;
420 vpStateAddFunction m_stateAdd;
421
422 bool m_useProcessFunction;
423 bool m_useCommandStateFunction;
424};
425
426template <typename MeasurementsType>
427vpUniRand vpParticleFilter<MeasurementsType>::sampler;
428
429template <typename MeasurementsType>
430vpUniRand vpParticleFilter<MeasurementsType>::samplerRandomIdx;
431
432template <typename MeasurementsType>
433vpParticleFilter<MeasurementsType>::vpParticleFilter(const unsigned int &N, const std::vector<double> &stdev, const long &seed, const int &nbThreads)
434 : m_N(N)
435 , m_particles(N)
436 , m_w(N, 1./static_cast<double>(N))
437 , m_useProcessFunction(false)
438 , m_useCommandStateFunction(false)
439{
440#ifndef VISP_HAVE_OPENMP
441 m_nbMaxThreads = 1;
442 if (nbThreads > 1) {
443 std::cout << "[vpParticleFilter::vpParticleFilter] WARNING: OpenMP is not available, maximum number of threads to use clamped to 1" << std::endl;
444 }
445#else
446 int maxThreads = omp_get_max_threads();
447 if (nbThreads <= 0) {
448 m_nbMaxThreads = maxThreads;
449 }
450 else if (nbThreads > maxThreads) {
451 m_nbMaxThreads = maxThreads;
452 std::cout << "[vpParticleFilter::vpParticleFilter] WARNING: maximum number of threads to use clamped to "
453 << maxThreads << " instead of " << nbThreads << " due to OpenMP restrictions." << std::endl;
454 std::cout << "[vpParticleFilter::vpParticleFilter] If you want more, consider to use omp_set_num_threads before." << std::endl;
455 }
456 else {
457 m_nbMaxThreads = nbThreads;
458 }
459#endif
460 // Generating the random generators
461 unsigned int sizeState = static_cast<unsigned int>(stdev.size());
462 m_noiseGenerators.resize(m_nbMaxThreads);
463 unsigned long long seedForGenerator;
464 if (seed > 0) {
465 seedForGenerator = seed;
466 }
467 else {
468 seedForGenerator = static_cast<unsigned long long>(vpTime::measureTimeMicros());
469 }
470
471 // Sampler for the simpleImportanceResampling method
472 sampler.setSeed(seed, 0x123465789ULL);
473 samplerRandomIdx.setSeed(seed + 4224, 0x123465789ULL);
474
475 vpUniRand seedGenerator(seedForGenerator);
476 for (unsigned int threadId = 0; threadId < m_nbMaxThreads; ++threadId) {
477 for (unsigned int stateId = 0; stateId < sizeState; ++stateId) {
478 m_noiseGenerators[threadId].push_back(vpGaussRand(stdev[stateId], 0., static_cast<long>(seedGenerator.uniform(0., 1e9))));
479 }
480 }
481}
482
483template <typename MeasurementsType>
485 const vpLikelihoodFunction &l,
486 const vpResamplingConditionFunction &checkResamplingFunc, const vpResamplingFunction &resamplingFunc,
487 const vpFilterFunction &filterFunc, const vpStateAddFunction &addFunc)
488{
489 if (x0.size() != m_noiseGenerators[0].size()) {
490 throw(vpException(vpException::dimensionError, "X0 does not have the same size than the vector of stdevs used to build the object"));
491 }
492 m_f = f;
493 m_stateFilterFunc = filterFunc;
494 m_likelihood = l;
495 m_checkIfResample = checkResamplingFunc;
496 m_resampling = resamplingFunc;
497 m_stateAdd = addFunc;
498 m_useProcessFunction = true;
499 m_useCommandStateFunction = false;
500
501 // Initialize the different particles
502 initParticles(x0);
503}
504
505template <typename MeasurementsType>
507 const vpLikelihoodFunction &l,
508 const vpResamplingConditionFunction &checkResamplingFunc, const vpResamplingFunction &resamplingFunc,
509 const vpFilterFunction &filterFunc, const vpStateAddFunction &addFunc)
510{
511 if (x0.size() != m_noiseGenerators[0].size()) {
512 throw(vpException(vpException::dimensionError, "X0 does not have the same size than the vector of stdevs used to build the object"));
513 }
514 m_bx = bx;
515 m_stateFilterFunc = filterFunc;
516 m_likelihood = l;
517 m_checkIfResample = checkResamplingFunc;
518 m_resampling = resamplingFunc;
519 m_stateAdd = addFunc;
520 m_useProcessFunction = false;
521 m_useCommandStateFunction = true;
522
523 // Initialize the different particles
524 initParticles(x0);
525}
526
527template <typename MeasurementsType>
528void vpParticleFilter<MeasurementsType>::filter(const MeasurementsType &z, const double &dt, const vpColVector &u)
529{
530 predict(dt, u);
531 update(z);
532}
533
534template <typename MeasurementsType>
536{
537 if (m_nbMaxThreads == 1) {
538 predictMonothread(dt, u);
539 }
540#ifdef VISP_HAVE_OPENMP
541 else {
542 predictMultithread(dt, u);
543 }
544#endif
545}
546
547template <typename MeasurementsType>
548void vpParticleFilter<MeasurementsType>::update(const MeasurementsType &z)
549{
550 if (m_nbMaxThreads == 1) {
551 updateMonothread(z);
552 }
553#ifdef VISP_HAVE_OPENMP
554 else {
555 updateMultithread(z);
556 }
557#endif
558 bool shouldResample = m_checkIfResample(m_N, m_w);
559 if (shouldResample) {
560 vpParticlesWithWeights particles_weights = m_resampling(m_particles, m_w);
561 m_particles = std::move(particles_weights.m_particles);
562 m_w = std::move(particles_weights.m_weights);
563 }
564}
565
566template <typename MeasurementsType>
568{
569 return m_stateFilterFunc(m_particles, m_w, m_stateAdd);
570}
571
572template <typename MeasurementsType>
573vpColVector vpParticleFilter<MeasurementsType>::weightedMean(const std::vector<vpColVector> &particles, const std::vector<double> &weights, const vpStateAddFunction &addFunc)
574{
575 size_t nbParticles = particles.size();
576 if (nbParticles == 0) {
577 throw(vpException(vpException::dimensionError, "No particles to add when computing the mean"));
578 }
579 vpColVector res = particles[0] * weights[0];
580 for (size_t i = 1; i < nbParticles; ++i) {
581 res = addFunc(res, particles[i] * weights[i]);
582 }
583 return res;
584}
585
586template <typename MeasurementsType>
587bool vpParticleFilter<MeasurementsType>::simpleResamplingCheck(const unsigned int &N, const std::vector<double> &weights)
588{
589 double sumSquare = 0.;
590 for (unsigned int i = 0; i < N; ++i) {
591 sumSquare += weights[i] * weights[i];
592 }
593 if (sumSquare < std::numeric_limits<double>::epsilon()) {
594 // All the particles diverged
595 return true;
596 }
597 double N_eff = 1.0 / sumSquare;
598 return (N_eff < (N / 2.0));
599}
600
601template <typename MeasurementsType>
602typename vpParticleFilter<MeasurementsType>::vpParticlesWithWeights vpParticleFilter<MeasurementsType>::simpleImportanceResampling(const std::vector<vpColVector> &particles, const std::vector<double> &weights)
603{
604 unsigned int nbParticles = static_cast<unsigned int>(particles.size());
605 double x = 0.;
606 double sumWeights = 0.;
607 std::vector<int> idx(nbParticles);
608
609 // Draw indices of the randomly chosen particles from the vector of particles
610 for (unsigned int i = 0; i < nbParticles; ++i) {
611 x = sampler();
612 sumWeights = 0.0;
613 int index = samplerRandomIdx.uniform(0, nbParticles); // In case all the weights are null
614 for (unsigned int j = 0; j < nbParticles; ++j) {
615 if (x < sumWeights + weights[j]) {
616 index = j;
617 break;
618 }
619 sumWeights += weights[j];
620 }
621 idx[i] = index;
622 }
623
624 // Draw the randomly chosen particles corresponding to the indices
625 vpParticlesWithWeights newParticlesWeights;
626 newParticlesWeights.m_particles.resize(nbParticles);
627 for (unsigned int i = 0; i < nbParticles; ++i) {
628 newParticlesWeights.m_particles[i] = particles[idx[i]];
629 }
630
631 // Reinitialize the weights
632 newParticlesWeights.m_weights.resize(nbParticles, 1.0/ static_cast<double>(nbParticles));
633 return newParticlesWeights;
634}
635
636template <typename MeasurementsType>
637void vpParticleFilter<MeasurementsType>::initParticles(const vpColVector &x0)
638{
639 unsigned int sizeState = x0.size();
640 unsigned int chunkSize = m_N / m_nbMaxThreads;
641 double uniformWeight = 1. / static_cast<double>(m_N);
642 for (unsigned int i = 0; i < m_nbMaxThreads; ++i) {
643 unsigned int idStart = chunkSize * i;
644 unsigned int idStop = chunkSize * (i + 1);
645 // Last chunk must go until the end
646 if (i == m_nbMaxThreads - 1) {
647 idStop = m_N;
648 }
649 for (unsigned int id = idStart; id < idStop; ++id) {
650 // Generating noise
651 vpColVector noise(sizeState);
652 for (unsigned int idState = 0; idState < sizeState; ++idState) {
653 noise[idState] = m_noiseGenerators[i][idState]();
654 }
655 // Adding noise to the initial state
656 m_particles[id] = m_stateAdd(x0, noise);
657
658 // (Re)initializing its weight
659 m_w[id] = uniformWeight;
660 }
661 }
662}
663
664#ifdef VISP_HAVE_OPENMP
665template <typename MeasurementsType>
667{
668 int iam, nt, ipoints, istart, npoints(m_N);
669 unsigned int sizeState = m_particles[0].size();
670
671#pragma omp parallel default(shared) private(iam, nt, ipoints, istart) num_threads(m_nbMaxThreads)
672 {
673 iam = omp_get_thread_num();
674 nt = omp_get_num_threads();
675 ipoints = npoints / nt;
676 // size of partition
677 istart = iam * ipoints; // starting array index
678 if (iam == nt-1) {
679 // last thread may do more
680 ipoints = npoints - istart;
681 }
682
683 for (int i = istart; i< istart + ipoints; ++i) {
684 // Updating the particles following the process (or command) function
685 if (m_useCommandStateFunction) {
686 m_particles[i] = m_bx(u, m_particles[i], dt);
687 }
688 else if (m_useProcessFunction) {
689 m_particles[i] = m_f(m_particles[i], dt);
690 }
691
692 // Generating noise to add to the particle
693 vpColVector noise(sizeState);
694 for (unsigned int j = 0; j < sizeState; ++j) {
695 noise[j] = m_noiseGenerators[iam][j]();
696 }
697
698 // Adding the noise to the particle
699 m_particles[i] = m_stateAdd(m_particles[i], noise);
700 }
701 }
702}
703
704template <typename MeasurementsType>
705double threadLikelihood(const typename vpParticleFilter<MeasurementsType>::vpLikelihoodFunction &likelihood, const std::vector<vpColVector> &v_particles,
706 const MeasurementsType &z, std::vector<double> &w, const int &istart, const int &ipoints)
707{
708 double sum(0.0);
709 for (int i = istart; i< istart + ipoints; ++i) {
710 w[i] = w[i] * likelihood(v_particles[i], z);
711 sum += w[i];
712 }
713 return sum;
714}
715
716template <typename MeasurementsType>
717void vpParticleFilter<MeasurementsType>::updateMultithread(const MeasurementsType &z)
718{
719 double sumWeights = 0.0;
720 int iam, nt, ipoints, istart, npoints(m_N);
721 vpColVector tempSums(m_nbMaxThreads, 0.0);
722 // Compute the weights depending on the likelihood of a particle with regard to the measurements
723#pragma omp parallel default(shared) private(iam, nt, ipoints, istart) num_threads(m_nbMaxThreads)
724 {
725 iam = omp_get_thread_num();
726 nt = omp_get_num_threads();
727 ipoints = npoints / nt;
728 // size of partition
729 istart = iam * ipoints; // starting array index
730 if (iam == nt-1) {
731 // last thread may do more
732 ipoints = npoints - istart;
733 }
734 tempSums[iam] = threadLikelihood<MeasurementsType>(m_likelihood, m_particles, z, m_w, istart, ipoints);
735 }
736 sumWeights = tempSums.sum();
737
738 if (sumWeights > std::numeric_limits<double>::epsilon()) {
739#pragma omp parallel default(shared) private(iam, nt, ipoints, istart)
740 {
741 iam = omp_get_thread_num();
742 nt = omp_get_num_threads();
743 ipoints = npoints / nt;
744 // size of partition
745 istart = iam * ipoints; // starting array index
746 if (iam == nt-1) {
747 // last thread may do more
748 ipoints = npoints - istart;
749 }
750
751 // Normalize the weights
752 for (int i = istart; i < istart + ipoints; ++i) {
753 m_w[i] = m_w[i] / sumWeights;
754 }
755 }
756 }
757}
758#endif
759
760template <typename MeasurementsType>
761void vpParticleFilter<MeasurementsType>::predictMonothread(const double &dt, const vpColVector &u)
762{
763 unsigned int sizeState = m_particles[0].size();
764 for (unsigned int i = 0; i < m_N; ++i) {
765 // Updating the particle following the process (or command) function
766 if (m_useCommandStateFunction) {
767 m_particles[i] = m_bx(u, m_particles[i], dt);
768 }
769 else if (m_useProcessFunction) {
770 m_particles[i] = m_f(m_particles[i], dt);
771 }
772 else {
773 throw(vpException(vpException::notInitialized, "vpParticleFilter has not been initialized before calling predict"));
774 }
775
776 // Generating noise to add to the particle
777 vpColVector noise(sizeState);
778 for (unsigned int j = 0; j < sizeState; ++j) {
779 noise[j] = m_noiseGenerators[0][j]();
780 }
781
782 // Adding the noise to the particle
783 m_particles[i] = m_stateAdd(m_particles[i], noise);
784 }
785}
786
787template <typename MeasurementsType>
788void vpParticleFilter<MeasurementsType>::updateMonothread(const MeasurementsType &z)
789{
790 double sumWeights = 0.;
791 // Compute the weights depending on the likelihood of a particle with regard to the measurements
792 for (unsigned int i = 0; i < m_N; ++i) {
793 m_w[i] = m_w[i] * m_likelihood(m_particles[i], z);
794 sumWeights += m_w[i];
795 }
796
797 // Normalize the weights
798 if (sumWeights > std::numeric_limits<double>::epsilon()) {
799 for (unsigned int i = 0; i < m_N; ++i) {
800 m_w[i] = m_w[i] / sumWeights;
801 }
802 }
803}
804END_VISP_NAMESPACE
805
806#if defined(__clang__)
807# pragma clang diagnostic pop
808#endif
809
810#endif
811#endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition vpArray2D.h:435
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition vpException.h:74
@ dimensionError
Bad dimension.
Definition vpException.h:71
Class for generating random number with normal probability density.
The class permits to use a Particle Filter.
std::function< vpParticlesWithWeights(const std::vector< vpColVector > &, const std::vector< double > &)> vpResamplingFunction
Function that takes as argument the vector of particles and the vector of associated weights....
virtual ~vpParticleFilter()
void setResamplingFunction(const vpResamplingFunction &resamplingFunc)
Set the resampling function that generate new particles and associated weights when the filter starts...
void setLikelihoodFunction(const vpLikelihoodFunction &likelihood)
Set the likelihood function that updates the weights of the particles based on the new measurements.
std::function< vpColVector(const std::vector< vpColVector > &, const std::vector< double > &, const vpStateAddFunction &)> vpFilterFunction
Filter function, which computes the filtered state of the particle filter. The first argument is the ...
void filter(const MeasurementsType &z, const double &dt, const vpColVector &u=vpColVector())
Perform first the prediction step and then the update step. If needed, resampling will also be perfor...
static bool simpleResamplingCheck(const unsigned int &N, const std::vector< double > &weights)
Returns true if the following condition is fulfilled, or if all the particles diverged: .
static vpColVector weightedMean(const std::vector< vpColVector > &particles, const std::vector< double > &weights, const vpStateAddFunction &addFunc)
Simple function to compute a weighted mean, which just does .
std::function< vpColVector(const vpColVector &, const double &)> vpProcessFunction
Process model function, which projects a particle forward in time. The first argument is a particle,...
struct vpParticleFilter::vpParticlesWithWeights vpParticlesWithWeights
Structure of vectors for which the i^th element of the weights vector is associated to the i^th eleme...
void init(const vpColVector &x0, const vpProcessFunction &f, const vpLikelihoodFunction &l, const vpResamplingConditionFunction &checkResamplingFunc, const vpResamplingFunction &resamplingFunc, const vpFilterFunction &filterFunc=weightedMean, const vpStateAddFunction &addFunc=simpleAdd)
Set the guess of the initial state.
std::function< vpColVector(const vpColVector &, const vpColVector &, const double &)> vpCommandStateFunction
Command model function, which projects a particle forward in time according to the command and its pr...
static vpParticlesWithWeights simpleImportanceResampling(const std::vector< vpColVector > &particles, const std::vector< double > &weights)
Function implementing the resampling of a Simple Importance Resampling Particle Filter.
std::function< bool(const unsigned int &, const std::vector< double > &)> vpResamplingConditionFunction
Function that takes as argument the number of particles and the vector of weights associated to each ...
static vpColVector simpleAdd(const vpColVector &a, const vpColVector &toAdd)
Simple function to compute an addition, which just does .
void setCheckResamplingFunction(const vpResamplingConditionFunction &resamplingCondFunc)
Set the function that returns true when the filter starts to degenerate and false otherwise.
void setFilterFunction(const vpFilterFunction &filterFunc)
Set the filter function that compute the filtered state from the particles and their associated weigh...
VP_EXPLICIT vpParticleFilter(const unsigned int &N, const std::vector< double > &stdev, const long &seed=-1, const int &nbThreads=-1)
Construct a new vpParticleFilter object.
std::function< double(const vpColVector &, const MeasurementsType &)> vpLikelihoodFunction
Likelihood function, which evaluates the likelihood of a particle with regard to the measurements....
void predict(const double &dt, const vpColVector &u=vpColVector())
Predict the new state based on the last state and how far in time we want to predict.
void setCommandStateFunction(const vpCommandStateFunction &bx)
Set the command function to use when projecting the particles in the future.
void setProcessFunction(const vpProcessFunction &f)
Set the process function to use when projecting the particles in the future.
void update(const MeasurementsType &z)
Update the weights of the particles based on a new measurement. The weights will be normalized (i....
std::function< vpColVector(const vpColVector &, const vpColVector &)> vpStateAddFunction
Function that computes either the equivalent of an addition in the state space. The first argument is...
vpColVector computeFilteredState()
Compute the filtered state from the particles and their associated weights.
Class for generating random numbers with uniform probability density.
Definition vpUniRand.h:127
int uniform(int a, int b)
VISP_EXPORT double measureTimeMicros()
Structure of vectors for which the i^th element of the weights vector is associated to the i^th eleme...