794 lines
25 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ConfigManager.h"
#include "VrError.h"
#include "VrLog.h"
#include "PathManager.h"
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
#include <cstring>
#include <algorithm>
#include <fstream>
// SystemConfig 实现
CameraUIParam* SystemConfig::GetCameraUIParam(int cameraIndex)
{
for (auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return &param;
}
}
return nullptr;
}
const CameraUIParam* SystemConfig::GetCameraUIParam(int cameraIndex) const
{
for (const auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return &param;
}
}
return nullptr;
}
void SystemConfig::SetCameraUIParam(const CameraUIParam& param)
{
for (auto& existingParam : cameraUIParams) {
if (existingParam.cameraIndex == param.cameraIndex) {
existingParam = param;
return;
}
}
// 如果不存在,则添加新的
cameraUIParams.push_back(param);
}
void SystemConfig::EnsureCameraUIParam(int cameraIndex)
{
for (const auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return; // 已存在
}
}
// 不存在,创建默认参数
CameraUIParam defaultParam;
defaultParam.cameraIndex = cameraIndex;
cameraUIParams.push_back(defaultParam);
}
// ConfigManager 实现
ConfigManager::ConfigManager()
: m_pVrConfig(nullptr)
, m_pConfigCmdShareMem(nullptr)
, m_bSharedMemMonitorRunning(false)
{
}
ConfigManager::~ConfigManager()
{
Shutdown();
}
bool ConfigManager::Initialize(const std::string& configFilePath)
{
LOG_INFO("ConfigManager initializing...\n");
// 保存配置文件路径
if (configFilePath.empty()) {
m_configFilePath = PathManager::GetInstance().GetConfigFilePath().toStdString();
} else {
m_configFilePath = configFilePath;
}
// 创建VrConfig实例
if (!IVrConfig::CreateInstance(&m_pVrConfig) || !m_pVrConfig) {
LOG_ERROR("Failed to create VrConfig instance\n");
return false;
}
// 加载配置文件
if (!LoadConfigFromFile(m_configFilePath)) {
LOG_WARNING("Failed to load config file, using default config\n");
_InitializeDefaultConfig();
}
LOG_INFO("ConfigManager initialized successfully\n");
return true;
}
void ConfigManager::Shutdown()
{
LOG_INFO("ConfigManager shutting down...\n");
// 停止共享内存监听
StopSharedMemoryMonitor();
// 清理监听器
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
m_listeners.clear();
}
// 释放VrConfig实例
if (m_pVrConfig) {
delete m_pVrConfig;
m_pVrConfig = nullptr;
}
LOG_INFO("ConfigManager shutdown completed\n");
}
SystemConfig ConfigManager::GetConfig() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig;
}
CameraUIParam ConfigManager::GetCameraUIParam(int cameraIndex) const
{
std::lock_guard<std::mutex> lock(m_configMutex);
const CameraUIParam* param = m_systemConfig.GetCameraUIParam(cameraIndex);
if (param) {
return *param;
}
// 返回默认参数
CameraUIParam defaultParam;
defaultParam.cameraIndex = cameraIndex;
return defaultParam;
}
VrAlgorithmParams ConfigManager::GetAlgorithmParams() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig.configResult.algorithmParams;
}
ConfigResult ConfigManager::GetConfigResult() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig.configResult;
}
bool ConfigManager::UpdateCameraUIParam(int cameraIndex, const CameraUIParam& param)
{
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
CameraUIParam* existingParam = m_systemConfig.GetCameraUIParam(cameraIndex);
if (!existingParam || memcmp(existingParam, &param, sizeof(CameraUIParam)) != 0) {
m_systemConfig.SetCameraUIParam(param);
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(cameraIndex);
LOG_INFO("Camera %d UI parameters updated\n", cameraIndex);
}
return true;
}
bool ConfigManager::UpdateAlgorithmParams(const VrAlgorithmParams& params)
{
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
if (memcmp(&m_systemConfig.configResult.algorithmParams, &params, sizeof(VrAlgorithmParams)) != 0) {
m_systemConfig.configResult.algorithmParams = params;
changed = true;
}
}
if (changed) {
_NotifyAlgorithmParamChanged();
LOG_INFO("Algorithm parameters updated\n");
}
return true;
}
bool ConfigManager::UpdateFullConfig(const SystemConfig& config)
{
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig = config;
}
_NotifyConfigChanged();
LOG_INFO("Full configuration updated\n");
return true;
}
bool ConfigManager::LoadConfigFromFile(const std::string& filePath)
{
if (!m_pVrConfig) {
LOG_ERROR("VrConfig instance not available\n");
return false;
}
try {
// 首先检查文件是否存在
std::ifstream fileCheck(filePath);
if (!fileCheck.good()) {
LOG_ERROR("Configuration file not found or cannot be read: %s\n", filePath.c_str());
return false;
}
fileCheck.close();
LOG_DEBUG("%d %s\n", __LINE__, filePath.c_str());
// 加载配置文件
int ret = m_pVrConfig->LoadConfig(filePath, m_systemConfig.configResult);
if (ret != LOAD_CONFIG_SUCCESS) {
LOG_ERROR("Failed to load config file directly, error code: %d\n", ret);
return false;
}
LOG_DEBUG("ConfigResult loaded successfully\n");
return true;
} catch (const std::exception& e) {
LOG_ERROR("Failed to load configuration from file %s: %s\n", filePath.c_str(), e.what());
return false;
} catch (...) {
LOG_ERROR("Unknown exception while loading configuration from file %s\n", filePath.c_str());
return false;
}
}
bool ConfigManager::SaveConfigToFile(const std::string& filePath)
{
if (!m_pVrConfig) {
LOG_ERROR("VrConfig instance not available\n");
return false;
}
try {
ConfigResult configResult;
{
std::lock_guard<std::mutex> lock(m_configMutex);
configResult = m_systemConfig.configResult;
}
bool result = m_pVrConfig->SaveConfig(filePath, configResult);
if (result) {
LOG_INFO("Configuration saved to file: %s\n", filePath.c_str());
} else {
LOG_ERROR("Failed to save configuration to file: %s\n", filePath.c_str());
}
return result;
} catch (const std::exception& e) {
LOG_ERROR("Exception while saving configuration to file %s: %s\n", filePath.c_str(), e.what());
return false;
}
}
void ConfigManager::AddConfigChangeListener(std::shared_ptr<IConfigChangeListener> listener)
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
m_listeners.push_back(listener);
LOG_DEBUG("Config change listener added, total listeners: %zu\n", m_listeners.size());
}
void ConfigManager::RemoveConfigChangeListener(std::shared_ptr<IConfigChangeListener> listener)
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
auto it = std::find_if(m_listeners.begin(), m_listeners.end(),
[&listener](const std::weak_ptr<IConfigChangeListener>& weak_listener) {
return weak_listener.lock() == listener;
});
if (it != m_listeners.end()) {
m_listeners.erase(it);
LOG_DEBUG("Config change listener removed, remaining listeners: %zu\n", m_listeners.size());
}
}
bool ConfigManager::StartSharedMemoryMonitor()
{
if (m_bSharedMemMonitorRunning) {
LOG_WARNING("Shared memory monitor is already running\n");
return true;
}
if (!_InitializeSharedMemory()) {
LOG_ERROR("Failed to initialize shared memory for config monitor\n");
return false;
}
// 启动监听线程
m_bSharedMemMonitorRunning = true;
m_sharedMemMonitorThread = std::thread(&ConfigManager::_SharedMemoryMonitorThread, this);
LOG_INFO("Shared memory monitor started\n");
return true;
}
void ConfigManager::StopSharedMemoryMonitor()
{
if (!m_bSharedMemMonitorRunning) {
return;
}
m_bSharedMemMonitorRunning = false;
// 等待线程结束
if (m_sharedMemMonitorThread.joinable()) {
m_sharedMemMonitorThread.join();
}
// 清理共享内存
_CleanupSharedMemory();
LOG_INFO("Shared memory monitor stopped\n");
}
void ConfigManager::_SharedMemoryMonitorThread()
{
LOG_INFO("Shared memory monitor thread started\n");
ConfigCmdSharedData lastData;
memset(&lastData, 0, sizeof(ConfigCmdSharedData));
while (m_bSharedMemMonitorRunning) {
try {
// 锁定共享内存并读取数据
int ret = m_pConfigCmdShareMem->Lock(1000); // 1秒超时
if (ret != SUCCESS) {
if (ret != SHAREMEM_ERR_TIMEOUT) {
LOG_ERROR("Failed to lock shared memory for config monitor, error: %d\n", ret);
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
ConfigCmdSharedData currentData;
ret = m_pConfigCmdShareMem->ReadData(0, &currentData, sizeof(ConfigCmdSharedData));
m_pConfigCmdShareMem->Unlock();
if (ret < 0) {
LOG_ERROR("Failed to read shared memory for config monitor, error: %d\n", ret);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查魔数和版本
if (strcmp(currentData.header.magic, "VRCFG001") != 0 || currentData.header.version != 1) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查是否有新数据
if (!currentData.header.hasNewData) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 验证校验和
if (!currentData.ValidateChecksum()) {
LOG_ERROR("Config command data checksum validation failed\n");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查是否是新的命令(与上次不同)
if (memcmp(&lastData.data, &currentData.data, sizeof(ConfigCmdData)) == 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 应用配置命令
LOG_INFO("Received new config command, type: %d, timestamp: %s\n",
currentData.data.cmdType, currentData.data.timestamp);
if (_ApplyConfigCommand(currentData.data)) {
LOG_INFO("Config command applied successfully\n");
} else {
LOG_ERROR("Failed to apply config command\n");
}
// 更新最后处理的数据
lastData = currentData;
// 标记数据已处理(清除新数据标志)
ret = m_pConfigCmdShareMem->Lock(1000);
if (ret == SUCCESS) {
ConfigCmdSharedData clearData = currentData;
clearData.header.hasNewData = false;
m_pConfigCmdShareMem->WriteData(0, &clearData, sizeof(ConfigCmdSharedData));
m_pConfigCmdShareMem->Unlock();
}
} catch (const std::exception& e) {
LOG_ERROR("Exception in config monitor thread: %s\n", e.what());
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
LOG_INFO("Shared memory monitor thread stopped\n");
}
bool ConfigManager::_ApplyConfigCommand(const ConfigCmdData& configData)
{
switch (configData.cmdType) {
case CONFIG_CMD_CAMERA_EXPOSE:
return _ApplyCameraExpose(configData.cameraParam);
case CONFIG_CMD_CAMERA_GAIN:
return _ApplyCameraGain(configData.cameraParam);
case CONFIG_CMD_CAMERA_FRAMERATE:
return _ApplyCameraFrameRate(configData.cameraParam);
case CONFIG_CMD_CAMERA_SWING:
return _ApplyCameraSwing(configData.swingParam);
case CONFIG_CMD_ALGO_PARAM:
return _ApplyAlgoParam(configData.algoParam);
case CONFIG_CMD_CALIB_PARAM:
return _ApplyCalibParam(configData.calibParam);
case CONFIG_CMD_FULL_CONFIG:
return _ApplyFullConfig(configData.fullConfigParam);
default:
LOG_ERROR("Unknown config command type: %d\n", configData.cmdType);
return false;
}
}
bool ConfigManager::_ApplyCameraExpose(const CameraConfigParam& param)
{
LOG_INFO("Applying camera expose setting: camera %d, expose time: %.2f\n",
param.cameraIndex, param.exposeTime);
if (param.cameraIndex == -1) {
// 应用到所有相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
for (auto& cameraParam : m_systemConfig.cameraUIParams) {
if (cameraParam.exposeTime != param.exposeTime) {
cameraParam.exposeTime = param.exposeTime;
changed = true;
}
}
}
if (changed) {
_NotifyConfigChanged();
}
} else {
// 应用到指定相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig.EnsureCameraUIParam(param.cameraIndex);
CameraUIParam* cameraParam = m_systemConfig.GetCameraUIParam(param.cameraIndex);
if (cameraParam && cameraParam->exposeTime != param.exposeTime) {
cameraParam->exposeTime = param.exposeTime;
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(param.cameraIndex);
}
}
return true;
}
bool ConfigManager::_ApplyCameraGain(const CameraConfigParam& param)
{
LOG_INFO("Applying camera gain setting: camera %d, gain: %.2f\n",
param.cameraIndex, param.gain);
if (param.cameraIndex == -1) {
// 应用到所有相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
for (auto& cameraParam : m_systemConfig.cameraUIParams) {
if (cameraParam.gain != param.gain) {
cameraParam.gain = param.gain;
changed = true;
}
}
}
if (changed) {
_NotifyConfigChanged();
}
} else {
// 应用到指定相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig.EnsureCameraUIParam(param.cameraIndex);
CameraUIParam* cameraParam = m_systemConfig.GetCameraUIParam(param.cameraIndex);
if (cameraParam && cameraParam->gain != param.gain) {
cameraParam->gain = param.gain;
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(param.cameraIndex);
}
}
return true;
}
bool ConfigManager::_ApplyCameraFrameRate(const CameraConfigParam& param)
{
LOG_INFO("Applying camera frame rate setting: camera %d, frame rate: %.2f\n",
param.cameraIndex, param.frameRate);
if (param.cameraIndex == -1) {
// 应用到所有相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
for (auto& cameraParam : m_systemConfig.cameraUIParams) {
if (cameraParam.frameRate != param.frameRate) {
cameraParam.frameRate = param.frameRate;
changed = true;
}
}
}
if (changed) {
_NotifyConfigChanged();
}
} else {
// 应用到指定相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig.EnsureCameraUIParam(param.cameraIndex);
CameraUIParam* cameraParam = m_systemConfig.GetCameraUIParam(param.cameraIndex);
if (cameraParam && cameraParam->frameRate != param.frameRate) {
cameraParam->frameRate = param.frameRate;
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(param.cameraIndex);
}
}
return true;
}
bool ConfigManager::_ApplyCameraSwing(const SwingConfigParam& param)
{
LOG_INFO("Applying camera swing setting: camera %d, speed: %.2f, angles: %.2f-%.2f\n",
param.cameraIndex, param.swingSpeed, param.startAngle, param.stopAngle);
if (param.cameraIndex == -1) {
// 应用到所有相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
for (auto& cameraParam : m_systemConfig.cameraUIParams) {
if (cameraParam.swingSpeed != param.swingSpeed ||
cameraParam.swingStartAngle != param.startAngle ||
cameraParam.swingStopAngle != param.stopAngle) {
cameraParam.swingSpeed = param.swingSpeed;
cameraParam.swingStartAngle = param.startAngle;
cameraParam.swingStopAngle = param.stopAngle;
changed = true;
}
}
}
if (changed) {
_NotifyConfigChanged();
}
} else {
// 应用到指定相机
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig.EnsureCameraUIParam(param.cameraIndex);
CameraUIParam* cameraParam = m_systemConfig.GetCameraUIParam(param.cameraIndex);
if (cameraParam && (cameraParam->swingSpeed != param.swingSpeed ||
cameraParam->swingStartAngle != param.startAngle ||
cameraParam->swingStopAngle != param.stopAngle)) {
cameraParam->swingSpeed = param.swingSpeed;
cameraParam->swingStartAngle = param.startAngle;
cameraParam->swingStopAngle = param.stopAngle;
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(param.cameraIndex);
}
}
return true;
}
bool ConfigManager::_ApplyAlgoParam(const AlgoConfigParam& param)
{
LOG_INFO("Applying algorithm parameter: %s = %.3f\n", param.paramName, param.paramValue);
// 算法参数设置暂时只记录日志,具体实现可以根据需要扩展
return true;
}
bool ConfigManager::_ApplyCalibParam(const CalibConfigParam& param)
{
LOG_INFO("Applying calibration parameter for camera %d\n", param.cameraIndex);
// 标定参数设置暂时只记录日志,具体实现可以根据需要扩展
return true;
}
bool ConfigManager::_ApplyFullConfig(const FullConfigParam& param)
{
LOG_INFO("Applying full configuration update\n");
// JSON反序列化和应用完整配置
SystemConfig newConfig;
if (_DeserializeConfigFromJson(param.configJson, newConfig)) {
UpdateFullConfig(newConfig);
return true;
}
LOG_ERROR("Failed to deserialize full configuration from JSON\n");
return false;
}
void ConfigManager::_NotifyConfigChanged()
{
SystemConfig currentConfig = GetConfig();
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnSystemConfigChanged(currentConfig);
} catch (const std::exception& e) {
LOG_ERROR("Exception in config change listener: %s\n", e.what());
}
}
}
}
void ConfigManager::_NotifyCameraParamChanged(int cameraIndex)
{
CameraUIParam cameraParam = GetCameraUIParam(cameraIndex);
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnCameraParamChanged(cameraIndex, cameraParam);
} catch (const std::exception& e) {
LOG_ERROR("Exception in camera param change listener: %s\n", e.what());
}
}
}
}
void ConfigManager::_NotifyAlgorithmParamChanged()
{
VrAlgorithmParams algorithmParams = GetAlgorithmParams();
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnAlgorithmParamChanged(algorithmParams);
} catch (const std::exception& e) {
LOG_ERROR("Exception in algorithm param change listener: %s\n", e.what());
}
}
}
}
void ConfigManager::_CleanupExpiredListeners()
{
// 移除已过期的weak_ptr
m_listeners.erase(
std::remove_if(m_listeners.begin(), m_listeners.end(),
[](const std::weak_ptr<IConfigChangeListener>& weak_listener) {
return weak_listener.expired();
}),
m_listeners.end());
}
bool ConfigManager::_InitializeSharedMemory()
{
if (m_pConfigCmdShareMem) {
return true; // 已经初始化
}
m_pConfigCmdShareMem = CreateShareMemInstance();
if (!m_pConfigCmdShareMem) {
return false;
}
// 尝试打开已存在的共享内存,如果不存在则创建
int ret = m_pConfigCmdShareMem->CreateOrOpen(CONFIG_CMD_SHARED_MEM_NAME, CONFIG_CMD_SHARED_MEM_SIZE, false);
if (ret != SUCCESS) {
// 如果打开失败,尝试创建新的
ret = m_pConfigCmdShareMem->CreateOrOpen(CONFIG_CMD_SHARED_MEM_NAME, CONFIG_CMD_SHARED_MEM_SIZE, true);
if (ret != SUCCESS) {
_CleanupSharedMemory();
return false;
}
}
// 映射内存
void* mappedAddr = m_pConfigCmdShareMem->MapView();
if (!mappedAddr) {
_CleanupSharedMemory();
return false;
}
return true;
}
void ConfigManager::_CleanupSharedMemory()
{
if (m_pConfigCmdShareMem) {
m_pConfigCmdShareMem->UnmapView();
m_pConfigCmdShareMem->Close();
DestroyShareMemInstance(m_pConfigCmdShareMem);
m_pConfigCmdShareMem = nullptr;
}
}
bool ConfigManager::_InitializeDefaultConfig()
{
std::lock_guard<std::mutex> lock(m_configMutex);
// 初始化默认ConfigResult所有字段自动使用IVrConfig.h中定义的默认值
m_systemConfig.configResult = ConfigResult();
// 添加默认相机配置
DeviceInfo defaultCamera;
defaultCamera.name = "Camera1";
defaultCamera.ip = "192.168.1.100";
m_systemConfig.configResult.cameraList.push_back(defaultCamera);
// 初始化默认的相机UI参数
m_systemConfig.cameraUIParams.clear();
CameraUIParam defaultCameraUI;
defaultCameraUI.cameraIndex = 1;
m_systemConfig.cameraUIParams.push_back(defaultCameraUI);
LOG_INFO("Default configuration initialized\n");
return true;
}
std::string ConfigManager::_SerializeConfigToJson(const SystemConfig& config)
{
// 简化的JSON序列化实现
// 在实际项目中建议使用完整的JSON库
return "{}"; // 暂时返回空JSON
}
bool ConfigManager::_DeserializeConfigFromJson(const std::string& json, SystemConfig& config)
{
// 简化的JSON反序列化实现
// 在实际项目中建议使用完整的JSON库
return false; // 暂时返回失败
}