Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
catchEigenConversion.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 conversion between ViSP and Eigen type.
32 */
33
39
40#include <visp3/core/vpConfig.h>
41#include <visp3/core/vpEigenConversion.h>
42
43#if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_CATCH2)
44
45#include <catch_amalgamated.hpp>
46
47#ifdef ENABLE_VISP_NAMESPACE
48using namespace VISP_NAMESPACE_NAME;
49#endif
50
51namespace
52{
53template <typename Type> std::ostream &operator<<(std::ostream &os, const Eigen::Quaternion<Type> &q)
54{
55 return os << "qw: " << q.w() << " ; qx: " << q.x() << " ; qy: " << q.y() << " ; qz: " << q.z();
56}
57
58template <typename Type> std::ostream &operator<<(std::ostream &os, const Eigen::AngleAxis<Type> &aa)
59{
60 return os << "angle: " << aa.angle() << " ; axis: " << aa.axis()(0) << " ; " << aa.axis()(1) << " ; " << aa.axis()(2)
61 << " ; thetau: " << aa.angle() * aa.axis()(0) << " ; " << aa.angle() * aa.axis()(1) << " ; "
62 << aa.angle() * aa.axis()(2);
63}
64} // namespace
65
66TEST_CASE("vpMatrix <--> Eigen::MatrixXd/Matrix3Xd conversion", "[eigen_conversion]")
67{
68 vpMatrix visp_m(3, 4);
69 for (unsigned int i = 0; i < visp_m.size(); i++) {
70 visp_m.data[i] = i;
71 }
72
73 {
74 Eigen::MatrixXd eigen_m;
75 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m);
76 std::cout << "Eigen MatrixXd:\n" << eigen_m << std::endl;
77
78 vpMatrix visp_m2;
79 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m2);
80 std::cout << "ViSP vpMatrix:\n" << visp_m2 << std::endl;
81
82 REQUIRE(visp_m == visp_m2);
83 std::cout << std::endl;
84 }
85 {
86 Eigen::Matrix3Xd eigen_m;
87 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m);
88 std::cout << "Eigen Matrix3Xd:\n" << eigen_m << std::endl;
89
90 vpMatrix visp_m2;
91 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m2);
92 std::cout << "ViSP vpMatrix:\n" << visp_m2 << std::endl;
93
94 REQUIRE(visp_m == visp_m2);
95 std::cout << std::endl;
96 }
97}
98
99TEST_CASE("Eigen::MatrixXd <--> vpMatrix conversion", "[eigen_conversion]")
100{
101 Eigen::MatrixXd eigen_m(3, 5);
102#if (VP_VERSION_INT(EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION) < 0x030300)
103 for (Eigen::DenseIndex i = 0; i < eigen_m.rows(); i++) {
104 for (Eigen::DenseIndex j = 0; j < eigen_m.cols(); j++) {
105#else
106 for (Eigen::Index i = 0; i < eigen_m.rows(); i++) {
107 for (Eigen::Index j = 0; j < eigen_m.cols(); j++) {
108#endif
109 eigen_m(i, j) = static_cast<double>(i * eigen_m.cols() + j);
110 }
111 }
112 std::cout << "Eigen Matrix (row major: " << eigen_m.IsRowMajor << "):\n" << eigen_m << std::endl;
113
114 vpMatrix visp_m;
115 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m);
116 std::cout << "ViSP vpMatrix:\n" << visp_m << std::endl;
117
118 Eigen::MatrixXd eigen_m2;
119 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m2);
120 std::cout << "Eigen MatrixXd (row major: " << eigen_m2.IsRowMajor << "):\n" << eigen_m2 << std::endl;
121
122 vpMatrix visp_m2;
123 VISP_NAMESPACE_NAME::eigen2visp(eigen_m2, visp_m2);
124 REQUIRE(visp_m == visp_m2);
125 std::cout << std::endl;
126 }
127
128TEST_CASE("Eigen::MatrixX4d <--> vpMatrix conversion", "[eigen_conversion]")
129{
130 Eigen::MatrixX4d eigen_m(2, 4);
131#if (VP_VERSION_INT(EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION) < 0x030300)
132 for (Eigen::DenseIndex i = 0; i < eigen_m.rows(); i++) {
133 for (Eigen::DenseIndex j = 0; j < eigen_m.cols(); j++) {
134#else
135 for (Eigen::Index i = 0; i < eigen_m.rows(); i++) {
136 for (Eigen::Index j = 0; j < eigen_m.cols(); j++) {
137#endif
138 eigen_m(i, j) = static_cast<double>(i * eigen_m.cols() + j);
139 }
140 }
141 std::cout << "Eigen MatrixX4d (row major: " << eigen_m.IsRowMajor << "):\n" << eigen_m << std::endl;
142
143 vpMatrix visp_m;
144 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m);
145 std::cout << "ViSP vpMatrix:\n" << visp_m << std::endl;
146
147 Eigen::MatrixX4d eigen_m2;
148 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m2);
149 std::cout << "Eigen MatrixX4d (row major: " << eigen_m2.IsRowMajor << "):\n" << eigen_m2 << std::endl;
150
151 vpMatrix visp_m2;
152 VISP_NAMESPACE_NAME::eigen2visp(eigen_m2, visp_m2);
153 REQUIRE(visp_m == visp_m2);
154 std::cout << std::endl;
155 }
156
157TEST_CASE("Eigen::Matrix<double, Dynamic, Dynamic, RowMajor> <--> vpMatrix conversion", "[eigen_conversion]")
158{
159 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> eigen_m(3, 5);
160#if (VP_VERSION_INT(EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION) < 0x030300)
161 for (Eigen::DenseIndex i = 0; i < eigen_m.rows(); i++) {
162 for (Eigen::DenseIndex j = 0; j < eigen_m.cols(); j++) {
163#else
164 for (Eigen::Index i = 0; i < eigen_m.rows(); i++) {
165 for (Eigen::Index j = 0; j < eigen_m.cols(); j++) {
166#endif
167 eigen_m(i, j) = static_cast<double>(i * eigen_m.cols() + j);
168 }
169 }
170 std::cout << "Eigen Matrix (RowMajor):\n" << eigen_m << std::endl;
171
172 vpMatrix visp_m;
173 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m);
174 std::cout << "ViSP vpMatrix:\n" << visp_m << std::endl;
175
176 Eigen::MatrixXd eigen_m2;
177 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m2);
178 std::cout << "Eigen MatrixXd (row major: " << eigen_m2.IsRowMajor << "):\n" << eigen_m2 << std::endl;
179
180 vpMatrix visp_m2;
181 VISP_NAMESPACE_NAME::eigen2visp(eigen_m2, visp_m2);
182 REQUIRE(visp_m == visp_m2);
183 std::cout << std::endl;
184 }
185
186TEST_CASE("Eigen::Matrix<double, Dynamic, Dynamic, ColMajor> <--> vpMatrix conversion", "[eigen_conversion]")
187{
188 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> eigen_m(3, 5);
189#if (VP_VERSION_INT(EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION) < 0x030300)
190 for (Eigen::DenseIndex i = 0; i < eigen_m.rows(); i++) {
191 for (Eigen::DenseIndex j = 0; j < eigen_m.cols(); j++) {
192#else
193 for (Eigen::Index i = 0; i < eigen_m.rows(); i++) {
194 for (Eigen::Index j = 0; j < eigen_m.cols(); j++) {
195#endif
196 eigen_m(i, j) = static_cast<double>(i * eigen_m.cols() + j);
197 }
198 }
199 std::cout << "Eigen Matrix (ColMajor):\n" << eigen_m << std::endl;
200
201 vpMatrix visp_m;
202 VISP_NAMESPACE_NAME::eigen2visp(eigen_m, visp_m);
203 std::cout << "ViSP vpMatrix:\n" << visp_m << std::endl;
204
205 Eigen::MatrixXd eigen_m2;
206 VISP_NAMESPACE_NAME::visp2eigen(visp_m, eigen_m2);
207 std::cout << "Eigen MatrixXd (row major: " << eigen_m2.IsRowMajor << "):\n" << eigen_m2 << std::endl;
208
209 vpMatrix visp_m2;
210 VISP_NAMESPACE_NAME::eigen2visp(eigen_m2, visp_m2);
211 REQUIRE(visp_m == visp_m2);
212 std::cout << std::endl;
213 }
214
215TEST_CASE("vpHomogeneousMatrix <--> Eigen::Matrix4d conversion", "[eigen_conversion]")
216{
217 vpHomogeneousMatrix visp_cMo(0.1, 0.2, 0.3, 0.1, 0.2, 0.3);
218 Eigen::Matrix4d eigen_cMo;
219 VISP_NAMESPACE_NAME::visp2eigen(visp_cMo, eigen_cMo);
220 std::cout << "Eigen Matrix4d cMo:\n" << eigen_cMo << std::endl;
221
222 vpHomogeneousMatrix visp_cMo2;
223 VISP_NAMESPACE_NAME::eigen2visp(eigen_cMo, visp_cMo2);
224 std::cout << "ViSP vpHomogeneousMatrix cMo:\n" << visp_cMo2 << std::endl;
225 REQUIRE(visp_cMo == visp_cMo2);
226 std::cout << std::endl;
227}
228
229TEST_CASE("vpHomogeneousMatrix <--> Eigen::Matrix4f + double casting conversion", "[eigen_conversion]")
230{
231 vpHomogeneousMatrix visp_cMo; // identity for float to double casting
232 Eigen::Matrix4d eigen_cMo_tmp;
233 VISP_NAMESPACE_NAME::visp2eigen(visp_cMo, eigen_cMo_tmp);
234 Eigen::Matrix4f eigen_cMo = eigen_cMo_tmp.cast<float>();
235 std::cout << "Eigen Matrix4f cMo:\n" << eigen_cMo << std::endl;
236
237 vpHomogeneousMatrix visp_cMo2;
238 VISP_NAMESPACE_NAME::eigen2visp(eigen_cMo.cast<double>(), visp_cMo2);
239 std::cout << "ViSP vpHomogeneousMatrix cMo:\n" << visp_cMo2 << std::endl;
240 REQUIRE(visp_cMo == visp_cMo2);
241 std::cout << std::endl;
242}
243
244TEST_CASE("vpQuaternionVector <--> Eigen::Quaternionf conversion", "[eigen_conversion]")
245{
246 vpQuaternionVector visp_quaternion(0, 1, 2, 3);
247 Eigen::Quaternionf eigen_quaternion;
248 VISP_NAMESPACE_NAME::visp2eigen(visp_quaternion, eigen_quaternion);
249 std::cout << "Eigen quaternion: " << eigen_quaternion << std::endl;
250
251 vpQuaternionVector visp_quaternion2;
252 VISP_NAMESPACE_NAME::eigen2visp(eigen_quaternion, visp_quaternion2);
253 std::cout << "ViSP quaternion: " << visp_quaternion2.t() << std::endl;
254 REQUIRE(visp_quaternion == visp_quaternion2);
255 std::cout << std::endl;
256}
257
258TEST_CASE("vpThetaUVector <--> Eigen::AngleAxisf conversion", "[eigen_conversion]")
259{
260 vpThetaUVector visp_thetau(0, 1, 2);
261 Eigen::AngleAxisf eigen_angle_axis;
262 VISP_NAMESPACE_NAME::visp2eigen(visp_thetau, eigen_angle_axis);
263 std::cout << "Eigen AngleAxis: " << eigen_angle_axis << std::endl;
264
265 vpThetaUVector visp_thetau2;
266 VISP_NAMESPACE_NAME::eigen2visp(eigen_angle_axis, visp_thetau2);
267 std::cout << "ViSP AngleAxis: " << visp_thetau2.t() << std::endl;
268 REQUIRE(visp_thetau == visp_thetau2);
269 std::cout << std::endl;
270}
271
272TEST_CASE("vpColVector <--> Eigen::VectorXd conversion", "[eigen_conversion]")
273{
274 vpColVector visp_col(4, 4);
275 visp_col = 10;
276 Eigen::VectorXd eigen_col;
277 VISP_NAMESPACE_NAME::visp2eigen(visp_col, eigen_col);
278 std::cout << "Eigen VectorXd: " << eigen_col.transpose() << std::endl;
279
280 vpColVector visp_col2;
281 VISP_NAMESPACE_NAME::eigen2visp(eigen_col, visp_col2);
282 std::cout << "ViSP vpColVector: " << visp_col2.t() << std::endl;
283 REQUIRE(visp_col == visp_col2);
284 std::cout << std::endl;
285}
286
287TEST_CASE("vpRowVector <--> Eigen::RowVectorXd conversion", "[eigen_conversion]")
288{
289 vpRowVector visp_row(4, 10);
290 visp_row = 10;
291 Eigen::RowVectorXd eigen_row;
292 VISP_NAMESPACE_NAME::visp2eigen(visp_row, eigen_row);
293 std::cout << "Eigen RowVectorXd: " << eigen_row << std::endl;
294
295 vpRowVector visp_row2;
296 VISP_NAMESPACE_NAME::eigen2visp(eigen_row, visp_row2);
297 std::cout << "ViSP vpRowVector: " << visp_row2 << std::endl;
298 REQUIRE(visp_row == visp_row2);
299 std::cout << std::endl;
300}
301
302TEST_CASE("Eigen::RowVector4d <--> vpRowVector conversion", "[eigen_conversion]")
303{
304 Eigen::RowVector4d eigen_row;
305 eigen_row << 9, 8, 7, 6;
306 vpRowVector visp_row;
307 VISP_NAMESPACE_NAME::eigen2visp(eigen_row, visp_row);
308 std::cout << "ViSP vpRowVector: " << visp_row << std::endl;
309
310 Eigen::RowVector4d eigen_row2;
311 VISP_NAMESPACE_NAME::visp2eigen(static_cast<vpMatrix>(visp_row), eigen_row2);
312 std::cout << "Eigen RowVector4d: " << eigen_row2 << std::endl;
313
314 vpRowVector visp_row2;
315 VISP_NAMESPACE_NAME::eigen2visp(eigen_row2, visp_row2);
316 REQUIRE(visp_row == visp_row2);
317 std::cout << std::endl;
318}
319
320TEST_CASE("vpRowVector <--> Eigen::RowVector4d conversion", "[eigen_conversion]")
321{
322 vpRowVector visp_row(4, 10);
323 visp_row = 10;
324 Eigen::RowVector4d eigen_row;
325 VISP_NAMESPACE_NAME::visp2eigen(static_cast<vpMatrix>(visp_row), eigen_row);
326 std::cout << "Eigen RowVector4d: " << eigen_row << std::endl;
327
328 vpRowVector visp_row2;
329 VISP_NAMESPACE_NAME::eigen2visp(static_cast<Eigen::RowVectorXd>(eigen_row), visp_row2);
330 std::cout << "ViSP vpRowVector: " << visp_row2 << std::endl;
331 REQUIRE(visp_row == visp_row2);
332 std::cout << std::endl;
333}
334
335int main(int argc, char *argv[])
336{
337 Catch::Session session;
338 session.applyCommandLine(argc, argv);
339 int numFailed = session.run();
340 return numFailed;
341}
342
343#else
344int main() { return EXIT_SUCCESS; }
345#endif
Implementation of column vector and the associated operations.
vpRowVector t() const
Implementation of an homogeneous matrix and operations on such kind of matrices.
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
Implementation of a rotation vector as quaternion angle minimal representation.
vpRowVector t() const
Implementation of row vector and the associated operations.
Implementation of a rotation vector as axis-angle minimal representation.
VISP_EXPORT void eigen2visp(const Eigen::MatrixXd &src, vpMatrix &dst)
void visp2eigen(const vpMatrix &src, Eigen::MatrixBase< Derived > &dst)