#include "stdafx.h" #include #include "sys\stat.h" #include //文件流库函数 #include #include "YuyingCtrl.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") YuyingCtrl* g_pYuyingCtrl = NULL; YuyingCtrl::YuyingCtrl() :m_hYuyingModule(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_FPD_Subtract_Offset(nullptr), API_YI_ImageReady_Callback_Register(nullptr), API_YI_ImageReady_Callback_Register_Ex(nullptr), API_YI_SystemInfo_Callback_Register(nullptr), API_YI_SystemInfo_Callback_Register_Ex(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_DO_Correction(nullptr), API_YI_FPD_Wifi_Re_Connect(nullptr), API_YI_FPD_Wifi_Set_Work_Mode(nullptr), API_YI_FPD_Wifi_Get_Work_Mode(nullptr), API_YI_FPD_Wifi_Set_Name(nullptr), API_YI_FPD_Wifi_Set_Power_Down(nullptr), API_YI_FPD_Wifi_Set_IP_Address(nullptr), API_YI_FPD_Wifi_Set_Route_Info(nullptr), m_strAppPath(""), m_strWorkPath(""), m_nPanelCount(0), m_nDetectorID(1), m_nDetectorIndex(0), m_nUpdateFPDID(0), m_nCurrentMode(-1), m_nSaveRaw(0), m_bInitialing(false), m_bInCalibrating(false), m_bInExposure(false), m_bForceGridSuppress(false), m_nSID(180), m_fFactorEXI2UGY(0.0f), m_pHardwareStatusThread(nullptr), m_hEndHWStatusThreadEvent(nullptr), m_hHWStatusThreadEndEvent(nullptr), m_pCurrentDPC(nullptr), m_eAppStatus(APP_STATUS_IDLE), m_nImageWidth(0), m_nImageHeight(0), m_nRawImgWidth(0), m_nRawImgHeight(0), m_nTopOffset(0), m_nBottomOffset(0), m_nLeftOffset(0), m_nRightOffset(0), m_nImgBits(16), m_nPixelPitch(150), m_bPreviewEnable(false), m_nPreviewWidth(0), m_nPreviewHeight(0), m_pImgBuffer(nullptr), m_pwRawImageData(nullptr), m_pwPreviewImg(nullptr), m_fCurrentDose(0.0f), m_hExitEvent(nullptr), m_hRecoverImage(nullptr), m_hCofirmCalib(nullptr), m_hEndCalibEvent(nullptr), m_hYuyingScanEnd(nullptr), m_hSharedEvent(nullptr), m_hWindowOffEvent(nullptr), m_pOffsetThread(nullptr), m_pXWindowoffThread(nullptr), m_hScanEventThread(nullptr), m_nCalibDueSetting(0), m_nCalibStatus(0), m_nDoseParam(0), m_nCalibrationMode(0), m_nDefectExpTimes(0), m_nDefectTotalTimes(0), m_nGainExpTimes(0), m_nGainTotalFrames(0), m_nDefectTotalFrames(0) { m_hInitThread = NULL; m_hScanEventThread = NULL; m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); m_vecDetectorID.clear(); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //m_nGainNodeCount = 0; //m_nGainNodeIndex = 0; //m_nGainExpCount = 0; //m_nGainExpIndex = 0; for (int i = 0; i < Yuying_SCAN_NUM; i++) { m_hArrayEvent[i] = nullptr; } } YuyingCtrl::~YuyingCtrl() { OnEXIT(); if (m_pImgBuffer) { delete[] m_pImgBuffer; m_pImgBuffer = NULL; } delete m_pDPC2PanelID; m_pDPC2PanelID = NULL; delete m_pPanelID2DPC; m_pPanelID2DPC = NULL; } bool YuyingCtrl::OnEXIT() { SetEvent(m_hEndHWStatusThreadEvent); Info("Waiting HWStatus Thread End"); int nResult = WaitForSingleObject(m_hHWStatusThreadEndEvent, 10000); if (WAIT_TIMEOUT == nResult) { Error("Yuying HWStatus Thread Quit Failed"); } else { Info("Yuying HWStatus Thread Quit Success"); } for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) { DisconnectFD(nDetectorID); //所有平板都断开 } SetEvent(m_hExitEvent); Info("Waiting Yuying ScanEvent Thread End"); nResult = WaitForSingleObject(m_hYuyingScanEnd, 2000); if (WAIT_TIMEOUT == nResult) { Error("Yuying ScanEvent Thread Quit Failed"); } else { Info("Yuying ScanEvent Thread Quit Success"); } DeleteHandle(); Info("Free Yuying DLL"); FreeYuyingDLL(); return true; } void YuyingCtrl::DeleteHandle() { if (m_hSharedEvent) { CloseHandle(m_hSharedEvent); m_hSharedEvent = NULL; } if (m_hExitEvent) { CloseHandle(m_hExitEvent); m_hExitEvent = NULL; } if (m_hRecoverImage) { CloseHandle(m_hRecoverImage); m_hRecoverImage = NULL; } if (m_hCofirmCalib) { CloseHandle(m_hCofirmCalib); m_hCofirmCalib = NULL; } if (m_hEndCalibEvent) { CloseHandle(m_hEndCalibEvent); m_hEndCalibEvent = NULL; } if (m_hYuyingScanEnd) { CloseHandle(m_hYuyingScanEnd); m_hYuyingScanEnd = NULL; } if (m_hHWStatusThreadEndEvent) { CloseHandle(m_hHWStatusThreadEndEvent); m_hHWStatusThreadEndEvent = NULL; } if (m_pwPreviewImg) { delete[] m_pwPreviewImg; m_pwPreviewImg = NULL; } if (m_pwRawImageData) { delete[] m_pwRawImageData; m_pwRawImageData = NULL; } } //等到SDK回调返回true, 超时返回false bool YuyingCtrl::WaitRespond(int nTimeOut, const char* szPosition) { Info("---{$} Wait Respond---: {$}ms", nTimeOut); DWORD nResult = WaitForSingleObject(m_hSharedEvent, nTimeOut); if (WAIT_TIMEOUT == nResult) { Warn("Timeout in wait respond"); ResetEvent(m_hSharedEvent); return false; } ResetEvent(m_hSharedEvent); return true; } void YuyingCtrl::SendNotify(const char* szPosition) { Info("---{$} Get Respond ---", szPosition); SetEvent(m_hSharedEvent); } void YuyingCtrl::ResetLock() { ResetEvent(m_hSharedEvent); } void YuyingCtrl::Pausetime(DWORD dwSpan) { DWORD dtstart = ::GetTickCount(); while ((::GetTickCount() - dtstart) < dwSpan) { MSG msg; while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } } bool YuyingCtrl::Init(string strAppPath) { m_strAppPath = strAppPath; m_strWorkPath = strAppPath + (string)m_ModeConfig["SDKPath"]; //"OEMDrivers\\Detector\\Yuying\\YuyingDR\\Yuying" Info("YuyingCtrl::Init {$}\n", m_strWorkPath.c_str()); if (!LoadYuyingDLL(m_strWorkPath)) { Error("YuyingCtrl::Init LoadYuyingDLL failed\n"); return false; } m_hSharedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hYuyingScanEnd = 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_hRecoverImage = CreateEvent(NULL, FALSE, FALSE, NULL); m_hCofirmCalib = CreateEvent(NULL, FALSE, FALSE, NULL); m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hExitEvent; m_hArrayEvent[1] = m_hRecoverImage; m_hArrayEvent[2] = m_hCofirmCalib; m_hArrayEvent[3] = m_hEndCalibEvent; Info("YuyingCtrl::Init over\n"); return true; } //启动初始化线程 void YuyingCtrl::StartInitFPDThread() { Info("Start Init Thread"); DWORD unThreadID; if (m_hInitThread == NULL) { m_hInitThread = CreateThread(0, 0, onInitPanel, this, 0, &unThreadID); if (m_hInitThread == NULL) { Fatal("Start Init Thread Error"); } } } //初始化 DWORD YuyingCtrl::onInitPanel(void* pParam) { YuyingCtrl* pInstance = (YuyingCtrl*)pParam; pInstance->Action_Init(); pInstance->m_hInitThread = NULL; return true; } void YuyingCtrl::Action_Init() { Info("YuyingCtrl::Action_Init"); m_bInitialing = true; for (int nID = 0; nID < m_nPanelCount; nID++) //连接多板 { int nDetectorID = nID + 1; Info("Start init Detector: {$}", nDetectorID); if (!DetectorInitProcess(nDetectorID)) { Error("Init process failed"); } } YuyingScanEventThread(); //StartHardwareStatusThread(); m_bInitialing = false; Info("Action init over\n"); } //初始化连接探测器 bool YuyingCtrl::DetectorInitProcess(int nDetectorID, bool bFDAttach) { int nDetectorIndex = nDetectorID - 1; bool bPingSucces = false; int nPingTotalTime = 30; //ping不通,一次约2s,共30次,1分钟左右超时 for (int nPingTimes = 0; nPingTimes < nPingTotalTime; nPingTimes++) { bPingSucces = IsConnected(m_stDeviceIndex[nDetectorIndex].strWiredIP); if (bPingSucces) { Info("Ping Detector successfully"); break; } Sleep(2000); } //ping不通就不用连接了 if (!bPingSucces) { Error("Ping detector failed, timeout!!!"); return false; } StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, ""); string strLocalIP = m_stDeviceIndex[nDetectorIndex].strLocalIP; int nLocalPort = 28000; string strRemoteIP = m_stDeviceIndex[nDetectorIndex].strWiredIP; int nRemotePort = 27999; char szDetectorID[100] = { 0 }; Info("LocalIP: {$}:28000, RemoteIP: {$}:27999", strLocalIP, strRemoteIP); int nRet = API_YI_Initialize_FPD_V4(strLocalIP.c_str(), nLocalPort, strRemoteIP.c_str(), nRemotePort, szDetectorID); if (TestError(nDetectorID, nRet, "API_YI_Initialize_FPD_V4")) { Error("Connect Detector {$} Failed", nDetectorID); RetryConnect(nDetectorID); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, ""); return false; } m_stDeviceIndex[nDetectorIndex].nDetectorID = nDetectorID; m_stDeviceIndex[nDetectorIndex].bConnectStatus = true; m_stDeviceIndex[nDetectorIndex].bInitOK = true; m_vecDetectorID.push_back(szDetectorID); Info("Connect Detector {$} Success", nDetectorID); nRet = API_YI_Set_Save_Log_Flag(m_stDeviceIndex[nDetectorIndex].bSDKSaveLog, m_stDeviceIndex[nDetectorIndex].strSDKSaveLogPath.c_str()); if (TestError(nDetectorID, nRet, "SaveLog")) { Error("{$} SDK save log failed!!! path: {$} ", (m_stDeviceIndex[nDetectorIndex].bSDKSaveLog ? "Enable" : "Disable"), m_stDeviceIndex[nDetectorIndex].strSDKSaveLogPath); } else { Info("{$} SDK save log success, path: {$}", (m_stDeviceIndex[nDetectorIndex].bSDKSaveLog ? "Enable" : "Disable"), m_stDeviceIndex[nDetectorIndex].strSDKSaveLogPath); } nRet = API_YI_Set_Image_Save_Path(szDetectorID, m_stDeviceIndex[nDetectorIndex].strSDKSaveRawPath.c_str()); nRet |= API_YI_Set_Image_Save_State(szDetectorID, m_stDeviceIndex[nDetectorIndex].bSDKSaveRaw); if (TestError(nDetectorID, nRet, "SaveRaw")) { Error("{$} SDK save raw image failed!!! path: {$} ", (m_stDeviceIndex[nDetectorIndex].bSDKSaveRaw ? "Enable" : "Disable"), m_stDeviceIndex[nDetectorIndex].strSDKSaveRawPath); } else { Info("{$} SDK save raw image success, path: {$}", (m_stDeviceIndex[nDetectorIndex].bSDKSaveRaw ? "Enable" : "Disable"), m_stDeviceIndex[nDetectorIndex].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")) { Error("Get detector({$}) image size failed", nDetectorID); } else { Info("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")) { Error("Reset ImageReadyCallbackProcess failed!!!"); } else { Info("Reset ImageReadyCallbackProcess success"); } nRet = API_YI_SystemInfo_Callback_Register(szDetectorID, nullptr); if (TestError(nDetectorID, nRet, "API_YI_SystemInfo_Callback_Register")) { Error("Reset SystemInfoCallbackProcess failed!!!"); } else { Info("Reset SystemInfoCallbackProcess success"); } nRet = API_YI_ImageReady_Callback_Register(szDetectorID, ImageReadyCallbackProcess); if (TestError(nDetectorID, nRet, "API_YI_ImageReady_Callback_Register")) { Error("Register ImageReadyCallbackProcess failed!!!"); } else { Info("Register ImageReadyCallbackProcess success"); } nRet = API_YI_SystemInfo_Callback_Register(szDetectorID, SystemInfoCallbackProcess); if (TestError(nDetectorID, nRet, "API_YI_SystemInfo_Callback_Register")) { Error("Register SystemInfoCallbackProcess failed!!!"); } else { Info("Register SystemInfoCallbackProcess success"); } //读取或设置common参数 YIConfigInfo_Common stConfigCommon = { 0 }; nRet = API_YI_FPD_Get_Configure_Common(szDetectorID, 1, &stConfigCommon); if (TestError(nDetectorID, nRet, "API_YI_FPD_Get_Configure_Common")) { Error("Get detector common config failed!!!"); } else { Info("Get detector common config success"); Info("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, 0, 1, &stConfigSyncOut); if (TestError(nDetectorID, nRet, "API_YI_FPD_Get_Configure_SyncOut_Mode")) { Error("Get detector syncmode config failed!!!"); } else { Info("Get detector syncmode config success"); Info("ExpWindow: {$}; ExpTimeout: {$}; ", stConfigSyncOut.usExposureWindow, stConfigSyncOut.usExposureTimeOut); } //加载模板 FPDLoadCorrectFiles(nDetectorID, szDetectorID); //设置工作模式 SetDetectorWorkMode(nDetectorID, szDetectorID, m_stDeviceIndex[nDetectorIndex].nSyncMode); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, ""); return true; } //重连接 bool YuyingCtrl::RetryConnect(int nDetectorID) { Info("RetryConnect start"); Sleep(500); Info("RetryConnect over"); return false; } bool YuyingCtrl::OnInitStatus(int nPanelIndex, ENUM_PANEL_EVENT_STATE ePanelState) { int nDetectorID = 0; if (PANEL_EVENT_START == ePanelState) { StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, ""); } else if (PANEL_EVENT_END_OK == ePanelState) { StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, ""); } else if (PANEL_EVENT_END_ERROR == ePanelState) { StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, ""); } else if (PANEL_EVENT_END == ePanelState) //未连接探测器 { StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, ""); } return true; } /************************************************************************************ 功能:启动线程,处理一些异步消息 ************************************************************************************/ void YuyingCtrl::YuyingScanEventThread() { if (m_hScanEventThread != NULL) { Info("ScanEvent Thread already run\n"); return; } Info("Start ScanEvent Thread"); DWORD unThreadID; m_hScanEventThread = (HANDLE)CreateThread(NULL, 0, onScanEvent, (LPVOID)this, 0, &unThreadID); if (m_hScanEventThread == NULL) { Fatal("Start Scan Event Error"); } else { Info("Start ScanEvent Thread ok"); } //endif } /************************************************************************************ 功能:启动线程,处理一些异步消息 m_hRecoverImage 异步,恢复图像 m_hCofirmCalib 异步,确认每一次校正的结果,如剂量大了/小了/ m_hReconnectFD 异步,初始化探测器 ************************************************************************************/ DWORD YuyingCtrl::onScanEvent(void* pParam) { YuyingCtrl* pInstance = (YuyingCtrl*)pParam; if (pInstance == NULL) { return false; } bool bExitFlag = true; while (bExitFlag) { Info("( Waiting for Signal...)"); DWORD dwResult = WaitForMultipleObjects(Yuying_SCAN_NUM, pInstance->m_hArrayEvent, FALSE, INFINITE); if (WAIT_OBJECT_0 == dwResult) //m_hExitEvent { Info("Get Exit Event"); bExitFlag = false; } else if (WAIT_OBJECT_0 + 1 == dwResult) //m_hRecoverImage { Info("Get RecoverImage Event"); pInstance->RecoverLastImageAuto(); } else if (WAIT_OBJECT_0 + 2 == dwResult) //m_hCofirmCalib { Info("Get Cofirm Calibration Event"); pInstance->ConfirmCalibration(); } else if (WAIT_OBJECT_0 + 3 == dwResult) //m_hEndCalibEvent { Info("Get EndCalibraion Event"); pInstance->OnEndCalibraion(); } } SetEvent(pInstance->m_hYuyingScanEnd); Info("Yuying ScanEvent Thread End"); return true; } //接口成功返回false,接口失败或有错返回true bool YuyingCtrl::TestError(int nDetectorID, int nErrorStatus, std::string strAPI) { switch (nErrorStatus) { case 0: { SystemErrorCode nErrorCode = SEC_Succeed; nErrorCode = (SystemErrorCode)API_YI_GetLastErrorCode(); Fatal("{$} Failed!!! ErrorCode: {$}", strAPI.c_str(), (int)nErrorCode); return true; break; } case 1: { Debug("{$} Success", strAPI); return false; break; } default: break; } return true; } bool YuyingCtrl::LoadYuyingDLL(string strWorkPath) { string strDllDir = strWorkPath; if (SetDllDirectory(strDllDir.c_str()) == 0) { DWORD dw = GetLastError(); Info("SetDllDirectory error,error code [{$}]", dw); return false; } string strDllPath = strWorkPath + "\\YuYingAPI.dll"; Info("Load Yuying API"); m_hYuyingModule = LoadLibrary(strDllPath.c_str()); if (NULL == m_hYuyingModule) { Fatal("Load Yuying API failed!"); return false; } API_YI_Initialize_FPD_V4 = (Func_YI_Initialize_FPD_V4)GetProcAddress(m_hYuyingModule, "YI_Initialize_FPD_V4"); if (nullptr == API_YI_Initialize_FPD_V4) { Fatal("Load YI_Initialize_FPD_V4 failed!"); return false; } API_YI_FPD_Set_Work_Mode = (Func_YI_FPD_Set_Work_Mode)GetProcAddress(m_hYuyingModule, "YI_FPD_Set_Work_Mode"); if (nullptr == API_YI_FPD_Set_Work_Mode) { Fatal("Load YI_FPD_Set_Work_Mode failed!"); return false; } API_YI_FPD_Stop_Capture_Image = (Func_YI_FPD_Stop_Capture_Image)GetProcAddress(m_hYuyingModule, "YI_FPD_Stop_Capture_Image"); if (nullptr == API_YI_FPD_Stop_Capture_Image) { Fatal("Load YI_FPD_Stop_Capture_Image failed!"); return false; } API_YI_FPD_Get_Configure_Common = (Func_YI_FPD_Get_Configure_Common)GetProcAddress(m_hYuyingModule, "YI_FPD_Get_Configure_Common"); if (nullptr == API_YI_FPD_Get_Configure_Common) { Fatal("Load YI_FPD_Get_Configure_Common failed!"); return false; } API_YI_FPD_Set_Configure_Common = (Func_YI_FPD_Set_Configure_Common)GetProcAddress(m_hYuyingModule, "YI_FPD_Set_Configure_Common"); if (nullptr == API_YI_FPD_Set_Configure_Common) { Fatal("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_hYuyingModule, "YI_FPD_Get_Configure_SyncOut_Mode"); if (nullptr == API_YI_FPD_Get_Configure_SyncOut_Mode) { Fatal("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_hYuyingModule, "YI_FPD_Set_Configure_SyncOut_Mode"); if (nullptr == API_YI_FPD_Set_Configure_SyncOut_Mode) { Fatal("Load YI_FPD_Set_Configure_SyncOut_Mode failed!"); return false; } API_YI_FPD_Restore_Factory_Settings = (Func_YI_FPD_Restore_Factory_Settings)GetProcAddress(m_hYuyingModule, "YI_FPD_Restore_Factory_Settings"); if (nullptr == API_YI_FPD_Restore_Factory_Settings) { Fatal("Load YI_FPD_Restore_Factory_Settings failed!"); return false; } API_YI_FPD_Subtract_Offset = (Func_YI_FPD_Subtract_Offset)GetProcAddress(m_hYuyingModule, "YI_FPD_Subtract_Offset"); if (nullptr == API_YI_FPD_Subtract_Offset) { Fatal("Load YI_FPD_Subtract_Offset failed!"); return false; } API_YI_ImageReady_Callback_Register = (Func_YI_ImageReady_Callback_Register)GetProcAddress(m_hYuyingModule, "YI_ImageReady_Callback_Register"); if (nullptr == API_YI_ImageReady_Callback_Register) { Fatal("Load YI_ImageReady_Callback_Register failed!"); return false; } API_YI_ImageReady_Callback_Register_Ex = (Func_YI_ImageReady_Callback_Register_Ex)GetProcAddress(m_hYuyingModule, "YI_ImageReady_Callback_Register_Ex"); if (nullptr == API_YI_ImageReady_Callback_Register_Ex) { Fatal("Load YI_ImageReady_Callback_Register_Ex failed!"); return false; } API_YI_SystemInfo_Callback_Register = (Func_YI_SystemInfo_Callback_Register)GetProcAddress(m_hYuyingModule, "YI_SystemInfo_Callback_Register"); if (nullptr == API_YI_SystemInfo_Callback_Register) { Fatal("Load YI_SystemInfo_Callback_Register failed!"); return false; } API_YI_SystemInfo_Callback_Register_Ex = (Func_YI_SystemInfo_Callback_Register_Ex)GetProcAddress(m_hYuyingModule, "YI_SystemInfo_Callback_Register_Ex"); if (nullptr == API_YI_SystemInfo_Callback_Register_Ex) { Fatal("Load YI_SystemInfo_Callback_Register_Ex failed!"); return false; } API_YI_Get_Callback_Image_Size = (Func_YI_Get_Callback_Image_Size)GetProcAddress(m_hYuyingModule, "YI_Get_Callback_Image_Size"); if (nullptr == API_YI_Get_Callback_Image_Size) { Fatal("Load YI_Get_Callback_Image_Size failed!"); return false; } API_YI_GetLastErrorCode = (Func_YI_GetLastErrorCode)GetProcAddress(m_hYuyingModule, "YI_GetLastErrorCode"); if (nullptr == API_YI_GetLastErrorCode) { Fatal("Load YI_GetLastErrorCode failed!"); return false; } API_YI_Set_Save_Log_Flag = (Func_YI_Set_Save_Log_Flag)GetProcAddress(m_hYuyingModule, "YI_Set_Save_Log_Flag"); if (nullptr == API_YI_Set_Save_Log_Flag) { Fatal("Load YI_Set_Save_Log_Flag failed!"); return false; } API_YI_GetLoacalIPs_V4 = (Func_YI_GetLoacalIPs_V4)GetProcAddress(m_hYuyingModule, "YI_GetLoacalIPs_V4"); if (nullptr == API_YI_GetLoacalIPs_V4) { Fatal("Load YI_GetLoacalIPs_V4 failed!"); return false; } API_YI_Set_Image_Save_State = (Func_YI_Set_Image_Save_State)GetProcAddress(m_hYuyingModule, "YI_Set_Image_Save_State"); if (nullptr == API_YI_Set_Image_Save_State) { Fatal("Load YI_Set_Image_Save_State failed!"); return false; } API_YI_Set_Image_Save_Path = (Func_YI_Set_Image_Save_Path)GetProcAddress(m_hYuyingModule, "YI_Set_Image_Save_Path"); if (nullptr == API_YI_Set_Image_Save_Path) { Fatal("Load YI_Set_Image_Save_Path failed!"); return false; } API_YI_FPD_Get_FPD_TYPE = (Func_YI_FPD_Get_FPD_TYPE)GetProcAddress(m_hYuyingModule, "YI_FPD_Get_FPD_TYPE"); if (nullptr == API_YI_FPD_Get_FPD_TYPE) { Fatal("Load YI_FPD_Get_FPD_TYPE failed!"); return false; } API_YI_FPD_Get_Invalid_Region = (Func_YI_FPD_Get_Invalid_Region)GetProcAddress(m_hYuyingModule, "YI_FPD_Get_Invalid_Region"); if (nullptr == API_YI_FPD_Get_Invalid_Region) { Fatal("Load YI_FPD_Get_Invalid_Region failed!"); return false; } API_YI_FPD_Capture_Image = (Func_YI_FPD_Capture_Image)GetProcAddress(m_hYuyingModule, "YI_FPD_Capture_Image"); if (nullptr == API_YI_FPD_Capture_Image) { Fatal("Load YI_FPD_Capture_Image failed!"); return false; } API_YI_FPD_Capture_Prepare = (Func_YI_FPD_Capture_Prepare)GetProcAddress(m_hYuyingModule, "YI_FPD_Capture_Prepare"); if (nullptr == API_YI_FPD_Capture_Prepare) { Fatal("Load YI_FPD_Capture_Prepare failed!"); return false; } API_YI_Load_Gain_Tmp_File = (Func_YI_Load_Gain_Tmp_File)GetProcAddress(m_hYuyingModule, "YI_Load_Gain_Tmp_File"); if (nullptr == API_YI_Load_Gain_Tmp_File) { Fatal("Load YI_Load_Gain_Tmp_File failed!"); return false; } API_YI_Load_Defect_Tmp_File = (Func_YI_Load_Defect_Tmp_File)GetProcAddress(m_hYuyingModule, "YI_Load_Defect_Tmp_File"); if (nullptr == API_YI_Load_Defect_Tmp_File) { Fatal("Load YI_Load_Defect_Tmp_File failed!"); return false; } API_YI_Load_Offset_Tmp_File = (Func_YI_Load_Offset_Tmp_File)GetProcAddress(m_hYuyingModule, "YI_Load_Offset_Tmp_File"); if (nullptr == API_YI_Load_Offset_Tmp_File) { Fatal("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_hYuyingModule, "YI_Load_AED_Offset_Tmp_File"); if (nullptr == API_YI_Load_AED_Offset_Tmp_File) { Fatal("Load YI_Load_AED_Offset_Tmp_File failed!"); return false; } API_YI_Set_Correct_Type = (Func_YI_Set_Correct_Type)GetProcAddress(m_hYuyingModule, "YI_Set_Correct_Type"); if (nullptr == API_YI_Set_Correct_Type) { Fatal("Load YI_Set_Correct_Type failed!"); return false; } API_YI_FPD_DO_Correction = (Func_YI_FPD_DO_Correction)GetProcAddress(m_hYuyingModule, "YI_FPD_DO_Correction"); if (nullptr == API_YI_FPD_DO_Correction) { Fatal("Load YI_FPD_DO_Correction failed!"); return false; } API_YI_FPD_Wifi_Re_Connect = (Func_YI_FPD_Wifi_Re_Connect)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Re_Connect"); if (nullptr == API_YI_FPD_Wifi_Re_Connect) { Fatal("Load YI_FPD_Wifi_Re_Connect failed!"); return false; } API_YI_FPD_Wifi_Set_Work_Mode = (Func_YI_FPD_Wifi_Set_Work_Mode)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Set_Work_Mode"); if (nullptr == API_YI_FPD_Wifi_Set_Work_Mode) { Fatal("Load YI_FPD_Wifi_Set_Work_Mode failed!"); return false; } API_YI_FPD_Wifi_Get_Work_Mode = (Func_YI_FPD_Wifi_Get_Work_Mode)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Get_Work_Mode"); if (nullptr == API_YI_FPD_Wifi_Get_Work_Mode) { Fatal("Load YI_FPD_Wifi_Get_Work_Mode failed!"); return false; } API_YI_FPD_Wifi_Set_Name = (Func_YI_FPD_Wifi_Set_Name)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Set_Name"); if (nullptr == API_YI_FPD_Wifi_Set_Name) { Fatal("Load YI_FPD_Wifi_Set_Name failed!"); return false; } API_YI_FPD_Wifi_Set_Power_Down = (Func_YI_FPD_Wifi_Set_Power_Down)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Set_Power_Down"); if (nullptr == API_YI_FPD_Wifi_Set_Power_Down) { Fatal("Load YI_FPD_Wifi_Set_Power_Down failed!"); return false; } API_YI_FPD_Wifi_Set_IP_Address = (Func_YI_FPD_Wifi_Set_IP_Address)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Set_IP_Address"); if (nullptr == API_YI_FPD_Wifi_Set_IP_Address) { Fatal("Load YI_FPD_Wifi_Set_IP_Address failed!"); return false; } API_YI_FPD_Wifi_Set_Route_Info = (Func_YI_FPD_Wifi_Set_Route_Info)GetProcAddress(m_hYuyingModule, "YI_FPD_Wifi_Set_Route_Info"); if (nullptr == API_YI_FPD_Wifi_Set_Route_Info) { Fatal("Load YI_FPD_Wifi_Set_Route_Info failed!"); return false; } Info("Load Yuying API over"); return true; } void YuyingCtrl::FreeYuyingDLL() { if (m_hYuyingModule) { FreeLibrary(m_hYuyingModule); m_hYuyingModule = NULL; Info(" Free Yuying DLL"); } } bool YuyingCtrl::AddDPCs(nsDPC::FPDDeviceYuying* pDrvDPC, ResDataObject& Configuration, DeviceIndexStruct& DeviceStruct) { map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { Warn("YuyingCtrl::AddDPCs This DPC already exist\n"); return false; } Info("--Func-- AddDPCs {$}", pDrvDPC); //拿到当前探测器的配置 m_stDeviceIndex[m_nPanelCount] = DeviceStruct; m_ObjFPDsInfo[m_nPanelCount] = Configuration; Info("AddDPCs, {$} {$} ", m_stDeviceIndex[m_nPanelCount].strDetectorModel, m_stDeviceIndex[m_nPanelCount].strDeviceName); m_pDPC2PanelID->insert(pair(pDrvDPC, m_nPanelCount)); m_pPanelID2DPC->insert(pair(m_nPanelCount, pDrvDPC)); m_ModeConfig = m_ObjFPDsInfo[m_nDetectorIndex]; m_nPanelCount++; Info("YuyingCtrl::AddDPCs ok {$}\n", m_nPanelCount); //初始化配置 try { m_nCalibrationMode = (int)Configuration["CalibrationMode"]; } catch (const std::exception& e) { Info("some configuration miss, {$}", e.what()); } return true; } bool YuyingCtrl::DelDPCs(nsDPC::FPDDeviceYuying* pDrvDPC) { map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { map::iterator PanelIdIter = m_pPanelID2DPC->find(DPCsIter->second); if (PanelIdIter != m_pPanelID2DPC->end()) { m_pPanelID2DPC->erase(PanelIdIter); } m_stDeviceIndex[DPCsIter->second] = {}; m_ObjFPDsInfo[DPCsIter->second].clear(); m_pDPC2PanelID->erase(DPCsIter); m_nPanelCount--; Info("YuyingCtrl::DelDPCs ok {$}\n", m_nPanelCount); } return true; } void YuyingCtrl::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 YuyingCtrl::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 YuyingCtrl::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 YuyingCtrl::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 YuyingCtrl::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 YuyingCtrl::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); } /********************************************************************/ /* 将文件删除 /********************************************************************/ bool YuyingCtrl::DeleteOneFolder(string strSourceFolder) { Info("Delete {$}", strSourceFolder.c_str()); if (!PathFileExists(strSourceFolder.c_str())) { Info("SourceFolder don't exist"); return false; } char pFolderSource[1024] = { 0 }; memset(pFolderSource, 0x00, 1024); strcpy(pFolderSource, strSourceFolder.c_str()); // 第一个文件 SHFILEOPSTRUCT sfo; memset(&sfo, 0, sizeof(SHFILEOPSTRUCT)); sfo.hwnd = NULL; sfo.wFunc = FO_DELETE;//FO_MOVE; sfo.pFrom = pFolderSource; sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;// | FOF_ALLOWUNDO; //| FOF_NOCONFIRMMKDIR; // FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件; //FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。 SHFileOperation(&sfo); Info("Delete File over"); return true; } //将strSrcPath文件拷贝到strDstPath目录 bool YuyingCtrl::CopyFile2Folder(string strSrcPath, string strDstPath) { //MSDN: This string must be double-null terminated strSrcPath += '\0'; strDstPath += '\0'; //上面两行代码非常重要,直接影响下面SHFileOperation的稳定性 Info("Copy {$} to {$}", strSrcPath.c_str(), strDstPath.c_str()); if (!PathFileExists(strSrcPath.c_str())) { Info("SourceFolder don't exist"); return false; } if (!PathFileExists(strDstPath.c_str())) { Info("DestFolder don't exist"); return false; } SHFILEOPSTRUCT sfo; sfo.hwnd = NULL; sfo.wFunc = FO_COPY;//FO_MOVE; sfo.pFrom = strSrcPath.c_str(); sfo.pTo = strDstPath.c_str(); sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO; //| FOF_NOCONFIRMMKDIR; // FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件; //FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。 int nRet = SHFileOperation(&sfo); Info("Copy File to Folder over, {$}", nRet); return true; } bool YuyingCtrl::SwithPanel(int nPanelId) { return true; } bool YuyingCtrl::ActivePanel(nsDPC::FPDDeviceYuying* pDrvDPC, bool bActive) { Info("ActivePanel start: {$}, DetectorIndex {$}", pDrvDPC, m_nDetectorIndex); map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { if (m_nDetectorIndex != DPCsIter->second) { Info("DetectorIndex {$} != DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second); if (!SwithPanel(DPCsIter->second)) { return false; } m_nDetectorIndex = DPCsIter->second; m_pCurrentDPC = pDrvDPC; m_nCurrentMode = -1; m_ModeConfig.clear(); m_ModeConfig = m_ObjFPDsInfo[m_nDetectorIndex]; Info("ActivePanel over: {$}, DetectorIndex {$}", pDrvDPC, m_nDetectorIndex); for (int i = 0; i < m_nPanelCount; i++) { ((nsDPC::FPDDeviceYuying*)(*m_pPanelID2DPC)[i])->UnactiveBySDK(pDrvDPC); } } else { Info("DetectorIndex {$} == DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second); } } else { Warn("Not find DPC in group"); return false; } return true; } bool YuyingCtrl::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; } Info("Enter exam: {$}", strLog.c_str()); m_eAppStatus = eStatus; return true; } /*** ** 说明:连接 ** 加载SDK,初始化SDK,连接探测器等初始化操作 ** 参数:strWorkPath,初始化SDK必须的conf路径 ***/ bool YuyingCtrl::Connect(string strAppPath, nsDPC::FPDDeviceYuying* pDrvDPC) { Info("--Func-- Connect"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return true"); return true; } StartInitFPDThread(); Info("=== Connect detector OK ==="); return true; } void YuyingCtrl::DisconnectFD(int nDetectorID) { Info("disconnect detector {$} over", nDetectorID); } /*** ** 说明:退出 ** 释放SDK ***/ bool YuyingCtrl::DisConnect(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return true; } Info("--Func-- DisConnect"); Info("DisConnect Over"); return true; } RET_STATUS YuyingCtrl::SetSyncMode(SYNC_MODE nSyncMode, HARDWARE_TRIGGER_MODE TriggerMode) { return RET_STATUS::RET_SUCCEED; } /*** ** 说明:设置当前的曝光模式 ** 参数:nLogicMode,从配置文件读取,与SDK配置application mode对应 ***/ bool YuyingCtrl::SelectExamMode(int nLogicMode, nsDPC::FPDDeviceYuying* pDrvDPC) { Info("YuyingCtrl::SelectExamMode start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC {$}, {$} != {$} ,return", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nDetectorIndex); return false; } if (m_stDeviceIndex[m_nDetectorIndex].bConnectStatus == false) { Error("Current detector {$} is not connect, return\n", m_nDetectorIndex); return false; } Info("SelectExamMode({$})", nLogicMode); if (m_nCurrentMode == nLogicMode) //同样appmode下没必要再次走下面的流程 { Info("Same appmode, return true"); return true; } m_nCurrentMode = nLogicMode; try { m_nRawImgHeight = m_stDeviceIndex[m_nDetectorIndex].nRawHeight; m_nRawImgWidth = m_stDeviceIndex[m_nDetectorIndex].nRawWidth; m_nImageWidth = m_stDeviceIndex[m_nDetectorIndex].nFullImageWidth; m_nImageHeight = m_stDeviceIndex[m_nDetectorIndex].nFullImageHeight; m_nLeftOffset = m_stDeviceIndex[m_nDetectorIndex].nImageLeftOffset; m_nTopOffset = m_stDeviceIndex[m_nDetectorIndex].nImageTopOffset; m_nRightOffset = m_stDeviceIndex[m_nDetectorIndex].nImageRightOffset; m_nBottomOffset = m_stDeviceIndex[m_nDetectorIndex].nImageBottomOffset; m_nImgBits = m_stDeviceIndex[m_nDetectorIndex].nImageBits; m_nPixelPitch = m_stDeviceIndex[m_nDetectorIndex].nPixelSpace; m_nSaveRaw = m_stDeviceIndex[m_nDetectorIndex].nSaveRaw; Info("Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$} {$} {$}), Bits({$}), PixelPitch({$}), SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nTopOffset, m_nBottomOffset, m_nLeftOffset, m_nRightOffset, m_nImgBits, m_nPixelPitch, m_nSaveRaw); string strCoef = (string)m_ModeConfig["Sensitivity"]; Info("Sensitivity: {$}", strCoef.c_str()); m_nPreviewWidth = m_stDeviceIndex[m_nDetectorIndex].nPreviewWidth; m_nPreviewHeight = m_stDeviceIndex[m_nDetectorIndex].nPreviewHeight; m_bPreviewEnable = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable; Info("Preview size(W*H {$}*{$}), PreviewEnable({$})", m_nPreviewWidth, m_nPreviewHeight, m_bPreviewEnable); } catch (ResDataObjectExption& exp) { Error("Get config failed: {$}", exp.what()); } if (m_pImgBuffer) { delete m_pImgBuffer; m_pImgBuffer = NULL; } m_pImgBuffer = new WORD[m_nImageHeight * m_nImageWidth]; ConfFeedback(EVT_CONF_RAW_WIDTH, m_nDetectorIndex, "", m_nImageWidth); ConfFeedback(EVT_CONF_RAW_HIGHT, m_nDetectorIndex, "", m_nImageHeight); ConfFeedback(EVT_CONF_RAW_BITS, m_nDetectorIndex, "", m_nImgBits); ConfFeedback(EVT_CONF_PIXELSPACE, m_nDetectorIndex, "", m_nPixelPitch); ConfFeedback(EVT_CONF_PREVIEW_WIDTH, m_nDetectorIndex, "", m_nPreviewWidth); ConfFeedback(EVT_CONF_PREVIEW_HIGHT, m_nDetectorIndex, "", m_nPreviewHeight); Info("selectExamMode {$} over \n", m_nCurrentMode); //加载校正文件,暂时先放到初始化流程中,同探测器多模式还需要考虑 //FPDLoadCorrectFiles(m_nDetectorID, m_vecDetectorID[m_nDetectorIndex].c_str()); return true; } bool YuyingCtrl::StartOffsetThread() { if (m_pOffsetThread == NULL) { DWORD m_NotifyThreadID; m_pOffsetThread = CreateThread(0, 0, OffsetThread, this, 0, &m_NotifyThreadID); if (m_pOffsetThread == NULL) { Fatal("Start Offset Thread Failed"); return false; } } return true; } DWORD YuyingCtrl::OffsetThread(LPVOID pParam) { YuyingCtrl* pCurPanel = (YuyingCtrl*)pParam; if (pCurPanel == NULL) { return false; } Info("OffsetThread"); pCurPanel->StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FINISH); pCurPanel->m_pOffsetThread = NULL; return true; } /********************************************************************/ /* 功能:Yuying没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ bool YuyingCtrl::StartXWindowOffThread() { if (m_pXWindowoffThread == NULL) { DWORD m_NotifyThreadID; m_pXWindowoffThread = CreateThread(0, 0, XWindowOffThread, this, 0, &m_NotifyThreadID); if (m_pXWindowoffThread == NULL) { Fatal("Start Inner Exp Thread Failed"); return false; } } return true; } /********************************************************************/ // /* 功能:Yuying没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ DWORD YuyingCtrl::XWindowOffThread(LPVOID pParam) { YuyingCtrl* pCurPanel = (YuyingCtrl*)pParam; if (pCurPanel == NULL) { return false; } DWORD dwTimer = pCurPanel->m_stDeviceIndex[pCurPanel->m_nDetectorIndex].nXWindow; DWORD dwResult = WaitForSingleObject(pCurPanel->m_hWindowOffEvent, dwTimer); Info("Simulate XWINDOW_OFF"); pCurPanel->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); pCurPanel->m_pXWindowoffThread = NULL; return true; } /*** ** 说明:曝光前的准备流程 ***/ RET_STATUS YuyingCtrl::PrepareAcquisition(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } if (m_stDeviceIndex[m_nDetectorIndex].bConnectStatus == false) { Info("Current detector is not connect, return"); return RET_STATUS::RET_FAILED; } int nTempTriggerMode = m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (ModeType::Idle == nTempTriggerMode) { Info("Idle"); } else if (ModeType::Software_Mode == nTempTriggerMode) //软同步 { Info("Softerware mode"); } else if (ModeType::AED_Offset_Mode == nTempTriggerMode) //AED_Offset { Info("AED offset mode"); } else if (ModeType::AED_Mode == nTempTriggerMode) //Free同步 { Info("AED mode"); } else if (ModeType::Outer_Mode == nTempTriggerMode) //外同步 { Info("Outer mode"); } else if (ModeType::Freerun_Mode == nTempTriggerMode) //Freerun { Info("Freerun mode"); } else { Error("The detector get undefined sync mode"); } return RET_STATUS::RET_SUCCEED; } RET_STATUS YuyingCtrl::StartAcquisition(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_FAILED; if (!m_stDeviceIndex[m_nDetectorIndex].bConnectStatus) { Warn("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_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (ModeType::Idle == nTempTriggerMode) { Info("Idle"); } else if (ModeType::Software_Mode == nTempTriggerMode) //软同步 { Info("Softerware mode"); int nRet = API_YI_FPD_Capture_Image(m_vecDetectorID[m_nDetectorIndex].c_str(), 1); if (TestError(m_nDetectorID, nRet, "Capture_Image")) { Error("Capture image failed"); } } else if (ModeType::AED_Offset_Mode == nTempTriggerMode) //AED_Offset { Info("AED offset mode"); } else if (ModeType::AED_Mode == nTempTriggerMode) //Free同步 { Info("AED mode"); } else if (ModeType::Outer_Mode == nTempTriggerMode) //外同步 { Info("Outer mode"); } else if (ModeType::Freerun_Mode == nTempTriggerMode) //Freerun { Info("Freerun mode"); } else { Error("The detector get undefined sync mode"); } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK); return RET_STATUS::RET_SUCCEED; } RET_STATUS YuyingCtrl::StopAcquisition(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } int nTempTriggerMode = 1; return RET_STATUS::RET_SUCCEED; } bool YuyingCtrl::GetYuyingPanelCalibItem() { m_listCalibItem.clear(); try { int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); for (int i = 0; i < nModeCount; i++) { int nCalibModeCount = (int)m_ModeConfig["ModeTable"][i]["CalibConfig"].GetKeyCount("NodeInfo"); for (int j = 0; j < nCalibModeCount; j++) { RefrenceCal stRefCal; stRefCal.nAvgNum = (int)m_ModeConfig["ModeTable"][i]["CalibConfig"][j]["ImgCount"]; stRefCal.nReferDose = (int)m_ModeConfig["ModeTable"][i]["CalibConfig"][j]["Dose"]; m_listCalibItem.push_back(stRefCal); } } } catch (...) { return false; } return true; } bool YuyingCtrl::InitCalibration() { m_nDefectExpTimes = 0; m_nDefectTotalTimes = 0; m_nGainExpTimes = 0; Info("InitCalibration Current Active FD Index:{$}", m_nDetectorIndex); if (m_nPanelCount < 0) { return false; } string strMode = "STE"; m_bInCalibrating = true; bool ret = GetYuyingPanelCalibItem(); if (!ret) { Error("GetPanelCalibItem failed\n"); return false; } list::iterator iter; for (iter = m_listCalibItem.begin(); iter != m_listCalibItem.end(); iter++) { Info("Calibration dose:{$},Number:{$}", iter->nReferDose, iter->nAvgNum); } m_iterCalibDose = m_listCalibItem.begin(); m_nDoseParam = m_iterCalibDose->nReferDose; DataFeedback(EVT_DATA_DOSEPARAM, NULL, m_nDoseParam); Info("First Calibration dose:{$},Number:{$},m_nDoseParam = {$}", m_iterCalibDose->nReferDose, m_iterCalibDose->nAvgNum, m_nDoseParam); m_nGainTotalFrames = 0; return true; } /*** ** 说明:激活校正 ** 增益校正(探测器采用post-offset,暗场校正基本没用了)时拿到dose回调,算作执行完毕 ***/ RET_STATUS YuyingCtrl::ActiveCalibration(CCOS_CALIBRATION_TYPE Type, nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_SUCCEED; int nTemp = (int)m_ModeConfig["Attached"]; if (nTemp == 0) { Warn("Current detector({$}) is not attached, return failed", m_nDetectorIndex); return RET_STATUS::RET_FAILED; } if (CCOS_CALIBRATION_TYPE_DARK == Type) { Info("ActiveDarkCalibration"); } else if (CCOS_CALIBRATION_TYPE_XRAY == Type) { Info("ActiveXrayCalibration"); StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); if (!InitCalibration()) { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); return RET_STATUS::RET_FAILED; } } else { Error("Active not supported calibration({$}), return! \n", (int)Type); Ret = RET_STATUS::RET_NOSUPPORT; return Ret; } m_eCaliType = Type; return Ret; } /*** ** 说明:开始校正(状态机FrameStart) ** Salmon项目只有普通rad模式,所以本接口基本没用 ***/ RET_STATUS YuyingCtrl::StartCalibration(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_FAILED; int nTemp = (int)m_ModeConfig["Attached"]; if (nTemp == 0) { Warn("Current detector({$}) is not attached, return failed", m_nDetectorIndex); return Ret; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { Info("StartDarkCalibration \n"); StartOffsetThread(); Ret = RET_STATUS::RET_SUCCEED; } else { Info("StartXrayCalibration \n"); Ret = RET_STATUS::RET_SUCCEED; } return Ret; } bool YuyingCtrl::ConfirmCalibration() { Info("Confirm Calibration"); return true; } bool YuyingCtrl::AcceptCalibration() { if ((PANEL_GAIN_CAL == m_nCalibStatus) && (m_nGainExpTimes >= m_nGainTotalFrames)) { Info("Gain exposure over"); if (CreateCalibrationFile()) { m_iterCalibDose++; m_nDoseParam = m_iterCalibDose->nReferDose; Info("Next Gain Calibration dose:{$},Number:{$}", m_iterCalibDose->nReferDose, m_iterCalibDose->nAvgNum); } else { StatusFeedback(EVT_STATUS_SINGLEEXP, PANEL_EVENT_END_ERROR); } } else if (PANEL_DEFECT_CAL == m_nCalibStatus) { int nAvgNum = m_iterCalibDose->nAvgNum; if (m_nDefectExpTimes >= nAvgNum) { m_nDefectExpTimes = 0; m_iterCalibDose++; m_nDoseParam = m_iterCalibDose->nReferDose; Info("Next Defect Calibration dose:{$},Number:{$}", m_iterCalibDose->nReferDose, m_iterCalibDose->nAvgNum); } if (m_nDefectTotalTimes >= m_nDefectTotalFrames) { Info("Defect exposure over"); StatusFeedback(EVT_STATUS_PREPARE_EDNCALIBRATION, 0); if (CreateCalibrationFile()) { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); } else { StatusFeedback(EVT_STATUS_SINGLEEXP, PANEL_EVENT_END_ERROR); } return true; } } DataFeedback(EVT_DATA_DOSEPARAM, NULL, m_nDoseParam); return true; } bool YuyingCtrl::CreateCalibrationFile() { return true; } bool YuyingCtrl::RejectCalibration() { Info("Reject Calibration"); return true; } /*** ** 说明:终止校正 ***/ RET_STATUS YuyingCtrl::AbortCalibration(nsDPC::FPDDeviceYuying* pDrvDPC) { _AutoLocker scLocker(this); if (!m_bInCalibrating) { Warn("Not in calibration status,omit it."); return RET_STATUS::RET_SUCCEED; } if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } Info("AbortCalibration \n"); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值 RET_STATUS Ret = RET_STATUS::RET_FAILED; if (m_nPanelCount < 0) { Info("No active detector"); return Ret; } if (m_bInCalibrating) { SetMarsCorrection(m_nDetectorIndex); } else { Info("Omit Abort Calibration"); } Ret = RET_STATUS::RET_SUCCEED; return Ret; } /*** ** 说明:准备校正(状态机FramePrep) ** 曝光使能过程,使探测器开窗 ***/ RET_STATUS YuyingCtrl::PrepareCalibration(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_FAILED; int nTemp = (int)m_ModeConfig["Attached"]; if (nTemp == 0) { Warn("Current detector({$}) is not attached, return failed", m_nDetectorIndex); return Ret; } Ret = RET_STATUS::RET_SUCCEED; Debug("PrepareCalibration Over"); return Ret; } /*** ** 说明:结束校正 ** DPC处理完校正报告后调用,此处上传map、报告等文件 ***/ RET_STATUS YuyingCtrl::CompleteCalibration(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } SetEvent(m_hEndCalibEvent); Info("CompleteCalibration"); return RET_STATUS::RET_SUCCEED; } void YuyingCtrl::OnEndCalibraion() { Info("OnEndCalibraion start"); m_bInCalibrating = false; bool bLTE = false; bool bRet = true; bool bResult = DownloadCalibrationFileToFD(true, bLTE); bResult = DownloadCalibrationFileToFD(false, bLTE); if (!bResult) { Info("UploadCalibrationFileToFD files"); } GetCalibrationTime(m_nDetectorIndex, bLTE); SetMarsCorrection(m_nDetectorIndex); string szTemp; szTemp = m_stDeviceIndex[m_nDetectorIndex].strCalibrationDate; WriteCumstomFile(m_nDetectorIndex);//上传校正报告,sensitivity BackupCalibFiles(m_nDetectorIndex, true, bLTE);//备份校正defect map/ if (bRet) { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END); } else { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END_ERROR); } Info("Calibration completed!"); return; } bool YuyingCtrl::RecoverLastImage() { Info("Recover Last Image"); return RecoverImage(); } bool YuyingCtrl::RecoverLastImageAuto() { Info("Recover Last Image Auto"); return true; } /********************************************************************/ /* 功能:对图像镜像 */ /********************************************************************/ bool YuyingCtrl::FlipX(WORD* pData, int nWidth, int nHeight) { int j = 0; int i = 0; Info("Flip Image Width:{$},Height:{$}", nWidth, nHeight); WORD temp; //修改翻转的判断,之前的代码会导致中央区域多翻转一个像素 for (i = 0; i < nHeight; i++) { for (j = 0; j < nWidth / 2; j++) { temp = pData[i * nWidth + j]; pData[i * nWidth + j] = pData[(i + 1) * nWidth - j - 1]; pData[(i + 1) * nWidth - j - 1] = temp; } } Info("Flip Image Over"); return true; } /********************************************************************/ /* 功能:对SDK输出的图像,先旋转90度,再做镜像 */ /********************************************************************/ bool YuyingCtrl::FlipXRotate90(WORD* pData, int nWidth, int nHeight) { Info("Rotate 270 angle"); WORD* ptempData = new WORD[nWidth * nHeight]; memcpy(ptempData, pData, nWidth * nHeight * sizeof(WORD)); for (int i = 0; i < nWidth; i++) for (int j = 0; j < nHeight; j++) pData[i * nWidth + j] = ptempData[j * nWidth + (nWidth - 1 - i)]; delete[]ptempData; ptempData = NULL; FlipX(pData, nWidth, nHeight); return true; } bool YuyingCtrl::ReadBatteryStatus(int nDetectorID) { return true; } //获取电池电量 bool YuyingCtrl::CheckBattery(int nDetectorID) { if (!m_stDeviceIndex[nDetectorID].bBatteryEnable) { Info("Battery disable"); return true; } return true; } //读取探测器WIFI bool YuyingCtrl::ReadWifiStatus(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bWireless) { return false; } Info("Read Wifi"); //FPDRESULT nResult = YuyingFnInvoke(nPanelID, Cmd_ReadWifiStatus, NULL, 0); //if (TestError(nDetectorID, nResult)) { Fatal("Read Wifi Failed"); return false; } bool bResult = WaitRespond(8000); if (bResult) { if (m_stDeviceIndex[nDetectorID].bReadWifi) { Info("Read Wifi Success"); return true; } return false; } Info("Read Wifi Timeout"); return false; } bool YuyingCtrl::CheckWiFi(int nDetectorID) { if (!m_stDeviceIndex[nDetectorID].bWifiEnable) { Info("Wifi disable"); return true; } return true; } bool YuyingCtrl::CheckTemperature(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bTemperatureEnable) { Info("Temperature disable"); return true; } float fTemperature1 = 0.0f; return true; } //读取探测器温度 bool YuyingCtrl::ReadTempStatus(int nDetectorID) { Info("Read Temperture"); Info("Read Temperture Timeout"); return false; } //清空板内校正的校正选项,否则写入参数可能会失败 bool YuyingCtrl::ClearCorrection(int nDetectorID) { Info("Clear Correction Option"); return true; } // 探测器是板内校正 // 设置探测器端校正参数,加载校正文件 bool YuyingCtrl::SetMarsCorrection(int nDetectorID) { Info("Set Mars Correction Option"); return true; } //设置探测器的工作模式 bool YuyingCtrl::SetDetectorWorkMode(int nDetectorID, const char* szFPD, int nWorkMode) { Info("Set detector({$})({$}) work mode: {$}", nDetectorID, szFPD, nWorkMode); if (ModeType::Idle == nWorkMode) { Info("Set workmode Idle"); } else if (ModeType::Software_Mode == nWorkMode) { Info("Set workmode software"); } else if (ModeType::AED_Offset_Mode == nWorkMode) { Info("Set workmode AED offset"); } else if (ModeType::AED_Mode == nWorkMode) //AED触发 { Info("Set workmode AED"); } else if (ModeType::Outer_Mode == nWorkMode) //硬同步(直连或者同步盒) { Info("Set Hardware outer"); } int nRet = API_YI_FPD_Set_Work_Mode(szFPD, (ModeType)nWorkMode); if (TestError(nDetectorID, nRet, "API_YI_FPD_Set_Work_Mode")) { Error("Set work mode failed!!!"); return false; } else { Info("Set work mode success"); } Info("SetDetectorWorkMode over"); return true; } //加载校正 bool CCOS::Dev::Detail::Detector::YuyingCtrl::FPDLoadCorrectFiles(int nDetectorID, const char* szDetectorID) { Info("FPDLoadCorrectFiles"); int nRet = 0; if (m_nCalibrationMode) { std::string strGainPath = m_strWorkPath + "\\Correct Files\\Gain.tf"; std::string strDefectPath = m_strWorkPath + "\\Correct Files\\Defect.tf"; nRet = API_YI_Load_Gain_Tmp_File(szDetectorID, strGainPath.c_str()); //加载Gain模板 if (TestError(nDetectorID, nRet, "Load_Gain")) { Error("Load gain template failed!"); } else { Info("Load gain tempplate success"); } nRet = API_YI_Load_Defect_Tmp_File(szDetectorID, strDefectPath.c_str()); if (TestError(nDetectorID, nRet, "Load_Defect")) { Error("Load defect template failed!"); } else { Info("Load defect template success"); } int nCorrectType = Do_Gain | Do_Defect; nRet = API_YI_Set_Correct_Type(szDetectorID, nCorrectType); if (TestError(nDetectorID, nRet, "Set_Correction")) { Error("Set correction failed!"); } else { Info("Set correction success"); } } else { Info("ZSKK calibration"); } //设置探测器做Offset校正 nRet = API_YI_FPD_Subtract_Offset(szDetectorID, true); if (TestError(nDetectorID, nRet, "Set_Offset")) { Error("Set offset failed!"); } else { Info("Set offset success"); } Info("FPDLoadCorrectFiles over"); return true; } bool YuyingCtrl::IsFWNeedUpdate(int nDetectorID) { return true; } //----------------------------------------------------------------------------- // 更新FW的指令 // //----------------------------------------------------------------------------- RET_STATUS YuyingCtrl::OnUpdateFirmware(nsDPC::FPDDeviceYuying* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } Info("Update FPD {$} Firmware", m_stDeviceIndex[m_nDetectorIndex].strPanelSerial.c_str()); m_nUpdateFPDID = m_nDetectorID; HANDLE hUpdateThread; DWORD unThreadID; hUpdateThread = CreateThread(NULL, 0, onUpdateFWThread, this, 0, &unThreadID); if (hUpdateThread == NULL) { Error("Start Update Firmware Thread Error"); } return RET_STATUS::RET_SUCCEED; } /*** ** 说明:升级固件线程 ***/ DWORD __stdcall YuyingCtrl::onUpdateFWThread(PVOID pvoid) { YuyingCtrl* pOpr = (YuyingCtrl*)pvoid; Info("Firmware update thread"); return pOpr->UpdateFirmware(pOpr->m_nUpdateFPDID, true); ; } bool YuyingCtrl::UpdateFirmware(int nDetectorID, bool bUpdate) { Info("Update FPD Firmware"); return true; } bool YuyingCtrl::UploadCalibFileFromFD(int nDetectorID, int nIndex, string strFileName, bool bGain) { return true; } //上传校正文件到探测器端,gain或defect文件 bool YuyingCtrl::DownloadCalibrationFileToFD(bool bGainFile, bool bExpMode) { return true; } //上传user edit defect文件,到探测器端 bool YuyingCtrl::DownloadUserDefectFileToFD(bool bLTE) { return true; } //从探测器端读取Sensitivity和校正报告文件 //下载到CalibrationData目录 bool YuyingCtrl::ReadCumstomFile(int nDetectorID) { return true; } //上传校正报告和Sensitivity文件到FD端, //Cmd_WriteCustomFile 的参数为文件所在的Folder bool YuyingCtrl::WriteCumstomFile(int nDetectorID) { return true; } //从校正文件中读取校正日期 bool YuyingCtrl::GetCalibrationTime(int nDetectorID, bool bExpMode) { return ((nsDPC::FPDDeviceYuying*)(*m_pPanelID2DPC)[nDetectorID])->GetCalibrationTime(bExpMode); } ////从探测器上下载文件: //Gain文件,defect文件; bool YuyingCtrl::DownloadfromDetector(int nDetectorID) { GetCalibrationTime(nDetectorID, false); GetCalibrationTime(nDetectorID, true); return true; } // 从SDK指定目录拷贝失败的校正文件到CalibrationFailedData中 bool YuyingCtrl::SaveFailedCalibFiles(int nDetectorID, bool bExpMode) { Info("SaveCalibrationFailedData over"); return true; } // 从CalibrationData中拷贝校正文件到SDK指定目录 bool YuyingCtrl::BackupCalibFiles(int nDetectorID, bool bBackupOrRestore, bool bExpMode) { return true; } bool YuyingCtrl::CleanCalibFiles(int nDetectorID, bool bExpMode) { return true; } bool YuyingCtrl::CleanCalibReport(int nDetectorID, bool bExpMode) { return true; } // 从CalibrationData中恢复校正报告文件 bool YuyingCtrl::RestoreCalibReport(int nDetectorID, bool bExpMode) { return true; } // 从CalibrationData中恢复Sensitivity文件 bool YuyingCtrl::RestoreSensitivity(int nDetectorID) { return true; } //----------------------------------------------------------------------------- // 检查探测器中是否有未传输成功的图像 // 知道图像是否传输成功 //----------------------------------------------------------------------------- bool YuyingCtrl::CheckLastImageStatus(int nDetectorID) { return true; } bool YuyingCtrl::CancelImageRecover() { Info("Cancel Image Recover"); return true; } //----------------------------------------------------------------------------- // 函数描述 : 恢复图像:将曝光未获取成功的图像,重新获取出来 /* */ //----------------------------------------------------------------------------- bool YuyingCtrl::RecoverImage() { return true; } bool YuyingCtrl::IsConnected(string strIP) { Info("Check ping {$}", strIP); CMyPingip obPingIp; StatusFeedback(EVT_STATUS_PING, 0, "true"); if (!obPingIp.PingFunction(strIP.c_str())) { Info("ping {$} Failed", strIP); StatusFeedback(EVT_STATUS_PING, 0, "false"); return false; } return true; } //----------------------------------------------------------------------------- // Reconnect探测器(上层有button) //----------------------------------------------------------------------------- bool YuyingCtrl::ResetFPD(nsDPC::FPDDeviceYuying* pDrvDPC) { Info("Reset FPD"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return false; } Info("Panel Count {$}\n", m_nPanelCount); for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) { if (!m_stDeviceIndex[nDetectorID].bWireless) { Error("Omit reconnection in fixed FD"); } else { DisconnectFD(nDetectorID); StartInitFPDThread(); } } return true; } void YuyingCtrl::OnProcessPreImg() { if (m_bPreviewEnable) { DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pwPreviewImg); } } void YuyingCtrl::OnProcessImg() { if (m_nLeftOffset != 0 || m_nTopOffset != 0) { if (m_nSaveRaw) { SaveRawImage("Before_Crop.raw", m_pwRawImageData, m_nRawImgWidth, m_nRawImgHeight); } Debug("Begin get effect image, m_nRawImgWidth {$}\n", m_nRawImgWidth); if (!GetEffectiveImage(m_pImgBuffer, m_pwRawImageData, m_nRawImgWidth)) { Error("Get effect image failed"); return; } Debug("Get effect image over"); if (m_nSaveRaw) { SaveRawImage("After_Crop.raw", m_pImgBuffer, m_nImageWidth, m_nImageHeight); } } else { memcpy(m_pImgBuffer, m_pwRawImageData, m_nImageHeight * m_nImageWidth * sizeof(WORD)); } //if (1) { FlipX(m_pImgBuffer, m_nImageWidth, m_nImageHeight); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); } // pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度 bool YuyingCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth) { if (pOutImg == NULL || pInImg == NULL || nInWidth < 0) { Error("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_nTopOffset) * nInWidth + m_nLeftOffset, m_nImageWidth * sizeof(WORD)); } } catch (...) { Error("Get effective image crashed. m_nImageWidth {$},m_nImageHeight {$},m_nWidthOffset {$},m_nHeightOffset {$},m_nBottomOffset {$}\n", m_nImageWidth, m_nImageHeight, m_nLeftOffset, m_nTopOffset, m_nBottomOffset); return false; } return true; } bool YuyingCtrl::StartHardwareStatusThread() { if (!m_stDeviceIndex[m_nDetectorIndex].bStatusPollEnable) { Warn("Detector status polling disable"); return true; } if (m_pHardwareStatusThread == NULL) { m_hEndHWStatusThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DWORD dwHardwareStatusID; m_pHardwareStatusThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &dwHardwareStatusID); if (m_pHardwareStatusThread == NULL) { Fatal("Start HardwareStatus Thread Failed"); return false; } } return true; } DWORD YuyingCtrl::HardwareStatusThread(LPVOID pParam) { YuyingCtrl* pCurPanel = (YuyingCtrl*)pParam; if (pCurPanel == NULL) { return false; } Info("HardwareStatusThread start"); DWORD dwTimer = 5000; while (true) { DWORD dwResult = WaitForSingleObject(pCurPanel->m_hEndHWStatusThreadEvent, dwTimer); if (dwResult == WAIT_OBJECT_0) { break; } else { pCurPanel->GetHardwareStatus(); } } CloseHandle(pCurPanel->m_hEndHWStatusThreadEvent); SetEvent(pCurPanel->m_hHWStatusThreadEndEvent); Info("HardwareStatusThread stop"); return true; } bool YuyingCtrl::GetHardwareStatus() { if (m_bInExposure) { Info("In Exposuring,omit check hw status"); return true; } for (int nID = 0; nID < m_nPanelCount; nID++) { if (!m_stDeviceIndex[nID].bConnectStatus) // 如果检测到平板探测器失去连接,那么要通知DROC { Info("Detector({$}) is communication error", nID + 1); ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nID + 1); } else if (m_stDeviceIndex[nID].bConnectStatus) { Info("Check FPD {$} Status", nID + 1); bool bResult = true; bResult = CheckBattery(nID); bResult = CheckWiFi(nID) && bResult; bResult = CheckTemperature(nID) && bResult; } } return true; } //----------------------------------------------------------------------------- // 手动编辑完坏点坏线,将校正文件上传到探测器端,并重新生成校正报告 // //----------------------------------------------------------------------------- bool YuyingCtrl::UploadCalibrationFiles(nsDPC::FPDDeviceYuying* pDrvDPC, string strFileName) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return false; } string strExpMode = "STE"; bool bLTE = false; StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_START); if (WriteCumstomFile(m_nDetectorIndex)) { StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END); } else { StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END_ERROR); } Info("UploadCalibrationFiles over"); return true; } /*** * 保存RAW图像 ***/ bool YuyingCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight) { Info("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight); if (pRawImg == NULL || pImgName == NULL) { return false; } string strImagePath = m_strAppPath + "\\Image\\" + pImgName; FILE* fp; if ((fp = fopen(strImagePath.c_str(), "wb")) == NULL) { DWORD dw = GetLastError(); Error("fopen {$} failed, {$}", strImagePath.c_str(), dw); return false; } fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp); fclose(fp); Info("End to Save Raw Image"); return true; } //图像回调 bool YuyingCtrl::ImageReadyCallbackProcess(const char* pImage, int iFlag) { return g_pYuyingCtrl->onImageReadyCallbackProcess(pImage, iFlag); } //系统回调 bool YuyingCtrl::SystemInfoCallbackProcess(SystemInfoCode iCodeIndex, const char* sContent) { return g_pYuyingCtrl->onSystemInfoCallbackProcess(iCodeIndex, sContent); } bool YuyingCtrl::onImageReadyCallbackProcess(const char* pImage, int iFlag) { Info("onImageReadyCallbackProcess"); if (NULL == pImage) { Fatal("Image Data is null"); return false; } if (ModeType::AED_Mode == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); StartXWindowOffThread(); } if (m_pwRawImageData) { delete[] m_pwRawImageData; m_pwRawImageData = NULL; } m_pwRawImageData = new WORD[m_nRawImgHeight * m_nRawImgWidth]; if (m_pwRawImageData == NULL) { Fatal("Allocate Raw Image Failed"); return false; } memcpy(m_pwRawImageData, pImage, m_nRawImgHeight * m_nRawImgWidth * sizeof(WORD)); OnProcessImg(); return true; } bool YuyingCtrl::onSystemInfoCallbackProcess(SystemInfoCode iCodeIndex, const char* sContent) { switch (iCodeIndex) { case SIC_Exposure_Window_Open: //软同步或者硬同步发开窗 { Info("SIC_Exposure_Window_Open"); if (ModeType::Software_Mode == m_stDeviceIndex[m_nDetectorIndex].nSyncMode || ModeType::Outer_Mode == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } break; } case SIC_Exposure_Winodw_Closed: { Info("SIC_Exposure_Winodw_Closed"); if (ModeType::Software_Mode == m_stDeviceIndex[m_nDetectorIndex].nSyncMode || ModeType::Outer_Mode == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); } break; } case SIC_Exposure_Window_Timeout: { Info("SIC_Exposure_Window_Timeout"); break; } case SIC_Device_Heart_Beat: { Info("SIC_Device_Heart_Beat: {$}", sContent); if (NULL == sContent) { Info("null content"); break; } if (!m_stDeviceIndex[m_nDetectorIndex].bStatusPollEnable) { Info("Disable status polling"); break; } //温度 if (m_stDeviceIndex[m_nDetectorIndex].bTemperatureEnable) { const char* pTempera = strstr(sContent, "T:"); if (pTempera != NULL) { float fTemperature = (float)atof(pTempera + 2); StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nDetectorIndex, fTemperature); } } //湿度 if (m_stDeviceIndex[m_nDetectorIndex].bHumidityEnable) { const char* pHumidity = strstr(sContent, "H:"); if (pHumidity != NULL) { int nHumidity = atoi(pHumidity + 2); // } } if (m_stDeviceIndex[m_nDetectorIndex].bBatteryEnable) { //供电方式(1电池供电,2电源供电) const char* pPower = strstr(sContent, "P:"); int nChargingType = 0; if (pPower != NULL) { nChargingType = atoi(pPower + 2); } if (nChargingType == 1) { Info("Power mode: Battery"); } else if (nChargingType == 2) { Info("Power mode: Cable"); } else { Info("Undefined power mode"); } //电量 const char* pBatt = strstr(sContent, "E:"); if (pBatt != NULL) { int nBatteryValue = atoi(pBatt + 2); StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryValue, "", m_nDetectorIndex); } } //信号强度 if (m_stDeviceIndex[m_nDetectorIndex].bWifiEnable) { const char* pSignalValue = strstr(sContent, "S:"); if (pSignalValue != NULL) { int nSignalValue = atoi(pSignalValue + 2); StatusFeedback(EVT_STATUS_WIFI, nSignalValue, "", m_nDetectorIndex); } } break; } case SIC_Physical_Connection_State: { Info("SIC_Physical_Connection_State: {$}", sContent ? sContent : "null"); if (NULL == sContent) { Info("null content"); break; } if (sContent[0] == '0') { Info("Detector disconnect"); } else { Info("Detector communication recovery"); } break; } case SIC_Upload_Tmp_File_Begin: { Info("SIC_Upload_Tmp_File_Begin"); break; } case SIC_Upload_Tmp_File_End: { Info("SIC_Upload_Tmp_File_End"); break; } case SIC_TCP_Connection_State: { Info("SIC_TCP_Connection_State"); break; } case SIC_Power_Low: { Info("SIC_Power_Low"); break; } case SIC_Power_Down_Soon: { Info("SIC_Power_Down_Soon"); break; } case SIC_FPD_Sleep_State: { Info("SIC_FPD_Sleep_State"); break; } case SIC_FPD_MultiFrame_Index: { Info("SIC_FPD_MultiFrame_Index"); break; } case SIC_FPD_IndustryMode_Prepare_Rready: { Info("SIC_FPD_IndustryMode_Prepare_Rready"); break; } case SIC_FPD_MFM_Prepare_Ready: { Info("SIC_FPD_MFM_Prepare_Ready"); break; } default: break; } return true; } //设置同步模式 bool YuyingCtrl::ActiveSyncMode(nsDPC::FPDDeviceYuying* pDrvDPC, int nSyncMode) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return false; } if (m_stDeviceIndex[m_nDetectorIndex].nSyncMode == nSyncMode) { Info("Same sync mode, omit set sync mode"); return true; } const char* szDetectorID = m_vecDetectorID[m_nDetectorIndex].c_str(); if (SetDetectorWorkMode(m_nDetectorID, szDetectorID, nSyncMode)) { m_stDeviceIndex[m_nDetectorIndex].nSyncMode = nSyncMode; Info("Set detector sync mode into {$}", nSyncMode); } else { Error("Set detector sync mode failed!"); } return true; }