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