diff --git a/src/handler.cpp b/src/handler.cpp index f5cfd731..7a41b9a3 100644 --- a/src/handler.cpp +++ b/src/handler.cpp @@ -1,228 +1,220 @@ #include "handler.hpp" +#include "../imgui-stdlib/imgui_stdlib.h" +#include "get_from_github.hpp" +#include "popups.hpp" #include -#include #include -#include "popups.hpp" -#include "get_from_github.hpp" -#include "../imgui-stdlib/imgui_stdlib.h" +#include std::vector getDeviceInfos() { - std::vector axisInfos; - std::vector> assignedEgus; - if (sampler.has_value()) { - for (auto const &device : sampler->sampleDevices) { - // TODO replace ADC counts with language variable - std::string egu = device.first->getEgu().value_or("ADC counts"); - auto id = device.first->getId(); - if (id.has_value()) { - Omniscope::Id deviceId = id.value(); - std::string timebase{std::to_string(deviceId.sampleRate)}; - if (captureData.find(deviceId) != captureData.end()) { - auto eguIterator = std::ranges::find( - assignedEgus, egu, - &std::pair::first); - if (eguIterator == assignedEgus.end()) { - if (assignedEgus.size() <= 3) { - ImAxis_ nextYAxis = static_cast( - ImAxis_Y1 + assignedEgus.size()); - assignedEgus.push_back( - std::make_pair(egu, nextYAxis)); - eguIterator = (assignedEgus.end() - 1); - } else { - fmt::print( - "too many Axes added, egu not added: " - "{}\nDevice id: {}", - egu, id.value()); - break; - } - } - AxisInfo axisInfo{ - std::make_pair(deviceId, - std::ref(captureData[deviceId])), - *eguIterator, timebase}; - axisInfos.push_back(axisInfo); - } + std::vector axisInfos; + std::vector> assignedEgus; + if (sampler.has_value()) { + for (auto const &device : sampler->sampleDevices) { + // TODO replace ADC counts with language variable + std::string egu = device.first->getEgu().value_or("ADC counts"); + auto id = device.first->getId(); + if (id.has_value()) { + Omniscope::Id deviceId = id.value(); + std::string timebase{std::to_string(deviceId.sampleRate)}; + if (captureData.find(deviceId) != captureData.end()) { + auto eguIterator = std::ranges::find( + assignedEgus, egu, &std::pair::first); + if (eguIterator == assignedEgus.end()) { + if (assignedEgus.size() <= 3) { + ImAxis_ nextYAxis = + static_cast(ImAxis_Y1 + assignedEgus.size()); + assignedEgus.push_back(std::make_pair(egu, nextYAxis)); + eguIterator = (assignedEgus.end() - 1); } else { - fmt::print("Error no device id found\n"); + fmt::print("too many Axes added, egu not added: " + "{}\nDevice id: {}", + egu, id.value()); + break; } + } + AxisInfo axisInfo{ + std::make_pair(deviceId, std::ref(captureData[deviceId])), + *eguIterator, timebase}; + axisInfos.push_back(axisInfo); } + } else { + fmt::print("Error no device id found\n"); + } } - return axisInfos; + } + return axisInfos; } -void addPlots(const char *name, bool const flagPaused, +void addPlots(const char *name, std::function axesSetup) { - static std::set firstRun; - auto const plotRegion = ImGui::GetContentRegionAvail(); - static int activeAxes{0}; - //TODO search devices must work aswell - if (plotAxes.size() <= activeAxes) { - plotAxes = getDeviceInfos(); - activeAxes = plotAxes.size(); + static std::set firstRun; + auto const plotRegion = ImGui::GetContentRegionAvail(); + static int activeAxes{0}; + // TODO search devices must work aswell + if (plotAxes.size() <= activeAxes) { + plotAxes = getDeviceInfos(); + activeAxes = plotAxes.size(); + } + if (ImPlot::BeginPlot(name, plotRegion, ImPlotFlags_NoFrame)) { + double x_min = std::numeric_limits::max(); + double x_max = std::numeric_limits::min(); + for (auto const &axes : plotAxes) { + // fmt::print("data size:{}, egu: {}\n", axes.data.second.size(), + // axes.egu.first); + if (!axes.data.second.empty()) { + x_max = std::max(x_max, axes.data.second.back().first); + // TODO save max and min value over same axis + auto [min, max] = std::minmax_element(axes.data.second.begin(), + axes.data.second.end()); + double yMin = min->first + (min->first * 0.15); + double yMax = max->second + (max->second * 0.15); + // fmt::print("yMin {}, yMax{}\n", yMin, yMax); + axesSetup(x_max, axes.egu.first, axes.egu.second, yMin, yMax); + } } - if (ImPlot::BeginPlot(name, plotRegion, ImPlotFlags_NoFrame)) { - double x_min = std::numeric_limits::max(); - double x_max = std::numeric_limits::min(); - for (auto const &axes : plotAxes) { - // fmt::print("data size:{}, egu: {}\n", axes.data.second.size(), - // axes.egu.first); - if (!axes.data.second.empty()) { - x_max = std::max(x_max, axes.data.second.back().first); - //TODO save max and min value over same axis - auto [min, max] = std::minmax_element(axes.data.second.begin(), - axes.data.second.end()); - double yMin = min->first + (min->first * 0.15); - double yMax = max->second + (max->second * 0.15); - // fmt::print("yMin {}, yMax{}\n", yMin, yMax); - axesSetup(x_max, axes.egu.first, axes.egu.second, yMin, yMax); - } - } + auto const limits = [&]() { + if (!firstRun.contains(name)) { + firstRun.insert(name); + return ImPlotRect(x_min, x_max, 0, 0); + } + return ImPlot::GetPlotLimits(); + }(); - auto const limits = [&]() { - if (!firstRun.contains(name)) { - firstRun.insert(name); - return ImPlotRect(x_min, x_max, 0, 0); - } - return ImPlot::GetPlotLimits(); + auto addPlot = [&](auto const &plot, ImAxis_ yAxis) { + if (!plot.second.empty()) { + auto const start = [&]() { + auto p = std::lower_bound(plot.second.begin(), plot.second.end(), + std::pair{limits.X.Min, 0}); + if (p != plot.second.begin()) + return p - 1; + return p; }(); - auto addPlot = [&](auto const &plot, ImAxis_ yAxis) { - if (!plot.second.empty()) { - auto const start = [&]() { - auto p = std::lower_bound( - plot.second.begin(), plot.second.end(), - std::pair{limits.X.Min, 0}); - if (p != plot.second.begin()) return p - 1; - return p; - }(); - - auto const end = [&]() { - auto p = std::upper_bound( - start, plot.second.end(), - std::pair{limits.X.Max, 0}); - if (p != plot.second.end()) return p + 1; - return p; - }(); - - std::size_t const stride = [&]() -> std::size_t { - auto const s = - std::distance(start, end) / (plotRegion.x * 2.0); - if (1 >= s) return 1; - return static_cast(s); - }(); + auto const end = [&]() { + auto p = std::upper_bound(start, plot.second.end(), + std::pair{limits.X.Max, 0}); + if (p != plot.second.end()) + return p + 1; + return p; + }(); - // determine which axes is the right one to choose - ImPlot::SetAxes(ImAxis_X1, yAxis); - ImPlot::PlotLine( - fmt::format("{}-{}", plot.first.type, plot.first.serial) - .c_str(), - std::addressof(start->first), std::addressof(start->second), - static_cast(std::distance(start, end)) / - stride, - 0, 0, 2 * sizeof(double) * stride); - } - }; - for (int count = 0; auto const &plot : plotAxes) { - ImPlot::SetNextLineStyle(ImVec4{ - colorMap[plot.data.first][0], colorMap[plot.data.first][1], - colorMap[plot.data.first][2], 1.0f}); - addPlot(plot.data, plot.egu.second); - } + std::size_t const stride = [&]() -> std::size_t { + auto const s = std::distance(start, end) / (plotRegion.x * 2.0); + if (1 >= s) + return 1; + return static_cast(s); + }(); - ImPlot::EndPlot(); + // determine which axes is the right one to choose + ImPlot::SetAxes(ImAxis_X1, yAxis); + ImPlot::PlotLine( + fmt::format("{}-{}", plot.first.type, plot.first.serial).c_str(), + std::addressof(start->first), std::addressof(start->second), + static_cast(std::distance(start, end)) / stride, 0, 0, + 2 * sizeof(double) * stride); + } + }; + for (int count = 0; auto const &plot : plotAxes) { + ImPlot::SetNextLineStyle(ImVec4{colorMap[plot.data.first][0], + colorMap[plot.data.first][1], + colorMap[plot.data.first][2], 1.0f}); + addPlot(plot.data, plot.egu.second); } + + ImPlot::EndPlot(); + } } void parseDeviceMetaData(Omniscope::MetaData metaData, std::shared_ptr &device) { - try { - nlohmann::json metaJson = nlohmann::json::parse(metaData.data); - fmt::print("{}\n", metaJson.dump()); - device->setScale(std::stod(metaJson["scale"].dump())); - device->setOffset(std::stod(metaJson["offset"].dump())); - device->setEgu(metaJson["egu"]); - } catch (...) { - fmt::print("parsing Meta Data error: {}", metaData.data); - } + try { + nlohmann::json metaJson = nlohmann::json::parse(metaData.data); + fmt::print("{}\n", metaJson.dump()); + device->setScale(std::stod(metaJson["scale"].dump())); + device->setOffset(std::stod(metaJson["offset"].dump())); + device->setEgu(metaJson["egu"]); + } catch (...) { + fmt::print("parsing Meta Data error: {}", metaData.data); + } } void initDevices() { - constexpr int VID = 0x2e8au; - constexpr int PID = 0x000au; + constexpr int VID = 0x2e8au; + constexpr int PID = 0x000au; - devices = deviceManager.getDevices(VID, PID); - for (auto &device : devices) { - auto metaDataCb = [&](auto const &msg) { - if (std::holds_alternative(msg)) { - parseDeviceMetaData(std::get(msg), device); - } - }; - auto id = device->getId().value(); - auto sampleRate = static_cast(id.sampleRate); - device->setTimeScale(static_cast(1 / sampleRate)); - if (!colorMap.contains(id)) { - ImPlot::PushColormap(ImPlotColormap_Dark); - auto c = ImPlot::GetColormapColor((colorMap.size() % 7) + 1); - colorMap[id] = std::array{c.x, c.y, c.z}; - ImPlot::PopColormap(); - } - auto &color = colorMap[id]; - device->send( - Omniscope::SetRgb{static_cast(color[0] * 255), - static_cast(color[1] * 255), - static_cast(color[2] * 255)}); - // set Callback for MetaData - device->setMessageCallback(metaDataCb); - device->send(Omniscope::GetMetaData{}); + devices = deviceManager.getDevices(VID, PID); + for (auto &device : devices) { + auto metaDataCb = [&](auto const &msg) { + if (std::holds_alternative(msg)) { + parseDeviceMetaData(std::get(msg), device); + } + }; + auto id = device->getId().value(); + auto sampleRate = static_cast(id.sampleRate); + device->setTimeScale(static_cast(1 / sampleRate)); + if (!colorMap.contains(id)) { + ImPlot::PushColormap(ImPlotColormap_Dark); + auto c = ImPlot::GetColormapColor((colorMap.size() % 7) + 1); + colorMap[id] = std::array{c.x, c.y, c.z}; + ImPlot::PopColormap(); } + auto &color = colorMap[id]; + device->send(Omniscope::SetRgb{static_cast(color[0] * 255), + static_cast(color[1] * 255), + static_cast(color[2] * 255)}); + // set Callback for MetaData + device->setMessageCallback(metaDataCb); + device->send(Omniscope::GetMetaData{}); + } } void devicesList(bool const &flagPaused) { - auto doDevice = [&](auto &device, auto msg) { - auto &color = colorMap[device->getId().value()]; - if (ImGui::ColorEdit3( - fmt::format("{:<32}", - fmt::format("{}-{}", device->getId().value().type, - device->getId().value().serial)) - .c_str(), - color.data(), - ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoPicker | - ImGuiColorEditFlags_NoTooltip)) { - device->send( - Omniscope::SetRgb{static_cast(color[0] * 255), - static_cast(color[1] * 255), - static_cast(color[2] * 255)}); - } - ImGui::SameLine(); - ImGui::TextUnformatted( - fmt::format("HW: v{}.{}.{} SW: v{}.{}.{} ", - device->getId().value().hwVersion.major, - device->getId().value().hwVersion.minor, - device->getId().value().hwVersion.patch, - device->getId().value().swVersion.major, - device->getId().value().swVersion.minor, - device->getId().value().swVersion.patch) - .c_str()); - ImGui::SameLine(); - if (device->isRunning()) - ImGui::TextUnformatted(fmt::format("{}", msg).c_str()); - else - ImGui::TextUnformatted("Error"); - }; - - if (sampler.has_value()) - for (auto &device : sampler->sampleDevices) { - if (!flagPaused) { - doDevice(device.first, appLanguage[Key::Measurement]); - } else { - doDevice(device.first, appLanguage[Key::Stop]); - } - } + auto doDevice = [&](auto &device, auto msg) { + auto &color = colorMap[device->getId().value()]; + if (ImGui::ColorEdit3( + fmt::format("{:<32}", + fmt::format("{}-{}", device->getId().value().type, + device->getId().value().serial)) + .c_str(), + color.data(), + ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoPicker | + ImGuiColorEditFlags_NoTooltip)) { + device->send( + Omniscope::SetRgb{static_cast(color[0] * 255), + static_cast(color[1] * 255), + static_cast(color[2] * 255)}); + } + ImGui::SameLine(); + ImGui::TextUnformatted(fmt::format("HW: v{}.{}.{} SW: v{}.{}.{} ", + device->getId().value().hwVersion.major, + device->getId().value().hwVersion.minor, + device->getId().value().hwVersion.patch, + device->getId().value().swVersion.major, + device->getId().value().swVersion.minor, + device->getId().value().swVersion.patch) + .c_str()); + ImGui::SameLine(); + if (device->isRunning()) + ImGui::TextUnformatted(fmt::format("{}", msg).c_str()); else - for (auto &device : devices) doDevice(device, appLanguage[Key::Ready]); + ImGui::TextUnformatted("Error"); + }; + + if (sampler.has_value()) + for (auto &device : sampler->sampleDevices) { + if (!flagPaused) { + doDevice(device.first, appLanguage[Key::Measurement]); + } else { + doDevice(device.first, appLanguage[Key::Stop]); + } + } + else + for (auto &device : devices) + doDevice(device, appLanguage[Key::Ready]); } void load_files(decltype(captureData) &loadedFiles, diff --git a/src/handler.hpp b/src/handler.hpp index 9d0987d3..3b6d7d02 100644 --- a/src/handler.hpp +++ b/src/handler.hpp @@ -30,7 +30,7 @@ inline std::map>> captureData; inline std::vector plotAxes; -void addPlots(const char *, const bool, std::function); +void addPlots(const char *, std::function); void parseDeviceMetaData(Omniscope::MetaData, std::shared_ptr&); void initDevices(); void devicesList(bool const& flagPaused); diff --git a/src/main.cpp b/src/main.cpp index aee0f868..50d918ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,7 @@ -#include -#include -#include - #include "popups.hpp" #include "settingspopup.hpp" #include "style.hpp" +#include int main() { const std::string configpath = "config/config.json"; @@ -15,21 +12,15 @@ int main() { load_json_file(load_json(config, "languagepath") + load_json(config, "language") + ".json"); // local variables - auto now = std::chrono::system_clock::now(); - std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); - std::tm now_tm = *std::gmtime(&now_time_t); - bool flagPaused{true}; - bool Development{false}, flagInitState{true}, - open_generate_training_data{false}, open_settings{false}; + bool flagPaused{true}, development{false}, open_generate_training_data{false}, + open_settings{false}; + std::once_flag flag; auto loadedFiles = captureData; std::map loadedFilenames; // main loop auto render = [&]() { - if (flagInitState) { - set_inital_config(config); - flagInitState = false; - } + std::call_once(flag, set_inital_config, std::ref(config)); SetupImGuiStyle(false, 0.99f); ImGui::SetNextWindowPos({0.f, 0.f}); auto windowSize{ImGui::GetIO().DisplaySize}; @@ -38,8 +29,8 @@ int main() { ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar); - if (Development && ImGui::Button("Development")) - ImGui::OpenPopup("Development Colors"); + if (development && ImGui::Button("Development")) + ImGui::OpenPopup("Development Colors"); // Popup-Window content if (ImGui::BeginPopup("Development Colors")) { @@ -91,37 +82,37 @@ int main() { // ############################ addPlots("Recording the data", ...) ImGui::Dummy({0.f, windowSize.y * .01f}); PushPlotRegionColors(); - ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, - windowSize.x * .009f); + ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, windowSize.x * .009f); ImGui::BeginChild("Record Data", {0.f, windowSize.y * 0.62f}, - ImGuiChildFlags_Border); - + ImGuiChildFlags_Border); // Axes 1 to 3 // Check if time base for axes are same // check if egu and timescale for plot are same // error if third device is added - addPlots("Recording the data", flagPaused, [&flagPaused](double x_max, std::string yLabel, ImAxis_ axis, double yMin, double yMax) { - ImPlot::SetupLegend(ImPlotLocation_NorthEast | - ImPlotLegendFlags_Outside); - auto auxFlagsMeasuring = - ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_NoGridLines; - auto auxFlagsPaused = ImPlotAxisFlags_NoGridLines; - ImPlot::SetupAxisTicks(ImAxis_Y1, -10, 200, 22, nullptr, true); + addPlots("Recording the data", [&flagPaused]( + double x_max, std::string yLabel, + ImAxis_ axis, double yMin, double yMax) { + ImPlot::SetupLegend(ImPlotLocation_NorthEast | ImPlotLegendFlags_Outside); + // auto auxFlagsMeasuring = + // ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_NoGridLines; + // auto auxFlagsPaused = ImPlotAxisFlags_NoGridLines; + ImPlot::SetupAxisTicks(ImAxis_Y1, -10, 200, 22, nullptr, true); - if(!flagPaused){ - ImPlot::SetupAxis(axis, yLabel.c_str(), ImPlotAxisFlags_AutoFit); - ImPlot::SetupAxis(ImAxis_X1, "time [s]", ImPlotAxisFlags_AutoFit); - ImPlot::SetupAxisLimits(axis, yMin - 2, yMax + 2, ImGuiCond_Always); - ImPlot::SetupAxisLimits(ImAxis_X1, x_max - 1, x_max + 9, ImGuiCond_Always); + if (!flagPaused) { + ImPlot::SetupAxis(axis, yLabel.c_str(), ImPlotAxisFlags_AutoFit); + ImPlot::SetupAxis(ImAxis_X1, "time [s]", ImPlotAxisFlags_AutoFit); + ImPlot::SetupAxisLimits(axis, yMin - 2, yMax + 2, ImGuiCond_Always); + ImPlot::SetupAxisLimits(ImAxis_X1, x_max - 1, x_max + 9, + ImGuiCond_Always); - }else{ - ImPlot::SetupAxis(ImAxis_X1, "time [s]"); - ImPlot::SetupAxis(axis, yLabel.c_str()); - ImPlot::SetupAxisLimits(ImAxis_X1, 0, 10); - ImPlot::SetupAxisLimits(axis, yMin - 2, yMax + 2); - } + } else { + ImPlot::SetupAxis(ImAxis_X1, "time [s]"); + ImPlot::SetupAxis(axis, yLabel.c_str()); + ImPlot::SetupAxisLimits(ImAxis_X1, 0, 10); + ImPlot::SetupAxisLimits(axis, yMin - 2, yMax + 2); + } }); - ImGui::EndChild(); // end child Record Data + ImGui::EndChild(); // end child Record Data ImGui::PopStyleVar(); PopPlotRegionColors(); // ############################ Devicelist diff --git a/src/saves_popup.cpp b/src/saves_popup.cpp index f667a481..751f1d11 100644 --- a/src/saves_popup.cpp +++ b/src/saves_popup.cpp @@ -17,12 +17,17 @@ static void save(const Omniscope::Id &device, device.sampleRate); std::string fileContent; fileContent.resize_and_overwrite( - // four bytes for each y_value, three for the number + // ten bytes for each y_value, nine for the number // and one new line as a separator between the numbers - values.size() * 4, [&values, &y_indx](char *begin, std::size_t) { + values.size() * 10, // take const ref to values + [&values = std::as_const(values), &y_indx](char *begin, std::size_t) { auto end = begin; + constexpr unsigned factor{100'000}; for (; y_indx < values.size(); y_indx++) { - end = std::to_chars(end, end + 3, values[y_indx].second).ptr; + double value = values[y_indx].second * factor; + value = std::floor(value); + value /= factor; + end = std::to_chars(end, end + 9, value).ptr; *end++ = '\n'; } return end - begin; @@ -216,7 +221,7 @@ void saves_popup(nlohmann::json const &config, nlohmann::json const &language, ImGui::Separator(); ImGui::NewLine(); - if (ImGui::Button(appLanguage[Key::Back])) + if (ImGui::Button(appLanguage[Key::Back])) ImGui::CloseCurrentPopup(); ImGui::SameLine(ImGui::GetWindowWidth() * 0.75f); // offset from start x @@ -229,7 +234,7 @@ void saves_popup(nlohmann::json const &config, nlohmann::json const &language, if (ImGui::Button(appLanguage[Key::Save])) { checked_devices_cnt = count_checked_devices(); flagDataNotSaved = false; - future = std::async( // const reference to the container + future = std::async( // const reference to the container std::launch::async, [=, &liveDvcs = std::as_const(liveDvcs)] { for (size_t i{}; const auto &[device, values] : liveDvcs) { // measurement saving preparation if device is checked @@ -254,11 +259,11 @@ void saves_popup(nlohmann::json const &config, nlohmann::json const &language, }); progress = true; } - if (progress) { // check selected devices are saved + if (progress) { // check selected devices are saved if (saved_files_cnt == checked_devices_cnt) { future.get(); progress = false; - inptTxtFields.clear(); // reset storage location(s) + inptTxtFields.clear(); // reset storage location(s) dvcCheckedArr.clear(); // rest check boxes saved_files_cnt = 0; ImGui::CloseCurrentPopup();