GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
graph_viewer_gui_controller.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 <string>
11
12#include <magic_enum.hpp>
13
14#include <Dxlib.h>
15
16#include "graphic_const.h"
17#include "graph_search_const.h"
18#include "keyboard.h"
19#include "leg_state.h"
20
21
22namespace designlab
23{
24
26 const std::vector<RobotStateNode>* const p_graph,
27 size_t* const p_display_node_index,
28 const std::shared_ptr<const ApplicationSettingRecord>& setting_ptr) :
29 graph_ptr_(p_graph),
30 display_node_index_ptr_(p_display_node_index),
31 setting_ptr_(setting_ptr)
32{
33}
34
35
37{
38 InputNumber();
39 UpdateChildrenList();
40 ChangeDisplayNodeIndex();
41
42 keyboard_.Update();
43}
44
45
47{
48 DrawGraphData();
49 DrawNodeControlPanel();
50
51 if (graph_ptr_->size() != 0 && *display_node_index_ptr_ < graph_ptr_->size())
52 {
53 // DrawNodeData(graph_ptr_->at(*display_node_index_ptr_));
54 }
55}
56
57
58void GraphViewerGUIController::DrawGraphData() const
59{
60 const int kBoxSizeX = 250;
61 const int kBoxSizeY = 200;
62 const int kBoxMinX = setting_ptr_->window_size_x - kBoxSizeX - 10;
63 const int kBoxMinY = setting_ptr_->window_size_y - kBoxSizeY - 10;
64 const unsigned int kBaseColor = GetColor(255, 255, 255);
65
66 // 枠
67 SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
68 DrawBox(kBoxMinX, kBoxMinY, kBoxMinX + kBoxSizeX, kBoxMinY + kBoxSizeY,
69 kBaseColor, TRUE);
70 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
71
72 const unsigned int kTextColor = GetColor(10, 10, 10);
73
74 // テキスト
75 if (graph_ptr_->size() == 0)
76 {
77 DrawString(kBoxMinX + 10, kBoxMinY + 10,
78 "ノード数 : 0", kTextColor);
79 DrawString(kBoxMinX + 10, kBoxMinY + 30,
80 "グラフを生成してください", kTextColor);
81 }
82 else
83 {
84 DrawFormatString(kBoxMinX + 10, kBoxMinY + 10, kTextColor,
85 "総ノード数:%d", graph_ptr_->size());
86 DrawFormatString(kBoxMinX + 10, kBoxMinY + 30, kTextColor,
87 "表示ノード:%d番", *display_node_index_ptr_);
88
89 // 深さごとのノードの数.
90 for (size_t i = 0; i < graph_node_depth_data_.size(); i++)
91 {
92 DrawFormatString(
93 kBoxMinX + 10,
94 kBoxMinY + 50 + 20 * static_cast<int>(i),
95 kTextColor,
96 " (深さ%dのノード:%d)",
97 static_cast<int>(i), static_cast<int>(graph_node_depth_data_.at(i)));
98 }
99 }
100}
101
102
103void GraphViewerGUIController::DrawNodeControlPanel() const
104{
105 const int kBoxSizeX = 350;
106 const int kBoxSizeY = 250;
107 const int kBoxMinX = 10;
108 const int kBoxMinY = 10;
109 const unsigned int kBaseColor = GetColor(255, 255, 255);
110
111 // 枠
112 SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
113 DrawBox(kBoxMinX, kBoxMinY,
114 kBoxMinX + kBoxSizeX, kBoxMinY + kBoxSizeY,
115 kBaseColor, TRUE);
116 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
117
118 const unsigned int kTextColor = GetColor(10, 10, 10);
119
120 // テキスト
121 DrawFormatString(kBoxMinX + 10, kBoxMinY + 10,
122 kTextColor, "input ( C でクリア)");
123
124 if (input_number_ < 0)
125 {
126 DrawFormatString(
127 kBoxMinX + 10, kBoxMinY + 30,
128 kTextColor, " 数字を入力してください");
129 }
130 else
131 {
132 DrawFormatString(
133 kBoxMinX + 10, kBoxMinY + 30,
134 kTextColor, " %d", input_number_);
135 }
136
137 if (graph_ptr_->size() > *display_node_index_ptr_)
138 {
139 DrawFormatString(
140 kBoxMinX + 10, kBoxMinY + 60, kTextColor,
141 "%d番ノードの親ノード:%d番",
142 *display_node_index_ptr_,
143 graph_ptr_->at(*display_node_index_ptr_).parent_index);
144
145 DrawFormatString(
146 kBoxMinX + 10, kBoxMinY + 90, kTextColor,
147 "%d番ノードの子ノード数:%d個",
148 children_list_.first,
149 children_list_.second.size());
150
151 std::string str = children_list_.second.size() == 0 ? "None" : " ";
152
153 for (size_t i = 0; i < children_list_.second.size(); i++)
154 {
155 if (i > (size_t)6 * 5 - 1)
156 {
157 str += "...";
158 break;
159 }
160
161 str += std::to_string(children_list_.second.at(i)) + ",";
162
163 if (i % 6 == 0 && i != 0)
164 {
165 str += "\n ";
166 }
167 }
168
169 DrawFormatString(
170 kBoxMinX + 10, kBoxMinY + 110,
171 kTextColor,
172 "%d番ノードの子ノードリスト", children_list_.first);
173 DrawFormatString(kBoxMinX + 10, kBoxMinY + 130, kTextColor, str.c_str());
174 }
175}
176
177
178void GraphViewerGUIController::DrawNodeData(const RobotStateNode& node) const
179{
182
183 const int kBoxSizeX = 400;
184 const int KBoxSizeY = 300;
185 const int kBoxMinX = setting_ptr_->window_size_x - 25 - kBoxSizeX;
186 const int kBoxMinY = 25;
187 const unsigned int kBoxColor = GetColor(255, 255, 255);
188 const unsigned int kBoxAlpha = 128;
189
190 // 枠.
191 SetDrawBlendMode(DX_BLENDMODE_ALPHA, kBoxAlpha);
192
193 DrawBox(
194 kBoxMinX, kBoxMinY,
195 kBoxMinX + kBoxSizeX, kBoxMinY + KBoxSizeY, kBoxColor, TRUE);
196
197 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
198
199 // テキスト.
200 const unsigned int kTextColor = GetColor(10, 10, 10);
201 const int kTextXPos = kBoxMinX + 10;
202 const int kTextYMinPos = kBoxMinY + 10;
203 const int kTextYInterval = 30;
204
205 int text_line = 0;
206
207 DrawFormatString(
208 kTextXPos,
209 kTextYMinPos + kTextYInterval * (text_line++),
210 kTextColor,
211 "重心:%d,脚位置:%d,%d,%d,%d,%d,%d",
212 GetDiscreteComPos(node.leg_state),
213 GetDiscreteLegPos(node.leg_state, 0),
214 GetDiscreteLegPos(node.leg_state, 1),
215 GetDiscreteLegPos(node.leg_state, 2),
216 GetDiscreteLegPos(node.leg_state, 3),
217 GetDiscreteLegPos(node.leg_state, 4),
218 GetDiscreteLegPos(node.leg_state, 5));
219
220 // 重心を表示する.
221 DrawFormatString(
222 kTextXPos,
223 kTextYMinPos + kTextYInterval * (text_line++),
224 kTextColor,
225 "重心位置(x:%5.3f,y:%5.3f,z:%5.3f)",
226 node.center_of_mass_global_coord.x,
227 node.center_of_mass_global_coord.y,
228 node.center_of_mass_global_coord.z);
229
230 // 遊脚か接地脚か.
231 std::string str = "";
232 for (int i = 0; i < HexapodConst::kLegNum; i++)
233 {
234 if (leg_func::IsGrounded(node.leg_state, i))
235 {
236 str += "接地,";
237 }
238 else
239 {
240 str += "遊脚,";
241 }
242 }
243
244 DrawFormatString(
245 kTextXPos,
246 kTextYMinPos + kTextYInterval * (text_line++),
247 kTextColor,
248 "脚の状態:%s",
249 str.c_str());
250
251 // 脚の位置を表示する.
252 for (int i = 0; i < HexapodConst::kLegNum; i++)
253 {
254 DrawFormatString(
255 kTextXPos,
256 kTextYMinPos + kTextYInterval * (text_line++),
257 kTextColor,
258 "%d番脚の位置(x:%5.3f,y:%5.3f,z:%5.3f)",
259 i, node.leg_pos[i].x,
260 node.leg_pos[i].y,
261 node.leg_pos[i].z);
262 }
263
264 // 深さと次の動作を表示する.
265 DrawFormatString(
266 kTextXPos,
267 kTextYMinPos + kTextYInterval * (text_line++),
268 kTextColor,
269 "深さ:%d, 次の動作 : %s",
270 node.depth,
271 static_cast<std::string>(magic_enum::enum_name(node.next_move)).c_str());
272}
273
274
275void GraphViewerGUIController::InputNumber()
276{
277 // Cキーでリセット.
278 if (keyboard_.GetPressingCount(KEY_INPUT_C) == 1)
279 {
280 input_number_ = -1;
281 return;
282 }
283
284 // 数字入力.
285 int input_number = -1;
286
287 if (keyboard_.GetPressingCount(KEY_INPUT_0) == 1)
288 {
289 input_number = 0;
290 }
291 else if (keyboard_.GetPressingCount(KEY_INPUT_1) == 1)
292 {
293 input_number = 1;
294 }
295 else if (keyboard_.GetPressingCount(KEY_INPUT_2) == 1)
296 {
297 input_number = 2;
298 }
299 else if (keyboard_.GetPressingCount(KEY_INPUT_3) == 1)
300 {
301 input_number = 3;
302 }
303 else if (keyboard_.GetPressingCount(KEY_INPUT_4) == 1)
304 {
305 input_number = 4;
306 }
307 else if (keyboard_.GetPressingCount(KEY_INPUT_5) == 1)
308 {
309 input_number = 5;
310 }
311 else if (keyboard_.GetPressingCount(KEY_INPUT_6) == 1)
312 {
313 input_number = 6;
314 }
315 else if (keyboard_.GetPressingCount(KEY_INPUT_7) == 1)
316 {
317 input_number = 7;
318 }
319 else if (keyboard_.GetPressingCount(KEY_INPUT_8) == 1)
320 {
321 input_number = 8;
322 }
323 else if (keyboard_.GetPressingCount(KEY_INPUT_9) == 1)
324 {
325 input_number = 9;
326 }
327
328 if (input_number >= 0)
329 {
330 if (input_number_ < 0)
331 {
332 input_number_ = input_number;
333 }
334 else
335 {
336 input_number_ *= 10;
337 input_number_ += input_number;
338 }
339 }
340}
341
342
343void GraphViewerGUIController::ChangeDisplayNodeIndex()
344{
345 if (graph_ptr_->size() == 0)
346 {
347 return;
348 }
349
350 if (keyboard_.GetPressingCount(KEY_INPUT_DOWN) == 1)
351 {
352 (*display_node_index_ptr_)--;
353 }
354 else if (keyboard_.GetPressingCount(KEY_INPUT_UP) == 1)
355 {
356 (*display_node_index_ptr_)++;
357 }
358 else if (keyboard_.GetPressingCount(KEY_INPUT_RETURN) == 1)
359 {
360 (*display_node_index_ptr_) = input_number_;
361 input_number_ = -1;
362 }
363 else if (keyboard_.GetPressingCount(KEY_INPUT_P) == 1)
364 {
365 if (graph_ptr_->size() > *display_node_index_ptr_)
366 {
367 (*display_node_index_ptr_) =
368 graph_ptr_->at(*display_node_index_ptr_).parent_index;
369 }
370 }
371 else if (keyboard_.GetPressingCount(KEY_INPUT_LEFT) == 1 &&
372 !children_list_.second.empty())
373 {
374 display_children_list_index_--;
375
376 if (display_children_list_index_ < 0)
377 {
378 display_children_list_index_ =
379 static_cast<int>(children_list_.second.size()) - 1;
380 }
381
382 display_children_list_index_ =
383 (display_children_list_index_ < 0) ? 0 : display_children_list_index_;
384
385 (*display_node_index_ptr_) =
386 children_list_.second.at(display_children_list_index_);
387 }
388 else if (keyboard_.GetPressingCount(KEY_INPUT_RIGHT) == 1 &&
389 !children_list_.second.empty())
390 {
391 display_children_list_index_++;
392
393 if (display_children_list_index_ >= children_list_.second.size())
394 {
395 display_children_list_index_ = 0;
396 }
397
398 (*display_node_index_ptr_) =
399 children_list_.second.at(display_children_list_index_);
400 }
401
402
403 if (*display_node_index_ptr_ < 0)
404 {
405 *display_node_index_ptr_ = graph_ptr_->size() - 1;
406 }
407 else if (*display_node_index_ptr_ >= graph_ptr_->size())
408 {
409 *display_node_index_ptr_ = 0;
410 }
411}
412
413
414void GraphViewerGUIController::UpdateChildrenList()
415{
416 if (graph_ptr_->size() == 0)
417 {
418 return;
419 }
420
421 if (keyboard_.GetPressingCount(KEY_INPUT_U) == 1)
422 {
423 children_list_.first = static_cast<int>(*display_node_index_ptr_);
424 children_list_.second.clear();
425
426 const size_t kGraphSize = graph_ptr_->size();
427
428 for (size_t i = 0; i < kGraphSize; i++)
429 {
430 if (graph_ptr_->at(i).parent_index == children_list_.first)
431 {
432 children_list_.second.push_back(static_cast<int>(i));
433 }
434 }
435 }
436}
437
438
440{
441 graph_node_depth_data_.clear();
442
443 if (graph_ptr_->size() > 0)
444 {
445 graph_node_depth_data_.resize((size_t)GraphSearchConst::kMaxDepth + 1);
446
447 for (size_t i = 0; i < graph_ptr_->size(); ++i)
448 {
449 const auto index = static_cast<size_t>(graph_ptr_->at(i).depth);
450 graph_node_depth_data_.at(index)++;
451 }
452 }
453}
454
455} // namespace designlab
static const int kMaxDepth
グラフ探索の最大深さ.
GraphViewerGUIController(const std::vector< RobotStateNode > *const graph_ptr, size_t *const display_node_index_ptr, const std::shared_ptr< const ApplicationSettingRecord > &setting_ptr)
static constexpr int kLegNum
void Update()
キー入力を更新する. これを毎フレーム実行しないと,キー入力を取得できない.
Definition keyboard.cpp:25
int GetPressingCount(const int key_code) const
keyCodeのキーが押されているフレーム数を取得する.
Definition keyboard.cpp:58
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
enums::DiscreteComPos GetDiscreteComPos(const LegStateBit &leg_state)
現在の脚状態から重心パターンを取得する.
enums::DiscreteLegPos GetDiscreteLegPos(const LegStateBit &leg_state, const int leg_index)
脚状態を取得する.