From 89a8d050f529657255dad8566930cd03d9ed4215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=B0=E4=BB=94?= Date: Sun, 8 Jun 2025 23:51:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=BA=E6=A2=B0=E8=87=82Mo?= =?UTF-8?q?dbusTCP=E7=9A=84=E5=8D=8F=E8=AE=AE=E4=BA=A4=E4=BA=92=EF=BC=9B?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=9B=B8=E6=9C=BA=E5=AF=B9=E8=AF=9D=E6=A1=86?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=92=8C=E5=BA=94=E7=94=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=A2=9E=E5=BC=BA=E9=94=99=E8=AF=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=8C=E6=9B=B4=E6=96=B0UI=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E4=BB=A5=E6=8F=90=E9=AB=98=E5=8F=AF=E8=AF=BB?= =?UTF-8?q?=E6=80=A7=EF=BC=9B=20=E5=A2=9E=E5=8A=A0=E7=9B=B8=E6=9C=BA?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GrabBagApp/IYGrabBagStatus.h | 2 +- GrabBagApp/Presenter/Inc/GrabBagPresenter.h | 35 +- GrabBagApp/Presenter/Inc/RobotProtocol.h | 7 + GrabBagApp/Presenter/Src/GrabBagPresenter.cpp | 401 ++++++++++++++---- GrabBagApp/Presenter/Src/RobotProtocol.cpp | 73 +++- GrabBagApp/dialogcamera.cpp | 155 ++++++- GrabBagApp/dialogcamera.h | 15 +- GrabBagApp/dialogcamera.ui | 20 +- GrabBagApp/dialogconfig.ui | 24 +- GrabBagApp/mainwindow.cpp | 111 +++-- GrabBagApp/mainwindow.h | 23 +- GrabBagApp/mainwindow.ui | 12 + .../ModbusTCPServer/Inc/IYModbusTCPServer.h | 6 +- Module/ModbusTCPServer/ModbusTCPServer.pro | 4 + .../ModbusTCPServer/Src/ModbusTCPServer.cpp | 194 +++++++-- Module/ModbusTCPServer/_Inc/ModbusTCPServer.h | 6 +- VrEyeDevice/Src/VrEyeCommon.cpp | 5 + VrEyeDevice/_Inc/VrEyeCommon.h | 5 +- VrUtils/Inc/VrSimpleLog.h | 75 +--- 19 files changed, 889 insertions(+), 284 deletions(-) diff --git a/GrabBagApp/IYGrabBagStatus.h b/GrabBagApp/IYGrabBagStatus.h index d1687f41..5edca613 100644 --- a/GrabBagApp/IYGrabBagStatus.h +++ b/GrabBagApp/IYGrabBagStatus.h @@ -19,7 +19,7 @@ inline std::string WorkStatusToString(WorkStatus status) { switch (status) { case WorkStatus::Ready: return "准备就绪"; case WorkStatus::Working: return "正在工作"; - case WorkStatus::Completed: return "监测完成"; + case WorkStatus::Completed: return "检测完成"; case WorkStatus::Error: return "设备异常"; default: return "未知状态"; } diff --git a/GrabBagApp/Presenter/Inc/GrabBagPresenter.h b/GrabBagApp/Presenter/Inc/GrabBagPresenter.h index d5011454..faa3e537 100644 --- a/GrabBagApp/Presenter/Inc/GrabBagPresenter.h +++ b/GrabBagApp/Presenter/Inc/GrabBagPresenter.h @@ -5,6 +5,7 @@ #include "IVrEyeDevice.h" #include "IYGrabBagStatus.h" #include "RobotProtocol.h" +#include "VZNL_Types.h" class GrabBagPresenter { @@ -24,6 +25,8 @@ public: // 停止检测 int StopDetection(); + IVrEyeDevice* GetEyeDevice(int index); + private: // 机械臂协议相关方法 int InitRobotProtocol(); @@ -32,19 +35,43 @@ private: void OnRobotConnectionChanged(bool connected); void OnRobotWorkSignal(bool startWork); + // 连接状态检查和更新 + void CheckAndUpdateWorkStatus(); + // 静态回调函数,用于传递给SDK static void _StaticCameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam); // 实例方法,处理回调 void _CameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam); + // 检测数据回调函数 + static void _StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pParam); + void _DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint); + + // 算法检测线程 + void _AlgoDetectThread(); + + int _DetectTask(); private: - IVrConfig* m_vrConfig = nullptr; - IVrEyeDevice* m_vrEyeDevice = nullptr; - IYGrabBagStatus* m_pStatus = nullptr; + IVrConfig* m_vrConfig = nullptr; + std::vector m_vrEyeDeviceList; + IYGrabBagStatus* m_pStatus = nullptr; - RobotProtocol* m_pRobotProtocol = nullptr; + RobotProtocol* m_pRobotProtocol = nullptr; + + // 连接状态标志 + bool m_bCameraConnected = false; // 相机连接状态 + bool m_bRobotConnected = false; // 机械臂连接状态 + WorkStatus m_currentWorkStatus = WorkStatus::Error; // 当前工作状态 + + std::atomic m_bAlgoDetectThreadRunning = false; + std::mutex m_algoDetectMutex; + std::condition_variable m_algoDetectCondition; + + // 检测数据缓存 + std::vector m_detectionDataCache; + std::mutex m_detectionDataMutex; }; #endif // GRABBAGPRESENTER_H diff --git a/GrabBagApp/Presenter/Inc/RobotProtocol.h b/GrabBagApp/Presenter/Inc/RobotProtocol.h index 623fd239..b5764cd9 100644 --- a/GrabBagApp/Presenter/Inc/RobotProtocol.h +++ b/GrabBagApp/Presenter/Inc/RobotProtocol.h @@ -107,6 +107,12 @@ private: */ void StopModbusTCPServer(); + /** + * @brief 处理ModbusTCP连接状态变化 + * @param connected true-连接,false-断开 + */ + void OnModbusTCPConnectionChanged(bool connected); + /** * @brief 处理线圈写入请求(工作信号) * @param unitId 单元ID @@ -155,6 +161,7 @@ private: WorkSignalCallback m_workSignalCallback; // 工作信号回调 // Modbus地址映射 + static const uint16_t COORD_X_ADDR = 0x0000; // X坐标地址 static const uint16_t COORD_Y_ADDR = 0x0002; // Y坐标地址 static const uint16_t COORD_Z_ADDR = 0x0004; // Z坐标地址 diff --git a/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp b/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp index a1d944aa..0a2a0531 100644 --- a/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp +++ b/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp @@ -7,9 +7,11 @@ GrabBagPresenter::GrabBagPresenter() : m_vrConfig(nullptr) - , m_vrEyeDevice(nullptr) , m_pStatus(nullptr) , m_pRobotProtocol(nullptr) + , m_bCameraConnected(false) + , m_bRobotConnected(false) + , m_currentWorkStatus(WorkStatus::Error) { } @@ -24,14 +26,22 @@ GrabBagPresenter::~GrabBagPresenter() } // 释放其他资源 - if (m_vrEyeDevice) { - // 关闭设备 - m_vrEyeDevice->CloseDevice(); + for(auto it = m_vrEyeDeviceList.begin(); it != m_vrEyeDeviceList.end(); it++) + { + (*it)->CloseDevice(); + delete (*it); } + m_vrEyeDeviceList.clear(); + } int GrabBagPresenter::Init() { + // 初始化连接状态 + m_bCameraConnected = false; + m_bRobotConnected = false; + m_currentWorkStatus = WorkStatus::Error; + // 初始化VrConfig模块 IVrConfig::CreateInstance(&m_vrConfig); @@ -43,19 +53,12 @@ int GrabBagPresenter::Init() // 读取IP列表 ConfigResult configResult = m_vrConfig->LoadConfig(configPath.toStdString()); - if (configResult.cameraList.size() == 0) { - m_pStatus->OnStatusUpdate("读取配置信息列表失败"); - m_pStatus->OnCamera1StatusChanged(false); - m_pStatus->OnCamera2StatusChanged(false); - m_pStatus->OnCameraCountChanged(0); - return ERR_CODE(DEV_CONFIG_ERR); - } // 初始化机械臂协议 int nRet = InitRobotProtocol(); if (nRet != 0) { m_pStatus->OnStatusUpdate("机械臂服务初始化失败"); - m_pStatus->OnWorkStatusChanged(WorkStatus::Error); + m_bRobotConnected = false; } else { m_pStatus->OnStatusUpdate("机械臂服务初始化成功"); } @@ -63,49 +66,90 @@ int GrabBagPresenter::Init() // 通知UI相机个数 int cameraCount = configResult.cameraList.size(); m_pStatus->OnCameraCountChanged(cameraCount); - - // 初始化VrEyeDevice模块 - IVrEyeDevice::CreateObject(&m_vrEyeDevice); - - nRet = m_vrEyeDevice->InitDevice(); - ERR_CODE_RETURN(nRet); + if(cameraCount > 0){ + if (cameraCount >= 1) { + // 尝试打开相机1 + // 初始化VrEyeDevice模块 + IVrEyeDevice* pDevice = nullptr; + IVrEyeDevice::CreateObject(&pDevice); + + nRet = pDevice->InitDevice(); + ERR_CODE_RETURN(nRet); - if (configResult.cameraList.size() >= 1) { + nRet = pDevice->OpenDevice(configResult.cameraList[0].ip.c_str(), &GrabBagPresenter::_StaticCameraNotify, this); + // 通过回调更新相机1状态 + bool camera1Connected = (SUCCESS == nRet); + if(camera1Connected) + { + m_vrEyeDeviceList.push_back(pDevice); + } + m_pStatus->OnCamera1StatusChanged(camera1Connected); + m_pStatus->OnStatusUpdate(camera1Connected ? "相机一连接成功" : "相机一连接失败"); + m_bCameraConnected = camera1Connected; + } + else { + m_pStatus->OnCamera1StatusChanged(false); + m_bCameraConnected = false; + } + ERR_CODE_RETURN(nRet); + + if (cameraCount >= 2) { + IVrEyeDevice* pDevice = nullptr; + IVrEyeDevice::CreateObject(&pDevice); + nRet = pDevice->InitDevice(); + ERR_CODE_RETURN(nRet); + // 尝试打开相机2 + nRet = pDevice->OpenDevice(configResult.cameraList[1].ip.c_str(), &GrabBagPresenter::_StaticCameraNotify, this); + // 通过回调更新相机2状态 + bool camera2Connected = (SUCCESS == nRet); + if(camera2Connected) + { + m_vrEyeDeviceList.push_back(pDevice); + } + m_pStatus->OnCamera2StatusChanged(camera2Connected); + m_pStatus->OnStatusUpdate(camera2Connected ? "相机二连接成功" : "相机二连接失败"); + // 只要有一个相机连接成功就认为相机连接正常 + if (camera2Connected) { + m_bCameraConnected = true; + } + } + else { + // 如果只有一个相机,则将相机2状态设为未连接 + m_pStatus->OnCamera2StatusChanged(false); + } + ERR_CODE_RETURN(nRet); + } else { + IVrEyeDevice* pDevice = nullptr; + IVrEyeDevice::CreateObject(&pDevice); + nRet = pDevice->InitDevice(); + ERR_CODE_RETURN(nRet); // 尝试打开相机1 - nRet = m_vrEyeDevice->OpenDevice(configResult.cameraList[0].ip.c_str(), &GrabBagPresenter::_StaticCameraNotify, this); + nRet = pDevice->OpenDevice(nullptr, &GrabBagPresenter::_StaticCameraNotify, this); // 通过回调更新相机1状态 - m_pStatus->OnCamera1StatusChanged(SUCCESS == nRet); - m_pStatus->OnStatusUpdate(SUCCESS == nRet ? "相机1连接成功" : "相机1连接失败"); + bool camera1Connected = (SUCCESS == nRet); + if(camera1Connected) + { + m_vrEyeDeviceList.push_back(pDevice); + } + m_pStatus->OnCamera1StatusChanged(camera1Connected); + m_pStatus->OnStatusUpdate(camera1Connected ? "相机一连接成功" : "相机一连接失败"); + m_bCameraConnected = camera1Connected; } - else { - m_pStatus->OnCamera1StatusChanged(false); - } - m_pStatus->OnWorkStatusChanged(SUCCESS == nRet ? WorkStatus::Ready : WorkStatus::Error); - ERR_CODE_RETURN(nRet); - - if (configResult.cameraList.size() >= 2) { - // 尝试打开相机2 - nRet = m_vrEyeDevice->OpenDevice(configResult.cameraList[1].ip.c_str(), &GrabBagPresenter::_StaticCameraNotify, this); - // 通过回调更新相机2状态 - m_pStatus->OnCamera2StatusChanged(SUCCESS == nRet); - m_pStatus->OnStatusUpdate(SUCCESS == nRet ? "相机2连接成功" : "相机2连接失败"); - } - else { - // 如果只有一个相机,则将相机2状态设为未连接 - m_pStatus->OnCamera2StatusChanged(false); - } - ERR_CODE_RETURN(nRet); + + m_bAlgoDetectThreadRunning = true; + std::thread algoDetectThread(&GrabBagPresenter::_AlgoDetectThread, this); + algoDetectThread.detach(); m_pStatus->OnStatusUpdate("设备初始化完成"); - m_pStatus->OnWorkStatusChanged(SUCCESS == nRet ? WorkStatus::Ready : WorkStatus::Error); + return SUCCESS; } // 初始化机械臂协议 int GrabBagPresenter::InitRobotProtocol() { - LOG_DEBUG("GrabBagPresenter::InitRobotProtocol - 开始初始化机械臂协议\n"); + LOG_DEBUG("Start initializing robot protocol\n"); // 创建RobotProtocol实例 if(nullptr == m_pRobotProtocol){ @@ -126,7 +170,7 @@ int GrabBagPresenter::InitRobotProtocol() int nRet = m_pRobotProtocol->Initialize(); ERR_CODE_RETURN(nRet); - LOG_INFO("GrabBagPresenter::InitRobotProtocol - 机械臂协议初始化成功\n"); + LOG_INFO("Robot protocol initialization successful\n"); return SUCCESS; } @@ -134,17 +178,23 @@ int GrabBagPresenter::InitRobotProtocol() // 机械臂协议回调函数实现 void GrabBagPresenter::OnRobotConnectionChanged(bool connected) { - LOG_INFO("GrabBagPresenter::OnRobotConnectionChanged - 机械臂连接状态变化:%s\n", (connected ? "已连接" : "已断开")); + LOG_INFO("Robot connection status changed: %s\n", (connected ? "connected" : "disconnected")); + + // 更新机械臂连接状态 + m_bRobotConnected = connected; if (m_pStatus) { m_pStatus->OnRobotConnectionChanged(connected); m_pStatus->OnStatusUpdate(connected ? "机械臂已连接" : "机械臂连接断开"); } + + // 检查并更新工作状态 + CheckAndUpdateWorkStatus(); } void GrabBagPresenter::OnRobotWorkSignal(bool startWork) { - LOG_INFO("GrabBagPresenter::OnRobotWorkSignal - 收到机械臂工作信号:%s\n", (startWork ? "开始工作" : "停止工作")); + LOG_INFO("Received robot work signal: %s\n", (startWork ? "start work" : "stop work")); if (nullptr == m_pStatus) { return; @@ -166,13 +216,233 @@ void GrabBagPresenter::SetStatusCallback(IYGrabBagStatus* status) // 模拟检测函数,用于演示 int GrabBagPresenter::StartDetection() { - LOG_INFO("GrabBagPresenter::StartDetection - 开始检测\n"); + LOG_INFO("Start detection\n"); + // 检查设备状态是否准备就绪 + if (m_currentWorkStatus != WorkStatus::Ready) { + LOG_INFO("Device not ready, cannot start detection\n"); + if (m_pStatus) { + m_pStatus->OnStatusUpdate("设备未准备就绪,无法开始检测"); + } + return ERR_CODE(DEV_BUSY); + } + // 通知UI工作状态变更为"正在工作" if (m_pStatus) { + m_currentWorkStatus = WorkStatus::Working; m_pStatus->OnWorkStatusChanged(WorkStatus::Working); } + if(m_vrEyeDeviceList.empty()) + { + LOG_ERROR("No camera device found\n"); + return ERR_CODE(DEV_NOT_FIND); + } + + // 清空检测数据缓存 + { + std::lock_guard lock(m_detectionDataMutex); + m_detectionDataCache.clear(); + } + + // 启动所有相机的检测 + for (size_t i = 0; i < m_vrEyeDeviceList.size(); ++i) { + IVrEyeDevice* pDevice = m_vrEyeDeviceList[i]; + if (pDevice) { + int ret = pDevice->StartDetect(&GrabBagPresenter::_StaticDetectionCallback, this); + if (ret == 0) { + LOG_INFO("Camera %zu start detection successfully\n", i + 1); + } else { + LOG_WARNING("Camera %zu start detection failed, error code: %d\n", i + 1, ret); + } + } + } + + + return 0; +} + +int GrabBagPresenter::StopDetection() +{ + LOG_INFO("Stop detection\n"); + + // 停止所有相机的检测 + for (size_t i = 0; i < m_vrEyeDeviceList.size(); ++i) { + IVrEyeDevice* pDevice = m_vrEyeDeviceList[i]; + if (pDevice) { + int ret = pDevice->StopDetect(); + if (ret == 0) { + LOG_INFO("Camera %zu stop detection successfully\n", i + 1); + } else { + LOG_WARNING("Camera %zu stop detection failed, error code: %d\n", i + 1, ret); + } + } + } + + // 通知UI工作状态变更为"就绪"(如果设备连接正常) + if (m_pStatus) { + // 检查设备连接状态,决定停止后的状态 + if (m_bCameraConnected && m_bRobotConnected) { + m_currentWorkStatus = WorkStatus::Ready; + m_pStatus->OnWorkStatusChanged(WorkStatus::Ready); + } else { + m_currentWorkStatus = WorkStatus::Error; + m_pStatus->OnWorkStatusChanged(WorkStatus::Error); + } + m_pStatus->OnStatusUpdate("检测已停止"); + } + + return 0; +} + +IVrEyeDevice *GrabBagPresenter::GetEyeDevice(int index) +{ + if(m_vrEyeDeviceList.size() <= index) return nullptr; + return m_vrEyeDeviceList[index]; +} + +// 静态回调函数实现 +void GrabBagPresenter::_StaticCameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam) +{ + // 从pInfoParam获取this指针,转换回GrabBagPresenter*类型 + GrabBagPresenter* pThis = reinterpret_cast(pInfoParam); + if (pThis) + { + // 调用实例的非静态成员函数 + pThis->_CameraNotify(eStatus, pExtData, nDataLength, pInfoParam); + } +} + +void GrabBagPresenter::_CameraNotify(EVzDeviceWorkStatus eStatus, void *pExtData, unsigned int nDataLength, void *pInfoParam) +{ + LOG_DEBUG("Camera notify received: status=%d, dataLength=%u\n", (int)eStatus, nDataLength); + + switch (eStatus) { + case EVzDeviceWorkStatus::keDeviceWorkStatus_Offline: + { + LOG_WARNING("Camera device offline/disconnected\n"); + + // 更新相机连接状态 + m_bCameraConnected = false; + + // 通知UI相机状态变更 + if (m_pStatus) { + // 这里需要判断是哪个相机离线,暂时更新相机1状态 + // 实际应用中可能需要通过pInfoParam或其他方式区分具体哪个相机 + m_pStatus->OnCamera1StatusChanged(false); + m_pStatus->OnStatusUpdate("相机设备离线"); + } + + // 检查并更新工作状态 + CheckAndUpdateWorkStatus(); + break; + } + + case EVzDeviceWorkStatus::keDeviceWorkStatus_Eye_Reconnect: + { + LOG_INFO("Camera device online/connected\n"); + + // 更新相机连接状态 + m_bCameraConnected = true; + + // 通知UI相机状态变更 + if (m_pStatus) { + m_pStatus->OnCamera1StatusChanged(true); + m_pStatus->OnStatusUpdate("相机设备已连接"); + } + + // 检查并更新工作状态 + CheckAndUpdateWorkStatus(); + break; + } + + case EVzDeviceWorkStatus::keDeviceWorkStatus_Device_Swing_Finish: + { + LOG_INFO("Received scan/trigger signal from camera\n"); + + // 如果当前状态为就绪,通知检测线程开始处理 + if (m_currentWorkStatus == WorkStatus::Ready) { + LOG_INFO("Notifying detection thread to start processing\n"); + + // 通知算法检测线程 + { + std::lock_guard lock(m_algoDetectMutex); + // 这里可以设置一个标志位,或者直接通知条件变量 + } + m_algoDetectCondition.notify_one(); + + if (m_pStatus) { + m_pStatus->OnStatusUpdate("收到扫描信号,开始检测处理"); + } + } else { + LOG_WARNING("Received scan signal but device not ready, current status: %d\n", (int)m_currentWorkStatus); + } + break; + } + + default: + LOG_DEBUG("Unhandled camera status: %d\n", (int)eStatus); + break; + } +} + +// 检测数据回调函数静态版本 +void GrabBagPresenter::_StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pUserData) +{ + GrabBagPresenter* pThis = reinterpret_cast(pUserData); + if (pThis && pLaserLinePoint) { + pThis->_DetectionCallback(eDataType, pLaserLinePoint); + } +} + +// 检测数据回调函数实例版本 +void GrabBagPresenter::_DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint) +{ + if (!pLaserLinePoint) { + return; + } + + // 将检测数据保存到缓存中 + { + std::lock_guard lock(m_detectionDataMutex); + m_detectionDataCache.push_back(pLaserLinePoint); + + // LOG_DEBUG("Detection data cached: Frame %llu, Points: %d\n", + // pLaserLinePoint->sLineData.llFrameIdx, + // pLaserLinePoint->sLineData.nPointCount); + } +} + +void GrabBagPresenter::CheckAndUpdateWorkStatus() +{ + if (m_bCameraConnected && m_bRobotConnected) { + m_currentWorkStatus = WorkStatus::Ready; + m_pStatus->OnWorkStatusChanged(WorkStatus::Ready); + m_pStatus->OnStatusUpdate("设备已准备好"); + } else { + m_currentWorkStatus = WorkStatus::Error; + m_pStatus->OnWorkStatusChanged(WorkStatus::Error); + m_pStatus->OnStatusUpdate("设备未准备好"); + } +} + +void GrabBagPresenter::_AlgoDetectThread() +{ + while(m_bAlgoDetectThreadRunning) + { + std::unique_lock lock(m_algoDetectMutex); + m_algoDetectCondition.wait(lock, [this]() { + return m_currentWorkStatus == WorkStatus::Ready; + }); + + // 检查设备状态是否准备就绪 + + _DetectTask(); + } +} + +int GrabBagPresenter::_DetectTask() +{ // 创建测试图像 QImage image(":/resource/result_image.jpg"); @@ -229,6 +499,7 @@ int GrabBagPresenter::StartDetection() // 检测完成后,将工作状态更新为"完成" if (m_pStatus) { + m_currentWorkStatus = WorkStatus::Completed; m_pStatus->OnWorkStatusChanged(WorkStatus::Completed); } @@ -247,41 +518,11 @@ int GrabBagPresenter::StartDetection() detectedCoord.rz = firstPos.yaw; m_pRobotProtocol->SetRobotCoordinate(detectedCoord); - LOG_INFO("GrabBagPresenter::StartDetection - 更新检测结果坐标: X=%.2f, Y=%.2f, Z=%.2f\n", + LOG_INFO("Update detection result coordinates: X=%.2f, Y=%.2f, Z=%.2f\n", detectedCoord.x, detectedCoord.y, detectedCoord.z); - } + } } - return 0; -} - -int GrabBagPresenter::StopDetection() -{ - LOG_INFO("GrabBagPresenter::StopDetection - 停止检测\n"); - - // 通知UI工作状态变更为"就绪" - if (m_pStatus) { - m_pStatus->OnWorkStatusChanged(WorkStatus::Ready); - m_pStatus->OnStatusUpdate("检测已停止"); - } - - - return 0; -} - -// 静态回调函数实现 -void GrabBagPresenter::_StaticCameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam) -{ - // 从pInfoParam获取this指针,转换回GrabBagPresenter*类型 - GrabBagPresenter* pThis = reinterpret_cast(pInfoParam); - if (pThis) - { - // 调用实例的非静态成员函数 - pThis->_CameraNotify(eStatus, pExtData, nDataLength, pInfoParam); - } -} - -void GrabBagPresenter::_CameraNotify(EVzDeviceWorkStatus eStatus, void *pExtData, unsigned int nDataLength, void *pInfoParam) -{ - + m_currentWorkStatus = WorkStatus::Ready; + return SUCCESS; } diff --git a/GrabBagApp/Presenter/Src/RobotProtocol.cpp b/GrabBagApp/Presenter/Src/RobotProtocol.cpp index dc50ac2a..a58a9c3c 100644 --- a/GrabBagApp/Presenter/Src/RobotProtocol.cpp +++ b/GrabBagApp/Presenter/Src/RobotProtocol.cpp @@ -21,7 +21,7 @@ RobotProtocol::~RobotProtocol() int RobotProtocol::Initialize(uint16_t port) { if (m_bServerRunning) { - LOG_WARNING("RobotProtocol::Initialize - 服务已经在运行中\n"); + LOG_WARNING("Server is already running\n"); return SUCCESS; } @@ -29,20 +29,40 @@ int RobotProtocol::Initialize(uint16_t port) // 创建ModbusTCP服务器实例 bool bRet = IYModbusTCPServer::CreateInstance(&m_pModbusServer); - LOG_ERRO("RobotProtocol::%s - 创建ModbusTCP服务器%s \n", __func__, bRet ? "失败" : "成功"); + LOG_ERRO("Create ModbusTCP server %s \n", bRet ? "success" : "failed"); m_bServerRunning = bRet; - ERR_CODE_RETURN(NET_ERR_CREAT_INIT); - + + // 设置ModbusTCP回调函数 + if (m_pModbusServer) { + // 设置写线圈回调 + m_pModbusServer->setWriteCoilsCallback([this](uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint8_t* values) { + return this->OnWriteCoils(unitId, startAddress, quantity, values); + }); + + // 设置写寄存器回调 + m_pModbusServer->setWriteRegistersCallback([this](uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values) { + return this->OnWriteRegisters(unitId, startAddress, quantity, values); + }); + + // 设置连接状态回调 + m_pModbusServer->setConnectionStatusCallback([this](bool connected) { + this->OnModbusTCPConnectionChanged(connected); + }); + } + + int nRet = m_pModbusServer->start(); + ERR_CODE_RETURN(nRet); + // 设置初始状态 m_robotStatus = STATUS_CONNECTED; - LOG_INFO("RobotProtocol::Initialize - ModbusTCP服务初始化完成\n"); - return 0; + LOG_INFO("ModbusTCP service initialization completed\n"); + return SUCCESS; } void RobotProtocol::Deinitialize() { - LOG_DEBUG("RobotProtocol::Deinitialize - 停止ModbusTCP服务\n"); + LOG_DEBUG("Stop ModbusTCP service\n"); // 停止ModbusTCP服务器 StopModbusTCPServer(); @@ -51,14 +71,14 @@ void RobotProtocol::Deinitialize() m_robotStatus = STATUS_DISCONNECTED; m_bServerRunning = false; - LOG_INFO("RobotProtocol::Deinitialize - ModbusTCP服务已停止\n"); + LOG_INFO("ModbusTCP service stopped\n"); } int RobotProtocol::SetRobotCoordinate(const RobotCoordinate& coordinate) { - LOG_DEBUG("RobotProtocol::SetRobotCoordinate - 设置机械臂坐标\n"); - LOG_DEBUG("坐标: X=%.2f, Y=%.2f, Z=%.2f\n", coordinate.x, coordinate.y, coordinate.z); - LOG_DEBUG("旋转: RX=%.2f, RY=%.2f, RZ=%.2f\n", coordinate.rx, coordinate.ry, coordinate.rz); + LOG_DEBUG("Set robot arm coordinates\n"); + LOG_DEBUG("Coordinates: X=%.2f, Y=%.2f, Z=%.2f\n", coordinate.x, coordinate.y, coordinate.z); + LOG_DEBUG("Rotation: RX=%.2f, RY=%.2f, RZ=%.2f\n", coordinate.rx, coordinate.ry, coordinate.rz); m_robotCoordinate = coordinate; @@ -93,7 +113,7 @@ bool RobotProtocol::IsRunning() const void RobotProtocol::StopModbusTCPServer() { - LOG_DEBUG("RobotProtocol::StopModbusTCPServer - 停止ModbusTCP服务器\n"); + LOG_DEBUG("Stop ModbusTCP server\n"); if (m_pModbusServer) { // 释放资源 @@ -102,22 +122,20 @@ void RobotProtocol::StopModbusTCPServer() } m_bServerRunning = false; - LOG_INFO("RobotProtocol::StopModbusTCPServer - ModbusTCP服务器已停止\n"); + LOG_INFO("ModbusTCP server stopped\n"); } IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteCoils(uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint8_t* values) { - LOG_DEBUG("RobotProtocol::OnWriteCoils - 单元ID:%d, 起始地址:%d, 数量:%d\n", - unitId, startAddress, quantity); + LOG_DEBUG("Write coils - UnitID:%d, StartAddress:%d, Quantity:%d\n", unitId, startAddress, quantity); // 处理工作信号线圈 if (startAddress <= WORK_SIGNAL_COIL && startAddress + quantity > WORK_SIGNAL_COIL) { uint16_t coilIndex = WORK_SIGNAL_COIL - startAddress; bool workSignal = (values[coilIndex / 8] >> (coilIndex % 8)) & 0x01; - LOG_INFO("RobotProtocol::OnWriteCoils - 收到工作信号:%s\n", - (workSignal ? "开始工作" : "停止工作")); + LOG_INFO("Received work signal: %s\n", (workSignal ? "start work" : "stop work")); // 触发工作信号回调 if (m_workSignalCallback) { @@ -131,8 +149,7 @@ IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteCoils(uint8_t unitId, uint16_ IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteRegisters(uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values) { - LOG_DEBUG("RobotProtocol::OnWriteRegisters - 单元ID:%d, 起始地址:%d, 数量:%d\n", - unitId, startAddress, quantity); + LOG_DEBUG("Write registers - UnitID:%d, StartAddress:%d, Quantity:%d\n", unitId, startAddress, quantity); // 处理坐标寄存器更新 if (startAddress >= COORD_X_ADDR && startAddress < STATUS_ADDR) { @@ -168,7 +185,7 @@ IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteRegisters(uint8_t unitId, uin IYModbusTCPServer::ErrorCode RobotProtocol::OnReadHoldingRegisters(uint8_t unitId, uint16_t startAddress, uint16_t quantity, uint16_t* values) { - LOG_DEBUG("RobotProtocol::OnReadHoldingRegisters - 单元ID:%d, 起始地址:%d, 数量:%d\n", + LOG_DEBUG("Read holding registers - UnitID:%d, StartAddress:%d, Quantity:%d\n", unitId, startAddress, quantity); for (uint16_t i = 0; i < quantity; i++) { @@ -202,4 +219,20 @@ IYModbusTCPServer::ErrorCode RobotProtocol::OnReadHoldingRegisters(uint8_t unitI } return IYModbusTCPServer::ErrorCode::SUCCESS; +} + +void RobotProtocol::OnModbusTCPConnectionChanged(bool connected) +{ + if (connected) { + LOG_INFO("ModbusTCP connection established\n"); + m_robotStatus = STATUS_CONNECTED; + } else { + LOG_INFO("ModbusTCP connection lost\n"); + m_robotStatus = STATUS_DISCONNECTED; + } + + // 触发上层连接状态回调 + if (m_connectionCallback) { + m_connectionCallback(connected); + } } diff --git a/GrabBagApp/dialogcamera.cpp b/GrabBagApp/dialogcamera.cpp index 6a1b6e01..add9c325 100644 --- a/GrabBagApp/dialogcamera.cpp +++ b/GrabBagApp/dialogcamera.cpp @@ -1,14 +1,165 @@ #include "dialogcamera.h" #include "ui_dialogcamera.h" +#include +#include "VrSimpleLog.h" -DialogCamera::DialogCamera(QWidget *parent) : +DialogCamera::DialogCamera(IVrEyeDevice* pDevice, QWidget *parent) : QDialog(parent), - ui(new Ui::DialogCamera) + ui(new Ui::DialogCamera), + m_pDevice(pDevice) { ui->setupUi(this); + + // 检查设备是否有效 + if (!m_pDevice) { + setWindowTitle("相机参数配置 - 设备错误"); + // 禁用所有控件 + setEnabled(false); + return; + } else { + setWindowTitle("相机参数配置"); + } + + // 初始化界面数据 + InitCameraParameters(); } DialogCamera::~DialogCamera() { delete ui; } + +void DialogCamera::on_btn_camer_ok_clicked() +{ + if (!m_pDevice) { + QMessageBox::warning(this, "错误", "设备未初始化"); + return; + } + + // 应用参数配置 + if (ApplyCameraParameters()) { + QMessageBox::information(this, "成功", "相机参数配置成功!"); + accept(); // 关闭对话框并返回Accepted + } else { + QMessageBox::warning(this, "失败", "相机参数配置失败,请检查设备连接!"); + } +} + +void DialogCamera::on_btn_camer_cancel_clicked() +{ + // 直接关闭窗口,不保存任何更改 + reject(); +} + +void DialogCamera::InitCameraParameters() +{ + if (!m_pDevice) return; + + try { + // 获取曝光时间 + unsigned int exposeTime = 0; + if (m_pDevice->GetEyeExpose(exposeTime) == 0) { + // 假设UI中有一个名为spinBox_expose的控件 + ui->lineEdit_export->setText(QString::number(exposeTime)); + LOG_DEBUG("Current expose time: %u\n", exposeTime); + } + + // 获取增益 + unsigned int gain = 0; + if (m_pDevice->GetEyeGain(gain) == 0) { + // 假设UI中有一个名为spinBox_gain的控件 + ui->lineEdit_gain->setText(QString::number(gain)); + LOG_DEBUG("Current gain: %u\n", gain); + } + + // 获取帧率 + int frame = 0; + if (m_pDevice->GetFrame(frame) == 0) { + // 假设UI中有一个名为spinBox_frame的控件 + ui->lineEdit_frame->setText(QString::number(frame)); + LOG_DEBUG("Current frame rate: %d\n", frame); + } + + // 获取摆动速度 + float swingSpeed = 0.0f; + if (m_pDevice->GetSwingSpeed(swingSpeed) == 0) { + // 假设UI中有一个名为doubleSpinBox_swing_speed的控件 + ui->lineEdit_swing_speed->setText(QString::number(swingSpeed)); + LOG_DEBUG("Swing speed: %.3f\n", swingSpeed); + } + + // 获取工作角度 + float minAngle = 0.0f, maxAngle = 0.0f; + if (m_pDevice->GetSwingAngle(minAngle, maxAngle) == 0) { + // 假设UI中有角度相关的控件 + ui->lineEdit_swing_start->setText(QString::number(minAngle)); + ui->lineEdit_swing_stop->setText(QString::number(maxAngle)); + LOG_DEBUG("Swing angle range: %.3f to %.3f\n", minAngle, maxAngle); + } + + } catch (...) { + QMessageBox::warning(this, "错误", "读取相机参数时发生异常"); + } +} + +bool DialogCamera::ApplyCameraParameters() +{ + if (!m_pDevice) return false; + + try { + bool success = true; + + // 设置曝光时间 + unsigned int exposeTime = ui->lineEdit_export->text().toUInt(); + if (m_pDevice->SetEyeExpose(exposeTime) != 0) { + LOG_WARNING("Failed to set expose time: %u\n", exposeTime); + success = false; + } else { + LOG_INFO("Set expose time: %u\n", exposeTime); + } + + // 设置增益 + unsigned int gain = ui->lineEdit_gain->text().toUInt(); + if (m_pDevice->SetEyeGain(gain) != 0) { + LOG_WARNING("Failed to set gain: %u\n", gain); + success = false; + } else { + LOG_INFO("Set gain: %u\n", gain); + } + + // 设置帧率 + int frame = ui->lineEdit_frame->text().toInt(); + if (m_pDevice->SetFrame(frame) != 0) { + LOG_WARNING("Failed to set frame rate: %d\n", frame); + success = false; + } else { + LOG_INFO("Set frame rate: %d\n", frame); + } + + // 设置摆动速度 + float swingSpeed = ui->lineEdit_swing_speed->text().toFloat(); + if (m_pDevice->SetSwingSpeed(swingSpeed) != 0) { + LOG_WARNING("Failed to set swing speed: %.3f\n", swingSpeed); + success = false; + } else { + LOG_INFO("Set swing speed: %.3f\n", swingSpeed); + } + + // 设置工作角度 + float minAngle = ui->lineEdit_swing_start->text().toFloat(); + float maxAngle = ui->lineEdit_swing_stop->text().toFloat(); + if (m_pDevice->SetSwingAngle(minAngle, maxAngle) != 0) { + LOG_WARNING("Failed to set swing angle: %.3f to %.3f\n", minAngle, maxAngle); + success = false; + } else { + LOG_INFO("Set swing angle: %.3f to %.3f\n", minAngle, maxAngle); + } + + return success; + + } catch (...) { + QMessageBox::warning(this, "错误", "应用相机参数时发生异常"); + return false; + } +} + diff --git a/GrabBagApp/dialogcamera.h b/GrabBagApp/dialogcamera.h index a82cb36d..8d3b957a 100644 --- a/GrabBagApp/dialogcamera.h +++ b/GrabBagApp/dialogcamera.h @@ -2,6 +2,7 @@ #define DIALOGCAMERA_H #include +#include namespace Ui { class DialogCamera; @@ -12,11 +13,23 @@ class DialogCamera : public QDialog Q_OBJECT public: - explicit DialogCamera(QWidget *parent = nullptr); + explicit DialogCamera(IVrEyeDevice* pDevice, QWidget *parent = nullptr); ~DialogCamera(); +private slots: + void on_btn_camer_ok_clicked(); + void on_btn_camer_cancel_clicked(); + +private: + // 初始化相机参数到界面 + void InitCameraParameters(); + + // 应用界面参数到相机 + bool ApplyCameraParameters(); + private: Ui::DialogCamera *ui; + IVrEyeDevice* m_pDevice = nullptr; }; #endif // DIALOGCAMERA_H diff --git a/GrabBagApp/dialogcamera.ui b/GrabBagApp/dialogcamera.ui index 8cd773fd..6c0f757e 100644 --- a/GrabBagApp/dialogcamera.ui +++ b/GrabBagApp/dialogcamera.ui @@ -13,7 +13,7 @@ 相机配置 - + 30 @@ -51,7 +51,7 @@ 基本参数 - + 20 @@ -81,7 +81,7 @@ - + 18 @@ -106,7 +106,7 @@ - + 18 @@ -131,7 +131,7 @@ - + 18 @@ -191,7 +191,7 @@ - + 18 @@ -216,7 +216,7 @@ - + 18 @@ -241,7 +241,7 @@ - + 18 @@ -254,7 +254,7 @@ - + 120 @@ -272,7 +272,7 @@ 应用 - + 280 diff --git a/GrabBagApp/dialogconfig.ui b/GrabBagApp/dialogconfig.ui index 33944bf0..9656e93f 100644 --- a/GrabBagApp/dialogconfig.ui +++ b/GrabBagApp/dialogconfig.ui @@ -17,8 +17,8 @@ 10 - 0 - 651 + 20 + 601 41 @@ -28,7 +28,7 @@ - 区域标定 + 区域框定 Qt::AlignCenter @@ -97,7 +97,7 @@ - ms + mm @@ -134,7 +134,7 @@ - ms + mm @@ -171,7 +171,7 @@ - ms + mm @@ -243,7 +243,7 @@ - ms + mm @@ -280,7 +280,7 @@ - ms + mm @@ -317,7 +317,7 @@ - ms + mm @@ -389,7 +389,7 @@ - ms + mm @@ -426,7 +426,7 @@ - ms + mm @@ -463,7 +463,7 @@ - ms + mm diff --git a/GrabBagApp/mainwindow.cpp b/GrabBagApp/mainwindow.cpp index d3316077..8fc01b15 100644 --- a/GrabBagApp/mainwindow.cpp +++ b/GrabBagApp/mainwindow.cpp @@ -5,7 +5,7 @@ #include #include #include - +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -36,11 +36,17 @@ MainWindow::MainWindow(QWidget *parent) setStatusDot(ui->label_camera_1_status, false); // 在线绿色 setStatusDot(ui->label_camera_2_status, false); // 在线绿色 setStatusDot(ui->label_robot_status, false); // 在线绿色 - + // 连接菜单信号 - connect(ui->menu_camera, &QMenu::aboutToShow, this, &MainWindow::on_menu_camera_triggered); - connect(ui->menu_config, &QMenu::aboutToShow, this, &MainWindow::on_menu_config_triggered); - connect(ui->menu_camera_adjust, &QMenu::aboutToShow, this, &MainWindow::on_menu_camera_adjust_triggered); +// connect(ui->menu_camera, &QMenu::aboutToShow, this, &MainWindow::on_menu_camera_triggered); +// connect(ui->menu_config, &QMenu::aboutToShow, this, &MainWindow::on_menu_config_triggered); +// connect(ui->menu_camera_adjust, &QMenu::aboutToShow, this, &MainWindow::on_menu_camera_adjust_triggered); + + // 连接工作状态更新信号槽 + connect(this, &MainWindow::workStatusUpdateRequested, this, &MainWindow::updateWorkStatusLabel); + + // 连接检测结果更新信号槽 + connect(this, &MainWindow::detectionResultUpdateRequested, this, &MainWindow::updateDetectionResultDisplay); updateStatusLog(tr("就绪")); @@ -140,10 +146,10 @@ void MainWindow::setStatusDot(QLabel* label, bool isOnline) { void MainWindow::on_btn_camera_clicked() { - if(nullptr == ui_dialogCamera){ - ui_dialogCamera = new DialogCamera; - } - ui_dialogCamera->show(); +// if(nullptr == ui_dialogCamera){ +// ui_dialogCamera = new DialogCamera; +// } +// ui_dialogCamera->show(); } void MainWindow::on_btn_config_clicked() @@ -154,16 +160,13 @@ void MainWindow::on_btn_config_clicked() ui_dialogConfig->show(); } - void MainWindow::on_btn_flow_clicked() { // 机械臂连接/断开 static bool isConnected = false; isConnected = !isConnected; - } - void MainWindow::on_btn_start_clicked() { // 使用Presenter启动检测 @@ -172,7 +175,6 @@ void MainWindow::on_btn_start_clicked() } } - void MainWindow::on_btn_stop_clicked() { if (m_presenter) { @@ -180,25 +182,19 @@ void MainWindow::on_btn_stop_clicked() } } -void MainWindow::on_menu_camera_triggered() -{ - qDebug() << __func__ ; - if(nullptr == ui_dialogCamera){ - ui_dialogCamera = new DialogCamera(this); - } - ui_dialogCamera->show(); -} - - -void MainWindow::on_menu_config_triggered() -{ - qDebug() << __func__ ; - if(nullptr == ui_dialogConfig){ - ui_dialogConfig = new DialogConfig(this); - } - ui_dialogConfig->show(); -} +//void MainWindow::on_menu_camera_triggered() +//{ +// qDebug() << __func__ ; +//} +//void MainWindow::on_menu_config_triggered() +//{ +// qDebug() << __func__ ; +// if(nullptr == ui_dialogConfig){ +// ui_dialogConfig = new DialogConfig(this); +// } +// ui_dialogConfig->show(); +//} void MainWindow::on_menu_camera_adjust_triggered() { @@ -213,11 +209,8 @@ void MainWindow::OnStatusUpdate(const std::string& statusMessage) void MainWindow::OnDetectionResult(const DetectionResult& result) { - // 显示检测结果图像 - displayImage(result.image); - - // 添加检测结果到列表 - addDetectionResult(result); + // 通过信号槽机制更新UI(确保在主线程中执行) + emit detectionResultUpdateRequested(result); } void MainWindow::OnCamera1StatusChanged(bool isConnected) @@ -226,7 +219,7 @@ void MainWindow::OnCamera1StatusChanged(bool isConnected) setStatusDot(ui->label_camera_1_status, isConnected); // 更新状态消息 - QString statusMsg = isConnected ? tr("相机1已连接") : tr("相机1已断开"); + QString statusMsg = isConnected ? tr("相机一已连接") : tr("相机一已断开"); ui->label_camera_1_txt->setText(statusMsg); updateStatusLog(statusMsg); } @@ -238,7 +231,7 @@ void MainWindow::OnCamera2StatusChanged(bool isConnected) setStatusDot(ui->label_camera_2_status, isConnected); // 更新状态消息 - QString statusMsg = isConnected ? tr("相机2已连接") : tr("相机2已断开"); + QString statusMsg = isConnected ? tr("相机二已连接") : tr("相机二已断开"); ui->label_camera_2_txt->setText(statusMsg); updateStatusLog(statusMsg); } @@ -272,11 +265,17 @@ void MainWindow::OnRobotConnectionChanged(bool isConnected) // 更新状态消息 QString statusMsg = isConnected ? tr("机械臂已连接") : tr("机械臂已断开"); - updateStatusLog(statusMsg); + updateStatusLog(statusMsg); } // 工作状态更新槽函数 void MainWindow::OnWorkStatusChanged(WorkStatus status) +{ + // 通过信号槽机制更新UI(确保在主线程中执行) + emit workStatusUpdateRequested(status); +} + +void MainWindow::updateWorkStatusLabel(WorkStatus status) { // 获取状态对应的显示文本 QString statusText = QString::fromStdString(WorkStatusToString(status)); @@ -309,6 +308,40 @@ void MainWindow::OnWorkStatusChanged(WorkStatus status) updateStatusLog(statusText); } +void MainWindow::updateDetectionResultDisplay(const DetectionResult& result) +{ + // 实现检测结果显示的逻辑 + displayImage(result.image); + addDetectionResult(result); +} + + +void MainWindow::on_action_camera_1_triggered() +{ + IVrEyeDevice* pDevice = m_presenter->GetEyeDevice(0); + if(nullptr == pDevice){ + QMessageBox::warning(this, "设备错误", "相机设备未正确初始化!"); + return; + } + if(nullptr == ui_dialogCamera){ + ui_dialogCamera = new DialogCamera(pDevice, this); + } + ui_dialogCamera->show(); +} + + +void MainWindow::on_action_camera_2_triggered() +{ + IVrEyeDevice* pDevice = m_presenter->GetEyeDevice(1); + if(nullptr == pDevice){ + QMessageBox::warning(this, "设备错误", "相机设备未正确初始化!"); + return; + } + if(nullptr == ui_dialogCamera){ + ui_dialogCamera = new DialogCamera(pDevice, this); + } + ui_dialogCamera->show(); +} diff --git a/GrabBagApp/mainwindow.h b/GrabBagApp/mainwindow.h index 8f0c6c14..ec03fe06 100644 --- a/GrabBagApp/mainwindow.h +++ b/GrabBagApp/mainwindow.h @@ -1,4 +1,4 @@ - #ifndef MAINWINDOW_H +#ifndef MAINWINDOW_H #define MAINWINDOW_H #include @@ -36,6 +36,13 @@ public: virtual void OnCameraCountChanged(int cameraCount) override; virtual void OnWorkStatusChanged(WorkStatus status) override; +signals: + // 工作状态更新信号 + void workStatusUpdateRequested(WorkStatus status); + + // 检测结果更新信号 + void detectionResultUpdateRequested(const DetectionResult& result); + private slots: // UI操作相关槽 void on_btn_camera_clicked(); @@ -43,9 +50,19 @@ private slots: void on_btn_flow_clicked(); void on_btn_start_clicked(); void on_btn_stop_clicked(); - void on_menu_camera_triggered(); - void on_menu_config_triggered(); +// void on_menu_camera_triggered(); +// void on_menu_config_triggered(); void on_menu_camera_adjust_triggered(); + + // 工作状态更新槽函数 + void updateWorkStatusLabel(WorkStatus status); + + // 检测结果更新槽函数 + void updateDetectionResultDisplay(const DetectionResult& result); + + void on_action_camera_1_triggered(); + + void on_action_camera_2_triggered(); private: Ui::MainWindow *ui; diff --git a/GrabBagApp/mainwindow.ui b/GrabBagApp/mainwindow.ui index d1f222dd..55365bf3 100644 --- a/GrabBagApp/mainwindow.ui +++ b/GrabBagApp/mainwindow.ui @@ -197,6 +197,8 @@ 相机配置 + + @@ -219,6 +221,16 @@ + + + 相机一配置 + + + + + 相机二配置 + + diff --git a/Module/ModbusTCPServer/Inc/IYModbusTCPServer.h b/Module/ModbusTCPServer/Inc/IYModbusTCPServer.h index a124675a..4969ef4d 100644 --- a/Module/ModbusTCPServer/Inc/IYModbusTCPServer.h +++ b/Module/ModbusTCPServer/Inc/IYModbusTCPServer.h @@ -32,6 +32,9 @@ public: // 写保持寄存器回调函数:unitId, startAddress, quantity, values -> ErrorCode using WriteRegistersCallback = std::function; + + // 连接状态回调函数:isConnected -> void + using ConnectionStatusCallback = std::function; public: virtual ~IYModbusTCPServer() = default; @@ -39,12 +42,13 @@ public: static bool CreateInstance(IYModbusTCPServer** ppModbusTCPServer); // 启动/停止服务器 - virtual bool start(int port = 502, int maxConnections = 10) = 0; + virtual int start(int port = 502, int maxConnections = 10) = 0; virtual void stop() = 0; // 设置回调函数 virtual void setWriteCoilsCallback(WriteCoilsCallback callback) = 0; virtual void setWriteRegistersCallback(WriteRegistersCallback callback) = 0; + virtual void setConnectionStatusCallback(ConnectionStatusCallback callback) = 0; // 更新数据接口 - 线程安全 virtual void updateCoil(uint16_t address, bool value) = 0; diff --git a/Module/ModbusTCPServer/ModbusTCPServer.pro b/Module/ModbusTCPServer/ModbusTCPServer.pro index 08b672e4..0c262f8d 100644 --- a/Module/ModbusTCPServer/ModbusTCPServer.pro +++ b/Module/ModbusTCPServer/ModbusTCPServer.pro @@ -19,6 +19,10 @@ DEFINES += DLLBUILD TEMPLATE = lib CONFIG += staticlib + +INCLUDEPATH += ../../VrCommon/Inc +INCLUDEPATH += ../../VrUtils/Inc + INCLUDEPATH += ./Inc INCLUDEPATH += ./_Inc diff --git a/Module/ModbusTCPServer/Src/ModbusTCPServer.cpp b/Module/ModbusTCPServer/Src/ModbusTCPServer.cpp index f5caf598..e056567a 100644 --- a/Module/ModbusTCPServer/Src/ModbusTCPServer.cpp +++ b/Module/ModbusTCPServer/Src/ModbusTCPServer.cpp @@ -3,6 +3,9 @@ #include #include +#include "VrError.h" +#include "VrSimpleLog.h" + #ifdef _WIN32 #include #include @@ -32,11 +35,11 @@ ModbusTCPServer::~ModbusTCPServer() stop(); } -bool ModbusTCPServer::start(int port, int maxConnections) +int ModbusTCPServer::start(int port, int maxConnections) { if (m_isRunning.load()) { setLastError("服务器已在运行"); - return true; + return SUCCESS; } m_port = port; @@ -46,7 +49,7 @@ bool ModbusTCPServer::start(int port, int maxConnections) m_modbusCtx = modbus_new_tcp("0.0.0.0", port); if (m_modbusCtx == nullptr) { setLastError("创建Modbus TCP上下文失败"); - return false; + return ERR_CODE(NET_ERR_CREAT_INIT); } // 创建数据映射 - 分配足够的空间 @@ -56,7 +59,7 @@ bool ModbusTCPServer::start(int port, int maxConnections) setLastError("创建数据映射失败"); modbus_free(m_modbusCtx); m_modbusCtx = nullptr; - return false; + return ERR_CODE(NET_ERR_CONFIG); } // 监听连接 @@ -67,7 +70,7 @@ bool ModbusTCPServer::start(int port, int maxConnections) m_mapping = nullptr; modbus_free(m_modbusCtx); m_modbusCtx = nullptr; - return false; + return ERR_CODE(NET_ERR_CREAT_LISTEN); } m_isRunning.store(true); @@ -76,7 +79,12 @@ bool ModbusTCPServer::start(int port, int maxConnections) // 启动服务器线程 m_serverThread = std::make_unique(&ModbusTCPServer::serverLoop, this); - return true; + // 初始状态:服务器启动但没有客户端连接 + if (m_connectionStatusCallback) { + m_connectionStatusCallback(false); + } + + return SUCCESS; } void ModbusTCPServer::stop() @@ -154,7 +162,7 @@ void ModbusTCPServer::serverLoop() if (selectResult == -1) { if (!m_shouldStop.load()) { - std::cerr << "select错误: " << strerror(errno) << std::endl; + LOG_WARNING("select error: %s\n", strerror(errno)); } break; } @@ -198,7 +206,7 @@ void ModbusTCPServer::handleNewConnection() int clientSocket = modbus_tcp_accept(m_modbusCtx, &m_serverSocket); if (clientSocket == -1) { if (!m_shouldStop.load()) { - std::cerr << "接受连接失败: " << modbus_strerror(errno) << std::endl; + LOG_ERRO("Accept connection failed: %s\n", modbus_strerror(errno)); } return; } @@ -206,7 +214,7 @@ void ModbusTCPServer::handleNewConnection() // 创建新的modbus context用于此客户端 modbus_t* clientCtx = modbus_new_tcp("0.0.0.0", m_port); if (clientCtx == nullptr) { - std::cerr << "为客户端创建Modbus上下文失败" << std::endl; + LOG_ERRO("Create Modbus context for client failed\n"); #ifdef _WIN32 closesocket(clientSocket); #else @@ -227,7 +235,12 @@ void ModbusTCPServer::handleNewConnection() m_clients[clientSocket] = client; } - std::cout << "新客户端连接: socket=" << clientSocket << std::endl; + LOG_INFO("New client connected: socket=%d\n", clientSocket); + + // 触发连接状态回调 + if (m_connectionStatusCallback) { + m_connectionStatusCallback(true); + } } void ModbusTCPServer::handleClientData(std::shared_ptr client) @@ -240,9 +253,9 @@ void ModbusTCPServer::handleClientData(std::shared_ptr client) if (bytesReceived <= 0) { // 连接断开或错误 if (bytesReceived == 0) { - std::cout << "客户端断开连接: socket=" << client->socket << std::endl; + LOG_VERBOSE("Client disconnected: socket=%d\n", client->socket); } else { - std::cerr << "接收数据错误: " << strerror(errno) << std::endl; + LOG_ERRO("Receive data error: %s\n", strerror(errno)); } throw std::runtime_error("客户端连接错误"); } @@ -256,8 +269,13 @@ void ModbusTCPServer::removeClient(int socket) std::lock_guard lock(m_clientsMutex); auto it = m_clients.find(socket); if (it != m_clients.end()) { - std::cout << "移除客户端连接: socket=" << socket << std::endl; + LOG_INFO("Remove client connection: socket=%d\n", socket); m_clients.erase(it); + + // 如果没有客户端连接了,触发断开回调 + if (m_clients.empty() && m_connectionStatusCallback) { + m_connectionStatusCallback(false); + } } } @@ -268,42 +286,134 @@ void ModbusTCPServer::processModbusRequest(std::shared_ptr cli int responseRc = modbus_reply(client->modbusCtx, query, queryLength, m_mapping); if (responseRc == -1) { - std::cerr << "发送响应失败: " << modbus_strerror(errno) << std::endl; + LOG_WARNING("Send response failed: %s\n", modbus_strerror(errno)); throw std::runtime_error("发送响应失败"); } - // 检查是否是写操作,如果是则调用回调 - if (queryLength >= 8) { // 确保有足够的字节 - uint8_t function = query[7]; // 功能码在TCP ADU的第8字节 - uint16_t address = (query[8] << 8) | query[9]; - uint16_t quantity = (query[10] << 8) | query[11]; - uint8_t unitId = query[6]; + // 解析ModbusTCP ADU - 最小长度检查 + if (queryLength < 8) { + LOG_DEBUG("Query too short: %d bytes\n", queryLength); + return; + } - switch (function) { - case MODBUS_FC_WRITE_SINGLE_COIL: - case MODBUS_FC_WRITE_MULTIPLE_COILS: - if (m_writeCoilsCallback) { - const uint8_t* values = &query[12]; // 数据从第13字节开始 - ErrorCode result = m_writeCoilsCallback(unitId, address, quantity, values); - if (result != ErrorCode::SUCCESS) { - // 发送异常响应 - modbus_reply_exception(client->modbusCtx, query, static_cast(result)); + // ModbusTCP ADU格式: [Transaction ID(2)] [Protocol ID(2)] [Length(2)] [Unit ID(1)] [Function Code(1)] [Data...] + uint16_t transactionId = (query[0] << 8) | query[1]; // Transaction ID + uint16_t protocolId = (query[2] << 8) | query[3]; // Protocol ID (should be 0 for ModbusTCP) + uint16_t length = (query[4] << 8) | query[5]; // Length field + uint8_t unitId = query[6]; // Unit ID + uint8_t function = query[7]; // Function Code + + // 验证协议ID + if (protocolId != 0) { + LOG_DEBUG("Invalid protocol ID: %d\n", protocolId); + return; + } + + // 验证长度字段 + if (length != (queryLength - 6)) { + LOG_DEBUG("Length mismatch: expected %d, got %d\n", length, queryLength - 6); + return; + } + + LOG_DEBUG("ModbusTCP request - TransID:%d, UnitID:%d, Function:0x%02X\n", + transactionId, unitId, function); + + // 根据功能码解析数据 + switch (function) { + case MODBUS_FC_WRITE_SINGLE_COIL: + { + if (queryLength >= 12) { + uint16_t address = (query[8] << 8) | query[9]; + uint16_t value = (query[10] << 8) | query[11]; + + LOG_DEBUG("Write single coil - Address:%d, Value:%d\n", address, value); + + if (m_writeCoilsCallback) { + uint8_t coilValue = (value == 0xFF00) ? 1 : 0; + ErrorCode result = m_writeCoilsCallback(unitId, address, 1, &coilValue); + if (result != ErrorCode::SUCCESS) { + LOG_DEBUG("Write coil callback returned error: %d\n", (int)result); + } } } - break; - - case MODBUS_FC_WRITE_SINGLE_REGISTER: - case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: - if (m_writeRegistersCallback) { - const uint16_t* values = reinterpret_cast(&query[12]); - ErrorCode result = m_writeRegistersCallback(unitId, address, quantity, values); - if (result != ErrorCode::SUCCESS) { - // 发送异常响应 - modbus_reply_exception(client->modbusCtx, query, static_cast(result)); + } + break; + + case MODBUS_FC_WRITE_MULTIPLE_COILS: + { + if (queryLength >= 13) { + uint16_t address = (query[8] << 8) | query[9]; + uint16_t quantity = (query[10] << 8) | query[11]; + uint8_t byteCount = query[12]; + + if (queryLength >= (13 + byteCount)) { + LOG_DEBUG("Write multiple coils - Address:%d, Quantity:%d, Bytes:%d\n", + address, quantity, byteCount); + + if (m_writeCoilsCallback) { + const uint8_t* values = &query[13]; + ErrorCode result = m_writeCoilsCallback(unitId, address, quantity, values); + if (result != ErrorCode::SUCCESS) { + LOG_DEBUG("Write coils callback returned error: %d\n", (int)result); + } + } } } - break; - } + } + break; + + case MODBUS_FC_WRITE_SINGLE_REGISTER: + { + if (queryLength >= 12) { + uint16_t address = (query[8] << 8) | query[9]; + uint16_t value = (query[10] << 8) | query[11]; + + LOG_DEBUG("Write single register - Address:%d, Value:%d\n", address, value); + + if (m_writeRegistersCallback) { + ErrorCode result = m_writeRegistersCallback(unitId, address, 1, &value); + if (result != ErrorCode::SUCCESS) { + LOG_DEBUG("Write register callback returned error: %d\n", (int)result); + } + } + } + } + break; + + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: + { + if (queryLength >= 13) { + uint16_t address = (query[8] << 8) | query[9]; + uint16_t quantity = (query[10] << 8) | query[11]; + uint8_t byteCount = query[12]; + + if (queryLength >= (13 + byteCount) && byteCount == (quantity * 2)) { + LOG_DEBUG("Write multiple registers - Address:%d, Quantity:%d, Bytes:%d\n", + address, quantity, byteCount); + + if (m_writeRegistersCallback) { + // 解析寄存器值(注意字节序) + std::vector values; + values.reserve(quantity); + + for (int i = 0; i < quantity; i++) { + uint16_t value = (query[13 + i*2] << 8) | query[13 + i*2 + 1]; + values.push_back(value); + } + + ErrorCode result = m_writeRegistersCallback(unitId, address, quantity, values.data()); + if (result != ErrorCode::SUCCESS) { + LOG_DEBUG("Write registers callback returned error: %d\n", (int)result); + } + } + } + } + } + break; + + default: + LOG_DEBUG("Unhandled function code: 0x%02X\n", function); + break; } } @@ -399,4 +509,4 @@ bool IYModbusTCPServer::CreateInstance(IYModbusTCPServer** ppModbusTCPServer) *ppModbusTCPServer = new ModbusTCPServer(); return true; -} \ No newline at end of file +} diff --git a/Module/ModbusTCPServer/_Inc/ModbusTCPServer.h b/Module/ModbusTCPServer/_Inc/ModbusTCPServer.h index ce9cd622..bb1e4969 100644 --- a/Module/ModbusTCPServer/_Inc/ModbusTCPServer.h +++ b/Module/ModbusTCPServer/_Inc/ModbusTCPServer.h @@ -47,13 +47,14 @@ public: // 实现IYModbusTCPServer接口 // 启动/停止服务器 - virtual bool start(int port = 502, int maxConnections = 10) override; + virtual int start(int port = 502, int maxConnections = 10) override; virtual void stop() override; bool isRunning() const { return m_isRunning.load(); } // 设置回调函数 virtual void setWriteCoilsCallback(WriteCoilsCallback callback) override { m_writeCoilsCallback = callback; } virtual void setWriteRegistersCallback(WriteRegistersCallback callback) override { m_writeRegistersCallback = callback; } + virtual void setConnectionStatusCallback(ConnectionStatusCallback callback) override { m_connectionStatusCallback = callback; } // 数据更新接口 - 线程安全 virtual void updateCoil(uint16_t address, bool value) override; @@ -111,6 +112,7 @@ private: // 回调函数 WriteCoilsCallback m_writeCoilsCallback; WriteRegistersCallback m_writeRegistersCallback; + ConnectionStatusCallback m_connectionStatusCallback; // 错误信息 mutable std::mutex m_errorMutex; @@ -120,4 +122,4 @@ private: void setLastError(const std::string& error); }; -#endif // MODBUS_TCP_SERVER_H \ No newline at end of file +#endif // MODBUS_TCP_SERVER_H diff --git a/VrEyeDevice/Src/VrEyeCommon.cpp b/VrEyeDevice/Src/VrEyeCommon.cpp index cc151d1b..62957e49 100644 --- a/VrEyeDevice/Src/VrEyeCommon.cpp +++ b/VrEyeDevice/Src/VrEyeCommon.cpp @@ -17,9 +17,14 @@ CVrEyeCommon* CVrEyeCommon::GetInstance() int CVrEyeCommon::InitDevice() { int nErrCode = SUCCESS; + if(m_bInit) return nErrCode; + // 初始化SDK SVzNLConfigParam sVzNlConfigParam; nErrCode = VzNL_Init(&sVzNlConfigParam); + + m_bInit = (SUCCESS == nErrCode); + return nErrCode; } diff --git a/VrEyeDevice/_Inc/VrEyeCommon.h b/VrEyeDevice/_Inc/VrEyeCommon.h index 30bd6efb..5dd345ef 100644 --- a/VrEyeDevice/_Inc/VrEyeCommon.h +++ b/VrEyeDevice/_Inc/VrEyeCommon.h @@ -1,6 +1,6 @@ #ifndef VREYECOMMON_H #define VREYECOMMON_H - +#include class CVrEyeCommon { @@ -12,6 +12,9 @@ public: int InitDevice(); +private: + std::atomic m_bInit = false; + }; #endif // VREYECOMMON_H diff --git a/VrUtils/Inc/VrSimpleLog.h b/VrUtils/Inc/VrSimpleLog.h index 2d531392..52eb02fc 100644 --- a/VrUtils/Inc/VrSimpleLog.h +++ b/VrUtils/Inc/VrSimpleLog.h @@ -54,7 +54,6 @@ #define _CRT_SECURE_NO_WARNINGS -////定义Log? ///******************************************************************************************************************/ #ifdef __ANDROID__ #include @@ -65,28 +64,6 @@ #define LOG_ERRO(...) __android_log_print(ANDROID_LOG_ERROR, "VrAPPE", ##__VA_ARGS__) #else -//#ifdef QT_CORE_LIB - - -//#define LOG_TIME do { \ -//std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); \ -// std::time_t timestamp = std::chrono::system_clock::to_time_t(now); \ -// std::tm local_time; \ -// localtime_s(&local_time, ×tamp); \ -// long long milliseconds = std::chrono::duration_cast(now.time_since_epoch()).count(); \ -// char varTime[128] = { 0 }; \ -// sprintf_s(varTime, "%d-%02d-%02d %02d:%02d:%02d.%03lld", local_time.tm_year + 1900 , local_time.tm_mon + 1, local_time.tm_mday, local_time.tm_hour, local_time.tm_min, local_time.tm_sec, milliseconds % 1000); \ -// _LOG_OUTPUT << varTime; \ -//} while(0) - -//#define LOG_VERBOSE(level,fmt, ...) do { if(level <= 1) { _EchoLog( true, "V", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_DEBUG(level,fmt, ...) do { if(level <= 2) { _EchoLog( true, "D", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_DEBUG_NOLINE(level,fmt, ...) do { if(level <= 3) { _EchoLog( false, "D", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_INFO(level,fmt, ...) do { if(level <= 3) { _EchoLog( true, "I", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_WARNING(level,fmt, ...) do { if(level <= 4) { _EchoLog( true, "W", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_ERRO(level,fmt, ...) do { if(level <= 5) { _EchoLog( true, "E", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#define LOG_ERR(level,fmt, ...) do { if(level <= 5) { _EchoLog( true, "E", logfilename(__FILE__), __LINE__, fmt ); }} while(0) -//#else #if 0 #include @@ -105,48 +82,14 @@ std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); } while(0) -#define LOG_VERBOSE(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" V[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -#define LOG_DEBUG(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" D[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -#define LOG_DEBUG_NOLINE(fmt, ...) do { { printf(fmt, ##__VA_ARGS__); }} while(0) -#define LOG_INFO(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" I[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -#define LOG_WARNING(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" W[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -#define LOG_ERRO(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" E[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -#define LOG_ERR(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" E[%s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); }} while(0) -//#endif +#define LOG_VERBOSE(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" V[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_DEBUG(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" D[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_DEBUG_NOLINE(fmt, ...) do { { printf(fmt, ##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_INFO(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" I[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout);} while(0) +#define LOG_WARNING(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" W[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_ERROR(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" E[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_ERRO(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" E[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) +#define LOG_ERR(fmt, ...) do { { LOG_TIME; _LOG_OUTPUT(" E[%20s : %4u] " fmt"", logfilename(__FILE__), __LINE__ ,##__VA_ARGS__); } fflush(stdout); } while(0) + #endif ///******************************************************************************************************************/ - -#if 0 - -static void _EchoLog(const bool bLogHead, const char* sTag, const char* fileName, const int nLenNo, const char* sFormat, ...) -{ - // load log info - va_list args; - va_start(args, sFormat); - char szLogInfo[1024] = { 0 }; -#ifdef _WIN32 - vsprintf_s(szLogInfo, sFormat, args); -#else - vsprintf(szLogInfo, sFormat, args); -#endif - va_end(args); - - std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - std::time_t timestamp = std::chrono::system_clock::to_time_t(now); - std::tm local_time; - localtime_s(&local_time, ×tamp); - long long milliseconds = std::chrono::duration_cast(now.time_since_epoch()).count(); - char varTime[128] = { 0 }; - sprintf_s(varTime, "%d-%02d-%02d %02d:%02d:%02d.%03lld", local_time.tm_year + 1900 , local_time.tm_mon + 1, local_time.tm_mday, local_time.tm_hour, local_time.tm_min, local_time.tm_sec, milliseconds % 1000); - - if(bLogHead) - { - _LOG_OUTPUT << varTime << "[" << sTag << fileName << ":" << nLenNo << "]" << szLogInfo; - } - else - { - _LOG_OUTPUT << szLogInfo; - } - -} -#endif