GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
dxlib_gui_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 <string>
11
12#include "cassert_define.h"
13#include "dxlib_util.h"
14#include "font_loader.h"
15#include "mouse.h"
16
17
18namespace designlab
19{
20
22 const int window_x, const int window_y,
23 const std::shared_ptr<const IHexapodCoordinateConverter>& converter_ptr,
24 const std::shared_ptr<const IHexapodJointCalculator>& calculator_ptr,
25 const std::shared_ptr<const IHexapodPostureValidator>& checker_ptr) :
26 AbstractDxlibGui(kWidth, kHeight),
27 window_x_(window_x),
28 window_y_(window_y),
29 converter_ptr_(converter_ptr),
30 calculator_ptr_(calculator_ptr),
31 checker_ptr_(checker_ptr)
32{
33 assert(converter_ptr_ != nullptr);
34 assert(calculator_ptr_ != nullptr);
35 assert(checker_ptr_ != nullptr);
36
37 const int button_distance = 10;
38 const int button_size = 60;
39
40 const int button_range = button_size + button_distance;
41 const int left_pos_x = gui_left_pos_x_ + button_range / 2 + 15;
42 const int top_pos_y = gui_top_pos_y_ + button_range / 2 + 40;
43
44 button_.push_back(std::make_unique<SimpleButton>(
45 "Toggle\nMode", left_pos_x, top_pos_y, button_size, button_size));
46 button_.back()->SetActivateFunction(
47 [this]() {auto_update_flag_ = !auto_update_flag_; });
48
49 button_.push_back(std::make_unique<SimpleButton>(
50 "Update", left_pos_x, top_pos_y + button_range, button_size, button_size));
51 button_.back()->SetActivateFunction(
52 [this]() { serial_communication_.SetWriteData(GetSerialData()); });
53
54 const int close_button_size = 28;
55 const int close_button_x = gui_left_pos_x_ + kWidth - close_button_size / 2 - 2;
56 const int close_button_y = gui_top_pos_y_ + close_button_size / 2 + 2;
57
58 button_.push_back(std::make_unique<SimpleButton>(
59 "×", close_button_x, close_button_y, close_button_size, close_button_size));
60 button_.back()->SetActivateFunction([this]() { SetVisible(false); });
61
62 // シリアル通信を開始する.
63 serial_communication_thread_ptr_ =
64 std::make_unique<boost::thread>(
65 &SerialCommunicationThread::Loop, &serial_communication_);
66}
67
69{
70 if (serial_communication_thread_ptr_)
71 {
72 serial_communication_.EndThread();
73
74 serial_communication_thread_ptr_->join();
75 }
76}
77
79{
80 // 各ボタンの処理.
81 for (auto& button : button_)
82 {
83 button->Update();
84 }
85
86 ++counter_;
87
88 if (auto_update_flag_ && counter_ % 120 == 0)
89 {
90 serial_communication_.SetWriteData(GetSerialData());
91 }
92
93 if (!IsInWindow())
94 {
95 SetVisible(false);
96 }
97}
98
100{
101 DrawBackground("RobotControl");
102
103 // 全てのボタンの描画.
104 for (auto& button : button_)
105 {
106 button->Draw();
107 }
108
109 DrawString();
110}
111
112void DxlibGuiRobotControl::DrawString() const
113{
114 const unsigned int str_color = GetColor(54, 54, 54);
115
116 const int text_interval_y = 20;
117 const int text_top_y = gui_top_pos_y_ + 190;
118
119 int text_line = 0;
120
121 // スレッドの状態を出力する.
122 if (serial_communication_.IsEnd())
123 {
124 DrawFormatStringToHandle(gui_left_pos_x_ + 10, text_top_y + text_interval_y * (text_line++), str_color, font_handle_, "スレッドは終了しています.");
125 }
126 else
127 {
128 DrawFormatStringToHandle(gui_left_pos_x_ + 10, text_top_y + text_interval_y * (text_line++), str_color, font_handle_, "スレッドは実行中です.");
129 }
130
131 // 通信されたデータの数を出力する.
132 const std::vector<std::string> read_data = serial_communication_.GetAllReadData();
133 DrawFormatStringToHandle(gui_left_pos_x_ + 10, text_top_y + text_interval_y * (text_line++), str_color, font_handle_, "受信したデータの数: %d", read_data.size());
134
135 // 通信されたデータから,最新のデータを出力する.
136 int display_num = 20;
137
138 for (auto i = read_data.rbegin(); i != read_data.rend(); ++i)
139 {
140 std::string str = "[" + std::to_string(static_cast<int>(read_data.size()) - (10 - display_num)) + "] ";
141 str += *i;
142
143 DrawFormatStringToHandle(gui_left_pos_x_ + 10, text_top_y + text_interval_y * (text_line++), str_color, font_handle_, "%s", str.c_str());
144
145 if (--display_num <= 0)
146 {
147 break;
148 }
149 }
150}
151
152bool DxlibGuiRobotControl::IsInWindow() const
153{
154 return gui_left_pos_x_ < window_x_ && gui_top_pos_y_ < window_y_ &&
155 0 < gui_left_pos_x_ + kWidth && 0 < gui_top_pos_y_ + kHeight;
156}
157
158std::string DxlibGuiRobotControl::GetSerialData() const
159{
160 // ノードの値から,脚先座標をシリアル通信で送信する.
161 // float を int に変換したのち,
162 // 64 byte に収まるように,int_8型 * 2 に変換する.
163 std::uint8_t send_data[64] = {};
164
165 for (size_t i = 0; i < HexapodConst::kLegNum; i++)
166 {
167 const std::uint32_t leg_x = abs(static_cast<int>(node_.leg_pos[i].x));
168
169 send_data[i * 8 + 0] = static_cast<std::uint8_t>(leg_x & 0x000000ff);
170 send_data[i * 8 + 1] = static_cast<std::uint8_t>((leg_x & 0x0000ff00) >> 8);
171
172 const std::uint32_t leg_y = abs(static_cast<int>(node_.leg_pos[i].y));
173
174 send_data[i * 8 + 2] = static_cast<std::uint8_t>(leg_y & 0x000000ff);
175 send_data[i * 8 + 3] = static_cast<std::uint8_t>((leg_y & 0x0000ff00) >> 8);
176
177 // zに補正をかける.
178 float leg_z_pos = node_.leg_pos[i].z;
179 if (-30 >= leg_z_pos && leg_z_pos >= -45) { leg_z_pos = -45; }
180 const std::uint32_t leg_z = abs(static_cast<int>(leg_z_pos));
181
182 send_data[i * 8 + 4] = static_cast<std::uint8_t>(leg_z & 0x000000ff);
183 send_data[i * 8 + 5] = static_cast<std::uint8_t>((leg_z & 0x0000ff00) >> 8);
184 }
185
186 // 正負のデータを送信する.
187 for (size_t i = 0; i < HexapodConst::kLegNum; i++)
188 {
189 const int already_sent_data_num = HexapodConst::kLegNum * 8;
190
191 send_data[already_sent_data_num + i] = 0;
192
193 if (node_.leg_pos[i].x < 0)
194 {
195 send_data[already_sent_data_num + i] |= 0x01;
196 }
197
198 if (node_.leg_pos[i].y < 0)
199 {
200 send_data[already_sent_data_num + i] |= 0x02;
201 }
202
203 if (node_.leg_pos[i].z < 0)
204 {
205 send_data[already_sent_data_num + i] |= 0x04;
206 }
207 }
208
209 // 送信データを文字列に変換する.
210 std::string str;
211
212 for (size_t i = 0; i < 64; i++)
213 {
214 str += static_cast<char>(send_data[i]);
215 }
216
217 return str;
218}
219
220} // namespace designlab
Dxlibを使ったGUIの抽象クラス.
void DrawBackground(const std::string &str) const
int gui_left_pos_x_
GUIの左端の位置.
int gui_top_pos_y_
GUIの上端の位置.
void SetVisible(bool visible) override
GUIの表示を行うかどうかを設定する.
int font_handle_
フォントハンドル.
std::vector< std::unique_ptr< SimpleButton > > button_
ボタンのリスト.
void Draw() const override
GUIの描画.
void Update() override
GUIの更新,毎フレーム実行すること.
DxlibGuiRobotControl()=delete
デフォルトコンストラクタは生成できない.
static constexpr int kLegNum
void SetWriteData(const std::string &str)
指定した文字列をシリアル通信で送信する. この時,排他制御を行う.
void EndThread()
シリアル通信のスレッドを終了する.
std::vector< std::string > GetAllReadData() const
シリアル通信で受信した文字列を全て取得する. この時,排他制御を行う.
std::array< Vector3, HexapodConst::kLegNum > leg_pos
[4 * 3 * 6 = 72 byte] 脚先の座標.(coxa(脚の付け根)を原点とする)