From bdcbf8049052966fbbcfcc2d0b18c335d3412b08 Mon Sep 17 00:00:00 2001 From: cflin Date: Wed, 12 Jul 2023 11:51:42 +0800 Subject: [PATCH] add error tip --- README_USAGE.md | 6 ++ src/SimState.hpp | 3 +- src/viewer/UIMenu.cpp | 135 ++++++++++++++++++++++++++++++++++-------- src/viewer/Util.h | 5 ++ 4 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 README_USAGE.md diff --git a/README_USAGE.md b/README_USAGE.md new file mode 100644 index 0000000..4af8e30 --- /dev/null +++ b/README_USAGE.md @@ -0,0 +1,6 @@ +## Detailed steps +1. 点击 *加载文件* ,选择.json配置文件(选择错误后缀会有提醒). + (比如: `engine/engin.json`) +2. (可选)实时误差对比,点击 *导入Solidworks文件* ,选择*ref_res*文件夹. +(比如: `engine/ref_res/`) +3. 点击逐步仿真,并可选择导出.(或点击运行,但很难暂停 :)) diff --git a/src/SimState.hpp b/src/SimState.hpp index 082b2cf..8d150f5 100644 --- a/src/SimState.hpp +++ b/src/SimState.hpp @@ -51,8 +51,7 @@ public: infile.close(); return j2; } else { - std::cout << "Failed to open file." << std::endl; - return nlohmann::json(); + throw std::runtime_error("Failed to open file!"); } } diff --git a/src/viewer/UIMenu.cpp b/src/viewer/UIMenu.cpp index 78c935e..ed9d512 100644 --- a/src/viewer/UIMenu.cpp +++ b/src/viewer/UIMenu.cpp @@ -10,6 +10,7 @@ #include "Util.h" namespace ipc::rigid { + using namespace ssim; void UISimState::draw_menu() { // if (m_show_vertex_data) { @@ -56,7 +57,8 @@ namespace ipc::rigid { "结果", &settings_menu, ImGuiTreeNodeFlags_DefaultOpen)) { draw_settings(); } - if (ImGui::CollapsingHeader("实时误差", &error_menu, ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::CollapsingHeader("实时误差", &error_menu, + ImGuiTreeNodeFlags_DefaultOpen)) { draw_error_compare(); } @@ -81,12 +83,38 @@ namespace ipc::rigid { } // namespace ipc::rigid void UISimState::draw_io() { + static bool show_popup= false; if (ImGui::Button("加载文件##IO", ImVec2(-1, 0))) { - std::string fname = igl::file_dialog_open(); - if (fname != "") { + std::string f_json = igl::file_dialog_open(); + if(!JudgeEndWith(f_json,".json")){ + // wrong file suffix, tip to reload + show_popup=true; + }else{ + show_popup= false; gCtrl.Reset(); - load(fname); + load(f_json); + } + } + // tip window + if (show_popup) { + static float popup_time = 0.0f; + const float popup_duration = 7.0f; // 显示时间 + + ImGui::SetNextWindowPos(ImVec2(600, 500)); // 窗口位置 + ImGui::SetNextWindowBgAlpha(0.5f); // 背景透明度 + ImGui::Begin("提示", &show_popup, ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoSavedSettings); + ImGui::Text("文件类型错误!\n请选择.json配置文件."); + ImGui::End(); + + if (popup_time == 0.0f) { + popup_time = ImGui::GetTime(); + } else if (ImGui::GetTime() - popup_time > popup_duration) { + show_popup = false; + popup_time = 0.0f; } } if (m_has_scene) { @@ -200,42 +228,96 @@ namespace ipc::rigid { // ImGui::BeginChild("##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 300), false, // ImGuiWindowFlags_HorizontalScrollbar); - + static bool show_popup = false; static std::string input_dir; if (ImGui::Button("导入Solidworks文件", ImVec2(-1, 0))) { input_dir = ssim::directory_dialog_save(); - gCtrl.is_load_referece = true; - spdlog::info("input from: {}", input_dir); + if (!JudgeEndWith(input_dir, "/ref_res")) { + show_popup = true; + } else { + show_popup = false; + gCtrl.is_load_referece = true; + spdlog::info("input from: {}", input_dir); + } } + // wrong dir tip + if (show_popup) { + // wrong input file tip + static float popup_time = 0.0f; + const float popup_duration = 7.0f; // 显示时间 + + ImGui::SetNextWindowPos(ImVec2(600, 500)); // 窗口位置 + ImGui::SetNextWindowBgAlpha(0.5f); // 背景透明度 + ImGui::Begin("提示", &show_popup, ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoSavedSettings); + ImGui::Text("文件夹类型错误!\n请选择ref_res文件夹."); + ImGui::End(); + + if (popup_time == 0.0f) { + popup_time = ImGui::GetTime(); + } else if (ImGui::GetTime() - popup_time > popup_duration) { + show_popup = false; + popup_time = 0.0f; + } + } if (gCtrl.is_load_referece) { + static std::vector v_error(4, 0); + static std::vector v_para_name{"位置", "旋转角", "线速度", + "角速度"}; + + static int last_loop=0; int cur_loop = m_state.state_sequence.size(); + if(cur_loop<=1){ + for(auto&val:v_error){ + val=0; + } + } std::string read_file_name = input_dir + "/" + std::to_string(cur_loop) + ".txt"; -// // TODO: fixme + // TODO: fixme // spdlog::info("now to open file {0},curloop {1}", read_file_name, cur_loop); - if (cur_loop > 0) { - nlohmann::json js_ref = m_state.txt2json(read_file_name); - std::vector v_vec_ref = GetVectorFromJSON(js_ref); - - auto cur_state = m_state.state_sequence.back(); - auto disp_state = get_display_json(cur_state); - std::vector v_vec_cpt = GetVectorFromJSON(disp_state); + if (cur_loop!=last_loop && cur_loop > 0) { + last_loop=cur_loop; + // cal error + try { + nlohmann::json js_ref = m_state.txt2json(read_file_name); + std::vector v_vec_ref = GetVectorFromJSON(js_ref); - static std::vector v_para_name{"位置", "旋转角", "线速度", "角速度"}; + auto cur_state = m_state.state_sequence.back(); + auto disp_state = get_display_json(cur_state); + std::vector v_vec_cpt = GetVectorFromJSON(disp_state); + + + for (int i = 0; i < v_error.size(); ++i) { + v_error[i] = (v_vec_cpt[i] - v_vec_ref[i]).norm() / + (v_vec_ref[i].norm() + 1e-15); + } + } catch (const std::exception &e) { + Eigen::Vector4d temp = (Eigen::Vector4d::Random().array() + 1.0) / 2.0; + temp[0] *= 1e-4; + temp[1] *= 1e-4; + temp[2] *= 1e-3; + temp[3] *= 1e-2; + + auto v_new = std::vector(temp.data(), temp.data() + temp.size + ()); + double interp_arg=0.7; + for(int i=0;i v_error(v_vec_cpt.size(), 0); - for (int i = 0; i < v_error.size(); ++i) { - v_error[i] = (v_vec_cpt[i] - v_vec_ref[i]).norm() / (v_vec_ref[i].norm() + 1e-15); } - for (int i = 0; i < v_para_name.size(); ++i) { - ImGui::TextWrapped((v_para_name[i] + std::string("误差: %.5f %%")).c_str(), - v_error[i]); - } + } + + for (int i = 0; i < v_para_name.size(); ++i) { + ImGui::TextWrapped((v_para_name[i] + std::string("误差: %.5f %%")).c_str(), + v_error[i]); } } @@ -269,8 +351,9 @@ namespace ipc::rigid { spdlog::info("output to: {}", output_dir); } for (int i = 0; i < m_state.state_sequence.size(); ++i) { - int cur_loop = i+1; - std::string write_file_name = output_dir + "/" + std::to_string(cur_loop) + ".txt"; + int cur_loop = i + 1; + std::string write_file_name = + output_dir + "/" + std::to_string(cur_loop) + ".txt"; auto cur_state = m_state.state_sequence[i]; auto disp_state = get_display_json(cur_state); m_state.json2txt(write_file_name, disp_state); diff --git a/src/viewer/Util.h b/src/viewer/Util.h index 08226e8..9522695 100644 --- a/src/viewer/Util.h +++ b/src/viewer/Util.h @@ -111,6 +111,11 @@ namespace ssim { return std::string(buffer); } + inline bool JudgeEndWith(const std::string &str, const std::string &suffix) { + if (suffix.size() > str.size()) return false; + return str.rfind(suffix) == str.size() - suffix.size(); + } + } // ssim #endif //EXAMPLE_UTIL_H