GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
node_creator_leg_hierarchy.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 "leg_state.h"
11
12
13namespace designlab
14{
15
17 const HexapodMove next_move,
18 const std::vector<enums::DiscreteLegPos>& discrete_leg_pos_list) :
19 next_move_(next_move),
20 discrete_leg_pos_list_(discrete_leg_pos_list)
21{
22 assert(discrete_leg_pos_list.size() != 0);
23}
24
25
27 const RobotStateNode& current_node,
28 const int current_node_index,
29 std::vector<RobotStateNode>* output_graph) const
30{
31 // 現在,接地している脚の本数を数える.
32 const int kLiftedLegNum = leg_func::GetLiftedLegNum(current_node.leg_state);
33
34 // 遊脚している脚の本数によって処理をする.
35 if (kLiftedLegNum == 1)
36 {
37 // 1 本遊脚している.
38 Create1LegLifted(current_node, current_node_index, output_graph);
39 }
40 else if (kLiftedLegNum == 2)
41 {
42 // 2 本遊脚している.
43 Create2LegLifted(current_node, current_node_index, output_graph);
44 }
45 else if (kLiftedLegNum == 3)
46 {
47 // 3 本遊脚している.
48 Create3LegLifted(current_node, current_node_index, output_graph);
49 }
50 else
51 {
52 // ここに来るのは接地している脚の数が6本 or 1本 or 2本の時.
53 // 地面についている脚が3本を切ることはない,何故ならロボットが倒れてしまうため.
54 // また6本接地しているならば脚を動かせない(遊脚する必要がある).
55 // よって処理を行わない.(そのままの状態を次のノードにする.)
56 RobotStateNode new_node = current_node;
57
58 // 次のノード用に,深さ・親・次の動作を更新する.
59 new_node.ChangeToNextNode(current_node_index, next_move_);
60
61 // 追加する.
62 (*output_graph).emplace_back(new_node);
63 }
64}
65
66
67// 全て上の関数にまとめると文量が増えるため,以下の関数に処理を分けておく.
68
69void NodeCreatorLegHierarchy::Create1LegLifted(
70 const RobotStateNode& current_node,
71 const int current_node_index,
72 std::vector<RobotStateNode>* output_graph) const
73{
74 // 遊脚している脚を探す.遊脚数は1なので1つの数字が帰るはず
75 std::vector<int> lifted_leg_list;
76
77 leg_func::GetLiftedLegIndexByVector(current_node.leg_state, &lifted_leg_list);
78
79
80 // 列挙体 DiscreteLegPos の全ての要素でループを回す.
81 for (const auto i : discrete_leg_pos_list_)
82 {
83 RobotStateNode new_node = current_node; // 新しい脚状態を生成する.
84
85 // 脚状態を変更する.
86 leg_func::ChangeDiscreteLegPos(lifted_leg_list[0], i, &new_node.leg_state);
87
88 // 次のノード用に,深さ・親・次の動作を更新する.
89 new_node.ChangeToNextNode(current_node_index, next_move_);
90
91 (*output_graph).emplace_back(new_node); // 追加する.
92 }
93}
94
95
96void NodeCreatorLegHierarchy::Create2LegLifted(
97 const RobotStateNode& current_node,
98 const int current_node_index,
99 std::vector<RobotStateNode>* output_graph) const
100{
102
103 // 遊脚している脚を探す.遊脚数は2なので2つの数字が帰るはず
104 std::vector<int> lifted_leg_list;
105
106 leg_func::GetLiftedLegIndexByVector(current_node.leg_state, &lifted_leg_list);
107
108
109 // 列挙体 DiscreteLegPos の全ての要素でループを回す.
110 for (const auto i : discrete_leg_pos_list_)
111 {
112 for (const auto j : discrete_leg_pos_list_)
113 {
114 RobotStateNode new_node = current_node; // 新しい脚状態を生成する.
115
116 // 脚状態を変更する.
117 ChangeDiscreteLegPos(lifted_leg_list[0], i, &new_node.leg_state);
118 ChangeDiscreteLegPos(lifted_leg_list[1], j, &new_node.leg_state);
119
120 // 次のノード用に,深さ・親・次の動作を更新する.
121 new_node.ChangeToNextNode(current_node_index, next_move_);
122
123 (*output_graph).emplace_back(new_node); // 追加する.
124 }
125 }
126}
127
128
129void NodeCreatorLegHierarchy::Create3LegLifted(
130 const RobotStateNode& current_node,
131 const int current_node_index,
132 std::vector<RobotStateNode>* output_graph) const
133{
135
136 // 遊脚している脚を探す.遊脚数は3なので3つの数字が帰るはず
137 std::vector<int> lifted_leg_list;
138
139 leg_func::GetLiftedLegIndexByVector(current_node.leg_state, &lifted_leg_list);
140
141
142 // 列挙体 DiscreteLegPos の全ての要素でループを回す.
143 for (const auto i : discrete_leg_pos_list_)
144 {
145 for (const auto j : discrete_leg_pos_list_)
146 {
147 for (const auto k : discrete_leg_pos_list_)
148 {
149 RobotStateNode new_node = current_node; // 新しい脚状態を生成する.
150
151 // 脚状態を変更する.
152 ChangeDiscreteLegPos(lifted_leg_list[0], i, &new_node.leg_state);
153 ChangeDiscreteLegPos(lifted_leg_list[1], j, &new_node.leg_state);
154 ChangeDiscreteLegPos(lifted_leg_list[2], k, &new_node.leg_state);
155
156 // 次のノード用に,深さ・親・次の動作を更新する.
157 new_node.ChangeToNextNode(current_node_index, next_move_);
158
159 (*output_graph).push_back(new_node); // 追加する.
160 }
161 }
162 }
163}
164
165} // namespace designlab
NodeCreatorLegHierarchy(HexapodMove next_move, const std::vector< enums::DiscreteLegPos > &discrete_leg_pos_list)
コンストラクタ.
void Create(const RobotStateNode &current_node, int current_node_index, std::vector< RobotStateNode > *output_nodes) const override
現在のノードから次のノード群を生成する.
void ChangeDiscreteLegPos(const int leg_index, const enums::DiscreteLegPos new_discretized_leg_pos, LegStateBit *leg_state)
脚の状態を変更する.遊脚を表すビットはそのまま.
int GetLiftedLegNum(const LegStateBit &leg_state)
遊脚している脚の本数を返す関数.
Definition leg_state.cpp:98
void GetLiftedLegIndexByVector(const LegStateBit &leg_state, std::vector< int > *res_index)
遊脚している脚の脚番号0~5を,引数_res_numberで参照渡しする関数.
HexapodMove
ロボットが次にどの動作をするのかを表す列挙体.
グラフ構造のためのノード(頂点).旧名 LNODE
leg_func::LegStateBit leg_state
[4 byte] 脚状態,重心パターンを bitで表す.旧名 leg_con.
constexpr void ChangeToNextNode(const int parent_index_, const HexapodMove next_move_)
次の動作を設定する関数. 深さを一つ深くして,親と次の動作を設定する.