Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
Loading...
Searching...
No Matches
vpThetaUVector.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
* Theta U parameterization for the rotation.
32
*/
33
38
39
#include <cmath>
// std::fabs
40
#include <limits>
// numeric_limits
41
42
#include <visp3/core/vpThetaUVector.h>
43
44
BEGIN_VISP_NAMESPACE
45
46
const
double
vpThetaUVector::minimum = 0.0001;
47
const
unsigned
int
vpThetaUVector::constr_val_3 = 3;
48
50
vpThetaUVector::vpThetaUVector
() :
vpRotationVector
(constr_val_3) { }
52
vpThetaUVector::vpThetaUVector
(
const
vpColVector
&tu) :
vpRotationVector
(constr_val_3) {
buildFrom
(tu); }
56
vpThetaUVector::vpThetaUVector
(
const
vpHomogeneousMatrix
&M) :
vpRotationVector
(constr_val_3) {
buildFrom
(M); }
60
vpThetaUVector::vpThetaUVector
(
const
vpPoseVector
&p) :
vpRotationVector
(constr_val_3) {
buildFrom
(p); }
64
vpThetaUVector::vpThetaUVector
(
const
vpRotationMatrix
&R) :
vpRotationVector
(constr_val_3) {
buildFrom
(R); }
65
69
vpThetaUVector::vpThetaUVector
(
const
vpRzyxVector
&rzyx) :
vpRotationVector
(constr_val_3) {
buildFrom
(rzyx); }
73
vpThetaUVector::vpThetaUVector
(
const
vpRzyzVector
&rzyz) :
vpRotationVector
(constr_val_3) {
buildFrom
(rzyz); }
77
vpThetaUVector::vpThetaUVector
(
const
vpRxyzVector
&rxyz) :
vpRotationVector
(constr_val_3) {
buildFrom
(rxyz); }
81
vpThetaUVector::vpThetaUVector
(
const
vpQuaternionVector
&q) :
vpRotationVector
(constr_val_3) {
buildFrom
(q); }
82
103
vpThetaUVector::vpThetaUVector
(
double
tux,
double
tuy,
double
tuz) :
vpRotationVector
(constr_val_3) {
buildFrom
(tux, tuy, tuz); }
104
108
vpThetaUVector::vpThetaUVector
(
const
std::vector<double> &tu) :
vpRotationVector
(constr_val_3) {
buildFrom
(tu); }
109
113
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpHomogeneousMatrix
&M)
114
{
115
vpRotationMatrix
R;
116
117
M.
extract
(R);
118
buildFrom
(R);
119
120
return
*
this
;
121
}
122
126
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpPoseVector
&p)
127
{
128
const
unsigned
int
val_3 = 3;
129
const
unsigned
int
index_3 = 3;
130
for
(
unsigned
int
i = 0; i < val_3; ++i) {
131
data
[i] = p[i + index_3];
132
}
133
134
return
*
this
;
135
}
136
140
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpRotationMatrix
&R)
141
{
142
double
s, c, theta;
143
const
unsigned
int
index_0 = 0;
144
const
unsigned
int
index_1 = 1;
145
const
unsigned
int
index_2 = 2;
146
147
s = ((R[1][0] - R[0][1]) * (R[1][0] - R[0][1])) + ((R[index_2][0] - R[0][index_2]) * (R[index_2][0] - R[0][index_2])) +
148
((R[index_2][index_1] - R[index_1][index_2]) * (R[index_2][index_1] - R[index_1][index_2]));
149
s = sqrt(s) / 2.0;
150
c = ((R[index_0][index_0] + R[index_1][index_1] + R[index_2][index_2]) - 1.0) / 2.0;
151
theta = atan2(s, c);
/* theta in [0, PI] since s > 0 */
152
153
// General case when theta != pi. If theta=pi, c=-1
154
if
((1 + c) > minimum)
// Since -1 <= c <= 1, no fabs(1+c) is required
155
{
156
double
sinc =
vpMath::sinc
(s, theta);
157
158
data
[index_0] = (R[index_2][index_1] - R[index_1][index_2]) / (2.0 * sinc);
159
data
[index_1] = (R[index_0][index_2] - R[index_2][index_0]) / (2.0 * sinc);
160
data
[index_2] = (R[index_1][index_0] - R[index_0][index_1]) / (2.0 * sinc);
161
}
162
else
/* theta near PI */
163
{
164
double
x = 0;
165
if
((R[0][0] - c) > std::numeric_limits<double>::epsilon()) {
166
x = sqrt((R[0][0] - c) / (1 - c));
167
}
168
169
double
y = 0;
170
if
((R[1][1] - c) > std::numeric_limits<double>::epsilon()) {
171
y = sqrt((R[1][1] - c) / (1 - c));
172
}
173
174
double
z = 0;
175
if
((R[index_2][index_2] - c) > std::numeric_limits<double>::epsilon()) {
176
z = sqrt((R[index_2][index_2] - c) / (1 - c));
177
}
178
179
if
((x > y) && (x > z)) {
180
if
((R[index_2][index_1] - R[index_1][index_2]) < 0) {
181
x = -x;
182
}
183
if
((
vpMath::sign
(x) *
vpMath::sign
(y)) != (
vpMath::sign
(R[0][1] + R[1][0]))) {
184
y = -y;
185
}
186
if
((
vpMath::sign
(x) *
vpMath::sign
(z)) != (
vpMath::sign
(R[index_0][index_2] + R[index_2][index_0]))) {
187
z = -z;
188
}
189
}
190
else
if
(y > z) {
191
if
((R[index_0][index_2] - R[index_2][index_0]) < 0) {
192
y = -y;
193
}
194
if
((
vpMath::sign
(y) *
vpMath::sign
(x)) != (
vpMath::sign
(R[index_1][index_0] + R[index_0][index_1]))) {
195
x = -x;
196
}
197
if
((
vpMath::sign
(y) *
vpMath::sign
(z)) != (
vpMath::sign
(R[index_1][index_2] + R[index_2][index_1]))) {
198
z = -z;
199
}
200
}
201
else
{
202
if
((R[1][0] - R[0][1]) < 0) {
203
z = -z;
204
}
205
if
((
vpMath::sign
(z) *
vpMath::sign
(x)) != (
vpMath::sign
(R[index_2][index_0] + R[index_0][index_2]))) {
206
x = -x;
207
}
208
if
((
vpMath::sign
(z) *
vpMath::sign
(y)) != (
vpMath::sign
(R[index_2][index_1] + R[index_1][index_2]))) {
209
y = -y;
210
}
211
}
212
data
[index_0] = theta * x;
213
data
[index_1] = theta * y;
214
data
[index_2] = theta * z;
215
}
216
217
return
*
this
;
218
}
219
222
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpRzyxVector
&rzyx)
223
{
224
vpRotationMatrix
R(rzyx);
225
226
buildFrom
(R);
227
return
*
this
;
228
}
229
232
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpRzyzVector
&rzyz)
233
{
234
vpRotationMatrix
R(rzyz);
235
236
buildFrom
(R);
237
return
*
this
;
238
}
239
242
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpRxyzVector
&rxyz)
243
{
244
vpRotationMatrix
R(rxyz);
245
246
buildFrom
(R);
247
return
*
this
;
248
}
249
253
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpQuaternionVector
&q)
254
{
255
vpRotationMatrix
R(q);
256
257
buildFrom
(R);
258
return
*
this
;
259
}
260
264
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
std::vector<double> &tu)
265
{
266
const
unsigned
int
val_3 = 3;
267
if
(tu.size() != val_3) {
268
throw
(
vpException
(
vpException::dimensionError
,
"Cannot construct a theta-u vector from a %d-dimension std::vector"
,
269
tu.size()));
270
}
271
for
(
unsigned
int
i = 0; i < val_3; ++i) {
272
data
[i] = tu[i];
273
}
274
275
return
*
this
;
276
}
277
281
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
vpColVector
&tu)
282
{
283
const
unsigned
int
val_3 = 3;
284
if
(tu.size() != val_3) {
285
throw
(
vpException
(
vpException::dimensionError
,
"Cannot construct a theta-u vector from a %d-dimension std::vector"
,
286
tu.size()));
287
}
288
for
(
unsigned
int
i = 0; i < val_3; ++i) {
289
data
[i] = tu[i];
290
}
291
292
return
*
this
;
293
}
294
298
vpThetaUVector
&
vpThetaUVector::buildFrom
(
const
double
&tux,
const
double
&tuy,
const
double
&tuz)
299
{
300
const
unsigned
int
index_0 = 0;
301
const
unsigned
int
index_1 = 1;
302
const
unsigned
int
index_2 = 2;
303
data
[index_0] = tux;
304
data
[index_1] = tuy;
305
data
[index_2] = tuz;
306
return
*
this
;
307
}
308
333
vpThetaUVector
&
vpThetaUVector::operator=
(
double
v)
334
{
335
for
(
unsigned
int
i = 0; i <
dsize
; ++i) {
336
data
[i] = v;
337
}
338
339
return
*
this
;
340
}
341
368
vpThetaUVector
&
vpThetaUVector::operator=
(
const
vpColVector
&tu)
369
{
370
if
(tu.size() !=
size
()) {
371
throw
(
vpException
(
vpException::dimensionError
,
"Cannot set a theta-u vector from a %d-dimension col vector"
,
372
tu.size()));
373
}
374
375
unsigned
int
l_size =
size
();
376
for
(
unsigned
int
i = 0; i < l_size; ++i) {
377
data
[i] = tu[i];
378
}
379
380
return
*
this
;
381
}
382
415
void
vpThetaUVector::extract
(
double
&theta,
vpColVector
&u)
const
416
{
417
const
unsigned
int
val_3 = 3;
418
u.resize(val_3);
419
420
theta =
getTheta
();
421
// --comment: if theta equals 0
422
if
(std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
423
u = 0;
424
return
;
425
}
426
for
(
unsigned
int
i = 0; i < val_3; ++i) {
427
u[i] =
data
[i] / theta;
428
}
429
}
430
457
double
vpThetaUVector::getTheta
()
const
458
{
459
const
unsigned
int
index_0 = 0;
460
const
unsigned
int
index_1 = 1;
461
const
unsigned
int
index_2 = 2;
462
return
sqrt((
data
[index_0] *
data
[index_0]) + (
data
[index_1] *
data
[index_1]) + (
data
[index_2] *
data
[index_2]));
463
}
464
492
vpColVector
vpThetaUVector::getU
()
const
493
{
494
vpColVector
u(3);
495
496
double
theta =
getTheta
();
497
// --comment: if theta equals 0
498
if
(std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
499
u = 0;
500
return
u;
501
}
502
const
unsigned
int
val_3 = 3;
503
for
(
unsigned
int
i = 0; i < val_3; ++i) {
504
u[i] =
data
[i] / theta;
505
}
506
return
u;
507
}
508
513
vpThetaUVector
vpThetaUVector::operator*
(
const
vpThetaUVector
&tu_b)
const
514
{
515
double
a_2 =
getTheta
() / 2;
516
vpColVector
a_hat =
getU
();
517
double
b_2 = tu_b.
getTheta
() / 2;
518
vpColVector
b_hat = tu_b.
getU
();
519
520
vpColVector
a_hat_sin_2 = a_hat * std::sin(a_2);
521
vpColVector
b_hat_sin_2 = b_hat * std::sin(b_2);
522
double
c = 2 * std::acos((std::cos(a_2) * std::cos(b_2)) - (
vpColVector::dotProd
(a_hat_sin_2, b_hat_sin_2)));
523
vpColVector
d = ((std::sin(a_2) * std::cos(b_2) * a_hat) + (std::cos(a_2) * std::sin(b_2) * b_hat)) +
524
(std::sin(a_2) * std::sin(b_2) *
vpColVector::crossProd
(a_hat, b_hat));
525
d = (c * d) / std::sin(c / 2.0);
526
527
return
vpThetaUVector
(d);
528
}
529
530
#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
552
vpThetaUVector
&
vpThetaUVector::operator=
(
const
std::initializer_list<double> &list)
553
{
554
if
(list.size() >
size
()) {
555
throw
(
vpException
(
556
vpException::dimensionError
,
557
"Cannot set theta u vector out of bounds. It has only %d values while you try to initialize with %d values"
,
558
size
(), list.size()));
559
}
560
std::copy(list.begin(), list.end(),
data
);
561
return
*
this
;
562
}
563
#endif
564
END_VISP_NAMESPACE
vpArray2D< double >::data
double * data
Definition
vpArray2D.h:149
vpArray2D< double >::dsize
unsigned int dsize
Definition
vpArray2D.h:1207
vpArray2D< double >::size
unsigned int size() const
Definition
vpArray2D.h:435
vpColVector
Implementation of column vector and the associated operations.
Definition
vpColVector.h:191
vpColVector::dotProd
static double dotProd(const vpColVector &a, const vpColVector &b)
Definition
vpColVector.cpp:569
vpColVector::crossProd
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
Definition
vpColVector.cpp:789
vpException
error that can be emitted by ViSP classes.
Definition
vpException.h:60
vpException::dimensionError
@ dimensionError
Bad dimension.
Definition
vpException.h:71
vpHomogeneousMatrix
Implementation of an homogeneous matrix and operations on such kind of matrices.
Definition
vpHomogeneousMatrix.h:221
vpHomogeneousMatrix::extract
void extract(vpRotationMatrix &R) const
Definition
vpHomogeneousMatrix.cpp:912
vpMath::sinc
static double sinc(double x)
Definition
vpMath.cpp:289
vpMath::sign
static int sign(double x)
Definition
vpMath.h:432
vpPoseVector
Implementation of a pose vector and operations on poses.
Definition
vpPoseVector.h:203
vpQuaternionVector
Implementation of a rotation vector as quaternion angle minimal representation.
Definition
vpQuaternionVector.h:106
vpRotationMatrix
Implementation of a rotation matrix and operations on such kind of matrices.
Definition
vpRotationMatrix.h:130
vpRotationVector::vpRotationVector
vpRotationVector()
Constructor that constructs a 0-size rotation vector.
Definition
vpRotationVector.h:106
vpRxyzVector
Implementation of a rotation vector as Euler angle minimal representation.
Definition
vpRxyzVector.h:183
vpRzyxVector
Implementation of a rotation vector as Euler angle minimal representation.
Definition
vpRzyxVector.h:184
vpRzyzVector
Implementation of a rotation vector as Euler angle minimal representation.
Definition
vpRzyzVector.h:182
vpThetaUVector::operator*
vpThetaUVector operator*(const vpThetaUVector &tu_b) const
Definition
vpThetaUVector.cpp:513
vpThetaUVector::getU
vpColVector getU() const
Definition
vpThetaUVector.cpp:492
vpThetaUVector::vpThetaUVector
vpThetaUVector()
Definition
vpThetaUVector.cpp:50
vpThetaUVector::extract
void extract(double &theta, vpColVector &u) const
Definition
vpThetaUVector.cpp:415
vpThetaUVector::buildFrom
vpThetaUVector & buildFrom(const vpHomogeneousMatrix &M)
Definition
vpThetaUVector.cpp:113
vpThetaUVector::operator=
vpThetaUVector & operator=(const vpColVector &tu)
Definition
vpThetaUVector.cpp:368
vpThetaUVector::getTheta
double getTheta() const
Definition
vpThetaUVector.cpp:457
BEGIN_VISP_NAMESPACE
Definition
vpMbtDistanceCircle.cpp:55
modules
core
src
math
transformation
vpThetaUVector.cpp
Generated by
1.17.0