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