完成框架目录和模块重构;新增核心、单例、工具、加密及框架 SDK;统一任务、相机和 RPC 接口,并增加离线检测、相机标定、备份恢复、版本管理、崩溃守护和心跳监控功能。
244 lines
9.2 KiB
C++
244 lines
9.2 KiB
C++
#pragma once
|
|
#pragma execution_character_set("utf-8")
|
|
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <eui_tools/json/generalJsonParsing.h>
|
|
#include <nlohmannJson.hpp>
|
|
|
|
struct viewerStruct {
|
|
std::string name;
|
|
int xPos, yPos, width, height;
|
|
std::vector<std::string>viewers;
|
|
};
|
|
|
|
|
|
struct cameraPixelPrecision {
|
|
double x_precision_mm_Pix; ///< 水平像素精度,单位:毫米/像素
|
|
double y_precision_mm_Pix; ///< 垂直像素精度,单位:毫米/像素
|
|
double z_precision_mm_Pix; ///< Z方向像素精度,单位:毫米/像素
|
|
};
|
|
|
|
|
|
struct SubUiWidgetConfig {
|
|
SubUiWidgetConfig() = default;
|
|
SubUiWidgetConfig(const SubUiWidgetConfig&) = default;
|
|
SubUiWidgetConfig& operator=(const SubUiWidgetConfig&) = default;
|
|
SubUiWidgetConfig(SubUiWidgetConfig&&) = default;
|
|
SubUiWidgetConfig& operator=(SubUiWidgetConfig&&) = default;
|
|
|
|
int height = 0;
|
|
std::string key;
|
|
double limitHigh = 0.0;
|
|
double limitLow = 0.0;
|
|
int maxPoints = 100;
|
|
std::string widgetType;
|
|
int width = 0;
|
|
int x = 0;
|
|
int y = 0;
|
|
nlohmann::ordered_json extra = nlohmann::ordered_json::object();
|
|
};
|
|
|
|
using SubUiPageConfig = std::map<std::string, std::vector<SubUiWidgetConfig>>;
|
|
|
|
class MissionConfig {
|
|
public:
|
|
MissionConfig() = default;
|
|
explicit MissionConfig(const std::string& jsonPath) { loadFromFile(jsonPath); }
|
|
|
|
MissionConfig(const MissionConfig&) = delete;
|
|
MissionConfig& operator=(const MissionConfig&) = delete;
|
|
MissionConfig(MissionConfig&&) = default;
|
|
MissionConfig& operator=(MissionConfig&&) = default;
|
|
|
|
void loadFromFile(const std::string& jsonPath) {
|
|
_jsonPath = jsonPath;
|
|
parseFromJson(readOrderedJsonFromPath(jsonPath));
|
|
}
|
|
|
|
void parseFromJson(const nlohmann::ordered_json& json) {
|
|
_lastSavedJson = nlohmann::ordered_json::object();
|
|
_lastSavedJsonPath.clear();
|
|
_hasLastSavedJson = false;
|
|
_rawJson = json.is_object() ? json : nlohmann::ordered_json::object();
|
|
|
|
if (!json.is_object()) {
|
|
softwareTile.clear();
|
|
backend = nlohmann::ordered_json::object();
|
|
imageViews.clear();
|
|
sublUiSetting.clear();
|
|
return;
|
|
}
|
|
|
|
softwareTile = json.value("softwareTile", "");
|
|
if (softwareTile.empty()) {
|
|
std::cout << "[Warning] softwareTile is empty" << std::endl;
|
|
}
|
|
|
|
backend = json.value("backend", nlohmann::ordered_json::object());
|
|
if (!json.contains("backend")) {
|
|
std::cout << "[Warning] 'backend' node missing from mission config" << std::endl;
|
|
}
|
|
|
|
imageViews.clear();
|
|
if (!json.contains("ImageView")) {
|
|
std::cout << "[Warning] 'ImageView' node missing" << std::endl;
|
|
} else if (json["ImageView"].empty()) {
|
|
std::cout << "[Warning] 'ImageView' node is empty" << std::endl;
|
|
} else {
|
|
for (auto it = json["ImageView"].begin(); it != json["ImageView"].end(); ++it) {
|
|
viewerStruct v{};
|
|
v.name = it.key();
|
|
auto& val = it.value();
|
|
if (!val.contains("xPos")) {
|
|
std::cout << "[Warning] ImageView[" << v.name
|
|
<< "] missing 'xPos'" << std::endl;
|
|
}
|
|
if (!val.contains("yPos")) {
|
|
std::cout << "[Warning] ImageView[" << v.name
|
|
<< "] missing 'yPos'" << std::endl;
|
|
}
|
|
if (!val.contains("viewer")) {
|
|
std::cout << "[Warning] ImageView[" << v.name
|
|
<< "] missing 'viewer' array" << std::endl;
|
|
}
|
|
v.xPos = val.value("xPos", 0);
|
|
v.yPos = val.value("yPos", 0);
|
|
v.width = val.value("width", 0);
|
|
v.height = val.value("height", 0);
|
|
if (val.contains("viewer")) {
|
|
v.viewers.assign(val["viewer"].begin(), val["viewer"].end());
|
|
}
|
|
imageViews.push_back(std::move(v));
|
|
}
|
|
}
|
|
|
|
sublUiSetting.clear();
|
|
if (!json.contains("sublUiSetting")) {
|
|
std::cout << "[Warning] 'sublUiSetting' node missing" << std::endl;
|
|
} else {
|
|
for (auto it = json["sublUiSetting"].begin(); it != json["sublUiSetting"].end(); ++it) {
|
|
std::string pageName = it.key();
|
|
std::vector<SubUiWidgetConfig> widgets;
|
|
for (auto& w : it.value()) {
|
|
SubUiWidgetConfig cfg;
|
|
if (w.is_object()) {
|
|
cfg.extra = w;
|
|
}
|
|
cfg.height = w.value("height", 0);
|
|
cfg.key = w.value("key", "");
|
|
cfg.limitHigh = w.value("limitHigh", 0.0);
|
|
cfg.limitLow = w.value("limitLow", 0.0);
|
|
cfg.maxPoints = w.value("maxPoints", 100);
|
|
cfg.widgetType = w.value("widgetType", "");
|
|
cfg.width = w.value("width", 0);
|
|
cfg.x = w.value("x", 0);
|
|
cfg.y = w.value("y", 0);
|
|
if (cfg.key.empty()) {
|
|
std::cout << "[Warning] sublUiSetting[" << pageName
|
|
<< "] entry missing 'key'" << std::endl;
|
|
}
|
|
if (cfg.widgetType.empty()) {
|
|
std::cout << "[Warning] sublUiSetting[" << pageName
|
|
<< "][" << cfg.key << "] missing 'widgetType'"
|
|
<< std::endl;
|
|
}
|
|
widgets.push_back(std::move(cfg));
|
|
}
|
|
sublUiSetting.emplace(pageName, std::move(widgets));
|
|
}
|
|
}
|
|
}
|
|
|
|
nlohmann::ordered_json toJson() const {
|
|
nlohmann::ordered_json json = _rawJson.is_object()
|
|
? _rawJson
|
|
: nlohmann::ordered_json::object();
|
|
json["softwareTile"] = softwareTile;
|
|
json["backend"] = backend;
|
|
|
|
auto rawImageView = json.value("ImageView", nlohmann::ordered_json::object());
|
|
auto& iv = json["ImageView"] = nlohmann::ordered_json::object();
|
|
for (const auto& v : imageViews) {
|
|
nlohmann::ordered_json item =
|
|
rawImageView.contains(v.name) && rawImageView[v.name].is_object()
|
|
? rawImageView[v.name]
|
|
: nlohmann::ordered_json::object();
|
|
item["xPos"] = v.xPos;
|
|
item["yPos"] = v.yPos;
|
|
item["width"] = v.width;
|
|
item["height"] = v.height;
|
|
item["viewer"] = nlohmann::ordered_json::array();
|
|
for (const auto& viewer : v.viewers) {
|
|
item["viewer"].push_back(viewer);
|
|
}
|
|
iv[v.name] = std::move(item);
|
|
}
|
|
|
|
auto rawSublUiSetting = json.value("sublUiSetting", nlohmann::ordered_json::object());
|
|
auto& subl = json["sublUiSetting"] = nlohmann::ordered_json::object();
|
|
for (const auto& page : sublUiSetting) {
|
|
auto rawPage =
|
|
rawSublUiSetting.contains(page.first) && rawSublUiSetting[page.first].is_array()
|
|
? rawSublUiSetting[page.first]
|
|
: nlohmann::ordered_json::array();
|
|
auto& pageArr = subl[page.first] = nlohmann::ordered_json::array();
|
|
for (size_t idx = 0; idx < page.second.size(); ++idx) {
|
|
const auto& w = page.second[idx];
|
|
nlohmann::ordered_json item =
|
|
idx < rawPage.size() && rawPage[idx].is_object()
|
|
? rawPage[idx]
|
|
: (w.extra.is_object() ? w.extra : nlohmann::ordered_json::object());
|
|
item["height"] = w.height;
|
|
item["key"] = w.key;
|
|
item["limitHigh"] = w.limitHigh;
|
|
item["limitLow"] = w.limitLow;
|
|
item["maxPoints"] = w.maxPoints;
|
|
item["widgetType"] = w.widgetType;
|
|
item["width"] = w.width;
|
|
item["x"] = w.x;
|
|
item["y"] = w.y;
|
|
pageArr.push_back(std::move(item));
|
|
}
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
void saveAsJson(const std::string& jsonPath = "", bool forceSave = true) const {
|
|
auto path = jsonPath.empty() ? _jsonPath : jsonPath;
|
|
if (path.empty()) {
|
|
return;
|
|
}
|
|
|
|
const auto currentJson = toJson();
|
|
if (!forceSave && _hasLastSavedJson && path == _lastSavedJsonPath
|
|
&& currentJson == _lastSavedJson) {
|
|
return;
|
|
}
|
|
|
|
if (!saveOrderedJsonFromPath(path, currentJson)) {
|
|
return;
|
|
}
|
|
|
|
_lastSavedJson = currentJson;
|
|
_lastSavedJsonPath = path;
|
|
_hasLastSavedJson = true;
|
|
}
|
|
|
|
std::vector<viewerStruct> imageViews;
|
|
std::string softwareTile;
|
|
nlohmann::ordered_json backend = nlohmann::ordered_json::object();
|
|
SubUiPageConfig sublUiSetting;
|
|
|
|
private:
|
|
std::string _jsonPath;
|
|
nlohmann::ordered_json _rawJson = nlohmann::ordered_json::object();
|
|
mutable nlohmann::ordered_json _lastSavedJson = nlohmann::ordered_json::object();
|
|
mutable std::string _lastSavedJsonPath;
|
|
mutable bool _hasLastSavedJson = false;
|
|
};
|