12#include <magic_enum.hpp>
30 const std::shared_ptr<const IHexapodCoordinateConverter>& converter_ptr,
31 const std::shared_ptr<const IHexapodJointCalculator>& calculator_ptr,
32 const std::shared_ptr<const IHexapodPostureValidator>& checker_ptr) :
34 converter_ptr_(converter_ptr),
35 calculator_ptr_(calculator_ptr),
36 checker_ptr_(checker_ptr),
37 display_type_(DisplayMode::kDefualt),
42 const int button_size_x = 90;
43 const int button_size_y = 30;
46 std::make_unique<SimpleButton>(
48 10 + button_size_x / 2,
53 button_.back()->SetActivateFunction(
54 [
this]() {display_type_ = DisplayMode::kDefualt; });
57 std::make_unique<SimpleButton>(
59 (10 + button_size_x / 2) + (10 + button_size_x),
64 button_.back()->SetActivateFunction(
65 [
this]() {display_type_ = DisplayMode::kJointState; });
68 std::make_unique<SimpleButton>(
70 (10 + button_size_x / 2) + (10 + button_size_x) * 2,
75 button_.back()->SetActivateFunction(
76 [
this]() {display_type_ = DisplayMode::kGlobalPos; });
78 const int close_button_size = 28;
80 const int close_button_y =
gui_top_pos_y_ + close_button_size / 2 + 2;
82 button_.push_back(std::make_unique<SimpleButton>(
83 "×", close_button_x, close_button_y,
84 close_button_size, close_button_size));
100 joint_state_ = calculator_ptr_->CalculateAllJointState(display_node_);
123 if (display_type_ == DisplayMode::kDefualt)
127 else if (display_type_ == DisplayMode::kJointState)
131 else if (display_type_ == DisplayMode::kGlobalPos)
143void DxlibGuiNodeDisplayer::DrawNodeInfo()
const
147 const unsigned int text_color = GetColor(10, 10, 10);
148 const unsigned int text_color_dark = GetColor(80, 80, 80);
152 const int text_interval_y = 20;
154 const std::array<std::string, HexapodConst::kLegNum> leg_name = {
155 "右前",
"右中",
"右後",
"左後",
"左中",
"左前" };
159 DrawFormatStringToHandle(
160 text_pos_x, text_pos_y_min + text_interval_y * (text_line++),
162 DrawFormatStringToHandle(
163 text_pos_x, text_pos_y_min + text_interval_y * (text_line++),
165 " bit : %s", display_node_.
leg_state.to_string().c_str());
167 const auto com_pos_name =
168 EnumToStringRemoveTopK(
172 DrawFormatStringToHandle(
173 text_pos_x, text_pos_y_min + text_interval_y * (text_line++),
175 " 重心 : %s(%d)", com_pos_name.c_str(), com_pos_num);
177 std::string str_leg_pos_right =
"";
178 std::string str_leg_pos_left =
"";
179 std::string str_ground =
"";
197 str_leg_pos_right += std::format(
201 static_cast<int>(pos));
205 str_leg_pos_left += std::format(
209 static_cast<int>(pos));
212 DrawFormatStringToHandle(
214 text_pos_y_min + text_interval_y * (text_line++),
216 " 脚位置 : ", str_leg_pos_right.c_str());
218 DrawFormatStringToHandle(
220 text_pos_y_min + text_interval_y * (text_line++),
222 " %s", str_leg_pos_right.c_str());
224 DrawFormatStringToHandle(
225 text_pos_x, text_pos_y_min + text_interval_y * (text_line++),
227 " %s", str_leg_pos_left.c_str());
229 DrawFormatStringToHandle(
230 text_pos_x, text_pos_y_min + text_interval_y * (text_line++),
232 " 脚の状態:%s", str_ground.c_str());
236 DrawFormatStringToHandle(
238 text_pos_y_min + text_interval_y * (text_line++),
242 DrawFormatStringToHandle(
244 text_pos_y_min + text_interval_y * (text_line++),
249 DrawFormatStringToHandle(
251 text_pos_y_min + text_interval_y * (text_line++),
253 "回転 (w:%5.3f,x:%5.3f,y:%5.3f,z:%5.3f)",
262 DrawFormatStringToHandle(
264 text_pos_y_min + text_interval_y * (text_line++),
266 " オイラー角(x:%5.3f[deg],y:%5.3f[deg],z:%5.3f[deg])",
273 DrawFormatStringToHandle(
275 text_pos_y_min + text_interval_y * (text_line++),
281 DrawFormatStringToHandle(
283 text_pos_y_min + text_interval_y * (text_line++),
287 display_node_.
leg_pos[i].ToString().c_str());
295 DrawFormatStringToHandle(
297 text_pos_y_min + text_interval_y * (text_line++),
299 " %s脚の基準座標は現在の脚位置と同じです.", leg_name[i].c_str());
303 DrawFormatStringToHandle(
305 text_pos_y_min + text_interval_y * (text_line++),
307 " %s脚の基準座標(x:%5.3f,y:%5.3f,z:%5.3f)",
318 DrawFormatStringToHandle(
320 text_pos_y_min + text_interval_y * (text_line++),
326 DrawFormatStringToHandle(
328 text_pos_y_min + text_interval_y * (text_line++),
330 "指定がなければ単位は長さが[mm],角度が[rad]");
333void DxlibGuiNodeDisplayer::DrawJointInfo()
const
338 const unsigned int text_color = GetColor(10, 10, 10);
339 const unsigned int error_text_color = GetColor(128, 10, 10);
342 const int text_interval_y = 20;
344 if (!calculator_ptr_)
346 DrawFormatStringToHandle(
348 text_pos_y_min + text_interval_y * 0,
351 "計算クラスが nullptr です");
356 DrawFormatStringToHandle(
358 text_pos_y_min + text_interval_y * 0,
361 "チェッカークラスが nullptr です");
367 if (joint_state_[i].joint_angle.size() != 3)
369 DrawFormatStringToHandle(
371 text_pos_y_min + text_interval_y * 0,
374 "間接の計算ができていない,またはされていません.");
378 if (joint_state_[i].joint_pos_leg_coordinate.size() != 4)
380 DrawFormatStringToHandle(
382 text_pos_y_min + text_interval_y * 0,
385 "間接の計算ができていない,またはされていません.");
396 const float coxa_angle_deg =
398 const float femur_angle_deg =
400 const float tibia_angle_deg =
403 DrawFormatStringToHandle(
405 text_pos_y_min + text_interval_y * (text_line++),
408 "[%d] c %s[deg],f %s[deg],t %s[deg]",
414 const auto coxa_to_femur = joint_state_[i].joint_pos_leg_coordinate[0] -
415 joint_state_[i].joint_pos_leg_coordinate[1];
416 const auto femur_to_tibia = joint_state_[i].joint_pos_leg_coordinate[1] -
417 joint_state_[i].joint_pos_leg_coordinate[2];
418 const auto tibia_to_end = joint_state_[i].joint_pos_leg_coordinate[2] -
419 joint_state_[i].joint_pos_leg_coordinate[3];
421 DrawFormatStringToHandle(
423 text_pos_y_min + text_interval_y * (text_line++),
426 " c %3.3f[mm],f %3.3f[mm],t %3.3f[mm]",
427 coxa_to_femur.GetLength(),
428 femur_to_tibia.GetLength(),
429 tibia_to_end.GetLength());
432 if (checker_ptr_->IsLegInRange(
433 i, joint_state_[i].joint_pos_leg_coordinate[3]))
435 DrawFormatStringToHandle(
437 text_pos_y_min + text_interval_y * (text_line++),
440 " 近似値された可動域内にあります.");
444 DrawFormatStringToHandle(
446 text_pos_y_min + text_interval_y * (text_line++),
453 std::string str =
"";
455 const float coxa_min_angle =
458 const float coxa_max_angle =
462 if (joint_state_[i].joint_angle[0] < coxa_min_angle)
467 if (joint_state_[i].joint_angle[0] > coxa_max_angle)
492 if (!joint_state_[i].is_in_range)
494 str +=
"脚先が届いていません ";
499 const size_t max_str_size = 30;
500 if (str.size() > max_str_size) { str = str.substr(0, max_str_size); }
502 DrawFormatStringToHandle(
504 text_pos_y_min + text_interval_y * (text_line++),
507 " 実際の可動域の外です. %s", str.c_str());
511 DrawFormatStringToHandle(
513 text_pos_y_min + text_interval_y * (text_line++),
521void DxlibGuiNodeDisplayer::DrawGlobalPosInfo()
const
523 const unsigned int text_color = GetColor(10, 10, 10);
526 const int text_interval_y = 20;
527 const std::array<std::string, HexapodConst::kLegNum> leg_name = {
528 "右前",
"右中",
"右後",
"左後",
"左中",
"左前" };
532 DrawFormatStringToHandle(text_pos_x,
533 text_pos_y_min + text_interval_y * (text_line++),
540 DrawFormatStringToHandle(
542 text_pos_y_min + text_interval_y * (text_line++),
547 display_node_.
leg_pos[i].ToString().c_str());
552 DrawFormatStringToHandle(text_pos_x,
553 text_pos_y_min + text_interval_y * (text_line++),
560 const std::string str =
561 converter_ptr_->ConvertLegToRobotCoordinate(
562 display_node_.
leg_pos[i], i).ToString();
564 DrawFormatStringToHandle(
566 text_pos_y_min + text_interval_y * (text_line++),
569 "%s %s", leg_name[i].c_str(), str.c_str());
573 DrawFormatStringToHandle(text_pos_x,
574 text_pos_y_min + text_interval_y * (text_line++),
579 DrawFormatStringToHandle(
581 text_pos_y_min + text_interval_y * (text_line++),
591 DrawFormatStringToHandle(
593 text_pos_y_min + text_interval_y * (text_line++),
598 converter_ptr_->ConvertLegToGlobalCoordinate(
603 true).ToString().c_str());
611 DrawFormatStringToHandle(
612 text_pos_x +
width_ / 2 * (i % 2),
613 text_pos_y_min + text_interval_y * text_line,
618 display_node_.
leg_pos[i].ProjectedXY().GetLength());
620 if (i % 2 == 1) { ++text_line; }
624bool DxlibGuiNodeDisplayer::IsInWindow()
const
void DrawBackground(const std::string &str) const
int gui_left_pos_x_
GUIの左端の位置.
static constexpr int kTitleBarHeight
タイトルバーの高さ.
int gui_top_pos_y_
GUIの上端の位置.
void SetVisible(bool visible) override
GUIの表示を行うかどうかを設定する.
int font_handle_
フォントハンドル.
std::vector< std::unique_ptr< SimpleButton > > button_
ボタンのリスト.
void SetNode(const RobotStateNode &node) override
ノードをセットする.
void Draw() const override
GUIの描画.
DxlibGuiNodeDisplayer(int window_x, int window_y, const std::shared_ptr< const IHexapodCoordinateConverter > &converter_ptr, const std::shared_ptr< const IHexapodJointCalculator > &calculator_ptr, const std::shared_ptr< const IHexapodPostureValidator > &checker_ptr)
void Update() override
GUIの更新,毎フレーム実行すること.
static constexpr int kLegNum
static constexpr float kTibiaAngleMax
static constexpr float kFemurAngleMin
第2関節の可動範囲の最大値[rad].詳しくは referenceフォルダ参照.
static constexpr float kFemurAngleMax
第2関節の可動範囲の最小値[rad].詳しくは referenceフォルダ参照.
static constexpr float kCoxaAngleMin
第1関節の可動範囲の最大値[rad].詳しくは referenceフォルダ参照.
static constexpr float kTibiaAngleMin
第2関節の可動範囲の最大値[rad].詳しくは referenceフォルダ参照.
static constexpr std::array< float, kPhantomXLegNum > kCoxaDefaultAngle
第1関節の初期角度[rad]
static constexpr float kCoxaAngleMax
第2関節の可動範囲の最小値[rad].詳しくは referenceフォルダ参照.
DiscreteLegPos
離散化された脚位置を表す列挙体. 先行研究では 1~7の int型の数値で表現されているが, 可読性を上げるために列挙体にした. 離散化された脚位置は 3bit (0 ~ 7)の範囲で表現される...
bool IsGrounded(const LegStateBit &leg_state, const int leg_index)
脚番号 leg_index 0 ~ 5 に応じて,その脚が接地しているかを調べる. 脚は右前脚を0番として,時計回りに0,1,2,3,4,5となる.左前足が5番.
enums::DiscreteComPos GetDiscreteComPos(const LegStateBit &leg_state)
現在の脚状態から重心パターンを取得する.
enums::DiscreteLegPos GetDiscreteLegPos(const LegStateBit &leg_state, const int leg_index)
脚状態を取得する.
std::string FloatingPointNumToString(const T num, const int digit=kDigit, const int width=kWidth)
小数を文字列に変換する関数. C++ では C のフォーマットのように %3.3f とかで小数を文字列に変換できないため自作する.
constexpr T ConvertRadToDeg(const T rad) noexcept
角度を [rad]から [deg] に変換する関数.
std::string EnumToStringRemoveTopK(const T &enum_value)
enumを文字列に変換する関数. Google C++ coding style だと enumの要素は 先頭にkをつけてキャメルケースで書くことが推奨されている. 例えば,
EulerXYZ ToEulerXYZ(const RotationMatrix3x3 &rot)
回転角行列からXYZオイラー角への変換.
グラフ構造のためのノード(頂点).旧名 LNODE
std::array< Vector3, HexapodConst::kLegNum > leg_pos
[4 * 3 * 6 = 72 byte] 脚先の座標.(coxa(脚の付け根)を原点とする)
leg_func::LegStateBit leg_state
[4 byte] 脚状態,重心パターンを bitで表す.旧名 leg_con.
Vector3 center_of_mass_global_coord
[4 * 3 = 12byte] グローバル座標系における重心の位置.旧名 GCOM
Quaternion posture
[4 * 4 = 16byte] 姿勢を表すクォータニオン.
std::array< Vector3, HexapodConst::kLegNum > leg_reference_pos
int depth
[4 byte] 自身の深さ.一番上の親が深さ0となる.
std::string ToString() const
このベクトルを文字列にして返す. (x, y, z) の形式,小数点以下3桁まで.