GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
system_main_result_viewer.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 <optional>
13#include <vector>
14
15#include "cmdio_util.h"
16#include "file_tree.h"
18#include "map_state.h"
20
21namespace designlab {
22
24 const std::shared_ptr<GraphicDataBroker>& broker_ptr,
25 const std::shared_ptr<const ApplicationSettingRecord> setting_ptr,
26 const std::shared_ptr<const IHexapodJointCalculator> joint_calculator,
27 const std::shared_ptr<const IHexapodCoordinateConverter> converter)
28 : broker_ptr_(broker_ptr),
29 joint_calculator_(joint_calculator),
30 converter_(converter) {}
31
33 using enum OutputDetail;
34
35 cmdio::OutputTitle("Result Viewer System");
36
37 while (true) {
38 // ファイルツリーを表示し,ファイルを選択する.
39 FileTree file_tree;
40
41 std::string res_path;
42
43 if (!file_tree.SelectFile(ResultFileConst::kDirectoryPath, -1, "csv",
45 cmdio::Output("No data were found. Terminate.", kError);
46
47 break;
48 }
49
50 // ファイルを読み込む.
51
52 std::vector<RobotStateNode> graph; // データを受け取るための変数.
53 MapState map_state;
54
55 if (result_importer_.ImportNodeListAndMapState(res_path, &graph,
56 &map_state)) {
57 // 異常値を出力する.
58 // OutputErrorLegPos(res_path, graph);
59
60 // データを仲介人に渡す.
61 broker_ptr_->graph.SetData(graph);
62 broker_ptr_->map_state.SetData(map_state);
63 broker_ptr_->simulation_end_index.SetData({graph.size() - 1});
64
65 // データを表示する.
66 cmdio::Output("Displays data.", kSystem);
71 } else {
72 cmdio::Output("Failed to read the file. Exit.", kError);
73 }
74
75 // 終了するかどうかを選択
76
77 if (cmdio::InputYesNo("Do you want to exit this mode?")) {
79
80 break;
81 }
82
84 }
85}
86
87void SystemMainResultViewer::OutputErrorLegPos(
88 const std::string& file, const std::vector<RobotStateNode>& nodes) {
89 cmdio::Output("Outputs data of abnormal values.", OutputDetail::kSystem);
90
91 // 後ろの .csv を削除する
92 std::string file_name = file.substr(0, file.size() - 4);
93
94 const std::string output_path = file_name + "_error_leg_pos.txt";
95
96 cmdio::Output("Output Directory: " + output_path, OutputDetail::kSystem);
97
98 // すでにファイルが存在する場合は削除する.
99 if (std::filesystem::exists(output_path)) {
100 std::filesystem::remove(output_path);
101 }
102
103 // まず,脚接地点が可動範囲外のノードを探す.
104 std::vector<Vector2> error_leg_pos;
105
106 for (int i = 0; i < nodes.size(); i++) {
107 for (int j = 0; j < HexapodConst::kLegNum; j++) {
108 HexapodJointState joint_state =
109 joint_calculator_->CalculateJointState(j, nodes[i].leg_pos[j]);
110
111 if (!joint_calculator_->IsValidJointState(j, nodes[i].leg_pos[j],
112 joint_state)) {
113 const auto length = nodes[i].leg_pos[j].ProjectedXY().GetLength();
114
115 error_leg_pos.push_back({length, nodes[i].leg_pos[j].z});
116 }
117 }
118 }
119
120 // 次に脚軌道が可動範囲外を通過するノードを探す.
121 std::vector<Vector2> error_first;
122 std::vector<Vector2> error_second;
123 std::vector<Vector2> error_end;
124
125 for (int i = 0; i < nodes.size() - 1; i++) {
126 for (int j = 0; j < HexapodConst::kLegNum; j++) {
127 // 現在と次のノードがともに可動範囲内にない場合,スキップする.
128 HexapodJointState current_joint_state =
129 joint_calculator_->CalculateJointState(j, nodes[i].leg_pos[j]);
130 HexapodJointState next_joint_state =
131 joint_calculator_->CalculateJointState(j, nodes[i + 1].leg_pos[j]);
132
133 if (!joint_calculator_->IsValidJointState(j, nodes[i].leg_pos[j],
134 current_joint_state) &&
135 !joint_calculator_->IsValidJointState(j, nodes[i + 1].leg_pos[j],
136 next_joint_state)) {
137 continue;
138 }
139
140 // 補完するノードを生成する.
141 InterpolatedNodeCreator creator(converter_);
142
143 std::vector<RobotStateNode> interpolated_nodes =
144 creator.CreateInterpolatedNode(nodes[i], nodes[i + 1]);
145
146 // 補完ノードの中で可動範囲外になるノードを探す.
147 bool error = false;
148
149 for (int k = 0; k < interpolated_nodes.size(); k++) {
150 HexapodJointState joint_state = joint_calculator_->CalculateJointState(
151 j, interpolated_nodes[k].leg_pos[j]);
152
153 if (!joint_calculator_->IsValidJointState(
154 j, interpolated_nodes[k].leg_pos[j], joint_state)) {
155 error = true;
156
157 break;
158 }
159 }
160
161 // 可動範囲外になるノードがあった場合,エラーとして記録する.
162 if (error) {
163 const auto length = nodes[i].leg_pos[j].ProjectedXY().GetLength();
164 error_first.push_back({length, nodes[i].leg_pos[j].z});
165
166 const auto length3 = nodes[i + 1].leg_pos[j].ProjectedXY().GetLength();
167 error_end.push_back({length3, nodes[i + 1].leg_pos[j].z});
168
169 Vector2 second;
170 if (length < length3) {
171 second = Vector2{error_first.back().x, error_end.back().y};
172 } else {
173 second = Vector2{error_end.back().x, error_first.back().y};
174 }
175
176 error_second.push_back(second);
177 }
178 }
179 }
180
181 // 結果をファイルに書き込む.
182
183 // ファイルを開く.
184 std::ofstream ofs(output_path);
185
186 {
187 ofs << " x_position += [";
188
189 for (int i = 0; i < error_leg_pos.size(); i++) {
190 ofs << error_leg_pos[i].x << ", ";
191 }
192
193 ofs << "]" << std::endl;
194 ofs << " z_position += [";
195
196 for (int i = 0; i < error_leg_pos.size(); i++) {
197 ofs << error_leg_pos[i].y << ", ";
198 }
199
200 ofs << "]" << std::endl;
201 }
202
203 // 中継点を出力する.
204 {
205 ofs << " x_position_first += [";
206
207 for (int i = 0; i < error_leg_pos.size(); i++) {
208 ofs << error_first[i].x << ", ";
209 }
210
211 ofs << "]" << std::endl;
212 ofs << " z_position_first += [";
213
214 for (int i = 0; i < error_leg_pos.size(); i++) {
215 ofs << error_first[i].y << ", ";
216 }
217
218 ofs << "]" << std::endl;
219 }
220
221 {
222 ofs << " x_position_second += [";
223
224 for (int i = 0; i < error_leg_pos.size(); i++) {
225 ofs << error_second[i].x << ", ";
226 }
227
228 ofs << "]" << std::endl;
229 ofs << " z_position_second += [";
230
231 for (int i = 0; i < error_leg_pos.size(); i++) {
232 ofs << error_second[i].y << ", ";
233 }
234
235 ofs << "]" << std::endl;
236 }
237
238 {
239 ofs << " x_position_end += [";
240
241 for (int i = 0; i < error_leg_pos.size(); i++) {
242 ofs << error_end[i].x << ", ";
243 }
244
245 ofs << "]" << std::endl;
246 ofs << " z_position_end += [";
247
248 for (int i = 0; i < error_leg_pos.size(); i++) {
249 ofs << error_end[i].y << ", ";
250 }
251
252 ofs << "]" << std::endl;
253 }
254}
255
256} // 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
ノードリストのファイル名 (プログラムの読み込み用)
static const std::string kDirectoryPath
出力先ディレクトリ(フォルダ)名.
bool ImportNodeListAndMapState(const std::string &file_path, std::vector< RobotStateNode > *node_list, MapState *map_state) const
ノードリストとマップの状態をファイルから読み込む.
SystemMainResultViewer(const std::shared_ptr< GraphicDataBroker > &broker_ptr, const std::shared_ptr< const ApplicationSettingRecord > setting_ptr, const std::shared_ptr< const IHexapodJointCalculator > joint_calculator, const std::shared_ptr< const IHexapodCoordinateConverter > converter)
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 で出力される.
OutputDetail
コマンドラインに文字を出力する際に,その詳細を指定するための列挙体.
@ kSystem
システムメッセージ,常に出力する.
@ kError
エラーメッセージ.