#include "stdafx.h" #include #include "sys\stat.h" #include //文件流库函数 #include #include "XiuYuanCtrl.h" #include "common_api.h" #include "CiniFile.h" #include "MyPingip.h" #include "CiniFile.h" extern Log4CPP::Logger* gLogger; #include #pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "Version.lib") XiuYuanCtrl* g_pXiuYuanCtrl = nullptr; XiuYuanCtrl::XiuYuanCtrl() :m_hXiuYuanModule(nullptr), API_YI_Initialize_FPD_V4(nullptr), API_YI_FPD_Set_Work_Mode(nullptr), API_YI_FPD_Stop_Capture_Image(nullptr), API_YI_FPD_Get_Configure_Common(nullptr), API_YI_FPD_Set_Configure_Common(nullptr), API_YI_FPD_Get_Configure_SyncOut_Mode(nullptr), API_YI_FPD_Set_Configure_SyncOut_Mode(nullptr), API_YI_FPD_Restore_Factory_Settings(nullptr), API_YI_ImageReady_Callback_Register(nullptr), API_YI_SystemInfo_Callback_Register(nullptr), API_YI_Get_Callback_Image_Size(nullptr), API_YI_GetLastErrorCode(nullptr), API_YI_Set_Save_Log_Flag(nullptr), API_YI_GetLoacalIPs_V4(nullptr), API_YI_Set_Image_Save_State(nullptr), API_YI_Set_Image_Save_Path(nullptr), API_YI_FPD_Get_FPD_TYPE(nullptr), API_YI_FPD_Get_Invalid_Region(nullptr), API_YI_FPD_Capture_Image(nullptr), API_YI_FPD_Capture_Prepare(nullptr), API_YI_Load_Gain_Tmp_File(nullptr), API_YI_Load_Defect_Tmp_File(nullptr), API_YI_Load_Offset_Tmp_File(nullptr), API_YI_Load_AED_Offset_Tmp_File(nullptr), API_YI_Set_Correct_Type(nullptr), API_YI_FPD_FreeBuffer(nullptr), m_strAppPath{}, m_strWorkPath{}, m_strAcqMode{}, m_nPanelCount{}, m_nDetectorID(1), m_nDetectorIndex{}, m_pZSKKCalib{}, m_bInCalibrating(false), m_bInExposure(false), m_bSaveRaw(false), m_bTemperatureEnable(false), m_bBatteryEnable(false), m_bWifiEnable(false), m_bConnectStatus(false), m_pHardwareStatusThread(nullptr), m_hEndHWStatusThreadEvent(nullptr), m_hHWStatusThreadEndEvent(nullptr), m_eAppStatus(APP_STATUS_IDLE), m_nImageWidth{}, m_nImageHeight{}, m_nRawImgWidth{}, m_nRawImgHeight{}, m_nHeightOffset{}, m_nWidthOffset{}, m_nSyncMode{}, m_nImgBits(16), m_nPixelPitch(150), m_pImgBuffer(nullptr), m_pRawImgBuffer(nullptr), m_hExitEvent(nullptr), m_hXiuYuanScanEnd(nullptr), m_hWindowOffEvent(nullptr), m_pOffsetThread(nullptr), m_pXWindowoffThread(nullptr), m_hScanEventThread(nullptr), m_nCalibStatus{}, m_nDoseParam{}, m_nCalibrationMode{}, m_nDefectExpTimes{}, m_nDefectTotalTimes{}, m_nGainExpTimes{}, m_nGainTotalFrames{}, m_nDefectTotalFrames{}, m_nExpWindowMode{}, m_nXWindow{}, m_bFreeBuffer(false), m_bStandbyFlag(false) { m_hInitThread = nullptr; m_hScanEventThread = nullptr; m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); m_vecDetectorID.clear(); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; for (int i = 0; i < XiuYuan_SCAN_NUM; i++) { m_hArrayEvent[i] = nullptr; } } XiuYuanCtrl::~XiuYuanCtrl() { OnEXIT(); if (m_pImgBuffer) { delete[] m_pImgBuffer; m_pImgBuffer = nullptr; } if (m_pZSKKCalib) { delete m_pZSKKCalib; m_pZSKKCalib = nullptr; } delete m_pDPC2PanelID; m_pDPC2PanelID = nullptr; delete m_pPanelID2DPC; m_pPanelID2DPC = nullptr; } bool XiuYuanCtrl::OnEXIT() { SetEvent(m_hEndHWStatusThreadEvent); FINFO("Waiting HWStatus Thread End"); int nResult = WaitForSingleObject(m_hHWStatusThreadEndEvent, 10000); if (WAIT_TIMEOUT == nResult) { FERROR("XiuYuan HWStatus Thread Quit Failed"); } else { FINFO("XiuYuan HWStatus Thread Quit Success"); } SetEvent(m_hExitEvent); FINFO("Waiting XiuYuan ScanEvent Thread End"); nResult = WaitForSingleObject(m_hXiuYuanScanEnd, 2000); if (WAIT_TIMEOUT == nResult) { FERROR("XiuYuan ScanEvent Thread Quit Failed"); } else { FINFO("XiuYuan ScanEvent Thread Quit Success"); } DeleteHandle(); FINFO("Free XiuYuan DLL"); FreeXiuYuanDLL(); return true; } void XiuYuanCtrl::DeleteHandle() { if (m_hExitEvent) { CloseHandle(m_hExitEvent); m_hExitEvent = nullptr; } if (m_hXiuYuanScanEnd) { CloseHandle(m_hXiuYuanScanEnd); m_hXiuYuanScanEnd = nullptr; } if (m_hHWStatusThreadEndEvent) { CloseHandle(m_hHWStatusThreadEndEvent); m_hHWStatusThreadEndEvent = nullptr; } if (m_pRawImgBuffer) { delete[] m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } } bool XiuYuanCtrl::Init(string strAppPath) { std::string strDllPath; strDllPath = strAppPath + (string)m_ModeConfig["SDKPath"]; m_strDetectorType = (string)m_ModeConfig["DeviceName"]; m_strAppPath = strAppPath; FINFO("XiuYuanCtrl::Init {$}", strDllPath.c_str()); if (!LoadXiuYuanDLL(strDllPath)) { FERROR("XiuYuanCtrl::Init LoadXiuYuanDLL failed"); return false; } m_hXiuYuanScanEnd = CreateEvent(NULL, FALSE, FALSE, NULL); m_hWindowOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hHWStatusThreadEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hExitEvent; FINFO("XiuYuanCtrl::Init over"); return true; } //初始化连接探测器 bool XiuYuanCtrl::DetectorInitProcess(int nDetectorID, bool bFDAttach) { FINFO("--XiuYuanCtrl Func-- DetectorInitProcess"); int nDetectorIndex = nDetectorID - 1; bool bPingSucces = false; int nPingTotalTime = 30; //ping不通,一次约2s,共30次,1分钟左右超时 int nLocalPort; int nRemotePort; bool bSDKSaveLog; bool bSDKSaveRaw; string strWirdIP; string strLocalIP; string strSDKSaveLogPath; string strSDKSaveRawPath; strWirdIP = (string)m_ModeConfig["DetectorWiredIP"]; for (int nPingTimes = 0; nPingTimes < nPingTotalTime; nPingTimes++) { bPingSucces = IsConnected(strWirdIP); if (bPingSucces) { FINFO("Ping Detector successfully"); break; } Sleep(2000); } //ping不通就不用连接了 if (!bPingSucces) { FERROR("Ping detector failed, timeout!!!"); return false; } m_bTemperatureEnable = ((int)m_ModeConfig["TemperatureEnable"] != 0) ? true : false; m_bBatteryEnable = ((int)m_ModeConfig["BatteryEnable"] != 0) ? true : false; m_bWifiEnable = ((int)m_ModeConfig["WifiEnable"] != 0) ? true : false; m_nExpWindowMode = (int)m_ModeConfig["ExpWindowMode"]; string strXWindowMode = "XWindow" + std::to_string(m_nExpWindowMode); m_nXWindow = (int)m_ModeConfig["ExpWindow"][strXWindowMode.c_str()]; StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, ""); strLocalIP = (string)m_ModeConfig["LocalIP"]; nLocalPort = 28000; nRemotePort = 27999; char szDetectorID[100] = { 0 }; FINFO("LocalIP: {$}:28000, RemoteIP: {$}:27999", strLocalIP, strWirdIP); int nRet = API_YI_Initialize_FPD_V4(strWirdIP.c_str(), nRemotePort, szDetectorID); if (TestError(nDetectorID, nRet, "API_YI_Initialize_FPD_V4")) { FERROR("Connect Detector {$} Failed", nDetectorID); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, ""); return false; } m_vecDetectorID.push_back(szDetectorID); FINFO("Connect Detector {$} Success", nDetectorID); m_bConnectStatus = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT); bSDKSaveLog = (bool)m_ModeConfig["SDKSaveLog"]; strSDKSaveLogPath = (string)m_ModeConfig["SDKSaveLogPath"]; nRet = API_YI_Set_Save_Log_Flag(bSDKSaveLog, strSDKSaveLogPath.c_str()); if (TestError(nDetectorID, nRet, "SaveLog")) { FERROR("{$} SDK save log failed!!! path: {$} ", (bSDKSaveLog ? "Enable" : "Disable"), strSDKSaveLogPath); } else { FINFO("{$} SDK save log success, path: {$}", (bSDKSaveLog ? "Enable" : "Disable"), strSDKSaveLogPath); } bSDKSaveRaw = (bool)m_ModeConfig["SDKSaveRaw"]; strSDKSaveRawPath = (string)m_ModeConfig["SDKSaveRawPath"]; nRet = API_YI_Set_Image_Save_Path(szDetectorID, strSDKSaveRawPath.c_str()); nRet |= API_YI_Set_Image_Save_State(szDetectorID, bSDKSaveRaw); if (TestError(nDetectorID, nRet, "SaveRaw")) { FERROR("{$} SDK save raw image failed!!! path: {$} ", (bSDKSaveRaw ? "Enable" : "Disable"), strSDKSaveRawPath); } else { FINFO("{$} SDK save raw image success, path: {$}", (bSDKSaveRaw ? "Enable" : "Disable"), strSDKSaveRawPath); } //获取尺寸 int nWidth = 0; int nHeight = 0; int nBits = 0; nRet = API_YI_Get_Callback_Image_Size(szDetectorID, nWidth, nHeight, nBits); if (TestError(nDetectorID, nRet, "API_YI_Get_Callback_Image_Size")) { FERROR("Get detector({$}) image size failed", nDetectorID); } else { FINFO("Get detector image size: {$}x{$}x{$}", nWidth, nHeight, nBits); } //注册回调 /*nRet = API_YI_ImageReady_Callback_Register(szDetectorID, nullptr); if (TestError(nDetectorID, nRet, "API_YI_ImageReady_Callback_Register")) { FERROR("Reset ImageReadyCallbackProcess failed!!!"); } else { FINFO("Reset ImageReadyCallbackProcess success"); }*/ nRet = API_YI_SystemInfo_Callback_Register(szDetectorID, nullptr); if (TestError(nDetectorID, nRet, "API_YI_SystemInfo_Callback_Register")) { FERROR("Reset SystemInfoCallbackProcess failed!!!"); } else { FINFO("Reset SystemInfoCallbackProcess success"); } nRet = API_YI_ImageReady_Callback_Register(szDetectorID, ImageReadyCallbackProcess); if (TestError(nDetectorID, nRet, "API_YI_ImageReady_Callback_Register")) { FERROR("Register ImageReadyCallbackProcess failed!!!"); } else { FINFO("Register ImageReadyCallbackProcess success"); } nRet = API_YI_SystemInfo_Callback_Register(szDetectorID, SystemInfoCallbackProcess); if (TestError(nDetectorID, nRet, "API_YI_SystemInfo_Callback_Register")) { FERROR("Register SystemInfoCallbackProcess failed!!!"); } else { FINFO("Register SystemInfoCallbackProcess success"); } //读取或设置common参数 YIConfigInfo_Common stConfigCommon = { 0 }; nRet = API_YI_FPD_Get_Configure_Common(szDetectorID, &stConfigCommon); if (TestError(nDetectorID, nRet, "API_YI_FPD_Get_Configure_Common")) { FERROR("Get detector common config failed!!!"); } else { FINFO("Get detector common config success"); FINFO("DetectorSN: {$}; FPGA version: {$}; MCU version: {$}; NetWork: {$}:{$}", stConfigCommon.arrProductInitSN, stConfigCommon.arrFPGAVerMain, stConfigCommon.arrMCUVerMain, stConfigCommon.arrLocalIPAddress, stConfigCommon.usLocalUDPPort); } //读取syncout参数 YIConfigInfo_SyncOut stConfigSyncOut = { 0 }; nRet = API_YI_FPD_Get_Configure_SyncOut_Mode(szDetectorID, &stConfigSyncOut); if (TestError(nDetectorID, nRet, "API_YI_FPD_Get_Configure_SyncOut_Mode")) { FERROR("Get detector syncmode config failed!!!"); } else { FINFO("Get detector syncmode config success"); FINFO("ExpWindow: {$}; ExpTimeout: {$}; ", stConfigSyncOut.usExposureWindow, stConfigSyncOut.usExposureTimeOut); } m_nCalibrationMode = (CCOS_CALIBRATION_MODE)((int)m_ModeConfig["CalibMode"]); m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"]; m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"]; if (m_nCalibrationMode == CCOS_CALIBRATION_MODE::CCOS_CALIBRATION_MODE_ZSKK) { Info("Load ZSKK Reference file"); m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "\\references\\"; //读取配置文件中RAD模式的高和宽 m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight; m_pZSKKCalib->m_nSaturationValue = 50000; if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strDetectorType)) { Warn("Load ZSKK Gain calibration failed"); } if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_strDetectorType)) { Warn("Load ZSKK Defect calibration failed"); } } else if (m_nCalibrationMode == CCOS_CALIBRATION_MODE::CCOS_CALIBRATION_MODE_OEM) { //加载模板 FPDLoadCorrectFiles(nDetectorID, szDetectorID); } //设置工作模式 FpdMode tempFpdMode; tempFpdMode.workMode = ModeType::Normal_Mode; tempFpdMode.trigType = TrigType::SENSOR_TRIG_MODE; SetDetectorWorkMode(nDetectorID, szDetectorID, &tempFpdMode); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, ""); FINFO("DetectorInitProcess Over"); return true; } //接口成功返回false,接口失败或有错返回true bool XiuYuanCtrl::TestError(int nDetectorID, int nErrorStatus, std::string strAPI) { switch (nErrorStatus) { case 0: { SystemErrorCode nErrorCode = SEC_Succeed; nErrorCode = (SystemErrorCode)API_YI_GetLastErrorCode(); FWARN("{$} Failed!!! ErrorCode: {$}", strAPI.c_str(), (int)nErrorCode); return true; break; } case 1: { FDEBUG("{$} Success", strAPI); return false; break; } default: break; } return true; } bool XiuYuanCtrl::LoadXiuYuanDLL(string strWorkPath) { FINFO("--XiuYuanCtrl Func-- LoadXiuYuanDLL"); string strDllDir = strWorkPath; if (SetDllDirectory(strDllDir.c_str()) == 0) { DWORD dw = GetLastError(); FINFO("SetDllDirectory error,error code [{$}]", dw); return false; } string strDllPath = strWorkPath + "\\YuYingAPI.dll"; FINFO("Load XiuYuan API, {$}", strDllPath); m_hXiuYuanModule = LoadLibrary(strDllPath.c_str()); if (nullptr == m_hXiuYuanModule) { FWARN("Load XiuYuan API failed!"); return false; } API_YI_Initialize_FPD_V4 = (Func_YI_Initialize_FPD_V4)GetProcAddress(m_hXiuYuanModule, "YI_Initialize_FPD_V4"); if (nullptr == API_YI_Initialize_FPD_V4) { FWARN("Load YI_Initialize_FPD_V4 failed!"); return false; } API_YI_FPD_Set_Work_Mode = (Func_YI_FPD_Set_Work_Mode)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Set_Work_Mode"); if (nullptr == API_YI_FPD_Set_Work_Mode) { FWARN("Load YI_FPD_Set_Work_Mode failed!"); return false; } API_YI_FPD_Stop_Capture_Image = (Func_YI_FPD_Stop_Capture_Image)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Stop_Capture_Image"); if (nullptr == API_YI_FPD_Stop_Capture_Image) { FWARN("Load YI_FPD_Stop_Capture_Image failed!"); return false; } API_YI_FPD_Get_Configure_Common = (Func_YI_FPD_Get_Configure_Common)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Get_Configure_Common"); if (nullptr == API_YI_FPD_Get_Configure_Common) { FWARN("Load YI_FPD_Get_Configure_Common failed!"); return false; } API_YI_FPD_Set_Configure_Common = (Func_YI_FPD_Set_Configure_Common)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Set_Configure_Common"); if (nullptr == API_YI_FPD_Set_Configure_Common) { FWARN("Load YI_FPD_Set_Configure_Common failed!"); return false; } API_YI_FPD_Get_Configure_SyncOut_Mode = (Func_YI_FPD_Get_Configure_SyncOut_Mode)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Get_Configure_SyncOut_Mode"); if (nullptr == API_YI_FPD_Get_Configure_SyncOut_Mode) { FWARN("Load YI_FPD_Get_Configure_SyncOut_Mode failed!"); return false; } API_YI_FPD_Set_Configure_SyncOut_Mode = (Func_YI_FPD_Set_Configure_SyncOut_Mode)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Set_Configure_SyncOut_Mode"); if (nullptr == API_YI_FPD_Set_Configure_SyncOut_Mode) { FWARN("Load YI_FPD_Set_Configure_SyncOut_Mode failed!"); return false; } API_YI_FPD_Restore_Factory_Settings = (Func_YI_FPD_Restore_Factory_Settings)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Restore_Factory_Settings"); if (nullptr == API_YI_FPD_Restore_Factory_Settings) { FWARN("Load YI_FPD_Restore_Factory_Settings failed!"); return false; } API_YI_Subtract_Offset = (Func_YI_Subtract_Offset)GetProcAddress(m_hXiuYuanModule, "YI_Subtract_Offset"); if (nullptr == API_YI_Subtract_Offset) { FWARN("Load YI_FPD_Subtract_Offset failed!"); return false; } API_YI_ImageReady_Callback_Register = (Func_YI_ImageReady_Callback_Register)GetProcAddress(m_hXiuYuanModule, "YI_ImageReady_Callback_Register"); if (nullptr == API_YI_ImageReady_Callback_Register) { FWARN("Load YI_ImageReady_Callback_Register failed!"); return false; } API_YI_SystemInfo_Callback_Register = (Func_YI_SystemInfo_Callback_Register)GetProcAddress(m_hXiuYuanModule, "YI_SystemInfo_Callback_Register"); if (nullptr == API_YI_SystemInfo_Callback_Register) { FWARN("Load YI_SystemInfo_Callback_Register failed!"); return false; } API_YI_Get_Callback_Image_Size = (Func_YI_Get_Callback_Image_Size)GetProcAddress(m_hXiuYuanModule, "YI_Get_Callback_Image_Size"); if (nullptr == API_YI_Get_Callback_Image_Size) { FWARN("Load YI_Get_Callback_Image_Size failed!"); return false; } API_YI_GetLastErrorCode = (Func_YI_GetLastErrorCode)GetProcAddress(m_hXiuYuanModule, "YI_GetLastErrorCode"); if (nullptr == API_YI_GetLastErrorCode) { FWARN("Load YI_GetLastErrorCode failed!"); return false; } API_YI_Set_Save_Log_Flag = (Func_YI_Set_Save_Log_Flag)GetProcAddress(m_hXiuYuanModule, "YI_Set_Save_Log_Flag"); if (nullptr == API_YI_Set_Save_Log_Flag) { FWARN("Load YI_Set_Save_Log_Flag failed!"); return false; } API_YI_GetLoacalIPs_V4 = (Func_YI_GetLoacalIPs_V4)GetProcAddress(m_hXiuYuanModule, "YI_GetLoacalIPs_V4"); if (nullptr == API_YI_GetLoacalIPs_V4) { FWARN("Load YI_GetLoacalIPs_V4 failed!"); return false; } API_YI_Set_Image_Save_State = (Func_YI_Set_Image_Save_State)GetProcAddress(m_hXiuYuanModule, "YI_Set_Image_Save_State"); if (nullptr == API_YI_Set_Image_Save_State) { FWARN("Load YI_Set_Image_Save_State failed!"); return false; } API_YI_Set_Image_Save_Path = (Func_YI_Set_Image_Save_Path)GetProcAddress(m_hXiuYuanModule, "YI_Set_Image_Save_Path"); if (nullptr == API_YI_Set_Image_Save_Path) { FWARN("Load YI_Set_Image_Save_Path failed!"); return false; } API_YI_FPD_Get_FPD_TYPE = (Func_YI_FPD_Get_FPD_TYPE)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Get_FPD_TYPE"); if (nullptr == API_YI_FPD_Get_FPD_TYPE) { FWARN("Load YI_FPD_Get_FPD_TYPE failed!"); return false; } API_YI_FPD_Get_Invalid_Region = (Func_YI_FPD_Get_Invalid_Region)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Get_Invalid_Region"); if (nullptr == API_YI_FPD_Get_Invalid_Region) { FWARN("Load YI_FPD_Get_Invalid_Region failed!"); return false; } API_YI_FPD_Capture_Image = (Func_YI_FPD_Capture_Image)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Capture_Image"); if (nullptr == API_YI_FPD_Capture_Image) { FWARN("Load YI_FPD_Capture_Image failed!"); return false; } /*API_YI_FPD_Capture_Prepare = (Func_YI_FPD_Capture_Prepare)GetProcAddress(m_hXiuYuanModule, "YI_FPD_Capture_Prepare"); if (nullptr == API_YI_FPD_Capture_Prepare) { FWARN("Load YI_FPD_Capture_Prepare failed!"); return false; }*/ API_YI_Load_Gain_Tmp_File = (Func_YI_Load_Gain_Tmp_File)GetProcAddress(m_hXiuYuanModule, "YI_Load_Gain_Tmp_File"); if (nullptr == API_YI_Load_Gain_Tmp_File) { FWARN("Load YI_Load_Gain_Tmp_File failed!"); return false; } API_YI_Load_Defect_Tmp_File = (Func_YI_Load_Defect_Tmp_File)GetProcAddress(m_hXiuYuanModule, "YI_Load_Defect_Tmp_File"); if (nullptr == API_YI_Load_Defect_Tmp_File) { FWARN("Load YI_Load_Defect_Tmp_File failed!"); return false; } API_YI_Load_Offset_Tmp_File = (Func_YI_Load_Offset_Tmp_File)GetProcAddress(m_hXiuYuanModule, "YI_Load_Offset_Tmp_File"); if (nullptr == API_YI_Load_Offset_Tmp_File) { FWARN("Load YI_Load_Offset_Tmp_File failed!"); return false; } API_YI_Load_AED_Offset_Tmp_File = (Func_YI_Load_AED_Offset_Tmp_File)GetProcAddress(m_hXiuYuanModule, "YI_Load_AED_Offset_Tmp_File"); if (nullptr == API_YI_Load_AED_Offset_Tmp_File) { FWARN("Load YI_Load_AED_Offset_Tmp_File failed!"); return false; } API_YI_Set_Correct_Type = (Func_YI_Set_Correct_Type)GetProcAddress(m_hXiuYuanModule, "YI_Set_Correct_Type"); if (nullptr == API_YI_Set_Correct_Type) { FWARN("Load YI_Set_Correct_Type failed!"); return false; } API_YI_FPD_FreeBuffer = (Func_YI_FPD_FreeBuffer)GetProcAddress(m_hXiuYuanModule, "YI_FPD_FreeBuffer"); if (nullptr == API_YI_FPD_FreeBuffer) { FWARN("Load YI_FPD_FreeBuffer failed!"); return false; } FINFO("LoadXiuYuanDLL Over"); return true; } void XiuYuanCtrl::FreeXiuYuanDLL() { FINFO("--XiuYuan Ctrl-- FreeXiuYuanDLL"); if (m_hXiuYuanModule) { FreeLibrary(m_hXiuYuanModule); m_hXiuYuanModule = nullptr; FINFO(" Free XiuYuan DLL"); } FINFO("FreeXiuYuanDLL Over"); } bool XiuYuanCtrl::DriverEntry(FPDDeviceXiuYuan* pDrvDPC, ResDataObject& Configuration) { FINFO("--XiuYuanCtrl Func-- DriverEntry"); map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { FERROR("This DPC already exist"); return false; } CPanelStatus* p = new CPanelStatus(); m_pStPanelStatus[m_nPanelCount] = p; m_pDPC2PanelID->insert(pair(pDrvDPC, m_nPanelCount)); m_pPanelID2DPC->insert(pair(m_nPanelCount, pDrvDPC)); m_nPanelCount++; m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储 FINFO("Config: {$}", m_ModeConfig.encode()); FINFO("DriverEntry Over"); return true; } bool XiuYuanCtrl::ActiveDetector(nsDPC::FPDDeviceXiuYuan* pDrvDPC, bool bActive) { FINFO("--XiuYuanCtrl Func-- ActiveDetector"); FINFO("ActivePanel start: {$}, DetectorIndex {$}", pDrvDPC, m_nDetectorIndex); map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { if (m_nDetectorIndex != DPCsIter->second) { FINFO("DetectorIndex {$} != DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second); m_nDetectorIndex = DPCsIter->second; FINFO("ActivePanel over: {$}, DetectorIndex {$}", pDrvDPC, m_nDetectorIndex); } else { FINFO("DetectorIndex {$} == DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second); } } else { FWARN("Not find DPC in group"); return false; } FINFO("ActiveDetector Over"); return true; } bool XiuYuanCtrl::EnterExam(APP_STATUS eStatus) { string strLog = ""; switch (eStatus) { case APP_STATUS_IDLE: strLog = "APP_STATUS_IDLE"; break; case APP_STATUS_WORK_BEGIN: strLog = "APP_STATUS_WORK_BEGIN"; m_bInCalibrating = false; break; case APP_STATUS_WORK_END: strLog = "APP_STATUS_WORK_END"; break; case APP_STATUS_DETSHARE_BEGIN: strLog = "APP_STATUS_DETSHARE_BEGIN"; break; case APP_STATUS_DETSHAR_END: strLog = "APP_STATUS_DETSHAR_END"; break; case APP_STATUS_CAL_BEGIN: strLog = "APP_STATUS_CAL_BEGIN"; break; case APP_STATUS_CAL_END: strLog = "APP_STATUS_CAL_END"; m_bInCalibrating = false; break; default: break; } FINFO("Enter exam: {$}", strLog.c_str()); m_eAppStatus = eStatus; return true; } /*** ** 说明:连接 ** 加载SDK,初始化SDK,连接探测器等初始化操作 ** 参数:strWorkPath,初始化SDK必须的conf路径 ***/ bool XiuYuanCtrl::Connect(FPDDeviceXiuYuan* pDrvDPC, string strWorkPath) { FINFO("--XiuYuanCtrl Func-- Connect"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return true"); return true; } if (!m_pZSKKCalib) { m_pZSKKCalib = new CZSKKCalibrationCtrl(); } m_strWorkPath = strWorkPath; if (!Init(strWorkPath)) { FERROR("Load Dll Failed"); } if (!DetectorInitProcess(1)) { FERROR("Init Detector failed"); } FINFO("=== Connect detector OK ==="); FINFO("Connect Over"); return true; } /*** ** 说明:退出 ** 释放SDK ***/ bool XiuYuanCtrl::DisConnect(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- DisConnect"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return true; } FINFO("DicConnect DoNothing"); FINFO("DisConnect Over"); return true; } /*** ** 说明:设置当前的曝光模式 ** 参数:nLogicMode,从配置文件读取,与SDK配置application mode对应 ***/ bool XiuYuanCtrl::SetAcqMode(string strLogicMode) { FINFO("--XiuYuanCtrl Func-- SetAcqMode"); if (m_bConnectStatus == false) { FERROR("Current detector {$} is not connect, return", m_nDetectorIndex); return false; } if (m_strAcqMode == "RAD") { FINFO("Same Acq Mode"); FINFO("SetAcqMode Over"); return true; } m_bSaveRaw = (bool)m_ModeConfig["IsSaveRaw"]; try { m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][0]["RawImgHeight"]; m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][0]["RawImgWidth"]; m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"]; m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"]; m_nWidthOffset = (int)m_ModeConfig["ModeTable"][0]["WidthOffset"]; m_nHeightOffset = (int)m_ModeConfig["ModeTable"][0]["HeightOffset"]; m_nImgBits = (int)m_ModeConfig["ModeTable"][0]["PhySizeInfoBit"]; m_nPixelPitch = (int)m_ModeConfig["ModeTable"][0]["PixelPitch"]; FINFO("Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$}), Bits({$}), PixelPitch({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nHeightOffset, m_nWidthOffset, m_nImgBits, m_nPixelPitch); } catch (ResDataObjectExption& exp) { FERROR("Get config failed: {$}", exp.what()); } if (m_pImgBuffer) { delete[] m_pImgBuffer; m_pImgBuffer = nullptr; } m_pImgBuffer = new WORD[m_nImageHeight * m_nImageWidth]; FINFO("SetAcqMode Over"); return true; } //设置同步模式 bool XiuYuanCtrl::SetSyncMode(int nSyncMode) { FINFO("--XiuYuanCtrl Func-- SetSyncMode"); FpdMode tempFpdMode; int tempSyncMode = 0; if (nSyncMode == 1) { tempSyncMode = TrigType::SOFT_TRIG_MODE; } else if (nSyncMode == 2) { tempSyncMode = TrigType::EXT_TRIG_MODE; } else if (nSyncMode == 3) { tempSyncMode = TrigType::SENSOR_TRIG_MODE; } FINFO("To SetDetectorWorkMode {$}", tempSyncMode); if (m_nSyncMode == tempSyncMode) { FINFO("Same sync mode, omit set sync mode"); FINFO("SetSyncMode Over"); return true; } tempFpdMode.workMode = ModeType::Normal_Mode; tempFpdMode.trigType = tempSyncMode; const char* szDetectorID = m_vecDetectorID[m_nDetectorIndex].c_str(); if (SetDetectorWorkMode(m_nDetectorID, szDetectorID, &tempFpdMode)) { m_nSyncMode = tempSyncMode; FINFO("Set detector sync mode into {$}", tempSyncMode); } else { FERROR("Set detector sync mode failed!"); } FINFO("SetSyncMode Over"); return true; } /*** ** 说明:曝光前的准备流程 ***/ RET_STATUS XiuYuanCtrl::PrepareAcquisition(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- PrepareAcquisition"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return RET_STATUS::RET_FAILED; } if (m_bConnectStatus == false) { FINFO("Current detector is not connect, return"); return RET_STATUS::RET_FAILED; } int nRet = API_YI_FPD_Stop_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str()); if (TestError(m_nDetectorID, nRet, "Stop_Capture_Image")) { FERROR("Stop Capture image failed"); } int nTempTriggerMode = m_nSyncMode; if (TrigType::SOFT_TRIG_MODE != nTempTriggerMode) { nRet = API_YI_FPD_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str(), 1); if (TestError(m_nDetectorID, nRet, "Capture_Image")) { FERROR("Capture image failed"); } } if (TrigType::SOFT_TRIG_MODE == nTempTriggerMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); } m_bStandbyFlag = true; m_bAEDWorkFlag = false; FINFO("PrepareAcquisition Over"); return RET_STATUS::RET_SUCCEED; } RET_STATUS XiuYuanCtrl::StartAcquisition(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- StartAcquisition"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_FAILED; if (!m_bConnectStatus) { FWARN("Detector not in connection when start acq, return failed"); return RET_STATUS::RET_FAILED; } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START); m_bInExposure = true; int nTempTriggerMode = m_nSyncMode; if (TrigType::SOFT_TRIG_MODE == nTempTriggerMode) //软同步 { FINFO("Softerware mode"); int nRet = API_YI_FPD_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str(), 1); if (TestError(m_nDetectorID, nRet, "Capture_Image")) { FERROR("Capture image failed"); } } /*int nRet = API_YI_FPD_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str(), 1); if (TestError(m_nDetectorID, nRet, "Capture_Image")) { FERROR("Capture image failed"); }*/ StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK); FINFO("PANEL_START_ACQ"); StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ); if (TrigType::SOFT_TRIG_MODE == nTempTriggerMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } if (m_nSyncMode == TrigType::SENSOR_TRIG_MODE) { FINFO("AED Work Flag"); m_bAEDWorkFlag = true; } FINFO("StartAcquisition Over"); return RET_STATUS::RET_SUCCEED; } RET_STATUS XiuYuanCtrl::StopAcquisition(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- StopAcquisition"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return RET_STATUS::RET_FAILED; } int nRet = API_YI_FPD_Stop_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str()); if (TestError(m_nDetectorID, nRet, "Stop_Capture_Image")) { FERROR("Stop Capture image failed"); } FINFO("StopAcquisition Over"); return RET_STATUS::RET_SUCCEED; } /********************************************************************/ //功能:XiuYuan没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ bool XiuYuanCtrl::StartXWindowOffThread() { if (m_pXWindowoffThread == nullptr) { DWORD m_NotifyThreadID; m_pXWindowoffThread = CreateThread(0, 0, XWindowOffThread, this, 0, &m_NotifyThreadID); if (m_pXWindowoffThread == nullptr) { FWARN("Start Inner Exp Thread Failed"); return false; } } return true; } /********************************************************************/ //功能:XiuYuan没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ DWORD XiuYuanCtrl::XWindowOffThread(LPVOID pParam) { XiuYuanCtrl* pCurPanel = (XiuYuanCtrl*)pParam; if (pCurPanel == nullptr) { return false; } DWORD dwTimer = pCurPanel->m_nXWindow; DWORD dwResult = WaitForSingleObject(pCurPanel->m_hWindowOffEvent, dwTimer); Sleep(50); FINFO("Simulate XWINDOW_OFF"); pCurPanel->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); pCurPanel->m_pXWindowoffThread = nullptr; return true; } /*** ** 说明:激活校正 ** 增益校正(探测器采用post-offset,暗场校正基本没用了)时拿到dose回调,算作执行完毕 ***/ bool XiuYuanCtrl::ActiveCalibration(nsDPC::FPDDeviceXiuYuan* pDrvDPC, CCOS_CALIBRATION_TYPE Type) { FINFO("--XiuYuanCtrl Func-- ActiveCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return RET_STATUS::RET_FAILED; } StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); m_eAppStatus = APP_STATUS_CAL_BEGIN; //激活校正,置为校正界面 m_eCaliType = Type; if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("Active Dark Calibration"); } if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("Active Xray Calibration"); if (m_nCalibrationMode) //厂商校正ActiveCalibration { } else //ZSKK校正 { if (!m_pZSKKCalib) { FERROR("ZSKK Calibration object is undefined"); } else { //加载ZSKK的校正文件 m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "\\references\\"; m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight; m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds; m_pZSKKCalib->m_nSaturationValue = 50000; //LoadZSKKGainMap 参数为false,意思是开始增益校正 m_pZSKKCalib->LoadZSKKGainMap(false, m_strDetectorType); m_pZSKKCalib->LoadZSKKPixelMap(false, m_strDetectorType); FINFO("Load ecom gain and pixel map, references file path: {$}", m_pZSKKCalib->m_strRefFilePath); } } } FINFO("ActiveCalibration Over"); return true; } /*** ** 说明:准备校正(状态机FramePrep) ** 曝光使能过程,使探测器开窗 ***/ bool XiuYuanCtrl::PrepareCalibration(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- PrepareCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return false; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("PrepareCalibration CCOS_CALIBRATION_TYPE_DARK == m_eCaliType"); //由于前端没有测试过暗场校正上图的情况,故此处不进行暗场上图 } else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("PrepareCalibration CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType"); m_bCancelFlag = false; //准备校正前恢复初值 bool ret = PrepareAcquisition(pDrvDPC); if (ret) { FINFO("PrepareCalibration PrepareAcquisition success!"); } else { FERROR("PrepareCalibration PrepareAcquisition fail!"); FERROR("PrepareCalibration Over"); return false; } } FINFO("PrepareCalibration Over"); return true; } /*** ** 说明:开始校正(状态机FrameStart) ***/ bool XiuYuanCtrl::StartCalibration(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- StartCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return false; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("StartCalibration DARK"); StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); m_pStPanelStatus[m_nDetectorIndex]->eFPDStatus = eDetStatus::DetStatus_Offset; } else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("StartCalibration XRAY"); bool ret = StartAcquisition(pDrvDPC); if (!ret) { FERROR("StartCalibration Over"); return false; } m_pStPanelStatus[m_nDetectorIndex]->eFPDStatus = eDetStatus::DetStatus_XrayCalibration; } FINFO("StartCalibration Over"); return true; } bool XiuYuanCtrl::StopCalibration(FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- StopCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FERROR("Not current DPC, return"); return false; } if (!m_bConnectStatus) { FERROR("bConnectState is false, Detector not connected, return"); return false; } m_bCancelFlag = true;//中止校正 m_eAppStatus = APP_STATUS_CAL_END; FINFO("StopCalibration Over"); return true; } /*** ** 说明:终止校正 ***/ bool XiuYuanCtrl::AbortCalibration(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCtrl Func-- AbortCalibration"); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值 if (m_nCalibrationMode) //厂商校正AbortCalibration { } else { FINFO("Reload Gain Map And Pixel Map"); //重新加载增益校正文件 if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strDetectorType)) { Warn("Load ZSKK Gain calibration failed"); } //放弃坏点校正并重新加载原来的坏点校正文件 m_pZSKKCalib->AbortZSKKPixMap(m_strDetectorType); } m_eAppStatus = APP_STATUS_CAL_END; FINFO("AbortCalibration Over"); return true; } bool XiuYuanCtrl::AcceptCalibration() { FINFO("--XiuYuanCtrl Func-- AcceptCalibration"); if (m_nCalibrationMode)//厂商校正AcceptCalibration { //不做处理 } else //ZSKK校正 { WORD* pImageBuffer = nullptr; //这里要注意使用的image buffer是哪个,裁剪和不裁剪是不一样的 if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { pImageBuffer = m_pImgBuffer; } else { pImageBuffer = m_pRawImgBuffer; } if (m_nCalibCurrentExposureIndex == 1) { m_pZSKKCalib->AddImageToPixMap(pImageBuffer); m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, true); } else { m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮 } } FINFO("AcceptCalibration Over"); return true; } bool XiuYuanCtrl::RejectCalibration() { FINFO("--XiuYuanCtrl Func-- RejectCalibration"); FINFO("Reject Calibration"); FINFO("RejectCalibration Over"); return true; } void XiuYuanCtrl::SetCalibRounds(int nCalibRounds) { FINFO("--XiuYuanCtrl Func-- SetCalibRounds"); m_nCalibrationRounds = nCalibRounds; FINFO("Set CalibrationRounds: {$}", m_nCalibrationRounds); FINFO("SetCalibRounds Over"); } bool XiuYuanCtrl::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound) { FINFO("--XiuYuanCtrl Func-- GetCalibrationStep"); m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound; m_nCalibrationRounds = nCalibrationRounds; m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex; m_nExposureNumCurrentRound = nExposureNumCurrentRound; FINFO("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds, nCalibCurrentExposureIndex, nExposureNumCurrentRound); FINFO("GetCalibrationStep Over"); return true; } /*** ** 说明:结束校正 ** DPC处理完校正报告后调用,此处上传map、报告等文件 ***/ bool XiuYuanCtrl::CompleteCalibration(nsDPC::FPDDeviceXiuYuan* pDrvDPC) { FINFO("--XiuYuanCrtl Func-- CompleteCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { FWARN("Not current DPC, return"); return false; } FINFO("Calib type {$}", (int)m_eCaliType); if (m_eCaliType == CCOS_CALIBRATION_TYPE_DARK) { FINFO("DARK Calib over"); } else if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY) { FINFO("XRAY Calib over"); m_eAppStatus = APP_STATUS_CAL_END; } FINFO("CompleteCalibration Over"); return true; } CCOS_CALIBRATION_TYPE XiuYuanCtrl::GetCalibType() { FINFO("--XiuYuanCtrl Func-- GetCalibType"); FINFO("CalibType: {$}", (int)m_eCaliType); FINFO("GetCalibType Over"); return m_eCaliType; } bool XiuYuanCtrl::UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode) { FINFO("--XiuYuanCtrl Func-- UpdateCalibMode"); FINFO("CalibMode: {$}", (int)eCalibMode); m_nCalibrationMode = eCalibMode; FINFO("UpdateCalibMode Over"); return true; } bool XiuYuanCtrl::SaveCalibrationFile() { FINFO("--XiuYuanCtrl Func-- SaveCalibrationFile"); if (m_nCalibrationMode)//厂商校正SaveCalibrationFile { //不做处理 } else { FINFO("Save ZSKK Calibration File"); m_pZSKKCalib->StoreZSKKGainMap(m_strDetectorType); m_pZSKKCalib->StoreZSKKPixMap(m_strDetectorType); } //更新配置文件中校正日期和时间 SYSTEMTIME stCurrentTime = { 0 }; GetLocalTime(&stCurrentTime); FINFO("save calib file time: {$04d}/{$02d}/{$02d} {$02d}:{$02d}:{$02d}:{$03d}", stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay, stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds); FINFO("SaveCalibrationFile over"); return true; } //设置探测器的工作模式 bool XiuYuanCtrl::SetDetectorWorkMode(int nDetectorID, const char* szFPD, FpdMode* stWorkMode) { FINFO("--XiuYuanCtrl Func-- SetDetectorWorkMode"); FINFO("Set detector({$})({$}) work mode: {$}", nDetectorID, szFPD, stWorkMode->workMode); int nRet = API_YI_FPD_Set_Work_Mode(szFPD, stWorkMode); if (TestError(nDetectorID, nRet, "API_YI_FPD_Set_Work_Mode")) { FERROR("Set work mode failed!!!"); FERROR("SetDetectorWorkMode Over"); return false; } else { FINFO("Set work mode success"); } FINFO("SetDetectorWorkMode Over"); return true; } //加载校正 bool XiuYuanCtrl::FPDLoadCorrectFiles(int nDetectorID, const char* szDetectorID) { FINFO("--XiuYuan Func-- FPDLoadCorrectFiles"); int nRet = 0; std::string strGainPath = m_stDeviceIndex[m_nDetectorIndex].strGainPath; std::string strDefectPath = m_stDeviceIndex[m_nDetectorIndex].strDefectPath; if (m_stDeviceIndex[m_nDetectorIndex].bGainDefectEnable) { nRet = API_YI_Load_Gain_Tmp_File(szDetectorID, strGainPath.c_str()); //加载Gain模板 if (TestError(nDetectorID, nRet, "Load_Gain")) { FERROR("Load gain template failed!"); } else { FINFO("Load gain tempplate success"); } nRet = API_YI_Load_Defect_Tmp_File(szDetectorID, strDefectPath.c_str()); if (TestError(nDetectorID, nRet, "Load_Defect")) { FERROR("Load defect template failed!"); } else { FINFO("Load defect template success"); } int nCorrectType = Do_Gain | Do_Defect; nRet = API_YI_Set_Correct_Type(szDetectorID, nCorrectType); if (TestError(nDetectorID, nRet, "Set_Correction")) { FERROR("Set correction failed!"); } else { FINFO("Set correction success"); } } //设置探测器做Offset校正 nRet = API_YI_Subtract_Offset(szDetectorID, true); if (TestError(nDetectorID, nRet, "Set_Offset")) { FERROR("Set offset failed!"); } else { FINFO("Set offset success"); } FINFO("FPDLoadCorrectFiles Over"); return true; } bool XiuYuanCtrl::IsConnected(string strIP) { FINFO("Check ping {$}", strIP); CMyPingip obPingIp; StatusFeedback(EVT_STATUS_PING, 0, "true"); if (!obPingIp.PingFunction(strIP.c_str())) { FINFO("ping {$} Failed", strIP); StatusFeedback(EVT_STATUS_PING, 0, "false"); return false; } return true; } void XiuYuanCtrl::OnProcessImg() { if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { FDEBUG("Begin get effect image, m_nRawImgWidth {$}", m_nRawImgWidth); if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, m_nRawImgWidth)) { FERROR("Get effect image failed"); return; } FDEBUG("Get effect image over"); if (m_eAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); } if (m_bSaveRaw) { std::string strFileName = m_strWorkPath + "\\rawdata"; strFileName += "\\AfterCalImage.raw"; std::filesystem::path file_path{ strFileName.c_str() }; std::ofstream file_stream(file_path, std::ios::binary); if (!file_stream.is_open()) { FERROR("Open Save File Failed"); } unsigned int nTempSize = m_nImageHeight * m_nImageWidth * 2; file_stream.write(reinterpret_cast(m_pImgBuffer), nTempSize); file_stream.close(); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); } else { //memcpy(m_pImgBuffer, m_pRawImgBuffer, m_nImageHeight * m_nImageWidth * sizeof(WORD)); if (m_eAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nRawImgHeight, m_nRawImgWidth, m_pRawImgBuffer); } if (m_bSaveRaw) { std::string strFileName = m_strWorkPath + "\\rawdata"; strFileName += "\\AfterCalImage.raw"; std::filesystem::path file_path{ strFileName.c_str() }; std::ofstream file_stream(file_path, std::ios::binary); if (!file_stream.is_open()) { FERROR("Open Save File Failed"); } unsigned int nTempSize = m_nRawImgHeight * m_nRawImgWidth * 2; file_stream.write(reinterpret_cast(m_pRawImgBuffer), nTempSize); file_stream.close(); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pRawImgBuffer); } } // pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度 bool XiuYuanCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth) { if (pOutImg == nullptr || pInImg == nullptr || nInWidth < 0) { FERROR("Illegal parameter, can not get effective image"); return false; } try { for (int i = 0; i < m_nImageHeight; i++) { memcpy(pOutImg + i * m_nImageWidth, pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset, m_nImageWidth * sizeof(WORD)); } } catch (...) { FERROR("Get effective image crashed. m_nImageWidth {$},m_nImageHeight {$},m_nWidthOffset {$},m_nHeightOffset {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset); return false; } return true; } /*** * 保存RAW图像 ***/ bool XiuYuanCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight) { FINFO("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight); if (pRawImg == nullptr || pImgName == nullptr) { return false; } string strImagePath = m_strAppPath + "\\rawdata\\" + pImgName; std::filesystem::path file_path{ strImagePath.c_str() }; std::ofstream file_stream(file_path, std::ios::binary); if (!file_stream.is_open()) { FERROR("Open {$} Failed!", strImagePath); } unsigned int nSize = nWidth * nHeight * sizeof(WORD); file_stream.write(reinterpret_cast(pRawImg), nSize); file_stream.close(); FINFO("End to Save Raw Image"); return true; } //图像回调 bool XiuYuanCtrl::ImageReadyCallbackProcess(const char* pImage, unsigned long iFlag) { return g_pXiuYuanCtrl->onImageReadyCallbackProcess(pImage, iFlag); } //系统回调 bool XiuYuanCtrl::SystemInfoCallbackProcess(SystemInfoCode iCodeIndex, const char* sContent) { return g_pXiuYuanCtrl->onSystemInfoCallbackProcess(iCodeIndex, sContent); } bool XiuYuanCtrl::onImageReadyCallbackProcess(const char* pImage, int iFlag) { FINFO("onImageReadyCallbackProcess"); if (nullptr == pImage) { FWARN("Image Data is null"); return false; } if (TrigType::SENSOR_TRIG_MODE == m_nSyncMode) { while (!m_bAEDWorkFlag) { Sleep(20); } StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); FINFO("StartXWindowOffThread"); StartXWindowOffThread(); } else if (TrigType::EXT_TRIG_MODE == m_nSyncMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); FINFO("StartXWindowOffThread"); StartXWindowOffThread(); } else if (TrigType::SOFT_TRIG_MODE == m_nSyncMode) { FINFO("StartXWindowOffThread"); StartXWindowOffThread(); } if (m_pRawImgBuffer) { delete[] m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } m_pRawImgBuffer = new WORD[m_nRawImgHeight * m_nRawImgWidth]; if (m_pRawImgBuffer == nullptr) { FWARN("Allocate Raw Image Failed"); return false; } memcpy(m_pRawImgBuffer, pImage, m_nRawImgHeight * m_nRawImgWidth * sizeof(WORD)); if (m_bSaveRaw) { std::string strFileName = m_strWorkPath + "\\rawdata"; strFileName += "\\Image.raw"; std::filesystem::path file_path{ strFileName.c_str() }; std::ofstream file_stream(file_path, std::ios::binary); if (!file_stream.is_open()) { FERROR("Open Save File Failed"); } unsigned int nTempSize = m_nRawImgHeight * m_nRawImgWidth * 2; file_stream.write(reinterpret_cast(m_pRawImgBuffer), nTempSize); file_stream.close(); } OnProcessImg(); return true; } bool XiuYuanCtrl::onSystemInfoCallbackProcess(SystemInfoCode iCodeIndex, const char* sContent) { switch (iCodeIndex) { case SIC_WAIT_EXP: FINFO("Send Standby---Ready"); if (m_bStandbyFlag) { StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); m_bStandbyFlag = false; } break; case SIC_IN_EXP: StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON); break; case SIC_TEMPERTURE: { FINFO("{$}", sContent); float value; if (sscanf(sContent, "temperature:%f", &value)) { FINFO("Get Temperature Success"); } StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", 0, value); } break; case SIC_BATTERY: { FINFO("{$}", sContent); float value; if (sscanf(sContent, "battery:%f", &value)) { FINFO("Get Battery Success"); } StatusFeedback(EVT_STATUS_BATTERY_VALUE, value, "", 0); StatusFeedback(EVT_STATUS_WIFI, 100, "", 0); } break; case SIC_ROIC_BUSY: if (!m_bFreeBuffer) { API_YI_FPD_FreeBuffer(m_vecDetectorID[m_nDetectorIndex].c_str()); } break; case SIC_ROIC_DONE: if (!m_bFreeBuffer) { API_YI_FPD_FreeBuffer(m_vecDetectorID[m_nDetectorIndex].c_str()); } break; default: break; } m_bFreeBuffer = true; return true; } void XiuYuanCtrl::SetNotifyStatusTimePeriod(int nTime) { FINFO("--XiuYuanCtrl Func-- SetNotifyStatusTimePeriod"); FINFO("SetNotifyStatusTimePeriod Time:{$}", nTime); m_nNotifyStatusTimePeriod = nTime; FINFO("SetNotifyStatusTimePeriod Over"); } void XiuYuanCtrl::SetReconnectTimePeriod(int nTime) { FINFO("--XiuYuanCtrl Func-- SetReconnectTimePeriod"); FINFO("SetReconnectTimePeriod nTime:{$}", nTime); m_nReconnectTimePeriod = nTime; FINFO("SetReconnectTimePeriod Over"); } void XiuYuanCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void XiuYuanCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void XiuYuanCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void XiuYuanCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void XiuYuanCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void XiuYuanCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); }