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