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 <Dxlib.h>
11
12#include <magic_enum.hpp>
13#include <string>
14
15#include "graphic_const.h"
16#include "keyboard.h"
17#include "leg_state.h"
18
19namespace designlab {
20
22 const std::vector<RobotStateNode>* const p_graph,
23 size_t* const p_display_node_index,
24 const std::shared_ptr<const ApplicationSettingRecord>& setting_ptr)
25 : graph_ptr_(p_graph),
26 display_node_index_ptr_(p_display_node_index),
27 setting_ptr_(setting_ptr) {}
28
30 InputNumber();
31 UpdateChildrenList();
32 ChangeDisplayNodeIndex();
33
34 keyboard_.Update();
35}
36
38 DrawGraphData();
39 DrawNodeControlPanel();
40
41 if (graph_ptr_->size() != 0 &&
42 *display_node_index_ptr_ < graph_ptr_->size()) {
43 // DrawNodeData(graph_ptr_->at(*display_node_index_ptr_));
44 }
45}
46
47void GraphViewerGUIController::DrawGraphData() const {
48 const int kBoxSizeX = 250;
49 const int kBoxSizeY = 200;
50 const int kBoxMinX = setting_ptr_->window_size_x - kBoxSizeX - 10;
51 const int kBoxMinY = setting_ptr_->window_size_y - kBoxSizeY - 10;
52 const unsigned int kBaseColor = GetColor(255, 255, 255);
53
54 // 枠
55 SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
56 DrawBox(kBoxMinX, kBoxMinY, kBoxMinX + kBoxSizeX, kBoxMinY + kBoxSizeY,
57 kBaseColor, TRUE);
58 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
59
60 const unsigned int kTextColor = GetColor(10, 10, 10);
61
62 // テキスト
63 if (graph_ptr_->size() == 0) {
64 DrawString(kBoxMinX + 10, kBoxMinY + 10, "ノード数 : 0", kTextColor);
65 DrawString(kBoxMinX + 10, kBoxMinY + 30, "グラフを生成してください",
66 kTextColor);
67 } else {
68 DrawFormatString(kBoxMinX + 10, kBoxMinY + 10, kTextColor, "総ノード数:%d",
69 graph_ptr_->size());
70 DrawFormatString(kBoxMinX + 10, kBoxMinY + 30, kTextColor,
71 "表示ノード:%d番", *display_node_index_ptr_);
72
73 // 深さごとのノードの数.
74 for (size_t i = 0; i < graph_node_depth_data_.size(); i++) {
75 DrawFormatString(kBoxMinX + 10, kBoxMinY + 50 + 20 * static_cast<int>(i),
76 kTextColor, " (深さ%dのノード:%d)", static_cast<int>(i),
77 static_cast<int>(graph_node_depth_data_.at(i)));
78 }
79 }
80}
81
82void GraphViewerGUIController::DrawNodeControlPanel() const {
83 const int kBoxSizeX = 350;
84 const int kBoxSizeY = 250;
85 const int kBoxMinX = 10;
86 const int kBoxMinY = 10;
87 const unsigned int kBaseColor = GetColor(255, 255, 255);
88
89 // 枠
90 SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
91 DrawBox(kBoxMinX, kBoxMinY, kBoxMinX + kBoxSizeX, kBoxMinY + kBoxSizeY,
92 kBaseColor, TRUE);
93 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
94
95 const unsigned int kTextColor = GetColor(10, 10, 10);
96
97 // テキスト
98 DrawFormatString(kBoxMinX + 10, kBoxMinY + 10, kTextColor,
99 "input ( C でクリア)");
100
101 if (input_number_ < 0) {
102 DrawFormatString(kBoxMinX + 10, kBoxMinY + 30, kTextColor,
103 " 数字を入力してください");
104 } else {
105 DrawFormatString(kBoxMinX + 10, kBoxMinY + 30, kTextColor, " %d",
106 input_number_);
107 }
108
109 if (graph_ptr_->size() > *display_node_index_ptr_) {
110 DrawFormatString(kBoxMinX + 10, kBoxMinY + 60, kTextColor,
111 "%d番ノードの親ノード:%d番", *display_node_index_ptr_,
112 graph_ptr_->at(*display_node_index_ptr_).parent_index);
113
114 DrawFormatString(kBoxMinX + 10, kBoxMinY + 90, kTextColor,
115 "%d番ノードの子ノード数:%d個", children_list_.first,
116 children_list_.second.size());
117
118 std::string str = children_list_.second.size() == 0 ? "None" : " ";
119
120 for (size_t i = 0; i < children_list_.second.size(); i++) {
121 if (i > (size_t)6 * 5 - 1) {
122 str += "...";
123 break;
124 }
125
126 str += std::to_string(children_list_.second.at(i)) + ",";
127
128 if (i % 6 == 0 && i != 0) {
129 str += "\n ";
130 }
131 }
132
133 DrawFormatString(kBoxMinX + 10, kBoxMinY + 110, kTextColor,
134 "%d番ノードの子ノードリスト", children_list_.first);
135 DrawFormatString(kBoxMinX + 10, kBoxMinY + 130, kTextColor, str.c_str());
136 }
137}
138
139void GraphViewerGUIController::DrawNodeData(const RobotStateNode& node) const {
142
143 const int kBoxSizeX = 400;
144 const int KBoxSizeY = 300;
145 const int kBoxMinX = setting_ptr_->window_size_x - 25 - kBoxSizeX;
146 const int kBoxMinY = 25;
147 const unsigned int kBoxColor = GetColor(255, 255, 255);
148 const unsigned int kBoxAlpha = 128;
149
150 // 枠.
151 SetDrawBlendMode(DX_BLENDMODE_ALPHA, kBoxAlpha);
152
153 DrawBox(kBoxMinX, kBoxMinY, kBoxMinX + kBoxSizeX, kBoxMinY + KBoxSizeY,
154 kBoxColor, TRUE);
155
156 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
157
158 // テキスト.
159 const unsigned int kTextColor = GetColor(10, 10, 10);
160 const int kTextXPos = kBoxMinX + 10;
161 const int kTextYMinPos = kBoxMinY + 10;
162 const int kTextYInterval = 30;
163
164 int text_line = 0;
165
166 DrawFormatString(kTextXPos, kTextYMinPos + kTextYInterval * (text_line++),
167 kTextColor, "重心:%d,脚位置:%d,%d,%d,%d,%d,%d",
168 GetDiscreteComPos(node.leg_state),
169 GetDiscreteLegPos(node.leg_state, 0),
170 GetDiscreteLegPos(node.leg_state, 1),
171 GetDiscreteLegPos(node.leg_state, 2),
172 GetDiscreteLegPos(node.leg_state, 3),
173 GetDiscreteLegPos(node.leg_state, 4),
174 GetDiscreteLegPos(node.leg_state, 5));
175
176 // 重心を表示する.
177 DrawFormatString(
178 kTextXPos, kTextYMinPos + kTextYInterval * (text_line++), kTextColor,
179 "重心位置(x:%5.3f,y:%5.3f,z:%5.3f)", node.center_of_mass_global_coord.x,
180 node.center_of_mass_global_coord.y, node.center_of_mass_global_coord.z);
181
182 // 遊脚か接地脚か.
183 std::string str = "";
184 for (int i = 0; i < HexapodConst::kLegNum; i++) {
185 if (leg_func::IsGrounded(node.leg_state, i)) {
186 str += "接地,";
187 } else {
188 str += "遊脚,";
189 }
190 }
191
192 DrawFormatString(kTextXPos, kTextYMinPos + kTextYInterval * (text_line++),
193 kTextColor, "脚の状態:%s", str.c_str());
194
195 // 脚の位置を表示する.
196 for (int i = 0; i < HexapodConst::kLegNum; i++) {
197 DrawFormatString(kTextXPos, kTextYMinPos + kTextYInterval * (text_line++),
198 kTextColor, "%d番脚の位置(x:%5.3f,y:%5.3f,z:%5.3f)", i,
199 node.leg_pos[i].x, node.leg_pos[i].y, node.leg_pos[i].z);
200 }
201
202 // 深さと次の動作を表示する.
203 DrawFormatString(
204 kTextXPos, kTextYMinPos + kTextYInterval * (text_line++), kTextColor,
205 "深さ:%d, 次の動作 : %s", node.depth,
206 static_cast<std::string>(magic_enum::enum_name(node.next_move)).c_str());
207}
208
209void GraphViewerGUIController::InputNumber() {
210 // Cキーでリセット.
211 if (keyboard_.GetPressingCount(KEY_INPUT_C) == 1) {
212 input_number_ = -1;
213 return;
214 }
215
216 // 数字入力.
217 int input_number = -1;
218
219 if (keyboard_.GetPressingCount(KEY_INPUT_0) == 1) {
220 input_number = 0;
221 } else if (keyboard_.GetPressingCount(KEY_INPUT_1) == 1) {
222 input_number = 1;
223 } else if (keyboard_.GetPressingCount(KEY_INPUT_2) == 1) {
224 input_number = 2;
225 } else if (keyboard_.GetPressingCount(KEY_INPUT_3) == 1) {
226 input_number = 3;
227 } else if (keyboard_.GetPressingCount(KEY_INPUT_4) == 1) {
228 input_number = 4;
229 } else if (keyboard_.GetPressingCount(KEY_INPUT_5) == 1) {
230 input_number = 5;
231 } else if (keyboard_.GetPressingCount(KEY_INPUT_6) == 1) {
232 input_number = 6;
233 } else if (keyboard_.GetPressingCount(KEY_INPUT_7) == 1) {
234 input_number = 7;
235 } else if (keyboard_.GetPressingCount(KEY_INPUT_8) == 1) {
236 input_number = 8;
237 } else if (keyboard_.GetPressingCount(KEY_INPUT_9) == 1) {
238 input_number = 9;
239 }
240
241 if (input_number >= 0) {
242 if (input_number_ < 0) {
243 input_number_ = input_number;
244 } else {
245 input_number_ *= 10;
246 input_number_ += input_number;
247 }
248 }
249}
250
251void GraphViewerGUIController::ChangeDisplayNodeIndex() {
252 if (graph_ptr_->size() == 0) {
253 return;
254 }
255
256 if (keyboard_.GetPressingCount(KEY_INPUT_DOWN) == 1) {
257 (*display_node_index_ptr_)--;
258 } else if (keyboard_.GetPressingCount(KEY_INPUT_UP) == 1) {
259 (*display_node_index_ptr_)++;
260 } else if (keyboard_.GetPressingCount(KEY_INPUT_RETURN) == 1) {
261 (*display_node_index_ptr_) = input_number_;
262 input_number_ = -1;
263 } else if (keyboard_.GetPressingCount(KEY_INPUT_P) == 1) {
264 if (graph_ptr_->size() > *display_node_index_ptr_) {
265 (*display_node_index_ptr_) =
266 graph_ptr_->at(*display_node_index_ptr_).parent_index;
267 }
268 } else if (keyboard_.GetPressingCount(KEY_INPUT_LEFT) == 1 &&
269 !children_list_.second.empty()) {
270 display_children_list_index_--;
271
272 if (display_children_list_index_ < 0) {
273 display_children_list_index_ =
274 static_cast<int>(children_list_.second.size()) - 1;
275 }
276
277 display_children_list_index_ =
278 (display_children_list_index_ < 0) ? 0 : display_children_list_index_;
279
280 (*display_node_index_ptr_) =
281 children_list_.second.at(display_children_list_index_);
282 } else if (keyboard_.GetPressingCount(KEY_INPUT_RIGHT) == 1 &&
283 !children_list_.second.empty()) {
284 display_children_list_index_++;
285
286 if (display_children_list_index_ >= children_list_.second.size()) {
287 display_children_list_index_ = 0;
288 }
289
290 (*display_node_index_ptr_) =
291 children_list_.second.at(display_children_list_index_);
292 }
293
294 if (*display_node_index_ptr_ < 0) {
295 *display_node_index_ptr_ = graph_ptr_->size() - 1;
296 } else if (*display_node_index_ptr_ >= graph_ptr_->size()) {
297 *display_node_index_ptr_ = 0;
298 }
299}
300
301void GraphViewerGUIController::UpdateChildrenList() {
302 if (graph_ptr_->size() == 0) {
303 return;
304 }
305
306 if (keyboard_.GetPressingCount(KEY_INPUT_U) == 1) {
307 children_list_.first = static_cast<int>(*display_node_index_ptr_);
308 children_list_.second.clear();
309
310 const size_t kGraphSize = graph_ptr_->size();
311
312 for (size_t i = 0; i < kGraphSize; i++) {
313 if (graph_ptr_->at(i).parent_index == children_list_.first) {
314 children_list_.second.push_back(static_cast<int>(i));
315 }
316 }
317 }
318}
319
321 graph_node_depth_data_.clear();
322 constexpr size_t kMaxDepth = 5;
323
324 if (graph_ptr_->size() > 0) {
325 graph_node_depth_data_.resize(kMaxDepth + 1);
326
327 for (size_t i = 0; i < graph_ptr_->size(); ++i) {
328 const auto index = static_cast<size_t>(graph_ptr_->at(i).depth);
329 graph_node_depth_data_.at(index)++;
330 }
331 }
332}
333
334} // namespace designlab
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:46
DiscreteLegPos GetDiscreteLegPos(const LegStateBit &leg_state, const int leg_index)
脚状態を取得する.
enums::DiscreteComPos GetDiscreteComPos(const LegStateBit &leg_state)
現在の脚状態から重心パターンを取得する.