Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
catchHomogeneousMatrix.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 * Test some vpHomogeneousMatrix functionalities.
32 */
33
39#include <visp3/core/vpConfig.h>
40
41#if defined(VISP_HAVE_CATCH2)
42#include <visp3/core/vpHomogeneousMatrix.h>
43
44#include <catch_amalgamated.hpp>
45
46#ifdef ENABLE_VISP_NAMESPACE
47using namespace VISP_NAMESPACE_NAME;
48#endif
49
50bool test_matrix_equal(const vpHomogeneousMatrix &M1, const vpHomogeneousMatrix &M2, double epsilon = 1e-10)
51{
52 for (unsigned int i = 0; i < 4; i++) {
53 for (unsigned int j = 0; j < 4; j++) {
54 if (!vpMath::equal(M1[i][j], M2[i][j], epsilon)) {
55 return false;
56 }
57 }
58 }
59 return true;
60}
61
62TEST_CASE("vpHomogeneousMatrix re-orthogonalize rotation matrix", "[vpHomogeneousMatrix]")
63{
64 CHECK_NOTHROW([]() {
65 vpHomogeneousMatrix M { 0.9835, -0.0581, 0.1716, 0.0072, -0.0489, -0.9972,
66 -0.0571, 0.0352, 0.1744, 0.0478, -0.9835, 0.9470 };
67 }());
68
69 SECTION("check re-orthogonalize rotation part")
70 {
71 vpHomogeneousMatrix M1 { 0.9835, -0.0581, 0.1716, 0.0072, -0.0489, -0.9972,
72 -0.0571, 0.0352, 0.1744, 0.0478, -0.9835, 0.9470 };
73
75 M2[0][0] = 0.9835;
76 M2[0][1] = -0.0581;
77 M2[0][2] = 0.1716;
78 M2[0][3] = 0.0072;
79 M2[1][0] = -0.0489;
80 M2[1][1] = -0.9972;
81 M2[1][2] = -0.0571;
82 M2[1][3] = 0.0352;
83 M2[2][0] = 0.1744;
84 M2[2][1] = 0.0478;
85 M2[2][2] = -0.9835;
86 M2[2][3] = 0.9470;
88
89 for (unsigned int i = 0; i < 4; i++) {
90 for (unsigned int j = 0; j < 4; j++) {
91 CHECK(M1[i][j] == Catch::Approx(M2[i][j]).margin(std::numeric_limits<double>::epsilon()));
92 }
93 }
94 }
95
96 CHECK_NOTHROW([]() {
97 vpHomogeneousMatrix M { 0.9835, -0.0581, 0.1716, 0.0072, -0.0937, -0.9738,
98 0.2072, 0.0481, 0.1551, -0.2199, -0.9631, 0.9583 };
99
100 std::cout << "Original data:" << std::endl;
101 std::cout << "0.9835 -0.0581 0.1716 0.0072" << std::endl;
102 std::cout << " -0.0937 -0.9738 0.2072 0.0481" << std::endl;
103 std::cout << "0.1551 -0.2199 -0.9631 0.9583" << std::endl;
104 std::cout << "0 0 0 1" << std::endl;
105 std::cout << "M after rotation re-orthogonalization:\n" << M << std::endl;
106 }());
107
108 CHECK_NOTHROW([]() {
109 vpHomogeneousMatrix M1 { 0.9835, -0.0581, 0.1716, 0.0072, -0.0937, -0.9738,
110 0.2072, 0.0481, 0.1551, -0.2199, -0.9631, 0.9583 };
111
112 // following R init should not throw an exception
113 vpRotationMatrix R { M1[0][0], M1[0][1], M1[0][2], M1[1][0], M1[1][1], M1[1][2], M1[2][0], M1[2][1], M1[2][2] };
114 }());
115
116 CHECK_THROWS([]() {
117 vpHomogeneousMatrix M { 0.983, -0.058, 0.171, 0.0072, -0.093, -0.973, 0.207, 0.0481, 0.155, -0.219, -0.963, 0.9583 };
118 }());
119}
120
121TEST_CASE("vpRotationMatrix re-orthogonalize rotation matrix", "[vpRotationMatrix]")
122{
123 CHECK_NOTHROW(
124 []() { vpRotationMatrix R { 0.9835, -0.0581, 0.1716, -0.0489, -0.9972, -0.0571, 0.1744, 0.0478, -0.9835 }; }());
125
126 CHECK_NOTHROW([]() {
127 vpRotationMatrix R { 0.9835, -0.0581, 0.1716, -0.0937, -0.9738, 0.2072, 0.1551, -0.2199, -0.9631 };
128
129 std::cout << "Original data:" << std::endl;
130 std::cout << "0.9835 -0.0581 0.1716" << std::endl;
131 std::cout << " -0.0937 -0.9738 0.2072" << std::endl;
132 std::cout << "0.1551 -0.2199 -0.9631" << std::endl;
133 std::cout << "R after rotation re-orthogonalization:\n" << R << std::endl;
134 }());
135
136 CHECK_NOTHROW([]() {
138 0.46682, -0.74434, 0.47754, -0.83228, -0.55233, -0.04733, 0.29899, -0.37535, -0.87734,
139 };
140
141 std::cout << "Original data:" << std::endl;
142 std::cout << "0.46682, -0.74434, 0.47754" << std::endl;
143 std::cout << "-0.83228, -0.55233, -0.04733" << std::endl;
144 std::cout << "0.29899, -0.37535, -0.87734" << std::endl;
145 std::cout << "R after rotation re-orthogonalization:\n" << R << std::endl;
146 }());
147
148 CHECK_NOTHROW([]() {
150 R = {
151 0.46682, -0.74434, 0.47754, -0.83228, -0.55233, -0.04733, 0.29899, -0.37535, -0.87734,
152 };
153
154 std::cout << "Original data:" << std::endl;
155 std::cout << "0.46682, -0.74434, 0.47754" << std::endl;
156 std::cout << "-0.83228, -0.55233, -0.04733" << std::endl;
157 std::cout << "0.29899, -0.37535, -0.87734" << std::endl;
158 std::cout << "R after rotation re-orthogonalization:\n" << R << std::endl;
159 }());
160
161 CHECK_THROWS([]() { vpRotationMatrix R { 0.983, -0.058, 0.171, -0.093, -0.973, 0.207, 0.155, -0.219, -0.963 }; }());
162}
163
164TEST_CASE("ENU to NED conversion", "[enu2ned]")
165{
166 vpHomogeneousMatrix enu_M_flu { 0, -1, 0, 0.2, 1, 0, 0, 1., 0, 0, 1, 0.3 };
167 std::cout << "enu_M_flu:\n" << enu_M_flu << std::endl;
168
169 vpHomogeneousMatrix enu_M_ned { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0 };
170 std::cout << "enu_M_ned:\n" << enu_M_ned << std::endl;
171
172 vpHomogeneousMatrix flu_M_frd { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0 };
173 std::cout << "flu_M_frd:\n" << flu_M_frd << std::endl;
174
175 vpHomogeneousMatrix enu_M_frd = enu_M_flu * flu_M_frd;
176
177 // Test1
178 {
179 vpHomogeneousMatrix ned_M_frd = enu_M_ned.inverse() * enu_M_flu * flu_M_frd;
180 std::cout << "ned_M_frd:\n" << ned_M_frd << std::endl;
181
182 vpHomogeneousMatrix ned_M_frd_est = vpMath::enu2ned(enu_M_frd);
183 std::cout << "ned_M_frd_est:\n" << ned_M_frd_est << std::endl;
184
185 bool success = test_matrix_equal(ned_M_frd, ned_M_frd_est);
186 std::cout << "Test enu2ned 1 " << (success ? "succeed" : "failed") << std::endl;
187
188 CHECK(success);
189 }
190 // Test2
191 {
192 vpHomogeneousMatrix ned_M_flu = enu_M_ned.inverse() * enu_M_flu;
193 std::cout << "ned_M_flu:\n" << ned_M_flu << std::endl;
194
195 vpHomogeneousMatrix ned_M_flu_est = vpMath::enu2ned(enu_M_flu);
196 std::cout << "ned_M_flu_est:\n" << ned_M_flu_est << std::endl;
197
198 bool success = test_matrix_equal(ned_M_flu, ned_M_flu_est);
199 std::cout << "Test enu2ned 2 " << (success ? "succeed" : "failed") << std::endl;
200
201 CHECK(success);
202 }
203}
204
205TEST_CASE("vpHomogenousMatrix * vpRotationMatrix", "[operator*]")
206{
207 // Test rotation_matrix * homogeneous_matrix
208 vpHomogeneousMatrix _1_M_2_ {
209 0.9835, -0.0581, 0.1716, 0.0072,
210 -0.0489, -0.9972, -0.0571, 0.0352,
211 0.1744, 0.0478, -0.9835, 0.9470
212 };
213 vpHomogeneousMatrix _2_M_3_truth {
214 0.9835, -0.0581, 0.1716, 0,
215 -0.0489, -0.9972, -0.0571, 0,
216 0.1744, 0.0478, -0.9835, 0
217 };
218
219 vpRotationMatrix _2_R_3_ = _2_M_3_truth.getRotationMatrix();
220 vpHomogeneousMatrix _1_M_3_(_1_M_2_* _2_R_3_);
221 vpHomogeneousMatrix _1_M_3_truth(_1_M_2_ * _2_M_3_truth);
222 bool success = test_matrix_equal(_1_M_3_, _1_M_3_truth);
223 std::cout << "Test vpHomogeneousMatrix vpHomogeneousMatrix::operator*(vpRotationMatrix) " << (success ? "succeed" : "failed") << std::endl;
224 CHECK(success);
225}
226
227int main(int argc, char *argv[])
228{
229 Catch::Session session;
230 session.applyCommandLine(argc, argv);
231 int numFailed = session.run();
232 return numFailed;
233}
234#else
235#include <iostream>
236
237int main() { return EXIT_SUCCESS; }
238#endif
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpRotationMatrix getRotationMatrix() const
vpHomogeneousMatrix inverse() const
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
static vpHomogeneousMatrix enu2ned(const vpHomogeneousMatrix &enu_M)
Definition vpMath.cpp:797
Implementation of a rotation matrix and operations on such kind of matrices.