Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMatrix_covariance.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 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 * Covariance matrix computation.
32 */
33
34#include <cmath> // std::fabs()
35#include <limits> // numeric_limits
36
37#include <visp3/core/vpColVector.h>
38#include <visp3/core/vpConfig.h>
39#include <visp3/core/vpHomogeneousMatrix.h>
40#include <visp3/core/vpMatrix.h>
41#include <visp3/core/vpMatrixException.h>
42#include <visp3/core/vpTranslationVector.h>
43
56{
57 double denom = (static_cast<double>(A.getRows())); // To consider MLE Estimate for sigma
58
59 if (denom <= std::numeric_limits<double>::epsilon()) {
61 "Impossible to compute covariance matrix: not enough data");
62 }
63
64 double sigma2 = (b - (A * x)).t() * (b - (A * x));
65
66 sigma2 /= denom;
67
68 return (A.t() * A).pseudoInverse(A.getCols() * std::numeric_limits<double>::epsilon()) * sigma2;
69}
70
85 const vpMatrix &W)
86{
87 double denom = 0.0;
88 vpMatrix W2(W.getCols(), W.getCols());
89 unsigned int w_cols = W.getCols();
90 for (unsigned int i = 0; i < w_cols; ++i) {
91 denom += W[i][i];
92 W2[i][i] = W[i][i] * W[i][i];
93 }
94
95 if (denom <= std::numeric_limits<double>::epsilon()) {
97 "Impossible to compute covariance matrix: not enough data");
98 }
99
100 // double sigma2 = ( ((W*b).t())*W*b - ( ((W*b).t())*W*A*x ) ); // Should
101 // be equivalent to line bellow.
102 double sigma2 = ((W * b) - (W * A * x)).t() * ((W * b) - (W * A * x));
103 sigma2 /= denom;
104
105 return (A.t() * W2 * A).pseudoInverse(A.getCols() * std::numeric_limits<double>::epsilon()) * sigma2;
106}
107
120 const vpMatrix &Ls)
121{
122 vpMatrix Js;
123 vpColVector deltaP;
124 vpMatrix::computeCovarianceMatrixVVS(cMo, deltaS, Ls, Js, deltaP);
125
126 return vpMatrix::computeCovarianceMatrix(Js, deltaP, deltaS);
127}
128
145 const vpMatrix &Ls, const vpMatrix &W)
146{
147 vpMatrix Js;
148 vpColVector deltaP;
149 vpMatrix::computeCovarianceMatrixVVS(cMo, deltaS, Ls, Js, deltaP);
150
151 return vpMatrix::computeCovarianceMatrix(Js, deltaP, deltaS, W);
152}
153
154void vpMatrix::computeCovarianceMatrixVVS(const vpHomogeneousMatrix &cMo, const vpColVector &deltaS, const vpMatrix &Ls,
155 vpMatrix &Js, vpColVector &deltaP)
156{
157 // building Lp
158 vpMatrix LpInv(6, 6);
159 LpInv = 0;
160 const unsigned int index_0 = 0;
161 const unsigned int index_1 = 1;
162 const unsigned int index_2 = 2;
163 LpInv[index_0][index_0] = -1.0;
164 LpInv[index_1][index_1] = -1.0;
165 LpInv[index_2][index_2] = -1.0;
166
167 vpTranslationVector ctoInit;
168
169 cMo.extract(ctoInit);
170 vpMatrix ctoInitSkew = ctoInit.skew();
171
172 vpThetaUVector thetau;
173 cMo.extract(thetau);
174
175 vpColVector tu(3);
176 const unsigned int val_3 = 3;
177 for (unsigned int i = 0; i < val_3; ++i) {
178 tu[i] = thetau[i];
179 }
180
181 double theta = sqrt(tu.sumSquare());
182
183 // --comment: declare variable Lthetau of three by three of type vpMatrix
184 vpMatrix LthetauInvAnalytic(3, 3);
185 vpMatrix I3(3, 3);
186 I3.eye();
187 // --comment: Lthetau equals -I3;
188 LthetauInvAnalytic = -I3;
189
190 if ((theta / (2.0 * M_PI)) > std::numeric_limits<double>::epsilon()) {
191 // Computing [theta/2 u]_x
192 vpColVector theta2u(3);
193 for (unsigned int i = 0; i < val_3; ++i) {
194 theta2u[i] = tu[i] / 2.0;
195 }
196 vpMatrix theta2u_skew = vpColVector::skew(theta2u);
197
198 vpColVector u(3);
199 for (unsigned int i = 0; i < val_3; ++i) {
200 u[i] = tu[i] / theta;
201 }
202 vpMatrix u_skew = vpColVector::skew(u);
203
204 LthetauInvAnalytic +=
205 -((vpMath::sqr(vpMath::sinc(theta / 2.0)) * theta2u_skew) - ((1.0 - vpMath::sinc(theta)) * u_skew * u_skew));
206 }
207
208 // --comment: vpMatrix LthetauInv equals Lthetau dot inverseByLU()
209
210 ctoInitSkew = ctoInitSkew * LthetauInvAnalytic;
211
212 const unsigned int index_3 = 3;
213 for (unsigned int a = 0; a < val_3; ++a) {
214 for (unsigned int b = 0; b < val_3; ++b) {
215 LpInv[a][b + index_3] = ctoInitSkew[a][b];
216 }
217 }
218
219 for (unsigned int a = 0; a < val_3; ++a) {
220 for (unsigned int b = 0; b < val_3; ++b) {
221 LpInv[a + index_3][b + index_3] = LthetauInvAnalytic[a][b];
222 }
223 }
224
225 // Building Js
226 Js = Ls * LpInv;
227
228 // building deltaP
229 deltaP = Js.pseudoInverse(Js.getRows() * std::numeric_limits<double>::epsilon()) * deltaS;
230}
231END_VISP_NAMESPACE
unsigned int getCols() const
Definition vpArray2D.h:423
unsigned int getRows() const
Definition vpArray2D.h:433
Implementation of column vector and the associated operations.
static vpMatrix skew(const vpColVector &v)
@ divideByZeroError
Division by zero.
Definition vpException.h:70
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double sinc(double x)
Definition vpMath.cpp:289
static double sqr(double x)
Definition vpMath.h:203
error that can be emitted by the vpMatrix class and its derivatives
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static vpMatrix computeCovarianceMatrixVVS(const vpHomogeneousMatrix &cMo, const vpColVector &deltaS, const vpMatrix &Ls, const vpMatrix &W)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
vpMatrix t() const
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.