ori_tool.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2021, Qiayuan Liao
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *******************************************************************************/
33 
34 //
35 // Created by qiayuan on 8/13/20.
36 //
37 
38 #include "rm_common/ori_tool.h"
40 #include <eigen3/Eigen/Eigenvalues>
41 
42 void quatToRPY(const geometry_msgs::Quaternion& q, double& roll, double& pitch, double& yaw)
43 {
44  double as = std::min(-2. * (q.x * q.z - q.w * q.y), .99999);
45  yaw = std::atan2(2 * (q.x * q.y + q.w * q.z), square(q.w) + square(q.x) - square(q.y) - square(q.z));
46  pitch = std::asin(as);
47  roll = std::atan2(2 * (q.y * q.z + q.w * q.x), square(q.w) - square(q.x) - square(q.y) + square(q.z));
48 }
49 
50 double yawFromQuat(const geometry_msgs::Quaternion& q)
51 {
52  double roll, pitch, yaw;
53  quatToRPY(q, roll, pitch, yaw);
54  return yaw;
55 }
56 
57 tf2::Quaternion getAverageQuaternion(const std::vector<tf2::Quaternion>& quaternions, const std::vector<double>& weights)
58 {
59  Eigen::MatrixXd Q = Eigen::MatrixXd::Zero(4, quaternions.size());
60  Eigen::Vector3d vec;
61  for (size_t i = 0; i < quaternions.size(); ++i)
62  {
63  // Weigh the quaternions according to their associated weight
64  tf2::Quaternion quat = quaternions[i] * weights[i];
65  // Append the weighted Quaternion to a matrix Q.
66  Q(0, i) = quat.x();
67  Q(1, i) = quat.y();
68  Q(2, i) = quat.z();
69  Q(3, i) = quat.w();
70  }
71  // Creat a solver for finding the eigenvectors and eigenvalues
72  Eigen::EigenSolver<Eigen::MatrixXd> es(Q * Q.transpose());
73  // Find index of maximum (real) Eigenvalue.
74  auto eigenvalues = es.eigenvalues();
75  size_t max_idx = 0;
76  double max_value = eigenvalues[max_idx].real();
77  for (size_t i = 1; i < 4; ++i)
78  {
79  double real = eigenvalues[i].real();
80  if (real > max_value)
81  {
82  max_value = real;
83  max_idx = i;
84  }
85  }
86  // Get corresponding Eigenvector, normalize it and return it as the average quat
87  auto eigenvector = es.eigenvectors().col(max_idx).normalized();
88  tf2::Quaternion mean_orientation(eigenvector[0].real(), eigenvector[1].real(), eigenvector[2].real(),
89  eigenvector[3].real());
90  return mean_orientation;
91 }
92 
93 tf2::Quaternion rotationMatrixToQuaternion(const Eigen::Map<Eigen::Matrix3d>& rot)
94 {
95  Eigen::Matrix3d r = rot.transpose();
96  tf2::Quaternion quat;
97  double trace = r.trace();
98  if (trace > 0.0)
99  {
100  double s = sqrt(trace + 1.0) * 2.0;
101  quat.setValue((r(2, 1) - r(1, 2)) / s, (r(0, 2) - r(2, 0)) / s, (r(1, 0) - r(0, 1)) / s, 0.25 * s);
102  }
103  else if ((r(0, 0) > r(1, 1)) && (r(0, 0) > r(2, 2)))
104  {
105  double s = sqrt(1.0 + r(0, 0) - r(1, 1) - r(2, 2)) * 2.0;
106  quat.setValue(0.25 * s, (r(0, 1) + r(1, 0)) / s, (r(0, 2) + r(2, 0)) / s, (r(2, 1) - r(1, 2)) / s);
107  }
108  else if (r(1, 1) > r(2, 2))
109  {
110  double s = sqrt(1.0 + r(1, 1) - r(0, 0) - r(2, 2)) * 2.0;
111  quat.setValue((r(0, 1) + r(1, 0)) / s, (r(0, 1) + r(1, 0)) / s, 0.25 * s, (r(0, 2) - r(2, 0)) / s);
112  }
113  else
114  {
115  double s = sqrt(1.0 + r(2, 2) - r(0, 0) - r(1, 1)) * 2.0;
116  quat.setValue((r(0, 2) + r(2, 0)) / s, (r(1, 2) + r(2, 1)) / s, 0.25 * s, (r(1, 0) - r(0, 1)) / s);
117  }
118  return quat;
119 }
s
XmlRpcServer s
math_utilities.h
ori_tool.h
rotationMatrixToQuaternion
tf2::Quaternion rotationMatrixToQuaternion(const Eigen::Map< Eigen::Matrix3d > &rot)
Definition: ori_tool.cpp:93
getAverageQuaternion
tf2::Quaternion getAverageQuaternion(const std::vector< tf2::Quaternion > &quaternions, const std::vector< double > &weights)
Definition: ori_tool.cpp:57
tf2::Quaternion
quatToRPY
void quatToRPY(const geometry_msgs::Quaternion &q, double &roll, double &pitch, double &yaw)
Definition: ori_tool.cpp:42
yawFromQuat
double yawFromQuat(const geometry_msgs::Quaternion &q)
Definition: ori_tool.cpp:50
square
T square(T val)
Definition: math_utilities.h:67


rm_common
Author(s):
autogenerated on Sun Apr 6 2025 02:22:01