794 lines
25 KiB
C++
Raw Normal View History

#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 = "相机";
defaultCamera.ip = "";
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; // 暂时返回失败
}