GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
com_candidate_polygon_maker.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 "cassert_define.h"
11#include "hexapod_const.h"
12#include "math_line_segment2.h"
13
14namespace designlab {
15
17 const std::shared_ptr<const IHexapodCoordinateConverter>& converter_ptr)
18 : converter_ptr_(converter_ptr) {}
19
21 const RobotStateNode& node,
22 std::array<ComPosAndPolygon, kMakePolygonNum>* output_poly) const {
23 assert(converter_ptr_ != nullptr); // nullptr でないことを確認する.
24 assert(output_poly != nullptr); // nullptr でないことを確認する.
25
26 // XY平面に射影した脚位置を算出する.(グローバル座標系)
27 std::array<Vector2, HexapodConst::kLegNum> leg_pos_xy;
28
29 for (int i = 0; i < HexapodConst::kLegNum; i++) {
30 // 脚位置(グローバル座標)をXY平面に射影する.
31 leg_pos_xy[i] =
32 converter_ptr_
33 ->ConvertLegToGlobalCoordinate(node.leg_pos[i], i,
35 node.posture, true)
36 .ProjectedXY();
37 }
38
39 // 中心を囲むように4角形を作成する.
40 MakeCandidateBox(leg_pos_xy, 0, &(*output_poly)[0].polygon);
41 (*output_poly)[0].com_pos = enums::DiscreteComPos::kFrontLeft;
42 (*output_poly)[0].is_able = true;
43
44 MakeCandidateBox(leg_pos_xy, 1, &(*output_poly)[1].polygon);
45 (*output_poly)[1].com_pos = enums::DiscreteComPos::kBackLeft;
46 (*output_poly)[1].is_able = true;
47
48 MakeCandidateBox(leg_pos_xy, 2, &(*output_poly)[2].polygon);
49 (*output_poly)[2].com_pos = enums::DiscreteComPos::kBack;
50 (*output_poly)[2].is_able = true;
51
52 MakeCandidateBox(leg_pos_xy, 3, &(*output_poly)[3].polygon);
53 (*output_poly)[3].com_pos = enums::DiscreteComPos::kBackRight;
54 (*output_poly)[3].is_able = true;
55
56 MakeCandidateBox(leg_pos_xy, 4, &(*output_poly)[4].polygon);
57 (*output_poly)[4].com_pos = enums::DiscreteComPos::kFrontRight;
58 (*output_poly)[4].is_able = true;
59
60 MakeCandidateBox(leg_pos_xy, 5, &(*output_poly)[5].polygon);
61 (*output_poly)[5].com_pos = enums::DiscreteComPos::kFront;
62 (*output_poly)[5].is_able = true;
63
64 // 中心に3角形を作成する.
65 MakeCandidateTriangle(leg_pos_xy, &(*output_poly)[6]);
66
67 // 生成した多角形が正しいかどうかをチェックし,異常なものは削除する.
68 if (kDoCheckPolygon) {
69 for (int i = 0; i < kMakePolygonNum; ++i) {
70 if (!IsAblePolygon((*output_poly)[i].polygon)) {
71 (*output_poly)[i].is_able = false;
72 }
73 }
74 }
75}
76
77void ComCandidatePolygonMaker::MakeCandidateBox(
78 const std::array<Vector2, HexapodConst::kLegNum>& leg_pos,
79 const int start_leg_num, Polygon2* output_poly) const {
80 // 脚位置を線で結ぶ.この交点から重心候補地点が存在する多角形を求める.
81 LineSegment2 leg_line_02(
82 leg_pos[(start_leg_num + 0) % HexapodConst::kLegNum],
83 leg_pos[(start_leg_num + 2) % HexapodConst::kLegNum]);
84
85 LineSegment2 leg_line_03(
86 leg_pos[(start_leg_num + 0) % HexapodConst::kLegNum],
87 leg_pos[(start_leg_num + 3) % HexapodConst::kLegNum]);
88
89 LineSegment2 leg_line_14(
90 leg_pos[(start_leg_num + 1) % HexapodConst::kLegNum],
91 leg_pos[(start_leg_num + 4) % HexapodConst::kLegNum]);
92
93 LineSegment2 leg_line_15(
94 leg_pos[(start_leg_num + 1) % HexapodConst::kLegNum],
95 leg_pos[(start_leg_num + 5) % HexapodConst::kLegNum]);
96
97 LineSegment2 leg_line_25(
98 leg_pos[(start_leg_num + 2) % HexapodConst::kLegNum],
99 leg_pos[(start_leg_num + 5) % HexapodConst::kLegNum]);
100
101 // 交点(intersection)を求める.
102 Vector2 intersection_02_14 = leg_line_02.GetIntersection(leg_line_14);
103 Vector2 intersection_02_15 = leg_line_02.GetIntersection(leg_line_15);
104 Vector2 intersection_03_14 = leg_line_03.GetIntersection(leg_line_14);
105 Vector2 intersection_03_15 = leg_line_03.GetIntersection(leg_line_15);
106
107 // 中心と0番の脚位置を結んだ線分を求める.
108 LineSegment2 leg_line_0_center(
109 leg_pos[(start_leg_num + 0) % HexapodConst::kLegNum], intersection_03_14);
110
111 // 多角形生成.
112
113 (*output_poly).Reset();
114
115 if (leg_line_0_center.HasIntersection(leg_line_25)) {
116 // 交点がある場合,5角形の多角形を作成する.
117 Vector2 intersection_03_25 = leg_line_03.GetIntersection(leg_line_25);
118 Vector2 intersection_14_25 = leg_line_14.GetIntersection(leg_line_25);
119
120 (*output_poly).AddVertexCheckForDuplicates(intersection_03_15);
121 (*output_poly).AddVertexCheckForDuplicates(intersection_02_15);
122 (*output_poly).AddVertexCheckForDuplicates(intersection_02_14);
123 (*output_poly).AddVertexCheckForDuplicates(intersection_14_25);
124 (*output_poly).AddVertexCheckForDuplicates(intersection_03_25);
125 } else {
126 // 交点がない場合,既に求めた4点で,4角形の多角形を作成する.
127 (*output_poly).AddVertex(intersection_03_15);
128 (*output_poly).AddVertex(intersection_02_15);
129 (*output_poly).AddVertex(intersection_02_14);
130 (*output_poly).AddVertex(intersection_03_14);
131 }
132}
133
134void ComCandidatePolygonMaker::MakeCandidateTriangle(
135 const std::array<Vector2, HexapodConst::kLegNum>& leg_pos,
136 ComPosAndPolygon* output) const {
137 LineSegment2 leg_line_03(leg_pos[0], leg_pos[3]);
138 LineSegment2 leg_line_14(leg_pos[1], leg_pos[4]);
139 LineSegment2 leg_line_25(leg_pos[2], leg_pos[5]);
140
141 // 交点(intersection)を求める.
142 Vector2 intersection_03_14 = leg_line_03.GetIntersection(leg_line_14);
143 Vector2 intersection_03_25 = leg_line_03.GetIntersection(leg_line_25);
144 Vector2 intersection_14_25 = leg_line_14.GetIntersection(leg_line_25);
145
146 // 三角形を作成する.
147 output->polygon.Reset();
148 output->polygon.AddVertex(intersection_03_14);
149 output->polygon.AddVertex(intersection_03_25);
150 output->polygon.AddVertex(intersection_14_25);
151
152 if (intersection_03_14.x > intersection_03_25.x) {
153 output->com_pos = enums::DiscreteComPos::kCenterBack;
154 } else {
155 output->com_pos = enums::DiscreteComPos::kCenterFront;
156 }
157
158 output->is_able = true;
159
160 return;
161}
162
163bool ComCandidatePolygonMaker::IsAblePolygon(const Polygon2& poly) const {
164 // 生成されるのは 3 or 4 or 5角形のみ.
165 if (poly.GetVertexNum() == 3 || poly.GetVertexNum() == 4 ||
166 poly.GetVertexNum() == 5) {
167 // 凸多角形であるかを確認する.
168 if (poly.IsConvex()) {
169 return true;
170 }
171 }
172
173 return false;
174}
175
176} // namespace designlab
static constexpr int kMakePolygonNum
作成する多角形の数.
ComCandidatePolygonMaker(const std::shared_ptr< const IHexapodCoordinateConverter > &converter_ptr)
void MakeCandidatePolygon(const RobotStateNode &node, std::array< ComPosAndPolygon, kMakePolygonNum > *output_poly) const
現在のロボットの状態を表すノードから, 重心位置の候補地点を示す多角形を作成する.
static constexpr int kLegNum
@ kFrontRight
重心が右前方にある.
@ kFrontLeft
重心が左前方にある.
@ kBack
重心が後方にある.
@ kCenterFront
重心が中央前方にある.三角形.
@ kFront
重心が前方にある.
@ kCenterBack
重心が中央後方にある.逆三角径.
@ kBackLeft
重心が左後方にある.
@ kBackRight
重心が右後方にある.
2次元の線分を表す構造体.
2次元の多角形を表す構造体.
グラフ構造のためのノード(頂点).
std::array< Vector3, HexapodConst::kLegNum > leg_pos
[4 * 3 * 6 = 72 byte] 脚先の座標.(coxa(脚の付け根)を原点とする)
Vector3 center_of_mass_global_coord
[4 * 3 = 12byte] グローバル座標系における重心の位置.旧名 GCOM
Quaternion posture
[4 * 4 = 16byte] 姿勢を表すクォータニオン.
2次元の位置ベクトルを表す構造体.