GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
system_main_robot_control.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 <format>
11#include <filesystem>
12
13#include <boost/thread.hpp>
14
15#include "cmdio_util.h"
16#include "file_tree.h"
18
19
20namespace designlab
21{
22
23SystemMainRobotControl::SystemMainRobotControl(const std::shared_ptr<GraphicDataBroker>& broker_ptr) :
24 broker_ptr_(broker_ptr)
25{
26 InitializeDirectory();
27}
28
30{
31 using enum OutputDetail;
32
33 CmdIOUtil::OutputTitle("Result Viewer System");
34
35 while (true)
36 {
37 // ファイルツリーを表示し,ファイルを選択する.
38 FileTree file_tree;
39
40 std::string res_path;
41
42 if (!file_tree.SelectFile(kResultFileDirectoryPath, -1, "csv", ResultFileConst::kNodeListName, &res_path))
43 {
44 CmdIOUtil::Output("No data were found. Terminate.", kSystem);
46
49 "Please put the file in the directory. \"./" + kResultFileDirectoryPath + "\"", kSystem);
50
51 break;
52 }
53
54 // ファイルを読み込む.
55
56 std::vector<RobotStateNode> graph; // データを受け取るための変数.
57 MapState map_state;
58
59 if (result_importer_.ImportNodeListAndMapState(res_path, &graph, &map_state))
60 {
61 RemoveDoNotMoveNode(&graph);
62 MergeContinuousMove(&graph);
63 DivideSwingAndStance(&graph);
64
65 // データを仲介人に渡す.
66 broker_ptr_->graph.SetData(graph);
67 broker_ptr_->map_state.SetData(map_state);
68 broker_ptr_->simulation_end_index.SetData({ graph.size() - 1 });
69
70 // データを表示する.
71 CmdIOUtil::Output("Displays data.", kSystem);
76 }
77 else
78 {
79 CmdIOUtil::Output("Failed to load file. Exit.", kSystem);
80 }
81
82 // 終了するかどうかを選択
83
84 if (CmdIOUtil::InputYesNo("Do you want to exit this mode?"))
85 {
87
88 break;
89 }
90
92 }
93};
94
95void SystemMainRobotControl::RemoveDoNotMoveNode(std::vector<RobotStateNode>* graph_ptr)
96{
97 // 脚先の座標のみを確認し,変更がない場合は削除する.
98 std::optional<RobotStateNode> prev_pos = std::nullopt;
99
100 for (auto itr = graph_ptr->begin(); itr != graph_ptr->end();)
101 {
102 if (prev_pos.has_value() && itr->leg_pos == prev_pos->leg_pos)
103 {
104 itr = graph_ptr->erase(itr);
105 }
106 else
107 {
108 prev_pos = *itr;
109 ++itr;
110 }
111 }
112}
113
114void SystemMainRobotControl::MergeContinuousMove(std::vector<RobotStateNode>* graph_ptr)
115{
116 // 胴体の平行移動を連続して行うノードをまとめる.
117 std::optional<RobotStateNode> prev_pos = std::nullopt;
118
119 bool prv_is_body_move = false;
120
121 for (auto itr = graph_ptr->begin(); itr != graph_ptr->end();)
122 {
123 if (prev_pos.has_value() &&
124 (*itr).center_of_mass_global_coord != prev_pos.value().center_of_mass_global_coord &&
125 (*itr).center_of_mass_global_coord.z == prev_pos.value().center_of_mass_global_coord.z)
126 {
127 prev_pos = *itr;
128
129 if (prv_is_body_move)
130 {
131 (*(itr - 1)) = *itr;
132 itr = graph_ptr->erase(itr);
133 prv_is_body_move = false;
134 }
135 else
136 {
137 prv_is_body_move = true;
138 ++itr;
139 }
140 }
141 else
142 {
143 prv_is_body_move = false;
144 prev_pos = *itr;
145 ++itr;
146 }
147 }
148}
149
150void SystemMainRobotControl::DivideSwingAndStance(std::vector<RobotStateNode>* graph_ptr)
151{
152 // 脚先の座標のみを確認し,変更がない場合は削除する.
153 std::optional<RobotStateNode> prev_pos = std::nullopt;
154
155 for (auto itr = graph_ptr->begin(); itr != graph_ptr->end(); ++itr)
156 {
157 // 前回のノードがないならば,更新して次へ.
158 if (!prev_pos.has_value())
159 {
160 prev_pos = *itr;
161 continue;
162 }
163
164 // 脚先の座標のZ座標,つまり高さが変化しているかどうかを確認する.
165 int swing_leg_num = 0;
166 int stance_leg_num = 0;
167
168 for (int i = 0; i < HexapodConst::kLegNum; i++)
169 {
170 if (!leg_func::IsGrounded(prev_pos.value().leg_state, i) && leg_func::IsGrounded((*itr).leg_state, i))
171 {
172 ++stance_leg_num;
173 }
174
175 if (leg_func::IsGrounded(prev_pos.value().leg_state, i) && !leg_func::IsGrounded((*itr).leg_state, i))
176 {
177 ++swing_leg_num;
178 }
179 }
180
181 // 遊脚・接地を分ける.
182 if (swing_leg_num > 0 && stance_leg_num > 0)
183 {
184 RobotStateNode stance_node = prev_pos.value();
185
186 for (int i = 0; i < HexapodConst::kLegNum; i++)
187 {
188 // 前に遊脚,現在支持脚の場合のみ処理をする.
189 if (!leg_func::IsGrounded(prev_pos.value().leg_state, i) && leg_func::IsGrounded((*itr).leg_state, i))
190 {
191 // 脚位置の変更
192 stance_node.leg_pos[i] = (*itr).leg_pos[i];
193
194 // 脚の状態の変更
195 leg_func::ChangeGround(i, true, &stance_node.leg_state);
196 }
197 }
198
199 // ノードを挿入する.
200 itr = graph_ptr->insert(itr, stance_node);
201 }
202
203 prev_pos = *itr;
204 }
205}
206
207void SystemMainRobotControl::InitializeDirectory()
208{
209 // ディレクトリが存在しているか確認する.
210 if (!std::filesystem::exists(kResultFileDirectoryPath))
211 {
212 std::filesystem::create_directory(kResultFileDirectoryPath);
213 }
214}
215
216
217} // namespace designlab
static void Output(const std::string &str, OutputDetail detail)
コマンドラインに文字を出力する関数. SetOutputLimit() で設定した出力の許可範囲内であれば出力される. 必ず SetOutputLimit() を呼び出してから使うこと.
static void WaitAnyKey(const std::string &str="Waiting for input.")
入力待ちをする関数. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
static void OutputNewLine(int num, OutputDetail detail)
コマンドラインで改行をする関数.
static void OutputTitle(const std::string &title_name, bool output_copy_right=false)
コマンドラインにこのソフトのタイトルを出力する関数. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
static void OutputHorizontalLine(const std::string &line_visual, OutputDetail detail)
コマンドラインに水平線を出力する関数.
static bool InputYesNo(const std::string &str="Are you sure?")
yesかnoを入力させる関数.返り値で yes なら true,noなら falseを返す. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
ファイルツリーを作成するクラス.
Definition file_tree.h:21
bool SelectFile(const std::string &path, int max_depth, const std::string &extension, const std::string keyword, std::string *output) const
ディレクトリの中から,ファイルを一つ選択する.
Definition file_tree.cpp:27
static constexpr int kLegNum
マップを表すクラス.
Definition map_state.h:32
static const std::string kNodeListName
ノードリストのファイル名 (プログラムの読み込み用)
bool ImportNodeListAndMapState(const std::string &file_path, std::vector< RobotStateNode > *node_list, MapState *map_state) const
ノードリストとマップの状態をファイルから読み込む.
SystemMainRobotControl(const std::shared_ptr< GraphicDataBroker > &broker_ptr)
void Main() override
主要な処理を行う関数.
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
void ChangeGround(const int leg_index, const bool is_ground, LegStateBit *leg_state)
脚の接地・遊脚情報を変更する.
OutputDetail
コマンドラインに文字を出力する際に,その詳細を指定するための列挙体.
@ kSystem
システムメッセージ,常に出力する.