2026-07-11 16:02:57 +08:00

332 lines
13 KiB
C++

#include "VrConfig.h"
#include <string>
#include "VrLog.h"
using namespace tinyxml2;
namespace {
const char* RootName()
{
return "ParkingSpaceGuideConfig";
}
void LoadStringAttribute(XMLElement* element, const char* name, std::string& value)
{
if (element && element->Attribute(name)) {
value = element->Attribute(name);
}
}
void LoadMvsCamera(XMLElement* root, MvsCameraConfig& config)
{
XMLElement* element = root->FirstChildElement("MvsCamera");
if (!element) {
XMLElement* oldElement = root->FirstChildElement("HikCamera");
if (oldElement) {
config.enabled = oldElement->BoolAttribute("enabled", config.enabled);
}
return;
}
config.enabled = element->BoolAttribute("enabled", config.enabled);
LoadStringAttribute(element, "serialNumber", config.serialNumber);
config.deviceIndex = element->IntAttribute("deviceIndex", config.deviceIndex);
}
void SaveMvsCamera(XMLDocument& doc, XMLElement* root, const MvsCameraConfig& config)
{
XMLElement* element = doc.NewElement("MvsCamera");
element->SetAttribute("enabled", config.enabled);
element->SetAttribute("serialNumber", config.serialNumber.c_str());
element->SetAttribute("deviceIndex", config.deviceIndex);
root->InsertEndChild(element);
}
void LoadRsLidar(XMLElement* root, RsLidarConfig& config)
{
XMLElement* element = root->FirstChildElement("RsLidar");
if (!element) {
return;
}
LoadStringAttribute(element, "lidarType", config.lidarType);
LoadStringAttribute(element, "hostAddress", config.hostAddress);
LoadStringAttribute(element, "frameId", config.frameId);
config.msopPort = static_cast<unsigned short>(element->UnsignedAttribute("msopPort", config.msopPort));
config.difopPort = static_cast<unsigned short>(element->UnsignedAttribute("difopPort", config.difopPort));
config.imuPort = static_cast<unsigned short>(element->UnsignedAttribute("imuPort", config.imuPort));
config.minDistance = element->FloatAttribute("minDistance", config.minDistance);
config.maxDistance = element->FloatAttribute("maxDistance", config.maxDistance);
config.densePoints = element->BoolAttribute("densePoints", config.densePoints);
config.useLidarClock = element->BoolAttribute("useLidarClock", config.useLidarClock);
config.tsFirstPoint = element->BoolAttribute("tsFirstPoint", config.tsFirstPoint);
config.waitForDifop = element->BoolAttribute("waitForDifop", config.waitForDifop);
config.startAngle = element->FloatAttribute("startAngle", config.startAngle);
config.endAngle = element->FloatAttribute("endAngle", config.endAngle);
config.splitAngle = element->FloatAttribute("splitAngle", config.splitAngle);
config.socketRecvBufBytes = element->UnsignedAttribute("socketRecvBufBytes", config.socketRecvBufBytes);
}
void SaveRsLidar(XMLDocument& doc, XMLElement* root, const RsLidarConfig& config)
{
XMLElement* element = doc.NewElement("RsLidar");
element->SetAttribute("lidarType", config.lidarType.c_str());
element->SetAttribute("hostAddress", config.hostAddress.c_str());
element->SetAttribute("msopPort", config.msopPort);
element->SetAttribute("difopPort", config.difopPort);
element->SetAttribute("imuPort", config.imuPort);
element->SetAttribute("minDistance", config.minDistance);
element->SetAttribute("maxDistance", config.maxDistance);
element->SetAttribute("densePoints", config.densePoints);
element->SetAttribute("useLidarClock", config.useLidarClock);
element->SetAttribute("tsFirstPoint", config.tsFirstPoint);
element->SetAttribute("waitForDifop", config.waitForDifop);
element->SetAttribute("startAngle", config.startAngle);
element->SetAttribute("endAngle", config.endAngle);
element->SetAttribute("splitAngle", config.splitAngle);
element->SetAttribute("frameId", config.frameId.c_str());
element->SetAttribute("socketRecvBufBytes", config.socketRecvBufBytes);
root->InsertEndChild(element);
}
void LoadLedDisplay(XMLElement* root, LedDisplayConfig& config)
{
XMLElement* element = root->FirstChildElement("LedDisplay");
if (!element) {
return;
}
LoadStringAttribute(element, "ip", config.ip);
config.port = element->IntAttribute("port", config.port);
config.slaveId = element->IntAttribute("slaveId", config.slaveId);
config.startAddress = element->IntAttribute("startAddress", config.startAddress);
config.timeoutMs = element->IntAttribute("timeoutMs", config.timeoutMs);
config.enabled = element->BoolAttribute("enabled", config.enabled);
config.controllerType = element->IntAttribute("controllerType", config.controllerType);
config.areaX = element->IntAttribute("areaX", config.areaX);
config.areaY = element->IntAttribute("areaY", config.areaY);
config.areaWidth = element->IntAttribute("areaWidth", config.areaWidth);
config.areaHeight = element->IntAttribute("areaHeight", config.areaHeight);
config.dynamicTimeoutSec = element->IntAttribute("dynamicTimeoutSec", config.dynamicTimeoutSec);
config.displayMode = element->IntAttribute("displayMode", config.displayMode);
config.speed = element->IntAttribute("speed", config.speed);
config.stayTime = element->IntAttribute("stayTime", config.stayTime);
}
void SaveLedDisplay(XMLDocument& doc, XMLElement* root, const LedDisplayConfig& config)
{
XMLElement* element = doc.NewElement("LedDisplay");
element->SetAttribute("ip", config.ip.c_str());
element->SetAttribute("port", config.port);
element->SetAttribute("slaveId", config.slaveId);
element->SetAttribute("startAddress", config.startAddress);
element->SetAttribute("timeoutMs", config.timeoutMs);
element->SetAttribute("enabled", config.enabled);
element->SetAttribute("controllerType", config.controllerType);
element->SetAttribute("areaX", config.areaX);
element->SetAttribute("areaY", config.areaY);
element->SetAttribute("areaWidth", config.areaWidth);
element->SetAttribute("areaHeight", config.areaHeight);
element->SetAttribute("dynamicTimeoutSec", config.dynamicTimeoutSec);
element->SetAttribute("displayMode", config.displayMode);
element->SetAttribute("speed", config.speed);
element->SetAttribute("stayTime", config.stayTime);
root->InsertEndChild(element);
}
void LoadUdpBroadcast(XMLElement* root, UdpBroadcastConfig& config)
{
XMLElement* element = root->FirstChildElement("UdpBroadcast");
if (!element) {
return;
}
config.enabled = element->BoolAttribute("enabled", config.enabled);
LoadStringAttribute(element, "address", config.address);
config.port = element->IntAttribute("port", config.port);
LoadStringAttribute(element, "targetId", config.targetId);
LoadStringAttribute(element, "parkId", config.parkId);
}
void SaveUdpBroadcast(XMLDocument& doc, XMLElement* root, const UdpBroadcastConfig& config)
{
XMLElement* element = doc.NewElement("UdpBroadcast");
element->SetAttribute("enabled", config.enabled);
element->SetAttribute("address", config.address.c_str());
element->SetAttribute("port", config.port);
element->SetAttribute("targetId", config.targetId.c_str());
element->SetAttribute("parkId", config.parkId.c_str());
root->InsertEndChild(element);
}
void LoadHttpServer(XMLElement* root, HttpServerConfig& config)
{
XMLElement* element = root->FirstChildElement("HttpServer");
if (!element) {
return;
}
config.enabled = element->BoolAttribute("enabled", config.enabled);
LoadStringAttribute(element, "address", config.address);
config.port = element->IntAttribute("port", config.port);
config.maxQueued = element->IntAttribute("maxQueued", config.maxQueued);
config.maxThreads = element->IntAttribute("maxThreads", config.maxThreads);
}
void SaveHttpServer(XMLDocument& doc, XMLElement* root, const HttpServerConfig& config)
{
XMLElement* element = doc.NewElement("HttpServer");
element->SetAttribute("enabled", config.enabled);
element->SetAttribute("address", config.address.c_str());
element->SetAttribute("port", config.port);
element->SetAttribute("maxQueued", config.maxQueued);
element->SetAttribute("maxThreads", config.maxThreads);
root->InsertEndChild(element);
}
void LoadAlgorithmParams(XMLElement* root, VrAlgorithmParams& params)
{
XMLElement* algo = root->FirstChildElement("AlgorithmParams");
if (!algo) {
return;
}
XMLElement* guide = algo->FirstChildElement("ParkingSpaceGuideParam");
if (!guide) {
return;
}
VrParkingSpaceGuideParam& p = params.guideParam;
p.minGuideDistance = guide->DoubleAttribute("minGuideDistance", p.minGuideDistance);
p.maxGuideDistance = guide->DoubleAttribute("maxGuideDistance", p.maxGuideDistance);
p.targetStopOffset = guide->DoubleAttribute("targetStopOffset", p.targetStopOffset);
p.lateralTolerance = guide->DoubleAttribute("lateralTolerance", p.lateralTolerance);
p.angleTolerance = guide->DoubleAttribute("angleTolerance", p.angleTolerance);
p.confidenceThreshold = guide->DoubleAttribute("confidenceThreshold", p.confidenceThreshold);
}
void SaveAlgorithmParams(XMLDocument& doc, XMLElement* root, const VrAlgorithmParams& params)
{
XMLElement* algo = doc.NewElement("AlgorithmParams");
root->InsertEndChild(algo);
const VrParkingSpaceGuideParam& p = params.guideParam;
XMLElement* guide = doc.NewElement("ParkingSpaceGuideParam");
guide->SetAttribute("minGuideDistance", p.minGuideDistance);
guide->SetAttribute("maxGuideDistance", p.maxGuideDistance);
guide->SetAttribute("targetStopOffset", p.targetStopOffset);
guide->SetAttribute("lateralTolerance", p.lateralTolerance);
guide->SetAttribute("angleTolerance", p.angleTolerance);
guide->SetAttribute("confidenceThreshold", p.confidenceThreshold);
algo->InsertEndChild(guide);
}
void LoadDebugParam(XMLElement* root, VrDebugParam& param)
{
XMLElement* element = root->FirstChildElement("DebugParam");
if (!element) {
return;
}
param.enableDebug = element->BoolAttribute("enableDebug", param.enableDebug);
param.savePointCloud = element->BoolAttribute("savePointCloud", param.savePointCloud);
param.saveDebugImage = element->BoolAttribute("saveDebugImage", param.saveDebugImage);
param.printDetailLog = element->BoolAttribute("printDetailLog", param.printDetailLog);
LoadStringAttribute(element, "debugOutputPath", param.debugOutputPath);
}
void SaveDebugParam(XMLDocument& doc, XMLElement* root, const VrDebugParam& param)
{
XMLElement* element = doc.NewElement("DebugParam");
element->SetAttribute("enableDebug", param.enableDebug);
element->SetAttribute("savePointCloud", param.savePointCloud);
element->SetAttribute("saveDebugImage", param.saveDebugImage);
element->SetAttribute("printDetailLog", param.printDetailLog);
element->SetAttribute("debugOutputPath", param.debugOutputPath.c_str());
root->InsertEndChild(element);
}
} // namespace
CVrConfig::CVrConfig() = default;
CVrConfig::~CVrConfig() = default;
int CVrConfig::LoadConfig(const std::string& filePath, ConfigResult& configResult)
{
XMLDocument doc;
const XMLError err = doc.LoadFile(filePath.c_str());
if (err != XML_SUCCESS) {
LOG_ERR("open config file failed: %s\n", filePath.c_str());
return LOAD_CONFIG_FILE_NOT_FOUND;
}
XMLElement* root = doc.RootElement();
if (!root || std::string(root->Name()) != RootName()) {
LOG_ERR("Config file format error: root element is not %s\n", RootName());
return LOAD_CONFIG_INVALID_FORMAT;
}
configResult = ConfigResult();
LoadMvsCamera(root, configResult.mvsCamera);
LoadRsLidar(root, configResult.lidarConfig);
LoadLedDisplay(root, configResult.ledDisplayConfig);
LoadUdpBroadcast(root, configResult.udpBroadcastConfig);
LoadHttpServer(root, configResult.httpServerConfig);
LoadAlgorithmParams(root, configResult.algorithmParams);
LoadDebugParam(root, configResult.debugParam);
configResult.Normalize();
return LOAD_CONFIG_SUCCESS;
}
bool CVrConfig::SaveConfig(const std::string& filePath, ConfigResult& configResult)
{
configResult.Normalize();
XMLDocument doc;
XMLDeclaration* declaration = doc.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
doc.InsertFirstChild(declaration);
XMLElement* root = doc.NewElement(RootName());
doc.InsertEndChild(root);
SaveMvsCamera(doc, root, configResult.mvsCamera);
SaveRsLidar(doc, root, configResult.lidarConfig);
SaveLedDisplay(doc, root, configResult.ledDisplayConfig);
SaveUdpBroadcast(doc, root, configResult.udpBroadcastConfig);
SaveHttpServer(doc, root, configResult.httpServerConfig);
SaveAlgorithmParams(doc, root, configResult.algorithmParams);
SaveDebugParam(doc, root, configResult.debugParam);
const XMLError err = doc.SaveFile(filePath.c_str());
if (err != XML_SUCCESS) {
LOG_ERR("save config file failed: %s\n", filePath.c_str());
return false;
}
if (m_pNotify) {
m_pNotify->OnConfigChanged(configResult);
}
return true;
}
void CVrConfig::SetConfigChangeNotify(IVrConfigChangeNotify* notify)
{
m_pNotify = notify;
}
bool IVrConfig::CreateInstance(IVrConfig** ppVrConfig)
{
if (!ppVrConfig) {
return false;
}
*ppVrConfig = new CVrConfig();
return *ppVrConfig != nullptr;
}