GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
robot_operator_for_gpg.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 <format>
11#include <iostream>
12#include <numbers>
13
14#include "cmdio_util.h"
15#include "math_rot_converter.h"
16
17namespace {
18
19// -π~πの範囲に収める
20float NormalizeAngle(float angle) {
21 while (angle > std::numbers::pi_v<float>) {
22 angle -= std::numbers::pi_v<float>;
23 }
24
25 while (angle < -std::numbers::pi_v<float>) {
26 angle += std::numbers::pi_v<float>;
27 }
28
29 return angle;
30}
31
32} // namespace
33
34namespace designlab {
35
37 : global_route_{
38 {4910, 630, 40}, {4890, 630, 40}, {4870, 630, 40}, {4850, 630, 40},
39 {4830, 650, 40}, {4810, 650, 40}, {4790, 630, 40}, {4770, 630, 40},
40 {4750, 650, 40}, {4730, 650, 40}, {4710, 630, 40}, {4690, 650, 40},
41 {4670, 650, 40}, {4650, 650, 40}, {4630, 650, 40}, {4610, 650, 40},
42 {4590, 650, 40}, {4570, 650, 40}, {4550, 650, 40}, {4530, 650, 40},
43 {4510, 650, 40}, {4490, 650, 40}, {4470, 650, 40}, {4450, 650, 40},
44 {4430, 650, 40}, {4410, 650, 40}, {4390, 650, 40}, {4370, 650, 40},
45 {4350, 630, 40}, {4330, 630, 40}, {4310, 630, 40}, {4290, 630, 40},
46 {4270, 630, 40}, {4250, 650, 40}, {4230, 650, 40}, {4210, 650, 40},
47 {4190, 650, 40}, {4170, 650, 40}, {4150, 630, 40}, {4130, 630, 40},
48 {4110, 630, 40}, {4090, 630, 40}, {4070, 650, 40}, {4050, 650, 40},
49 {4030, 650, 40}, {4010, 650, 40}, {3990, 650, 40}, {3970, 650, 40},
50 {3950, 650, 40}, {3930, 650, 40}, {3910, 650, 40}, {3890, 650, 40},
51 {3870, 650, 40}, {3850, 630, 40}, {3830, 630, 40}, {3810, 630, 40},
52 {3790, 630, 40}, {3770, 630, 40}, {3750, 630, 40}, {3730, 650, 40},
53 {3710, 650, 40}, {3690, 650, 40}, {3670, 650, 40}, {3650, 650, 40},
54 {3630, 650, 40}, {3610, 650, 40}, {3590, 650, 40}, {3570, 650, 40},
55 {3550, 650, 40}, {3530, 650, 40}, {3510, 630, 40}, {3490, 630, 40},
56 {3470, 630, 40}, {3450, 630, 40}, {3430, 630, 40}, {3410, 630, 40},
57 {3390, 630, 40}, {3370, 630, 40}, {3350, 630, 40}, {3330, 630, 40},
58 {3310, 630, 40}, {3290, 630, 40}, {3270, 630, 40}, {3250, 630, 40},
59 {3230, 630, 40}, {3210, 630, 40}, {3190, 630, 40}, {3170, 630, 40},
60 {3150, 610, 40}, {3130, 590, 40}, {3110, 570, 40}, {3090, 570, 40},
61 {3070, 570, 40}, {3050, 550, 40}, {3030, 530, 40}, {3010, 530, 40},
62 {2990, 510, 40}, {2970, 490, 40}, {2950, 470, 40}, {2930, 450, 40},
63 {2910, 430, 40},
64
65 } {}
66
67RobotOperation RobotOperatorForGpg::Init() const { return RobotOperation(); }
68
69RobotOperation RobotOperatorForGpg::Update(const RobotStateNode& node) {
70 using enum OutputDetail;
71 using enum RobotOperationType;
72
73 // まず,現在の重心位置から最も近い点を探す.
74 int most_near_index = 0;
75 float min_distance = 100000.f;
76
77 for (int i = 0; i < global_route_.size(); ++i) {
78 const float now_distance = global_route_[i].ProjectedXY().GetDistanceFrom(
80
81 if (min_distance > now_distance) {
82 min_distance = now_distance;
83
84 most_near_index = i;
85 }
86 }
87
88 cmdio::Output(std::format("most_near_index : {}", most_near_index), kDebug);
89
90 // 次の地点への角度を計算する.
91 const float euler_z_angle = NormalizeAngle(ToEulerXYZ(node.posture).z_angle);
92 const Vector3 diff_vector =
93 global_route_[most_near_index - 1] - global_route_[most_near_index];
94 const float target_angle =
95 NormalizeAngle(atan2(diff_vector.y, diff_vector.x));
96 const float rot_dif = target_angle - euler_z_angle;
97
98 cmdio::Output(std::format("target_angle : {} / now_angle : {}",
99 math_util::ConvertRadToDeg(target_angle),
100 math_util::ConvertRadToDeg(euler_z_angle)),
101 kDebug);
102
103 if (abs(rot_dif) > kAllowableAngleError) {
104 RobotOperation operation;
106 operation.spot_turn_last_posture =
107 Quaternion::MakeByAngleAxis(target_angle, Vector3::GetUpVec());
108
109 cmdio::Output(std::format("target_angle : {} / now_angle : {}",
110 math_util::ConvertRadToDeg(target_angle),
111 math_util::ConvertRadToDeg(euler_z_angle)),
112 kDebug);
113
114 return operation;
115 }
116
117 const int loop_num = 10;
118 Vector3 target_vector;
119
120 for (int i = 0; i < loop_num; i++) {
121 if (most_near_index - i < 0) {
122 break;
123 }
124
125 target_vector += (global_route_[most_near_index - i] -
127 static_cast<float>(i + 1);
128 }
129
130 cmdio::Output(std::format("target_vector : {}", target_vector.ToString()),
131 kDebug);
132
133 RobotOperation operation;
135 operation.straight_move_vector =
136 Vector3(target_vector.x, target_vector.y, 0).GetNormalized();
137
138 return operation;
139}
140
141} // namespace designlab
RobotOperationType
Robotをどのように動かすかを表す列挙体.
@ kStraightMoveVector
直線移動をさせる(移動したい方向をベクトルで示す)
@ kSpotTurnLastPosture
その場で旋回させる(最終的な姿勢 Posture を示す)
OutputDetail
コマンドラインに文字を出力する際に,その詳細を指定するための列挙体.
@ kDebug
デバッグ時のみ出力,一番優先度が低い.
EulerXYZ ToEulerXYZ(const RotationMatrix3x3 &rot)
回転角行列からXYZオイラー角への変換.
float z_angle
Z 軸周りの回転 [rad]
Definition math_euler.h:101
探索において目標となる座標や角度,評価する値についてまとめた構造体.
Vector3 straight_move_vector
< 目標方向.正規化されたベクトル.
RobotOperationType operation_type
Quaternion spot_turn_last_posture
旋回時の回転軸.右ねじの回転.
グラフ構造のためのノード(頂点).
Vector3 center_of_mass_global_coord
[4 * 3 = 12byte] グローバル座標系における重心の位置.旧名 GCOM
Quaternion posture
[4 * 4 = 16byte] 姿勢を表すクォータニオン.
3次元の位置ベクトルを表す構造体.
float x
ロボットの正面方向に正.
Vector3 GetNormalized() const noexcept
単位ベクトルを返す. normalizeとは,ベクトルを正規化(単位ベクトルに変換)する操作を表す. 絶対値が0のベクトルの場合,そのまま0ベクトルを返す.
constexpr Vector2 ProjectedXY() const noexcept
XY平面に射影したベクトルを返す.
std::string ToString() const
このベクトルを文字列にして返す. (x, y, z) の形式,小数点以下3桁まで.
float y
ロボットの左向きに正.