GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
com_type.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
8#include "com_type.h"
9
10#include <utility>
11
12#include <magic_enum.hpp>
13
14#include "cassert_define.h"
15
16
17// com_func 内の関数は実際に処理を行う際に計算を行うと遅くなるため,
18// 初期化時に一度だけ呼び出して,結果を保存しておく.
19// その値を呼び出すことで速度を上げている.
20// このように無名名前空間の中に変数を宣言することで,
21// このファイル内でのみ使用可能になる.こうしてできた変数に結果を保存する.
22// アクセスするには,先頭に::をつける.
24namespace
25{
31
33LegGroundedMap MakeLegGroundedMap()
34{
36 int counter = 0;
37
38
39 // 脚が接地している場合1,遊脚の場合0として,6bitの数値を作成する.
40 // 0番脚が遊脚,残り接地の場合 111 110 .
41 // そしてそれに 0 から始まる番号を割り振る.(管理しやすくするため.)
42 // 全パターンを総当りで書いてあるけど,本当はこのリストを作成する関数を作りたい.
43
44 // トライポット歩容に使用するパターン.
45 res.insert(LegGroundedMapValue(LegGroundedBit("010101"), counter++));
46 res.insert(LegGroundedMapValue(LegGroundedBit("101010"), counter++));
47
48 // 6脚全て接地している場合.
49 res.insert(LegGroundedMapValue(LegGroundedBit("111111"), counter++));
50
51
52 // 5脚接地している場合.
53
54 res.insert(LegGroundedMapValue(LegGroundedBit("011111"), counter++));
55 res.insert(LegGroundedMapValue(LegGroundedBit("101111"), counter++));
56 res.insert(LegGroundedMapValue(LegGroundedBit("110111"), counter++));
57 res.insert(LegGroundedMapValue(LegGroundedBit("111011"), counter++));
58 res.insert(LegGroundedMapValue(LegGroundedBit("111101"), counter++));
59 res.insert(LegGroundedMapValue(LegGroundedBit("111110"), counter++));
60
61
62 // 4脚接地している場合
63
64 res.insert(LegGroundedMapValue(LegGroundedBit("001111"), counter++));
65 res.insert(LegGroundedMapValue(LegGroundedBit("010111"), counter++));
66 res.insert(LegGroundedMapValue(LegGroundedBit("011011"), counter++));
67 res.insert(LegGroundedMapValue(LegGroundedBit("011101"), counter++));
68 res.insert(LegGroundedMapValue(LegGroundedBit("011110"), counter++));
69 res.insert(LegGroundedMapValue(LegGroundedBit("100111"), counter++));
70 res.insert(LegGroundedMapValue(LegGroundedBit("101011"), counter++));
71 res.insert(LegGroundedMapValue(LegGroundedBit("101101"), counter++));
72 res.insert(LegGroundedMapValue(LegGroundedBit("101110"), counter++));
73 res.insert(LegGroundedMapValue(LegGroundedBit("110011"), counter++));
74 res.insert(LegGroundedMapValue(LegGroundedBit("110101"), counter++));
75 res.insert(LegGroundedMapValue(LegGroundedBit("110110"), counter++));
76 res.insert(LegGroundedMapValue(LegGroundedBit("111001"), counter++));
77 res.insert(LegGroundedMapValue(LegGroundedBit("111010"), counter++));
78 res.insert(LegGroundedMapValue(LegGroundedBit("111100"), counter++));
79
80
81 // 3脚接地している場合.隣り合う3脚が遊脚している場合は除く(転倒してしまうため).
82
83 // res.insert(LegGroundedMapValue(LegGroundedBit("000111"), counter++));
84 res.insert(LegGroundedMapValue(LegGroundedBit("001011"), counter++));
85 res.insert(LegGroundedMapValue(LegGroundedBit("001101"), counter++));
86 // res.insert(LegGroundedMapValue(LegGroundedBit("001110"), counter++));
87 res.insert(LegGroundedMapValue(LegGroundedBit("010011"), counter++));
88 res.insert(LegGroundedMapValue(LegGroundedBit("010110"), counter++));
89 res.insert(LegGroundedMapValue(LegGroundedBit("011001"), counter++));
90 res.insert(LegGroundedMapValue(LegGroundedBit("011010"), counter++));
91 // res.insert(LegGroundedMapValue(LegGroundedBit("011100"), counter++));
92 // res.insert(LegGroundedMapValue(LegGroundedBit("100011"), counter++));
93 res.insert(LegGroundedMapValue(LegGroundedBit("100101"), counter++));
94 res.insert(LegGroundedMapValue(LegGroundedBit("100110"), counter++));
95 res.insert(LegGroundedMapValue(LegGroundedBit("101001"), counter++));
96 res.insert(LegGroundedMapValue(LegGroundedBit("101100"), counter++));
97 // res.insert(LegGroundedMapValue(LegGroundedBit("110001"), counter++));
98 res.insert(LegGroundedMapValue(LegGroundedBit("110010"), counter++));
99 res.insert(LegGroundedMapValue(LegGroundedBit("110100"), counter++));
100 // res.insert(LegGroundedMapValue(LegGroundedBit("111000"), counter++));
101
102 return std::move(res);
103}
104
107const LegGroundedMap kLegGroundedPatternMap = MakeLegGroundedMap();
108
110const int kLegGroundedPatternNum = static_cast<int>(kLegGroundedPatternMap.size());
111
112
113
119bool IsLegPairFree(int leg_index, int leg_ground_pattern_index)
120{
121 LegGroundedBit leg_ground_pattern;
122
123 // indexから遊脚のパターンを取得する.
124 try
125 {
126 leg_ground_pattern =
127 ::kLegGroundedPatternMap.right.at(leg_ground_pattern_index);
128 }
129 catch (...)
130 {
131 return false;
132 }
133
134 // 両隣が遊脚の場合は true を返す.
135 if (!leg_ground_pattern[leg_index % HexapodConst::kLegNum] &&
136 !leg_ground_pattern[(leg_index + 1) % HexapodConst::kLegNum])
137 {
138 return true;
139 }
140 else
141 {
142 return false;
143 }
144}
145
148std::unordered_map<DiscreteComPos, std::vector<int>> MakeLegGroundedPatternBanList()
149{
150 std::unordered_map<DiscreteComPos, std::vector<int>> res;
151
152
153 // ロボットの体が前に寄っている時に前足が両方とも遊脚だと転倒してしまう.
154 // そのため,離散化された重心から,とることができない,
155 // 連続する脚が両方とも遊脚になるパターンを禁止するのがこの関数の目的である.
156 std::unordered_map<DiscreteComPos, std::vector<int>> ban_leg_index_list;
157 ban_leg_index_list[DiscreteComPos::kFront] = { 0, 4, 5 };
158 ban_leg_index_list[DiscreteComPos::kFrontRight] = { 0, 1, 5 };
159 ban_leg_index_list[DiscreteComPos::kFrontLeft] = { 3, 4, 5 };
160 ban_leg_index_list[DiscreteComPos::kBack] = { 1, 2, 3 };
161 ban_leg_index_list[DiscreteComPos::kBackRight] = { 0, 1, 2 };
162 ban_leg_index_list[DiscreteComPos::kBackLeft] = { 2, 3, 4 };
163 ban_leg_index_list[DiscreteComPos::kCenterBack] = { 0, 2, 4 };
164 ban_leg_index_list[DiscreteComPos::kCenterFront] = { 1, 3, 5 };
165
166
167 // DiscreteComPosの要素数だけループする.
168 // magic_enum::enum_values<DiscreteComPos>() は,
169 // DiscreteComPos の要素を列挙した array を返す.
170 for (const auto& i : magic_enum::enum_values<DiscreteComPos>())
171 {
172 if (ban_leg_index_list.count(i) == 0) { continue; }
173
174 for (auto& j : ban_leg_index_list[i])
175 {
176 for (int k = 0; k < ::kLegGroundedPatternNum; ++k)
177 {
178 if (IsLegPairFree(j, k))
179 {
180 res[i].push_back(k);
181 }
182 }
183 }
184 }
185
186 return std::move(res);
187}
188
191std::vector<std::vector<int>> MakeLegGroundedPatternBanListFromLeg()
192{
193 std::vector<std::vector<int>> res;
194
195 res.resize(designlab::HexapodConst::kLegNum); // 脚の数だけ vector を確保する.
196
197 // i 番脚を接地しなければ,取ることができないものを保存する.
198 for (int i = 0; i < designlab::HexapodConst::kLegNum; i++)
199 {
200 for (int j = 0; j < ::kLegGroundedPatternNum; ++j)
201 {
202 // i番目のビットを確認し,立っているならば
203 // (つまり,その脚を接地しなければいけないなら),そのパターンを禁止する.
204 if (::kLegGroundedPatternMap.right.at(j)[i])
205 {
206 res[i].push_back(j);
207 }
208 }
209 }
210
211 return std::move(res);
212}
213
214
216const std::unordered_map<::designlab::enums::DiscreteComPos, std::vector<int>>
217kLegGroundedPatternBanList = MakeLegGroundedPatternBanList();
218
220const std::vector<std::vector<int>> kLegGroundedPatternBanListFromLeg =
221MakeLegGroundedPatternBanListFromLeg();
222
223} // namespace
224
225
227{
228
230{
231 return kLegGroundedPatternNum;
232}
233
235 const int leg_ground_pattern_index)
236{
238
239 // indexから遊脚のパターンを取得する.
240 res = ::kLegGroundedPatternMap.right.at(leg_ground_pattern_index);
241
242 return res;
243}
244
245
247 boost::dynamic_bitset<>* output)
248{
249 assert(output != nullptr);
250 assert((*output).size() == GetLegGroundPatternNum());
251
252 // kLegGroundedPatternBanListFromLeg にキーが存在していないことや,
253 // 値が GetLegGroundPatternNum() を超えてないことを確認していない.
254 // エラーが出たら,そこが原因の可能性がある
255 for (auto& i : kLegGroundedPatternBanList.at(discrete_com_pos))
256 {
257 (*output)[i] = false;
258 }
259}
260
261void RemoveLegGroundPatternFromNotGroundableLeg(int not_groundable_leg_index,
262 boost::dynamic_bitset<>* output)
263{
264 assert(output != nullptr);
265 assert((*output).size() == GetLegGroundPatternNum());
266
267 // kLegGroundedPatternBanListFromLeg にキーが存在していないことや,
268 // 値が GetLegGroundPatternNum() を超えてないことを確認していない.
269 // エラーが出たら,そこが原因の可能性がある.
270
271 for (auto& i : kLegGroundedPatternBanListFromLeg[not_groundable_leg_index])
272 {
273 (*output)[i] = false;
274 }
275}
276
278 int not_lift_leg_index,
279 boost::dynamic_bitset<>* output)
280{
281 assert(output != nullptr);
282 assert((*output).size() == GetLegGroundPatternNum());
283
284 // kLegGroundedPatternBanListFromLeg にキーが存在していないことや,
285 // 値が GetLegGroundPatternNum() を超えてないことを確認していない.
286 // エラーが出たら,そこが原因の可能性がある.
287 boost::dynamic_bitset<> inverse_output(GetLegGroundPatternNum());
288
289 for (auto& i : kLegGroundedPatternBanListFromLeg[not_lift_leg_index])
290 {
291 inverse_output[i] = true;
292 }
293
294 (*output) &= inverse_output;
295}
296
297} // namespace designlab::com_func
Hexapodの定数をまとめたクラス.
static constexpr int kLegNum
重心タイプに関する名前空間.Center of Mass Function の略.
Definition com_type.cpp:227
void RemoveLegGroundPatternFromCom(enums::DiscreteComPos discrete_com_pos, boost::dynamic_bitset<> *output)
離散化された重心位置から,その重心位置では取り得ない脚接地パターンを falseにする.
Definition com_type.cpp:246
LegGroundedMap::value_type LegGroundedMapValue
脚の接地パターンを表すマップの値の型.
Definition com_type.h:64
int GetLegGroundPatternNum()
脚の接地パターンの総数を返す.
Definition com_type.cpp:229
leg_func::LegGroundedBit GetLegGroundedBitFromLegGroundPatternIndex(const int leg_ground_pattern_index)
脚の接地パターンの番号から,その番号に該当する接地パターンを返す.
Definition com_type.cpp:234
void RemoveLegGroundPatternFromNotGroundableLeg(int not_groundable_leg_index, boost::dynamic_bitset<> *output)
接地できない脚番号から, その脚が接地できない場合に取り得ない接地パターンを falseにする.
Definition com_type.cpp:261
boost::bimaps::bimap< leg_func::LegGroundedBit, int > LegGroundedMap
脚の接地パターンを表す型.leftがビットのデータ,rightが int型の番号. bimaps::bimap は,左右の型の両方からアクセスできる map. key→value,value→key...
Definition com_type.h:61
void RemoveLegGroundPatternFromNotFreeLeg(int not_lift_leg_index, boost::dynamic_bitset<> *output)
遊脚できない脚番号から, その脚が遊脚できない場合に取り得ない接地パターンを falseにする.
Definition com_type.cpp:277
std::bitset< HexapodConst::kLegNum > LegGroundedBit
脚の遊脚・接地を表す型.6bitのビット型.接地が 1 遊脚が 0.
Definition leg_state.h:59