GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
leg_state.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 "leg_state.h"
9
10#include "cassert_define.h"
11
13{
14
16 const enums::DiscreteComPos discrete_com_pos,
17 const std::array<bool, HexapodConst::kLegNum>& is_ground,
18 const std::array<enums::DiscreteLegPos, HexapodConst::kLegNum>& discretized_leg_pos)
19{
20 LegStateBit res = 0;
21
22 // bitに変換する.
23 LegStateBit discrete_com_pos_bit = static_cast<unsigned int>(discrete_com_pos);
24 res |= discrete_com_pos_bit << kShiftToComNum; // 重心パターンの数値だけビットを立てる.
25
26 for (int i = 0; i < HexapodConst::kLegNum; i++)
27 {
28 // 接地しているならば上位ビットを立てる.
29 size_t ground_bit_index = static_cast<size_t>(i + 1) * 4 - 1;
30 if (is_ground[i]) { res[ground_bit_index] = true; }
31
32 // 脚のビットを立てる.
33 LegStateBit discrete_leg_pos_bit = static_cast<unsigned int>(discretized_leg_pos[i]);
34 size_t shift_num = static_cast<size_t>(i) * 4; // 4bitずつずらす
35
36 res |= discrete_leg_pos_bit << shift_num; // 脚の位置の数値だけビットを立てる
37 }
38
39 return res;
40}
41
42
43bool IsGrounded(const LegStateBit& leg_state, const int leg_index)
44{
45 // leg_indexは0~5の範囲にある必要がある.
46 assert(0 <= leg_index);
47 assert(leg_index < HexapodConst::kLegNum);
48
49 // 指定された脚の接地脚のビットが立っているか調べる.
50 size_t ground_bit_index = static_cast<size_t>(leg_index + 1) * 4 - 1;
51
52 if (leg_state[ground_bit_index])
53 {
54 return true;
55 }
56 else
57 {
58 return false;
59 }
60}
61
63{
65
66 for (int i = 0; i < HexapodConst::kLegNum; i++)
67 {
68 if (IsGrounded(leg_state, i))
69 {
70 res[i] = true;
71 }
72 else
73 {
74 res[i] = false;
75 }
76 }
77
78 return res;
79}
80
81int GetGroundedLegNum(const LegStateBit& leg_state)
82{
83 int res = 0;
84
85 // 脚の本数分ループする.
86 for (int i = 0; i < HexapodConst::kLegNum; i++)
87 {
88 if (IsGrounded(leg_state, i))
89 {
90 // 接地している脚があればカウントアップする.
91 res++;
92 }
93 }
94
95 return res;
96}
97
98int GetLiftedLegNum(const LegStateBit& leg_state)
99{
100 return HexapodConst::kLegNum - GetGroundedLegNum(leg_state);
101}
102
103void GetGroundedLegIndexByVector(const LegStateBit& leg_state, std::vector<int>* res_index)
104{
105 // res_index は nullptr でないこと,かつ空である必要がある.
106 assert(res_index != nullptr);
107 assert((*res_index).size() == 0);
108
109 // 脚は6本あるので6回ループする.
110 for (int i = 0; i < HexapodConst::kLegNum; i++)
111 {
112 if (IsGrounded(leg_state, i))
113 {
114 // 接地している脚の脚番号を vector に代入.
115 (*res_index).push_back(i);
116 }
117 }
118}
119
120void GetLiftedLegIndexByVector(const LegStateBit& leg_state, std::vector<int>* res_index)
121{
122 // res_index は nullptr でないこと,かつ空である必要がある.
123 assert(res_index != nullptr);
124 assert((*res_index).size() == 0);
125
126 // 脚は6本あるので6回ループする.
127 for (int i = 0; i < HexapodConst::kLegNum; i++)
128 {
129 if (!IsGrounded(leg_state, i))
130 {
131 // 浮いている脚の脚番号を vector に代入.
132 (*res_index).push_back(i);
133 }
134 }
135}
136
137enums::DiscreteLegPos GetDiscreteLegPos(const LegStateBit& leg_state, const int leg_index)
138{
139 // leg_indexは0~5の範囲にある必要がある.
140 assert(0 <= leg_index);
141 assert(leg_index < HexapodConst::kLegNum);
142
143 const int shift_num = 4 * leg_index; // 4bitずつずらす
144
145 const int res = static_cast<int>(
146 ((leg_state & (kLegPosMaskBit << shift_num)) >> shift_num).to_ulong());
147
148 return static_cast<enums::DiscreteLegPos>(res);
149}
150
152{
153 // 重心パターンを保存するビットをマスクし,その値だけ取得できるように右へシフトする.
154 const int res = static_cast<int>(((leg_state & kComStateMaskBit) >> kShiftToComNum).to_ulong());
155
156 return static_cast<enums::DiscreteComPos>(res);
157}
158
159
161 const int leg_index,
162 const enums::DiscreteLegPos new_discretized_leg_pos,
163 const bool is_ground,
164 LegStateBit* leg_state
165)
166{
167 // leg_indexは0~5の範囲にある必要がある.
168 assert(0 <= leg_index);
169 assert(leg_index < HexapodConst::kLegNum);
170
171 // leg_state は nullptrではない
172 assert(leg_state != nullptr);
173
174 ChangeDiscreteLegPos(leg_index, new_discretized_leg_pos, leg_state);
175 ChangeGround(leg_index, is_ground, leg_state);
176}
177
179 const int leg_index,
180 const enums::DiscreteLegPos new_discretized_leg_pos,
181 LegStateBit* leg_state
182)
183{
184 // leg_indexは0~5の範囲にある必要がある.
185 assert(0 <= leg_index);
186 assert(leg_index < HexapodConst::kLegNum);
187
188 // leg_state は nullptrではない.
189 assert(leg_state != nullptr);
190
191
192 // 新しい脚状態を生成する.
193 const size_t shift_num = static_cast<size_t>(leg_index) * 4; // 4bitずつずらす.
194
195 // 4bitのデータを変更する地点までマスクをずらす.
196 const LegStateBit mask = kLegPosMaskBit << shift_num;
197
198 // bitに変換する.
199 const LegStateBit discreate_leg_pos_bit = static_cast<unsigned int>(new_discretized_leg_pos);
200
201 // 脚位置のデータは4bitづつ配置されているのでその位置まで移動する.
202 const LegStateBit state = discreate_leg_pos_bit << shift_num;
203
204 // 浮いている脚の脚位置のみを変更(排他的論理和による特定ビットの交換.
205 // 参考 : https://qiita.com/vivisuke/items/bc707190e008551ca07f (アクセス日 2023/12/27)
206 LegStateBit res = ((*leg_state) ^ state) & mask;
207 (*leg_state) ^= res;
208}
209
210void ChangeGround(const int leg_index, const bool is_ground, LegStateBit* leg_state)
211{
212 // leg_indexは0~5の範囲にある必要がある.
213 assert(0 <= leg_index);
214 assert(leg_index < HexapodConst::kLegNum);
215
216 // leg_state は nullptrではない
217 assert(leg_state != nullptr);
218
219
220 // 指定された脚の接地脚のビットを立てるか消すかする.
221 const size_t ground_bit_index = static_cast<size_t>(leg_index + 1) * 4 - 1;
222
223 if (is_ground)
224 {
225 (*leg_state)[ground_bit_index] = true;
226 }
227 else
228 {
229 (*leg_state)[ground_bit_index] = false;
230 }
231}
232
233void ChangeAllLegGround(const LegGroundedBit& is_ground_list, LegStateBit* leg_state)
234{
235 // leg_state は nullptrではない.
236 assert(leg_state != nullptr);
237
238 for (int i = 0; i < HexapodConst::kLegNum; i++)
239 {
240 ChangeGround(i, is_ground_list[i], leg_state);
241 }
242}
243
244void ChangeDiscreteComPos(const enums::DiscreteComPos new_com_pattern, LegStateBit* leg_state)
245{
246 // leg_state は nullptrではない.
247 assert(leg_state != nullptr);
248
249 const LegStateBit state = static_cast<unsigned int>(new_com_pattern) << kShiftToComNum;
250 LegStateBit sub = ((*leg_state) ^ state) & kComStateMaskBit;
251 (*leg_state) ^= sub;
252}
253
254
255} // namespace designlab::leg_func
static constexpr int kLegNum
DiscreteLegPos
離散化された脚位置を表す列挙体. 先行研究では 1~7の int型の数値で表現されているが, 可読性を上げるために列挙体にした. 離散化された脚位置は 3bit (0 ~ 7)の範囲で表現される...
このプログラムでは脚状態をビット(28bit)の情報で表す. そのデータを処理するための関数.
Definition leg_state.cpp:13
constexpr LegStateBit kLegPosMaskBit(0b0111)
脚位置は4bitの下位三桁で管理されるので,そこをマスクする.
void ChangeDiscreteLegPos(const int leg_index, const enums::DiscreteLegPos new_discretized_leg_pos, LegStateBit *leg_state)
脚の状態を変更する.遊脚を表すビットはそのまま.
int GetGroundedLegNum(const LegStateBit &leg_state)
接地している脚の本数を返す関数.
Definition leg_state.cpp:81
std::bitset< HexapodConst::kLegNum > LegGroundedBit
脚の遊脚・接地を表す型.6bitのビット型.接地が 1 遊脚が 0.
Definition leg_state.h:59
bool IsGrounded(const LegStateBit &leg_state, const int leg_index)
脚番号 leg_index 0 ~ 5 に応じて,その脚が接地しているかを調べる. 脚は右前脚を0番として,時計回りに0,1,2,3,4,5となる.左前足が5番.
Definition leg_state.cpp:43
constexpr int kShiftToComNum
重心パターンを保存するビットまで行くために,どれだけビットをシフトするか.
Definition leg_state.h:73
int GetLiftedLegNum(const LegStateBit &leg_state)
遊脚している脚の本数を返す関数.
Definition leg_state.cpp:98
constexpr LegStateBit kComStateMaskBit
重心パターンを保存するビットをマスクするビット.
Definition leg_state.h:76
enums::DiscreteComPos GetDiscreteComPos(const LegStateBit &leg_state)
現在の脚状態から重心パターンを取得する.
void ChangeDiscreteComPos(const enums::DiscreteComPos new_com_pattern, LegStateBit *leg_state)
重心のデータを変更する.
void ChangeGround(const int leg_index, const bool is_ground, LegStateBit *leg_state)
脚の接地・遊脚情報を変更する.
void GetLiftedLegIndexByVector(const LegStateBit &leg_state, std::vector< int > *res_index)
遊脚している脚の脚番号0~5を,引数_res_numberで参照渡しする関数.
enums::DiscreteLegPos GetDiscreteLegPos(const LegStateBit &leg_state, const int leg_index)
脚状態を取得する.
LegGroundedBit GetLegGroundedBit(const LegStateBit &leg_state)
脚が接地しているなら1,遊脚を0としたビット列で遊脚・接地脚の状態を返す. 例えば 0 番脚のみが遊脚しているなら 0b111 110 を返す.
Definition leg_state.cpp:62
void GetGroundedLegIndexByVector(const LegStateBit &leg_state, std::vector< int > *res_index)
接地している脚の脚番号0~5を,引数で参照渡しする関数.
void ChangeAllLegGround(const LegGroundedBit &is_ground_list, LegStateBit *leg_state)
全ての脚の接地・遊脚情報を変更する.
LegStateBit MakeLegStateBit(const enums::DiscreteComPos discrete_com_pos, const std::array< bool, HexapodConst::kLegNum > &is_ground, const std::array< enums::DiscreteLegPos, HexapodConst::kLegNum > &discretized_leg_pos)
脚状態を作成して返す関数.脚状態は重心パターン, 脚の接地・遊脚,離散化した脚位置のデータが含まれる.
Definition leg_state.cpp:15
std::bitset< kLegStateBitNum > LegStateBit
脚状態を保存する型.28bitのビット型.
Definition leg_state.h:56
void ChangeLegState(const int leg_index, const enums::DiscreteLegPos new_discretized_leg_pos, const bool is_ground, LegStateBit *leg_state)
脚の情報を変更する.