GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
math_rot_converter.cpp
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
9
10#include "math_util.h"
11
12
13namespace designlab
14{
15
17{
18 Quaternion q;
19
20 q.w = sqrt(1.0f + rot.element[0][0] +
21 rot.element[1][1] + rot.element[2][2]) / 2.0f;
22
23 const float w4 = (4.0f * q.w);
24 q.v.x = (rot.element[2][1] - rot.element[1][2]) / w4;
25 q.v.y = (rot.element[0][2] - rot.element[2][0]) / w4;
26 q.v.z = (rot.element[1][0] - rot.element[0][1]) / w4;
27
28 q.Normalize();
29
30 return q;
31}
32
34{
35 const float cos_x = std::cos(e.x_angle / 2.0f);
36 const float cos_y = std::cos(e.y_angle / 2.0f);
37 const float cos_z = std::cos(e.z_angle / 2.0f);
38 const float sin_x = std::sin(e.x_angle / 2.0f);
39 const float sin_y = std::sin(e.y_angle / 2.0f);
40 const float sin_z = std::sin(e.z_angle / 2.0f);
41
42 Quaternion q;
43 q.w = cos_x * cos_y * cos_z + sin_x * sin_y * sin_z;
44 q.v.x = sin_x * cos_y * cos_z - cos_x * sin_y * sin_z;
45 q.v.y = cos_x * sin_y * cos_z + sin_x * cos_y * sin_z;
46 q.v.z = cos_x * cos_y * sin_z - sin_x * sin_y * cos_z;
47
48 if (math_util::IsEqual(q.GetNorm(), 0.0f))
49 {
50 return Quaternion{};
51 }
52 else
53 {
54 assert(math_util::IsEqual(q.GetNorm(), 1.0f));
55 return q;
56 }
57}
58
60{
62 Quaternion q_norm = q.GetNormalized();
63
64 const float x2 = q_norm.v.x * q_norm.v.x;
65 const float y2 = q_norm.v.y * q_norm.v.y;
66 const float z2 = q_norm.v.z * q_norm.v.z;
67 const float xy = q_norm.v.x * q_norm.v.y;
68 const float xz = q_norm.v.x * q_norm.v.z;
69 const float yz = q_norm.v.y * q_norm.v.z;
70 const float wx = q_norm.w * q_norm.v.x;
71 const float wy = q_norm.w * q_norm.v.y;
72 const float wz = q_norm.w * q_norm.v.z;
73
74 mat.element[0][0] = 1.0f - 2.0f * (y2 + z2);
75 mat.element[0][1] = 2.0f * (xy - wz);
76 mat.element[0][2] = 2.0f * (xz + wy);
77
78 mat.element[1][0] = 2.0f * (xy + wz);
79 mat.element[1][1] = 1.0f - 2.0f * (x2 + z2);
80 mat.element[1][2] = 2.0f * (yz - wx);
81
82 mat.element[2][0] = 2.0f * (xz - wy);
83 mat.element[2][1] = 2.0f * (yz + wx);
84 mat.element[2][2] = 1.0f - 2.0f * (x2 + y2);
85
86 return mat;
87}
88
90{
94
95 // X→Y→Zの順に回転する.
96 return mat_z * mat_y * mat_x;
97}
98
100{
101 float x = std::atan2(rot.element[2][1], rot.element[2][2]);
102 float y = std::atan2(-rot.element[2][0],
103 std::sqrt(rot.element[2][1] * rot.element[2][1] +
104 rot.element[2][2] * rot.element[2][2]));
105 float z = std::atan2(rot.element[1][0], rot.element[0][0]);
106
107 return EulerXYZ{ x, y, z };
108}
109
111{
112 // クォータニオンを回転行列に変換してから,回転行列をオイラー角に変換する.
113 return ToEulerXYZ(ToRotationMatrix(q));
114}
115
116
117} // namespace designlab
constexpr bool IsEqual(const T num1, const T num2) noexcept
C++において,小数同士の計算は誤差が出てしまう. 誤差込みで値が等しいか調べる.
Definition math_util.h:45
EulerXYZ ToEulerXYZ(const RotationMatrix3x3 &rot)
回転角行列からXYZオイラー角への変換.
RotationMatrix3x3 ToRotationMatrix(const Quaternion &q)
クォータニオンから回転角行列への変換.
Quaternion ToQuaternion(const RotationMatrix3x3 &rot)
回転角行列からクォータニオンへの変換.
XYZオイラー角を用いた回転を表す構造体.
Definition math_euler.h:33
float x_angle
X 軸周りの回転 [rad]
Definition math_euler.h:109
float y_angle
Y 軸周りの回転 [rad]
Definition math_euler.h:110
float z_angle
Z 軸周りの回転 [rad]
Definition math_euler.h:111
クォータニオンを表す構造体.
Quaternion GetNormalized() const noexcept
正規化したクォータニオンを返す. クォータニオンの正規化とは,ノルムを1にすることを表す. クォータニオンqの正規化は,q / |q| で求められる.
void Normalize() noexcept
自身を正規化する.ノルムが1になる.
float GetNorm() const noexcept
クォータニオンのノルムを返す. ノルムとは,ベクトルの大きさのこと. クォータニオンのノルムは,w^2 + x^2 + y^2 + z^2 の平方根で求められる.
Vector3 v
ベクトル成分.
float w
スカラー成分.
3次元の回転行列を表す構造体.
static RotationMatrix3x3 CreateRotationMatrixZ(float angle)
z軸周りに回転する回転行列を生成する.
std::array< std::array< float, 3 >, 3 > element
static RotationMatrix3x3 CreateRotationMatrixY(float angle)
y軸周りに回転する回転行列を生成する.
static RotationMatrix3x3 CreateRotationMatrixX(float angle)
x軸周りに回転する回転行列を生成する.
float x
ロボットの正面方向に正.
float z
ロボットの上向きに正.
float y
ロボットの左向きに正.