Visual Servoing Platform version 3.5.0
testQuaternion.cpp
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 * Tests quaternion operations.
33 *
34 * Author:
35 * Souriya Trinh
36 *
37 *****************************************************************************/
38
44#include <limits>
45#include <visp3/core/vpException.h>
46#include <visp3/core/vpMath.h>
47#include <visp3/core/vpQuaternionVector.h>
48
49int main()
50{
51 try {
52 // Test addition of two quaternions
53 vpQuaternionVector q1(2.1, -1, -3.7, 1.5);
54 vpQuaternionVector q2(0.5, 1.4, 0.7, 2.5);
55 vpQuaternionVector q3 = q1 + q2;
56 std::cout << "q3=" << q3 << std::endl;
57 if (!vpMath::equal(q3.x(), 2.6, std::numeric_limits<double>::epsilon()) ||
58 !vpMath::equal(q3.y(), 0.4, std::numeric_limits<double>::epsilon()) ||
59 !vpMath::equal(q3.z(), -3.0, std::numeric_limits<double>::epsilon()) ||
60 !vpMath::equal(q3.w(), 4.0, std::numeric_limits<double>::epsilon())) {
61 throw vpException(vpException::fatalError, "Problem with addition of two quaternions !");
62 }
63
64 // Test subtraction of two quaternions
65 vpQuaternionVector q4 = q3 - q1;
66 std::cout << "q4=" << q4 << std::endl;
67 if (!vpMath::equal(q4.x(), q2.x(), std::numeric_limits<double>::epsilon() * 1e4) ||
68 !vpMath::equal(q4.y(), q2.y(), std::numeric_limits<double>::epsilon() * 1e4) ||
69 !vpMath::equal(q4.z(), q2.z(), std::numeric_limits<double>::epsilon() * 1e4) ||
70 !vpMath::equal(q4.w(), q2.w(), std::numeric_limits<double>::epsilon() * 1e4)) {
71 throw vpException(vpException::fatalError, "Problem with subtraction of two quaternions !");
72 }
73
74 // Test multiplication of two quaternions
75 // https://www.wolframalpha.com/input/?i=quaternion+-Sin%5BPi%5D%2B3i%2B4j%2B3k+multiplied+by+-1j%2B3.9i%2B4-3k&lk=3
76 vpQuaternionVector q5(3.0, 4.0, 3.0, -sin(M_PI));
77 vpQuaternionVector q6(3.9, -1.0, -3.0, 4.0);
78 vpQuaternionVector q7 = q5 * q6;
79 std::cout << "q7=" << q7 << std::endl;
80 if (!vpMath::equal(q7.x(), 3.0, std::numeric_limits<double>::epsilon() * 1e4) ||
81 !vpMath::equal(q7.y(), 36.7, std::numeric_limits<double>::epsilon() * 1e4) ||
82 !vpMath::equal(q7.z(), -6.6, std::numeric_limits<double>::epsilon() * 1e4) ||
83 !vpMath::equal(q7.w(), 1.3, std::numeric_limits<double>::epsilon() * 1e4)) {
84 throw vpException(vpException::fatalError, "Problem with multiplication of two quaternions !");
85 }
86
87 // Test quaternion conjugate
88 vpQuaternionVector q7_conj = q7.conjugate();
89 std::cout << "q7_conj=" << q7_conj << std::endl;
90 if (!vpMath::equal(q7_conj.x(), -3.0, std::numeric_limits<double>::epsilon() * 1e4) ||
91 !vpMath::equal(q7_conj.y(), -36.7, std::numeric_limits<double>::epsilon() * 1e4) ||
92 !vpMath::equal(q7_conj.z(), 6.6, std::numeric_limits<double>::epsilon() * 1e4) ||
93 !vpMath::equal(q7_conj.w(), 1.3, std::numeric_limits<double>::epsilon() * 1e4)) {
94 throw vpException(vpException::fatalError, "Problem with quaternion conjugate !");
95 }
96
97 // Test quaternion inverse
98 vpQuaternionVector q7_inv = q7.inverse();
99 std::cout << "q7_inv=" << q7_inv << std::endl;
100 if (!vpMath::equal(q7_inv.x(), -0.00214111, 0.000001) || !vpMath::equal(q7_inv.y(), -0.026193, 0.000001) ||
101 !vpMath::equal(q7_inv.z(), 0.00471045, 0.000001) || !vpMath::equal(q7_inv.w(), 0.000927816, 0.000001)) {
102 throw vpException(vpException::fatalError, "Problem with quaternion inverse !");
103 }
104
105 // Test quaternion norm
106 double q7_norm = q7.magnitude();
107 std::cout << "q7_norm=" << q7_norm << std::endl;
108 if (!vpMath::equal(q7_norm, 37.4318, 0.0001)) {
109 throw vpException(vpException::fatalError, "Problem with quaternion magnitude !");
110 }
111
112 // Test quaternion normalization
113 q7.normalize();
114 std::cout << "q7_unit=" << q7 << std::endl;
115 if (!vpMath::equal(q7.x(), 0.0801457, 0.00001) || !vpMath::equal(q7.y(), 0.98045, 0.00001) ||
116 !vpMath::equal(q7.z(), -0.176321, 0.00001) || !vpMath::equal(q7.w(), 0.0347298, 0.00001)) {
117 throw vpException(vpException::fatalError, "Problem with quaternion normalization !");
118 }
119
120 // Test copy constructor
121 vpQuaternionVector q_copy1 = vpQuaternionVector(0, 0, 1, 1);
122 std::cout << "q_copy1=" << q_copy1 << std::endl;
123 vpQuaternionVector q_copy2 = q_copy1;
124 q_copy1.set(1, 0, 1, 10);
125 std::cout << "q_copy1 after set=" << q_copy1 << std::endl;
126 std::cout << "q_copy2=" << q_copy2 << std::endl;
127
128 // Test assignment operator
129 vpQuaternionVector q_copy3(10, 10, 10, 10);
130 q_copy3 = q_copy1;
131 std::cout << "q_copy3=" << q_copy3 << std::endl;
132
133 std::cout << "vpQuaternion operations are ok !" << std::endl;
134 return 0;
135 } catch (const vpException &e) {
136 std::cerr << "Catch an exception: " << e << std::endl;
137 return 1;
138 }
139}
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ fatalError
Fatal error.
Definition: vpException.h:96
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:295
Implementation of a rotation vector as quaternion angle minimal representation.
double w() const
Returns w-component of the quaternion.
double y() const
Returns y-component of the quaternion.
vpQuaternionVector conjugate() const
vpQuaternionVector inverse() const
void set(double x, double y, double z, double w)
double z() const
Returns z-component of the quaternion.
double x() const
Returns x-component of the quaternion.