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