#include "stdafx.h" #include #include "sys\stat.h" #include //文件流库函数 #include #include "IRayCtrl.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") const int nINIT_TIME = 50000; const int nCMD_TIME = 5000; IRayCtrl* g_pIRayCtrl = NULL; void SDKCallbackProxy(int nDetectorID, int nEventID, int nEventLevel, const char* pszMsg, int nParam1, int nParam2, int nPtrParamLen, void* pParam) { g_pIRayCtrl->ProcessEvent(nDetectorID, nEventID, nEventLevel, pszMsg, nParam1, nParam2, nPtrParamLen, pParam); } #define MAX_STRING 1024 IRayCtrl::IRayCtrl() : g_strAppPath("") , m_nPanelCount(0) , m_nDetectorID(1) , m_nDetectorIndex(0) , m_nCorrectionType(0) , m_hIRayModule(nullptr) , m_fpCreate(nullptr) , m_fpDestroy(nullptr) , m_fpGetAttr(nullptr) , m_fpSetAttr(nullptr) , m_fpInvoke(nullptr) , m_pRegisterScanNotify(nullptr) , m_pScanOnce(nullptr) , m_pFnGetErrorInfo(nullptr) , m_pfAbort(nullptr) , m_pfOpenDefectTemplateFile(nullptr) , m_pfCloseDefectTemplateFile(nullptr) , m_hInitThread(nullptr) , m_hExitEvent(nullptr) , m_hRecoverImage(nullptr) , m_hCofirmCalib(nullptr) , m_hEndCalibEvent(nullptr) , m_hIRayScanEnd(nullptr) , m_hSharedEvent(nullptr) , m_hWindowOffEvent(nullptr) , m_pXWindowoffThread(nullptr) , m_hScanEventThread(nullptr) , m_nCurrentMode(-1) , m_strCurrentExamType("") , m_bSaveRaw(false) , m_pwPreviewImg(nullptr) , m_pwRawImageData(nullptr) , m_nFrameID(0) , m_nExiThreshold(0) , m_bOffsetAll(false) , m_bGrabStatus(false) , m_nUpdateFPDID(-1) , m_fFrameRate(0.0f) { m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); //m_pImageBuffer = NULL; m_strWorkPath = ""; m_eAppStatus = APP_STATUS_IDLE; m_nImageWidth = 0; m_nImageHeight = 0; m_nRawImgWidth = 0; m_nRawImgHeight = 0; m_nWidthOffset = 0; m_nHeightOffset = 0; m_nImgBits = 16; m_nPixelPitch = 150; m_bPreviewEnable = false; m_nPreviewWidth = 0; m_nPreviewHeight = 0; m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; m_nDoseParam = 0; m_fCurrentDose = 0; m_nCaliFailedCount = 0; m_bGainPreparing = false; m_bGainProcess = false; m_bConfirmCaliRst = false; m_bPreviewImg = false; //m_nGainNodeCount = 0; //m_nGainNodeIndex = 0; //m_nGainExpCount = 0; //m_nGainExpIndex = 0; m_bIsImageRecovering = false; m_bInCalibrating = false; m_bFDAttaching = false; m_pHardwareStatusThread = NULL; m_bFirmwareUpdating = false; m_bInExposure = false; m_bWindowOn = false; m_nRecoverImageTimes = 0; m_bImageRecoverBeCanceled = false; for (int i = 0; i < IRAY_SCAN_NUM; i++) { m_hArrayEvent[i] = nullptr; } m_bSetCorrectFile = false; m_mapLogicModeOperationMode.clear(); } IRayCtrl::~IRayCtrl() { OnEXIT(); delete m_pDPC2PanelID; m_pDPC2PanelID = NULL; delete m_pPanelID2DPC; m_pPanelID2DPC = NULL; m_mapLogicModeOperationMode.clear(); } bool IRayCtrl::OnEXIT() { SetEvent(m_hEndHWStatusThreadEvent); Info("Waiting HWStatus Thread End"); int nResult = WaitForSingleObject(m_hHWStatusThreadEndEvent, 10000); if (WAIT_TIMEOUT == nResult) { Error("iRay HWStatus Thread Quit Failed"); } else { Info("iRay HWStatus Thread Quit Success"); } for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) { DisconnectFD(nDetectorID); //两块板都断开,防止系统异常退出后,再次启动系统后没有释放socket的连接无法再次连接。 } SetEvent(m_hExitEvent); Info("Waiting iRay ScanEvent Thread End"); nResult = WaitForSingleObject(m_hIRayScanEnd, 2000); if (WAIT_TIMEOUT == nResult) { Error("iRay ScanEvent Thread Quit Failed"); } else { Info("iRay ScanEvent Thread Quit Success"); } DeleteHandle(); Info("Free IRay DLL"); FreeIRayDLL(); return true; } void IRayCtrl::DeleteHandle() { if (m_hSharedEvent) { CloseHandle(m_hSharedEvent); m_hSharedEvent = nullptr; } if (m_hExitEvent) { CloseHandle(m_hExitEvent); m_hExitEvent = nullptr; } if (m_hRecoverImage) { CloseHandle(m_hRecoverImage); m_hRecoverImage = nullptr; } if (m_hCofirmCalib) { CloseHandle(m_hCofirmCalib); m_hCofirmCalib = nullptr; } if (m_hEndCalibEvent) { CloseHandle(m_hEndCalibEvent); m_hEndCalibEvent = nullptr; } if (m_hIRayScanEnd) { CloseHandle(m_hIRayScanEnd); m_hIRayScanEnd = nullptr; } 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; } } FPDRESULT IRayCtrl::IrayFnInvoke(int nDetectorID, int nCommandID, IRayCmdParam pars[], int nParCount) { int trytimes = 0; FPDRESULT nResult = Err_OK; while (trytimes++ < 6) { nResult = m_fpInvoke(nDetectorID, nCommandID, pars, nParCount); if (Err_StateErr != nResult) return nResult; else Sleep(1000); } return nResult; } //SDK回调函数 void IRayCtrl::ProcessEvent(int nDetectorID, int nEventID, int nEventLevel, const char* pszMsg, int nParam1, int nParam2, int nPtrParamLen, void* pParam) { string strDescrip = pszMsg; Info("DetectorID:{$},Event:{$},Param1:{$},Param2:{$},Description:{$}", nDetectorID, nEventID, nParam1, nParam2, strDescrip.c_str()); switch (nEventID) { case Evt_GeneralWarn: Warn("[ Evt_GeneralWarn ]"); break; case Evt_OffsetAmassingTime: { Info("[ Evt_OffsetAmassingTime ]"); } break; case Evt_Exp_Prohibit: { Info("[ Event:Evt_Exp_Prohibit ]"); } break; case Evt_Exp_Enable: { Info("[ Event:Evt_Exp_Enable ]"); m_bWindowOn = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } break; case Evt_TaskResult_Canceled: { Info("[ Evt_TaskResult_Canceled ]"); OnProcessTaskResult2(nDetectorID, nParam1, nParam2, false); } break; case Evt_AutoTask_Started: { Info("[ Evt_AutoTask_Started ]"); OnProcessTaskResult2(nDetectorID, nParam1, nParam2, true); } break; case Evt_TaskResult_Succeed: OnProcessTaskResult(nDetectorID, nParam1, nParam2, true); break; case Evt_TaskResult_Failed: OnProcessTaskResult(nDetectorID, nParam1, nParam2, false); break; case Evt_TemplateFileUpload_Result: break; case Evt_LivingTime: { Info("[ Event:Evt_LivingTime ]"); break; } case Evt_Retransfer_Image: { Info("[ Event:Evt_Retransfer_Image ],Omit it"); } break; case Evt_Image: { Info("[ Event:Evt_Image ]"); IRayImage* pstImg = (IRayImage*)pParam; if (pstImg == NULL) { Fatal("Image Data is NULL"); return; } if (!m_bGrabStatus) { Warn("Invalid image, omit"); return; } int nRawImgHeight = pstImg->nHeight; int nRawImgWidth = pstImg->nWidth; Info("Image Height:{$},Width:{$}", nRawImgHeight, nRawImgWidth); memcpy(m_pwRawImageData, pstImg->pData, nRawImgHeight * nRawImgWidth * sizeof(WORD)); OnProcessImg(); } break; case Evt_Prev_Image: { Info("[ Event:Evt_Prev_Image ]"); IRayImage* pstImg = (IRayImage*)pParam; m_stDeviceIndex[nDetectorID - 1].nImageBits = pstImg->nBytesPerPixel * 8; int nPreviewHeight = pstImg->nHeight; int nPreviewWidth = pstImg->nWidth; if (m_pwPreviewImg != NULL) { delete[] m_pwPreviewImg; m_pwPreviewImg = NULL; } if (m_pwPreviewImg == NULL) { m_pwPreviewImg = new WORD[nPreviewHeight * nPreviewWidth]; if (m_pwPreviewImg == NULL) { Fatal("Allocate Preview Image Memery Failed"); return; } } memcpy(m_pwPreviewImg, pstImg->pData, nPreviewHeight * nPreviewWidth * sizeof(WORD)); if (m_stDeviceIndex[nDetectorID - 1].strDeviceName.find("1717X") >= 0) { FlipX(m_pwPreviewImg, nPreviewWidth, nPreviewHeight); } else { FlipXRotate90(m_pwPreviewImg, nPreviewWidth, nPreviewHeight); } OnProcessPreImg(); } break; case Evt_LastImageID: { int nImageID = nParam1; bool bTranslatedSuccess = nParam2 ? true : false; Info("Last ImageID:{$},is Transfered:{$}", nParam1, bTranslatedSuccess); m_stDeviceIndex[nDetectorID - 1].nLastImageID = nParam1; m_stDeviceIndex[nDetectorID - 1].bImagePending = !bTranslatedSuccess; } break; case Evt_TemperatureHigh: { Info("[ Evt_TemperatureHigh ]"); } break; case Evt_LowBattery: { Info("[ Evt_LowBattery ]"); } break; case Evt_WaitImage_Timeout: { Info("[ Evt_WaitImage_Timeout ],Omit"); } break; case Evt_Exp_Timeout: { Info("[ Evt_Exp_Timeout ]"); } break; default: break; } } void IRayCtrl::OnProcessTaskResult2(int nDetectorID, int nParam1, int nParam2, bool bResult) { string strTaskResult = " Task Started"; if (!bResult) { strTaskResult = " Task Canceled"; } switch (nParam1) { case Cmd_GainInit: { Info("Cmd_GainInit {$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_DefectInit: { Info("Cmd_DefectInit {$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_OffsetGeneration: { Info("Cmd_OffsetGeneration{$}", strTaskResult.c_str()); SendNotify(); } break; } } void IRayCtrl::OnProcessTaskResult(int nDetectorID, int nParam1, int nParam2, bool bResult) { int nDetectorIndex = nDetectorID - 1; string strTaskResult = " Task Success"; if (!bResult) { strTaskResult = " Task Failed"; } switch (nParam1) { case 0: { TestError(nDetectorID, nParam2); if (Err_TemplateFileNotExist == nParam2) //暂时把该Error作为 Cmd_SetCorrectOption的返回 { } } break; case Cmd_Disconnect: { Info("FPD {$} is Disconnected", nDetectorID); SendNotify(); m_stDeviceIndex[nDetectorIndex].bConnectStatus = false; //SendDetectorInfo(nDetectorID); //状态栏图标更新状态 } break; case Cmd_Connect: { Info("[ Cmd_Connect ]"); if (bResult) { Info("FPD {$} is Connected", nDetectorID); m_stDeviceIndex[nDetectorIndex].bConnectStatus = true; m_stDeviceIndex[nDetectorIndex].bConnectChanged = true; //连接恢复之后,都要先查询一次有没有未传输成功的图像 m_nCmdConnectResult = nParam2; ErrorFeedback(EVT_ERR_COMMUNICATE, "false", nDetectorID); } else { m_stDeviceIndex[nDetectorIndex].bConnectStatus = false; Fatal("FPD {$} connect failed", nDetectorID); ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nDetectorID); m_nCmdConnectResult = nParam2; } SendNotify(); } break; case Cmd_SetCaliSubset: { Info("Cmd_SetCaliSubset{$}", strTaskResult); SendNotify(); } break; case Cmd_Acq2: Info("[ Cmd_Acq2 ]"); break; case Cmd_SyncStart: Info("Cmd_SyncStart"); break; case Cmd_SyncCancel: Info("Cmd_SyncCancel"); break; case Cmd_SyncAcq: Info("Cmd_SyncAcq"); break; case Cmd_ReadUserROM: Info("[ Cmd_ReadUserROM ]"); break; case Cmd_WriteUserROM: { m_stDeviceIndex[nDetectorIndex].bWriteROM = bResult; Info("Cmd_WriteUserROM {$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_OffsetGeneration: { Info("Cmd_OffsetGeneration{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_GainInit: { Info("Cmd_GainInit{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_DefectInit: { Info("Cmd_DefectInit{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_DefectSelectCurrent: { Info("Cmd_DefectSelectCurrent{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_FinishGenerationProcess: { Info("Cmd_FinishGenerationProcess{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_UpdateFirmware: { Info("Cmd_UpdateFirmware{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorIndex].bUpdateFirmware = bResult; if (TestError(nDetectorID, nParam2)) { SendNotify(); } } break; case Cmd_ReadTemperature: { Info("Cmd_ReadTemperature{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_ReadBatteryStatus: { Info("Cmd_ReadBatteryStatus{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_QueryLivingTime: { Info("Cmd_QueryLivingTime {$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_ReadWifiStatus: { Info("Cmd_ReadWifiStatus{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_SetCorrectOption: { Info("Cmd_SetCorrectOption{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorIndex].bSetCorrection = bResult; SendNotify(); } break; case Cmd_ReadHumidity: { Info("Cmd_ReadHumidity"); } break; case Cmd_ReadWifiSettings: { Info("Cmd_ReadWifiSettings"); } break; case Cmd_QueryLastImageID: { Info("Cmd_QueryLastImageID{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_GetImageByImageID: { Info("Cmd_GetImageByImageID{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorIndex].bTaskEnd = true; } break; case Cmd_ReadHallSensor: { Info("Cmd_ReadHallSensor{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_ClearAcq: { Info("Cmd_ClearAcq{$}", strTaskResult.c_str()); m_bInExposure = false; m_stDeviceIndex[nDetectorIndex].bTaskEnd = true; if (m_bInCalibrating) { if (TestError(nDetectorID, nParam2)) { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); } return; } if (!bResult) { TestError(nDetectorID, nParam2, false); //Err_ImgChBreak 30 Err_DetectorRespTimeout 24 switch (nParam2) { case Err_ImgChBreak: Fatal("Error Code 30:Err_ImgChBreak"); break; case Err_DetectorRespTimeout: Fatal("Error Code 24:Err_DetectorRespTimeout"); break; case Err_FPD_AcquisitionBlock: Fatal("Error Code 1040:Err_FPD_AcquisitionBlock"); break; default: break; } if (m_bWindowOn) { Info("need Reocover image"); //SetEvent(m_hRecoverImage); m_stDeviceIndex[nDetectorIndex].bImagePending = true; ErrorFeedback(EVT_ERR_GET_IMAGE, "true"); //图像没拿到 } } } break; case Cmd_SetTimeByDiff: { Info("Cmd_SetTimeByDiff{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_Clear: { Info("Cmd_Clear"); } break; case Cmd_StartAcq: { Info("Cmd_StartAcq{$}", strTaskResult.c_str()); } break; case Cmd_HwGeneratePreOffsetTemplate: { Info("Cmd_HwGeneratePreOffsetTemplate{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_DownloadCaliFile: { Info("Cmd_DownloadCaliFile{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_UploadCaliFile: { m_stDeviceIndex[nDetectorIndex].bUploadCalibFile = bResult; Info("Cmd_UploadCaliFile{$}", strTaskResult.c_str()); SendNotify(); break; } case Cmd_SelectCaliFile: { m_stDeviceIndex[nDetectorIndex].bUploadCalibFile = bResult; Info("Cmd_SelectCaliFile{$}", strTaskResult.c_str()); SendNotify(); } break; case Cmd_ProhibOutExp: { Info("Cmd_ProhibOutExp"); } break; case Cmd_EnableOutExp: { Info("Cmd_EnableOutExp"); } break; case Cmd_Wakeup: { Info("Cmd_Wakeup"); } break; case Cmd_Sleep: { Info("Cmd_Sleep"); } break; case Cmd_StopAcq: { Info("Cmd_StopAcq"); SendNotify(); } break; case Cmd_ReadCustomFile: { Info("Cmd_ReadCustomFile{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorIndex].bUploadCalibFile = bResult; SendNotify(); } break; case Cmd_WriteCustomFile: { Info("Cmd_WriteCustomFile{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorIndex].bUploadCalibFile = bResult; SendNotify(); } break; default: break; } } //等到SDK回调返回true, 超时返回false bool IRayCtrl::WaitRespond(int nTimeOut) { Info("---WaitRespond---:{$}", nTimeOut); DWORD nResult = WaitForSingleObject(m_hSharedEvent, nTimeOut); if (WAIT_TIMEOUT == nResult) //偶尔会出现EVT_HARDWARE太慢的情况 { Warn("Lock TimeOut");//出现超时,肯定是有问题了 ResetEvent(m_hSharedEvent); return false; } ResetEvent(m_hSharedEvent); return true; } void IRayCtrl::SendNotify() { Info("---SendNotify---"); SetEvent(m_hSharedEvent); } void IRayCtrl::ResetLock() { ResetEvent(m_hSharedEvent); } void IRayCtrl::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 IRayCtrl::WaitReady(int nDetectorID, int nMs) { int nState = 0; int nWaitMs = 0; bool bResult = true; string strLog; do { bResult = GetDetectorStatus(nDetectorID, nState); if (nState == Enm_State_Ready) { return true; } else { nWaitMs += 100; Pausetime(100); Info("WaitReady has waited [{$}] ms", nWaitMs); } } while (nWaitMs < nMs); return false; } bool IRayCtrl::Init(string strAppPath) { g_strAppPath = strAppPath; m_strWorkPath = strAppPath + (string)m_ModeConfig["SDKPath"]; //"OEMDrivers\\Detector\\iRay\\iRayDF\\IRay" Info("IRayCtrl::Init {$}\n", m_strWorkPath.c_str()); if (!LoadIRayDLL(m_strWorkPath)) { Error("IRayCtrl::Init LoadIRayDLL failed\n"); return false; } m_hSharedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hWindowOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hHWStatusThreadEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); Info("IRayCtrl::Init over\n"); return true; } //启动初始化线程 void IRayCtrl::StartInitFPDThread() { if (m_hInitThread) { Warn("Init thread already exsit, omit"); return; } Info("Start Init Thread"); DWORD unThreadID = 0; m_hInitThread = CreateThread(0, 0, onInitPanel, this, 0, &unThreadID); if (m_hInitThread == nullptr) { Fatal("Start Init Thread Error"); } return; } //初始化 DWORD IRayCtrl::onInitPanel(void* pParam) { IRayCtrl* pInstance = (IRayCtrl*)pParam; pInstance->Action_Init(); pInstance->m_hInitThread = nullptr; return true; } void IRayCtrl::Action_Init() { Info("IRayCtrl::Action_Init"); m_bInitialing = true; for (int i = 0; i < m_nPanelCount; i++) //连接多板 { string strWorkDir = m_stDeviceIndex[i].strWorkDir; Info("Start Register Detector: {$}", strWorkDir.c_str()); int nDetectorID = 0; int nRet = m_fpCreate(strWorkDir.c_str(), SDKCallbackProxy, &nDetectorID); if (TestError(nDetectorID, nRet, false)) { Error("Register Detector {$} Callback Failed", nDetectorID); continue; } Info("Register Detector {$} Callback Success", nDetectorID); if (!DetectorInitProcess(nDetectorID)) { Error("Init process failed"); } } iRayScanEventThread(); StartHardwareStatusThread(); m_bInitialing = false; Info("Action init over\n"); } //初始化连接探测器 bool IRayCtrl::DetectorInitProcess(int nDetectorID, bool bFetchCalibration) { OnInitStatus(nDetectorID, PANEL_EVENT_START); 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; } Info("Call FnInvoke:Connect"); int nRet = IrayFnInvoke(nDetectorID, Cmd_Connect, NULL, 0); //wait Cmd_Connect if (TestError(nDetectorID, nRet)) { Error("Connect Detector {$} Failed", nDetectorID); if (m_stDeviceIndex[nDetectorIndex].bActived) { m_stDeviceIndex[nDetectorIndex].bExisted = true; m_stDeviceIndex[nDetectorIndex].bConnectStatus = false; } return false; } ResetLock(); if (!WaitRespond(nINIT_TIME)) { Error("Connect Detector {$} timeout", nDetectorID); } if (m_stDeviceIndex[nDetectorIndex].bConnectStatus) { Info("Connect Detector {$} Success", nDetectorID); } else { bool bRet = false; if (m_nCmdConnectResult == Err_GeneralSocketErr) { Info("first connect return error 32, retry connect one more time"); Sleep(10000); //过10秒后再重新连接 bRet = RetryConnect(nDetectorID); } if (!bRet) { if (m_stDeviceIndex[nDetectorIndex].bActived) { m_stDeviceIndex[nDetectorIndex].bExisted = true; } return false; } } //获取系统信息 GetROMInfo(nDetectorID); //获取HVG信号状态 GetHVGSignalStatus(nDetectorID); //设置工作模式 //SetDetectorWorkMode(); if (bFetchCalibration) //特殊需求,同步校正文件//正常初始化,不同步校正文件 { DownloadfromDetector(nDetectorID); } //暗场的模式组成map SetOffsetModeScope(); //加载校正 //SetDetectorCorrection(nDetectorID, m_nCorrectionType); //SetDetectorXWindow(nDetectorID, 500, m_stDeviceIndex[nDetectorIndex].nXWindow, m_stDeviceIndex[nDetectorIndex].nXWindow); m_stDeviceIndex[nDetectorIndex].bExisted = true; m_stDeviceIndex[nDetectorIndex].bInitOK = true; OnInitStatus(nDetectorID, PANEL_EVENT_END_OK); return true; } //重连接 bool IRayCtrl::RetryConnect(int nDetectorID) { Info("RetryConnect start"); int nPanelID = nDetectorID + 1; Info("Call Cmd_Disconnect"); int nResult = IrayFnInvoke(nPanelID, Cmd_Disconnect, NULL, 0); if (TestError(nDetectorID, nResult)) { Info("Disconnect Detector {$} Failed", nPanelID); } Sleep(500); int nRet = IrayFnInvoke(nPanelID, Cmd_Connect, NULL, 0); if (TestError(nDetectorID, nRet)) { Info("RetryConnect Detector {$} Failed", nDetectorID); return false; } ResetLock(); if (!WaitRespond(nINIT_TIME)) { Error("Connect Detector {$} timeout", nPanelID); } if (m_stDeviceIndex[m_nDetectorIndex].bConnectStatus) { Info("RetryConnect Detector {$} Success", nDetectorID); return true; } else { Error("RetryConnect Detector {$} Failed", nDetectorID); } return false; } bool IRayCtrl::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, ""); }//end if return true; } //辅助线程句柄 void IRayCtrl::ScanAddHandle() { 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_hOffsetEvent = 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; m_hArrayEvent[4] = m_hOffsetEvent; m_hIRayScanEnd = CreateEvent(NULL, FALSE, FALSE, NULL); return; } /************************************************************************************ 功能:启动线程,处理一些异步消息 ************************************************************************************/ void IRayCtrl::iRayScanEventThread() { if (m_hScanEventThread) { Info("ScanEvent Thread already run\n"); return; } Info("Start ScanEvent Thread"); ScanAddHandle(); 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 IRayCtrl::onScanEvent(void* pParam) { IRayCtrl* pInstance = (IRayCtrl*)pParam; if (pInstance == NULL) { return false; } bool bExitFlag = true; while (bExitFlag) { Info("( Waiting for Signal...)"); DWORD dwResult = WaitForMultipleObjects(IRAY_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 { if (pInstance->m_nRecoverImageTimes < 2) { Info("Get RecoverImage Event"); pInstance->m_nRecoverImageTimes++; pInstance->RecoverLastImageAuto(); } else { Info("Get RecoverImage Event already retry 2 times, omit it"); if (pInstance->m_bWindowOn) { pInstance->ErrorFeedback(EVT_ERR_GET_IMAGE, "true"); } } } 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(); } else if (WAIT_OBJECT_0 + 4 == dwResult) //m_hOffsetEvent { Info("Get Offset Event"); pInstance->OffsetCalibration(); } } SetEvent(pInstance->m_hIRayScanEnd); Info("iRay ScanEvent Thread End"); return true; } bool IRayCtrl::GetProductNo(int nDetectorID, int& nProductNo) { return GetAttr(nDetectorID, Attr_UROM_ProductNo, nProductNo); } bool IRayCtrl::GetSrcIP(int nDetectorID, char* pszUROM_SrcIP) { return GetAttr(nDetectorID, Attr_UROM_SrcIP, pszUROM_SrcIP); } bool IRayCtrl::GetSerialNo(int nDetectorID, char* pszUROM_SerialNo) { return GetAttr(nDetectorID, Attr_UROM_SerialNo, pszUROM_SerialNo); } bool IRayCtrl::GetMainVersion(int nDetectorID, char* pszMainVersion) { return GetAttr(nDetectorID, Attr_UROM_MainVersion, pszMainVersion); } bool IRayCtrl::GetReadVersion(int nDetectorID, char* pszReadVersion) { return GetAttr(nDetectorID, Attr_UROM_ReadVersion, pszReadVersion); } bool IRayCtrl::GetMcuVersion(int nDetectorID, char* pszMcuVersion) { return GetAttr(nDetectorID, Attr_UROM_McuVersion, pszMcuVersion); } bool IRayCtrl::GetBatterySN(int nDetectorID, char* inoutSN) { return GetAttr(nDetectorID, Attr_Battery_SN, inoutSN); } bool IRayCtrl::GetArmVersion(int nDetectorID, char* pszArmVersion) { return GetAttr(nDetectorID, Attr_UROM_ArmVersion, pszArmVersion); } bool IRayCtrl::GetSyncMode(int nDetectorID, int& nTriggerMode) { return GetAttr(nDetectorID, Attr_UROM_TriggerMode, nTriggerMode); } bool IRayCtrl::GetKernelVersion(int nDetectorID, char* pszKernelVersion) { return GetAttr(nDetectorID, Attr_UROM_KernelVersion, pszKernelVersion); } bool IRayCtrl::GetWifiLinkQuality(int nDetectorID, int& nQuality) { return GetAttr(nDetectorID, Attr_WifiStatu_WorkingLinkQuality, nQuality); } bool IRayCtrl::GetConnState(int nDetectorID, int& nConnState) { return GetAttr(nDetectorID, Attr_ConnState, nConnState); } //ClearAcq窗口时间(以毫秒为单位) bool IRayCtrl::GetDelayTime(int nDetectorID, int& nDelayTime) { return GetAttr(nDetectorID, Cfg_ClearAcqParam_DelayTime, nDelayTime); } bool IRayCtrl::SetDelayTime(int nDetectorID, int nDelayTime) { return SetAttr(nDetectorID, Cfg_ClearAcqParam_DelayTime, nDelayTime); } //Acq2窗口时间(以毫秒为单位) bool IRayCtrl::GetXWindowDelay(int nDetectorID, int& nXWidnowTime) { return GetAttr(nDetectorID, Attr_UROM_SetDelayTime, nXWidnowTime); } bool IRayCtrl::SetXWindowDelay(int nDetectorID, int nXWidnowTime) { if (SetAttr(nDetectorID, Attr_UROM_SetDelayTime_W, nXWidnowTime)) { return WriteRom(nDetectorID); } return false; } //Clear+StartAcq窗口时间(以毫秒为单位) bool IRayCtrl::GetExpWindowTime(int nDetectorID, int& nExpWindowTime) { return GetAttr(nDetectorID, Attr_UROM_ExpWindowTime, nExpWindowTime); } bool IRayCtrl::SetExpWindowTime(int nDetectorID, int nExpWindow) { if (SetAttr(nDetectorID, Attr_UROM_ExpWindowTime_W, nExpWindow)) { return WriteRom(nDetectorID); } return false; } bool IRayCtrl::GetPrepCapMode(int nDetectorID, int& nPrepCapMode) { return GetAttr(nDetectorID, Attr_UROM_PrepCapMode, nPrepCapMode); } bool IRayCtrl::GetSelfCapEnable(int nDetectorID, int& nSelfCapEnable) { return GetAttr(nDetectorID, Attr_UROM_SelfCapEnable, nSelfCapEnable); } bool IRayCtrl::GetSelfClearEnable(int nDetectorID, int& nSelfClearEnable) { return GetAttr(nDetectorID, Attr_UROM_SelfClearEnable, nSelfClearEnable); } bool IRayCtrl::GetDynaOffsetGapTime(int nDetectorID, int& nDynOffsetGapTime) { return GetAttr(nDetectorID, Attr_UROM_DynaOffsetGapTime, nDynOffsetGapTime); } bool IRayCtrl::GetBatteryExist(int nDetectorID, int& nExist) { return GetAttr(nDetectorID, Attr_Battery_Exist, nExist); } bool IRayCtrl::GetBatteryRemaining(int nDetectorID, int& nRemaining) { return GetAttr(nDetectorID, Attr_Battery_Remaining, nRemaining); } bool IRayCtrl::GetBatteryChargingStatus(int nDetectorID, int& nStatus) { return GetAttr(nDetectorID, Attr_Battery_ChargingStatus, nStatus); } //静态板T1,动态板T2 bool IRayCtrl::GetFPDTempT1(int nDetectorID, float& fTempT1) { return GetAttr(nDetectorID, Attr_RdResult_T1, fTempT1); } bool IRayCtrl::GetFPDTempT2(int nDetectorID, float& fTempT2) { return GetAttr(nDetectorID, Attr_RdResult_T2, fTempT2); } bool IRayCtrl::GetHallSensor(int nDetectorID, int& nPosition) { return GetAttr(nDetectorID, Attr_HallSensorValue, nPosition); } bool IRayCtrl::GetLifeTime(int nDetectorID, int& nLifeTime) { return GetAttr(nDetectorID, Attr_FD_LifeTime, nLifeTime); } bool IRayCtrl::GetPowerOnCount(int nDetectorID, int& nCount) { return GetAttr(nDetectorID, Attr_FD_PowerOnCount, nCount); } bool IRayCtrl::GetDetectorStatus(int nDetectorID, int& state) { bool bResult = GetAttr(nDetectorID, Attr_State, state); Info("FPD {$} Status is [{$}]", nDetectorID, DetectorState[state]); return bResult; } bool IRayCtrl::GetCorrectionOption(int nDetectorID, int& nOption) { return GetAttr(nDetectorID, Attr_CurrentCorrectOption, nOption); } bool IRayCtrl::GetFWUpdateProgress(int nDetectorID, int& nOption) { return GetAttr(nDetectorID, Attr_FWUpdateProgress, nOption); } bool IRayCtrl::SetPrepCapMode(int nDetectorID, int nPrepCapMode) { if (SetAttr(nDetectorID, Attr_UROM_PrepCapMode_W, nPrepCapMode)) { return true; } return false; } bool IRayCtrl::SetInnerSubFlowAttr(int nDetectorID, int nInnerSubFlow) { if (SetAttr(nDetectorID, Attr_UROM_InnerSubFlow_W, nInnerSubFlow)) { return true; } return false; } bool IRayCtrl::SetSelfCapEnable(int nDetectorID, int nSelfCapEnable) { return SetAttr(nDetectorID, Attr_UROM_SelfCapEnable_W, nSelfCapEnable); } bool IRayCtrl::SetSelfClearEnable(int nDetectorID, int nSelfClearEnable) { return SetAttr(nDetectorID, Attr_UROM_SelfClearEnable_W, nSelfClearEnable); } bool IRayCtrl::SetDynaOffsetGapTime(int nDetectorID, int nDynaOffsetGapTime) { return SetAttr(nDetectorID, Attr_UROM_DynaOffsetGapTime_W, nDynaOffsetGapTime); } bool IRayCtrl::SetAppMode(int nDetectorID, int nMode) { Info("Set detector({$}) work mode: {$}", nDetectorID, nMode); string strAppMode = "Mode" + std::to_string(nMode); //先停止 m_pfAbort(nDetectorID); Info("Abort detector"); if (!WaitReady(nDetectorID, 500)) { Fatal("Detector status error"); return false; } IRayCmdParam param; param.var.vt = IVT_STR; strcpy_s(param.var.val.strVal, strAppMode.c_str()); ResetLock(); Info("Call Cmd_SetCaliSubset FPD {$}", nDetectorID); FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_SetCaliSubset, ¶m, 1); if (TestError(nDetectorID, nResult)) { Fatal("Cmd_SetCaliSubset Failed"); return false; } if (!WaitRespond(nCMD_TIME)) { Fatal("Cmd_SetCaliSubset Respond Failed. "); return false; } return true; } bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, int& nValue) { IRayVariant var; var.vt = IVT_INT; var.val.nVal = 0; FPDRESULT result = m_fpGetAttr(nDetectorID, nAttrID, &var); if (TestError(nDetectorID - 1, result)) { Fatal("Get Attribute Failed"); return false; } nValue = var.val.nVal; return true; } bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, float& fValue) { float ftemp = 0.0f; IRayVariant var; var.vt = IVT_FLT; var.val.fVal = ftemp; FPDRESULT result = m_fpGetAttr(nDetectorID, nAttrID, &var); if (TestError(nDetectorID - 1, result)) { Fatal("Get Attribute Failed"); return false; } fValue = var.val.fVal; return true; } bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, char* pszAttr) { IRayVariant var; var.vt = IVT_STR; memset(var.val.strVal, 0, IRAY_MAX_STR_LEN); FPDRESULT result = m_fpGetAttr(nDetectorID, nAttrID, &var); if (TestError(nDetectorID - 1, result)) { Fatal("Get Attribute Failed"); return false; } size_t len = strlen(var.val.strVal); strcpy_s(pszAttr, len + 1, var.val.strVal); return true; } bool IRayCtrl::SetAttr(int nDetectorID, int nAttrID, int nValue) { IRayVariant var; var.vt = IVT_INT; var.val.nVal = nValue; FPDRESULT result = m_fpSetAttr(nDetectorID, nAttrID, &var); if (TestError(nDetectorID - 1, result)) { Fatal("Get Attribute Failed"); return false; } return true; } //接口成功返回false,接口失败或有错返回true bool IRayCtrl::TestError(int nDetectorID, int nErrorStatus, bool bPopUp) { string strLog = ""; switch (nErrorStatus) { case Err_OK: return false; case Err_TaskPending: { return false; } case Err_Unknown: Fatal("Err_Unknown"); break; case Err_NotInitialized: Fatal("Err_NotInitialized"); break; case Err_TemplateFileNotExist: case Err_TemplateFileNotMatch: { //string strError = WAR_FPD_LOAD_CORRECT_FILE; //OnWarn(nDetectorID, strError, ""); break; } case Err_InvalidPacketNo: case Err_InvalidPacketFormat: case Err_PacketDataCheckFailed: Fatal("25/26/27 Transfering image not finished"); break; case Err_ImgChBreak: Fatal("Err_ImgChBreak"); break; case Err_FPD_AcquisitionBlock: Fatal("Err_FPD_AcquisitionBlock"); break; case Err_GeneralSocketErr: Fatal("Err_GeneralSocketErr"); break; case Err_ApplyFirmwareFailed: case Err_FPD_General_Detector_Error: case Err_FPD_General_FirmwareUpgrade_Error: case Err_FPD_FirmwareFallback: case Err_FPD_Busy: case Err_FPD_Busy_Initializing: case Err_FPD_Busy_Last_Command_Suspending: case Err_FPD_Busy_MCU_Busy: case Err_FPD_Busy_FPGA_Busy: case Err_FPD_Busy_FPGA_Timeout: case Err_FPD_Busy_System_Error: case Err_FPD_CmdExecuteTimeout: case Err_TaskTimeOut: case Err_DetectorRespTimeout: { if (bPopUp) { //string strError = ERR_FPD_RESTART; //OnError(nDetectorID, strError, ""); } break; } case Err_NotEnoughMemorySpace: break; case Err_ConfigFileNotExist: default: { ErrorInfo info; m_pFnGetErrorInfo(nErrorStatus, &info); string strDes = (info.szDescription); string strSolution = (info.szSolution); Fatal("Get ErrCode:{$} Description:{$} Solution:{$}", nErrorStatus, strDes.c_str(), strSolution.c_str()); if (bPopUp) { //string strError = ERR_FPD_FATAL_ERROR; //OnError(nDetectorID, strError, ""); } } break; } return true; } bool IRayCtrl::LoadIRayDLL(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 + "\\FpdSys.dll"; Info("Load FpdSys.dll"); m_hIRayModule = LoadLibrary(strDllPath.c_str()); if (NULL == m_hIRayModule) { Fatal("Load FpdSys.DLL failed!"); return false; } m_fpCreate = (FnCreate)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_CREATE); if (NULL == m_fpCreate) { Fatal("GetProcAddress:Create failed!"); return false; } m_fpDestroy = (FnDestroy)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_DESTROY); if (NULL == m_fpDestroy) { Fatal("GetProcAddress:Destroy failed!"); return false; } m_fpGetAttr = (FnGetAttr)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_GETATTR); if (NULL == m_fpGetAttr) { Fatal("GetProcAddress:GetAttr failed!"); return false; } m_fpSetAttr = (FnSetAttr)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_SETATTR); if (NULL == m_fpSetAttr) { Fatal("GetProcAddress:SetAttr failed!"); return false; } m_fpInvoke = (FnInvoke)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_INVOKE); if (NULL == m_fpInvoke) { Fatal("GetProcAddress:Invoke failed!"); return false; } m_pRegisterScanNotify = (FnRegisterScanNotify)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_REGISTER_SCANNotify); if (NULL == m_pRegisterScanNotify) { Fatal(" GetProcAddress:RegisterScanNotify Failed!"); return false; } m_pScanOnce = (FnScanOnce)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_SCAN); if (NULL == m_pScanOnce) { Fatal(" GetProcAddress:m_pScanOnce Failed!"); return false; } m_pFnGetErrorInfo = (FnGetErrInfo)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_GET_ERROR_INFO); if (NULL == m_pFnGetErrorInfo) { Fatal(" GetProcAddress:GetErrInfo Failed!"); return false; } m_pfAbort = (FnAbort)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_ABORT); if (NULL == m_pfAbort) { Fatal(" GetProcAddress:FnAbort Failed!"); return false; } m_pfOpenDefectTemplateFile = (FnOpenDefectTemplateFile)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_DEFECT_OPEN); if (NULL == m_pfOpenDefectTemplateFile) { Fatal(" GetProcAddress:FnOpenDefectTemplateFile Failed!"); return false; } m_pfCloseDefectTemplateFile = (FnCloseDefectTemplateFile)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_DEFECT_CLOSE); if (NULL == m_pfCloseDefectTemplateFile) { Fatal(" GetProcAddress:FnCloseDefectTemplateFile Failed!"); return false; } return true; } void IRayCtrl::FreeIRayDLL() { if (m_hIRayModule) { FreeLibrary(m_hIRayModule); m_hIRayModule = NULL; Info(" Free IRay DLL"); } } bool IRayCtrl::AddDPCs(nsDPC::FPDDeviceIRay* pDrvDPC, ResDataObject& Configuration, DeviceIndexStruct& DeviceStruct) { map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { Warn("IRayCtrl::AddDPCs This DPC already exist\n"); return false; } Info("--Func-- AddDPCs {$}", pDrvDPC); m_pCurrentDPC = 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 = Configuration; m_bPreviewImg = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable; m_nCorrectionType = m_stDeviceIndex[m_nDetectorIndex].AcqModeInfo.nCorrectionType; m_nPanelCount++; Info("IRayCtrl::AddDPCs ok {$}\n", m_nPanelCount); return true; } bool IRayCtrl::DelDPCs(nsDPC::FPDDeviceIRay* 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("IRayCtrl::DelDPCs ok {$}\n", m_nPanelCount); } return true; } void IRayCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void IRayCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void IRayCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void IRayCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void IRayCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void IRayCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nDetectorIndex; } ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /********************************************************************/ /* 将文件删除 /********************************************************************/ bool IRayCtrl::DeleteOneFolder(string strSourceFolder) { Info("Delete {$}", strSourceFolder.c_str()); if (!PathFileExists(strSourceFolder.c_str())) { Info("SourceFolder don't exist"); return false; } char pFolderSource[MAX_STRING] = { 0 }; memset(pFolderSource, 0x00, MAX_STRING); 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 IRayCtrl::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 IRayCtrl::SwithPanel(int nPanelId) { return true; } bool IRayCtrl::ActivePanel(nsDPC::FPDDeviceIRay* 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]; m_bPreviewImg = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable; Info("ActivePanel over: {$}, m_nDetectorIndex {$}", pDrvDPC, m_nDetectorIndex); for (int i = 0; i < m_nPanelCount; i++) { ((nsDPC::FPDDeviceIRay*)(*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 IRayCtrl::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; case APP_STATUS_WORK_IN_SENSITIVITY: strLog = "APP_STATUS_WORK_IN_SENSITIVITY"; break; default: break; } Info("Enter exam: {$}", strLog.c_str()); m_eAppStatus = eStatus; return true; } /*** ** 说明:连接 ** 加载SDK,初始化SDK,连接探测器等初始化操作 ** 参数:strWorkPath,初始化SDK必须的conf路径 ***/ bool IRayCtrl::Connect(string strAppPath, nsDPC::FPDDeviceIRay* 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 IRayCtrl::DisconnectFD(int nDetectorID) { int nPanelID = nDetectorID + 1; int nResult = 0; Info("Call Cmd_Disconnect"); nResult = IrayFnInvoke(nPanelID, Cmd_Disconnect, NULL, 0); if (TestError(nDetectorID, nResult)) { Info("Disconnect Detector {$} Failed", nPanelID); } else { //fixbug: 8411 : disattach 探测器,断联后直接销毁,否正SDK会重新扫描添加该探测器 //bool bResult = WaitRespond(2000); } Info("Call Destroy"); nResult = m_fpDestroy(nPanelID); TestError(nDetectorID, nResult); Info("Destroy Over"); Info("disconnect FD {$} over\n", nPanelID); } /*** ** 说明:退出 ** 释放SDK ***/ bool IRayCtrl::DisConnect(nsDPC::FPDDeviceIRay* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return true; } Info("--Func-- DisConnect"); int nPanelID = m_nDetectorIndex + 1; int nResult = IrayFnInvoke(nPanelID, Cmd_Disconnect, NULL, 0); if (TestError(m_nDetectorIndex, nResult)) { Info("Disconnect Detector {$} Failed", nPanelID); } else { //fixbug: 8411 : disattach 探测器,断联后直接销毁,否正SDK会重新扫描添加该探测器 //bool bResult = WaitRespond(2000); } Info("Call Destroy"); nResult = m_fpDestroy(nPanelID); TestError(m_nDetectorIndex, nResult); ErrorFeedback(EVT_ERR_MAX_NUMBER, "false", m_nDetectorIndex); Info("DisConnect Over"); return true; } /********************************************************************/ /* 功能:iRay没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ bool IRayCtrl::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; } /********************************************************************/ // /* 功能:iRay没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层 /********************************************************************/ DWORD IRayCtrl::XWindowOffThread(LPVOID pParam) { IRayCtrl* pCurPanel = (IRayCtrl*)pParam; if (pCurPanel == NULL) { return false; } DWORD dwTimer = pCurPanel->m_stDeviceIndex[pCurPanel->m_nDetectorIndex].AcqModeInfo.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 IRayCtrl::SetSyncMode(SYNC_MODE nSyncMode, HARDWARE_TRIGGER_MODE TriggerMode) { return RET_STATUS::RET_SUCCEED; } bool IRayCtrl::SetAcqMode(nsDPC::FPDDeviceIRay* pDrvDPC, int nLogicMode, DetModeInfo& AcqModeInfo) { Info("## SetAcqMode ##({$})", nLogicMode); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC {$}, {$} != {$} ,return", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nDetectorIndex); return false; } if (!SetAppMode(m_nDetectorID, AcqModeInfo.nOperationMode)) { Error("Set application mode failed"); return false; } m_nCurrentMode = nLogicMode; m_strCurrentExamType = AcqModeInfo.strExamType; m_nRawImgWidth = AcqModeInfo.nRawImgWidth; m_nRawImgHeight = AcqModeInfo.nRawImgHeight; m_nImageWidth = AcqModeInfo.nImageWidth; m_nImageHeight = AcqModeInfo.nImageHeight; m_nImgBits = AcqModeInfo.nPhySizeInfoBit; m_nPixelPitch = AcqModeInfo.nPixelPitch; m_bSaveRaw = AcqModeInfo.bSaveRawEnable; m_nCorrectionType = AcqModeInfo.nCorrectionType; m_nExiThreshold = AcqModeInfo.nExiThreshold; Info("RawImage({$}*{$}), Bits({$}), CorrectionType: {$}; SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImgBits, m_nCorrectionType, m_bSaveRaw); if (m_pwRawImageData) { delete[] m_pwRawImageData; m_pwRawImageData = nullptr; } m_pwRawImageData = new WORD[m_nRawImgWidth * m_nRawImgHeight]; if (m_pwRawImageData == nullptr) { Fatal("Allocate Raw Image Failed"); return false; } //加载校正 SetDetectorCorrection(m_nDetectorID, m_nCorrectionType); //设置触发方式 SetDetectorFluSync(m_nDetectorID, AcqModeInfo.nTriggerType); Info("Set mode over"); return true; } /*** ** 说明:曝光前的准备流程 ***/ RET_STATUS IRayCtrl::PrepareAcquisition(nsDPC::FPDDeviceIRay* 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; } return RET_STATUS::RET_FAILED; } RET_STATUS IRayCtrl::StartAcquisition(nsDPC::FPDDeviceIRay* 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 (-1 == m_nCurrentMode) { Warn("Current mode({$}) is illegal, may not select exam mode successfully, return failed", m_nCurrentMode); return Ret; } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START); if (!WaitReady(m_nDetectorID, 1000)) { Error("Detector isn't Ready"); return Ret; } FPDRESULT nResult = m_fpInvoke(m_nDetectorID, Cmd_StartAcq, NULL, 0); if (TestError(m_nDetectorID, nResult)) { Error("StartAcq Failed"); return Ret; } m_bInExposure = true; m_bGrabStatus = true; m_bWindowOn = false; m_nFrameID = 0; StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); if (m_strCurrentExamType.find("RAD") != std::string::npos) //只有点片才发关窗终止Workflow { StartXWindowOffThread(); } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK); return RET_STATUS::RET_SUCCEED; } RET_STATUS IRayCtrl::StopAcquisition(nsDPC::FPDDeviceIRay* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } Info("**StopAcquisition**"); RET_STATUS Ret = RET_STATUS::RET_FAILED; FPDRESULT nResult = m_fpInvoke(m_nDetectorID, Cmd_StopAcq, NULL, 0); if (TestError(m_nDetectorID, nResult)) { Error("Stop Acq Error"); return Ret; } if (!WaitRespond(nCMD_TIME)) { Error("Stop Acq Timeout"); } Info("Stop Acq Success"); m_bInExposure = false; m_bGrabStatus = false; Ret = RET_STATUS::RET_SUCCEED; return Ret; } bool IRayCtrl::GetiRayPanelCalibItem() { 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 IRayCtrl::InitCalibration() { m_nDefectExpTimes = 0; m_nDefectTotalTimes = 0; m_nGainExpTimes = 0; string strMode = "STE"; m_bCalibResultFailed = false; m_bInCalibrating = true; int nPanelID = m_nDetectorIndex + 1; 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); if (!WaitReady(nPanelID, 1000)) { Error("Detector isn't Ready"); return false; } m_nGainTotalFrames = 0; if (!GetAttr(nPanelID, Attr_GainTotalFrames, m_nGainTotalFrames)) { Error("Get GainTotalFrames failed"); } m_nDefectTotalFrames = 0; if (!GetAttr(nPanelID, Attr_DefectTotalFrames, m_nDefectTotalFrames)) { Error("Get DefectTotalFrames failed"); } Info("GainTotalFrames: {$},DefectTotalFrames: {$}", m_nGainTotalFrames, m_nDefectTotalFrames); m_nCalibStatus = PANEL_GAIN_CAL; ResetLock(); Info("Call Cmd_GainInit"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_GainInit, NULL, 0); if (!TestError(m_nDetectorIndex, nResult)) { if (WaitRespond(5000)) { Info("call Cmd_GainInit Success"); } else { Error("call Cmd_GainInit Failed"); return false; } } return true; } /*** ** 说明:激活校正 ** 增益校正(探测器采用post-offset,暗场校正基本没用了)时拿到dose回调,算作执行完毕 ***/ RET_STATUS IRayCtrl::ActiveCalibration(CCOS_CALIBRATION_TYPE Type, nsDPC::FPDDeviceIRay* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } RET_STATUS Ret = RET_STATUS::RET_SUCCEED; 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 IRayCtrl::StartCalibration(nsDPC::FPDDeviceIRay* 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 (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { Info("StartDarkCalibration \n"); //SetEvent(m_hOffsetEvent); Ret = RET_STATUS::RET_SUCCEED; } else { Info("StartXrayCalibration \n"); int nPanelID = m_nDetectorIndex + 1; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ClearAcq, NULL, 0); if (TestError(m_nDetectorIndex, nResult)) { Error("Invoke Cmd_ClearAcq Failed"); m_bInExposure = false; StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); return Ret; } else { m_stDeviceIndex[m_nDetectorIndex].bTaskEnd = false; Info("Send BeginCapture message"); } Ret = RET_STATUS::RET_SUCCEED; } return Ret; } bool IRayCtrl::ConfirmCalibration() { Info("confirm Calibration"); if (PANEL_GAIN_CAL == m_nCalibStatus) { IRayCmdParam param[2]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; param[0].var.val.nVal = 0; param[1].pt = IPT_VARIANT; param[1].var.vt = IVT_INT; param[1].var.val.nVal = m_nGainExpTimes; Info("Call Cmd_GainSelectCurrent:{$}", m_nGainExpTimes); int nPanelID = m_nDetectorIndex + 1; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_GainSelectCurrent, param, 2); if (!TestError(m_nDetectorIndex, nResult, false)) { Info("Cmd_GainSelectCurrent Success"); m_nGainExpTimes++; StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_ACCEPT); AcceptCalibration(); } else { switch (nResult) { case Err_Cali_UnexpectImage_DoseOver://3007 { Info("DOSE_TOO_HIGH"); StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_HIGH); break; } case Err_Cali_UnexpectImage_DoseUnder://3008 { Info("DOSE_TOO_LOW"); StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_LOW); break; } case Err_Cali_UnexpectImage_ObjectDetected:// 3009 { Info("DOSE_OBJECT"); StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_OBJECT); break; } default: break; } Error("Cmd_GainSelectCurrent Failed"); } } else if (PANEL_DEFECT_CAL == m_nCalibStatus) { IRayCmdParam param[1]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; param[0].var.val.nVal = m_nDefectTotalTimes; Info("Call Cmd_DefectSelectCurrent "); int nPanelID = m_nDetectorIndex + 1; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_DefectSelectCurrent, param, 1); if (!TestError(m_nDetectorIndex, nResult, false)) { Info("Cmd_DefectSelectCurrent Success"); m_nDefectExpTimes++; m_nDefectTotalTimes++; StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_ACCEPT); AcceptCalibration(); } else { switch (nResult) { case Err_Cali_UnexpectImage_DoseOver://3007 { StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_HIGH); Info("DOSE_TOO_HIGH"); break; } case Err_Cali_UnexpectImage_DoseUnder://3008 { StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_LOW); Info("DOSE_TOO_LOW"); break; } case Err_Cali_UnexpectImage_ObjectDetected:// 3009 { StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_OBJECT); Info("DOSE_OBJECT"); break; } default: break; } Error("Cmd_DefectSelectCurrent Failed"); } } return true; } bool IRayCtrl::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 IRayCtrl::CreateCalibrationFile() { int nPanelIndex = m_nDetectorIndex + 1;; if (PANEL_GAIN_CAL == m_nCalibStatus) { Info("Call Cmd_GainGeneration"); FPDRESULT nResult = IrayFnInvoke(nPanelIndex, Cmd_GainGeneration, NULL, 0); if (!TestError(m_nDetectorIndex, nResult)) { Info("Cmd_GainGeneration Success"); } else { Error("Cmd_GainGeneration Failed"); return false; } } else { Info("Call Cmd_DefectGeneration"); FPDRESULT nResult = IrayFnInvoke(nPanelIndex, Cmd_DefectGeneration, NULL, 0); if (!TestError(m_nDetectorIndex, nResult)) { Info("Cmd_DefectGeneration Success"); } else { Error("Cmd_DefectGeneration Failed"); return false; } } //Clean up Info("Call Cmd_FinishGenerationProcess"); FPDRESULT nResult = IrayFnInvoke(nPanelIndex, Cmd_FinishGenerationProcess, NULL, 0); if (!TestError(m_nDetectorIndex, nResult)) { if (WaitRespond(10000)) //defect finish慢,5,6秒左右 { Info("call Cmd_FinishGenerationProcess Success"); } else { Error("call Cmd_FinishGenerationProcess Failed"); return false; } } if (PANEL_GAIN_CAL == m_nCalibStatus) { m_nCalibStatus = PANEL_DEFECT_CAL; ResetLock(); Info("Call Cmd_DefectInit"); nResult = IrayFnInvoke(nPanelIndex, Cmd_DefectInit, NULL, 0); if (!TestError(m_nDetectorIndex, nResult)) { if (WaitRespond(10000)) { Info("call Cmd_DefectInit Success"); } else { Error("call Cmd_DefectInit Failed"); return false; } } } return true; } bool IRayCtrl::RejectCalibration() { Info("Reject Calibration"); return true; } /*** ** 说明:终止校正 ***/ RET_STATUS IRayCtrl::AbortCalibration(nsDPC::FPDDeviceIRay* pDrvDPC) { 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; //恢复初值 m_bConfirmCaliRst = false; //终止校正,恢复初值 RET_STATUS Ret = RET_STATUS::RET_FAILED; if (m_nPanelCount < 0) { Info("No active detector"); return Ret; } bool bLTE = false; if (m_bInCalibrating) { if (m_bInExposure) { bool bResult = WaitRespond(10000); } m_bInCalibrating = false; Info("Call m_pfAbort"); int nPanelID = m_nDetectorIndex + 1; int ret = m_pfAbort(nPanelID); if (TestError(m_nDetectorIndex, ret, false)) { Info("Abort Cmd Failed"); if (m_bCalibResultFailed) { SaveFailedCalibFiles(m_nDetectorIndex, bLTE); m_bCalibResultFailed = false; } CleanCalibFiles(m_nDetectorIndex, bLTE); return Ret; } bool bResult = WaitRespond(120 * 1000); if (bResult) { Info("Abort Calibration Success"); //return true; } else { Error("Abort Calibration Timeout"); //return false; } } else { Info("Omit Abort Calibration"); } if (m_bCalibResultFailed) { SaveFailedCalibFiles(m_nDetectorIndex, bLTE); m_bCalibResultFailed = false; } //恢复校正文件 CleanCalibFiles(m_nDetectorIndex, bLTE); Ret = RET_STATUS::RET_SUCCEED; return Ret; } /*** ** 说明:准备校正(状态机FramePrep) ** 曝光使能过程,使探测器开窗 ***/ RET_STATUS IRayCtrl::PrepareCalibration(nsDPC::FPDDeviceIRay* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } Debug("PrepareCalibration Over"); return RET_STATUS::RET_SUCCEED; } /*** ** 说明:结束校正 ** DPC处理完校正报告后调用,此处上传map、报告等文件 ***/ RET_STATUS IRayCtrl::CompleteCalibration(nsDPC::FPDDeviceIRay* 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 IRayCtrl::OnEndCalibraion() { Info("OnEndCalibraion start"); m_fCalibTemperature2 = m_stDeviceIndex[m_nDetectorIndex].fCurrentTemperValue; m_stDeviceIndex[m_nDetectorIndex].fCalibTemperature1 = m_fCalibTemperature1; m_stDeviceIndex[m_nDetectorIndex].fCalibTemperature2 = m_fCalibTemperature2; m_fCalibTemperature = (m_fCalibTemperature1 + m_fCalibTemperature2) / 2; 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); string szTemp; szTemp = m_stDeviceIndex[m_nDetectorIndex].strCalibrationDate; WriteCumstomFile(m_nDetectorIndex);//上传校正报告,sensitivity if (bRet) { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END); } else { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END_ERROR); } Info("Calibration completed!"); return; } bool IRayCtrl::GetCorrectFileIndex(int& nGainMapIndex, int& nDefectMapIndex) { int nDetectorIdx = m_nDetectorIndex + 1; if (!GetAttr(nDetectorIdx, Attr_HwTmpl_Gain_ValidIndex, nGainMapIndex)) { Error("Get GainMapIndex failed"); return false; } else { Info("Current GainMapIndex is {$}", nGainMapIndex); } if (!GetAttr(nDetectorIdx, Attr_HwTmpl_Defect_ValidIndex, nDefectMapIndex)) { Error("Get DefectMapIndex failed"); return false; } else { Info("Current DefectMapIndex is {$}", nDefectMapIndex); } return true; } bool IRayCtrl::SetCorrectFile() { bool bRet = true; int nGainMapIndex = 0; int nDefectMapIndex = 0; if (GetCorrectFileIndex(nGainMapIndex, nDefectMapIndex)) { if (nGainMapIndex == 10 && nDefectMapIndex == 10) { Info("Calibration files already is 10"); return bRet; } } IRayCmdParam param[2]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; param[0].var.val.nVal = Enm_File_Gain; param[1].pt = IPT_VARIANT; param[1].var.vt = IVT_INT; param[1].var.val.nVal = 1; m_bSetCorrectFile = true; int nPanelID = m_nDetectorIndex + 1; if (nGainMapIndex != param[1].var.val.nVal) { Info("Active gain calibration files to {$}", param[1].var.val.nVal); if (!WaitReady(nPanelID, 2000)) { Error("Active gain calibration files Failed"); return false; } m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile = false; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_SelectCaliFile, param, 2); if (!TestError(nPanelID, nResult)) { if (WaitRespond(16000)) { if (m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile) { Info("Cmd_SelectCaliFile Success"); } else { Info("Cmd_SelectCaliFile Failed"); bRet &= false; } } else { Info("Cmd_SelectCaliFile timeout"); bRet &= false; } } else { Info("Cmd_SelectCaliFile Failed"); bRet &= false; } } else { Info("gain calibration files already in {$}", param[1].var.val.nVal); } if (nDefectMapIndex != param[1].var.val.nVal) { Info("Active defect calibration files to {$}", param[1].var.val.nVal); param[0].var.val.nVal = Enm_File_Defect; if (!WaitReady(nPanelID, 2000)) { Error("Active defect calibration files Failed"); return false; } m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile = false; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_SelectCaliFile, param, 2); if (!TestError(nPanelID, nResult)) { if (WaitRespond(16000)) { if (m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile) { Info("Cmd_SelectCaliFile Success"); } else { Info("Cmd_SelectCaliFile Failed"); bRet &= false; } } else { Info("Cmd_SelectCaliFile timeout"); bRet &= false; } } else { Info("Cmd_SelectCaliFile Failed"); bRet &= false; } } else { Info("defect calibration files already in {$}", param[1].var.val.nVal); } if (bRet) { Info("Cmd_SelectCaliFile {$} Success", param[1].var.val.nVal); } m_bSetCorrectFile = false; return bRet; } bool IRayCtrl::RecoverLastImage() { Info("Recover Last Image"); if (m_bIsImageRecovering) { Warn("Recover Image is processing, return"); return false; } return RecoverImage(); } bool IRayCtrl::RecoverLastImageAuto() { Info("Recover Last Image Auto"); if (m_bIsImageRecovering) { Warn("Recover Image is processing, return"); return false; } if (m_bImageRecoverBeCanceled) { Info("Image Recover Be Canceled"); return false; } ResetLock(); Info("Call Cmd_QueryLastImageID"); m_stDeviceIndex[m_nLastExpFDIndex].bRecoveringImage = true; m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID = -1; int nPanelID = m_nLastExpFDIndex + 1; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_QueryLastImageID, NULL, 0); if (TestError(m_nLastExpFDIndex, nResult)) { Error("Invoke Cmd_QueryLastImageID Failed"); return false; } else { Info("Query LastImageID success"); } bool bResult = false; bResult = WaitRespond(5000); //Evt_LastImageID if (!bResult) { Error("Evt_LastImageID timeout. "); SetEvent(m_hRecoverImage); return false; } if (!m_stDeviceIndex[m_nLastExpFDIndex].bImagePending) { Warn("this image already be Transfered"); return false; } if (-1 == m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID) { Error("Evt_LastImageID timeout2 "); SetEvent(m_hRecoverImage); return false; } m_stDeviceIndex[m_nLastExpFDIndex].bConnectStatus = true; IRayCmdParam param; param.var.vt = IVT_INT; param.var.val.nVal = m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID; nResult = IrayFnInvoke(nPanelID, Cmd_GetImageByImageID, ¶m, 1); Info("Call Cmd_GetImageByImageID , ID = {$} , result = {$}", m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID, nResult); if (TestError(m_nLastExpFDIndex, nResult)) { Error("Invoke Cmd_GetImageByImageID Failed"); SetEvent(m_hRecoverImage); return false; } else { m_stDeviceIndex[m_nLastExpFDIndex].bTaskEnd = false; Info("Get Image ByImageID success"); } return true; } /********************************************************************/ // /* 功能:1717VS固定板,需要对SDK输出的图像进行镜像,做到所见即所得。 */ /********************************************************************/ bool IRayCtrl::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; } /********************************************************************/ // /* 功能:1717VS固定板,需要对SDK输出的图像,先旋转90度,再做镜像,做到所见即所得。 */ /********************************************************************/ bool IRayCtrl::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 IRayCtrl::ReadBatteryStatus(int nDetectorID) { if (!m_stDeviceIndex[m_nDetectorIndex].bBatteryEnable) { return false; } Debug("Begin to Read Battery"); if (!WaitReady(nDetectorID, 600)) { Fatal("Read Battery Failed"); return false; } FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_ReadBatteryStatus, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Battery Failed"); return false; } if (!WaitRespond(nCMD_TIME)) { Warn("Read Battery Timeout"); return false; } Debug("Read Battery Success"); return true; } bool IRayCtrl::CheckBattery(int nDetectorID) { int nPanelID = nDetectorID; if (!m_stDeviceIndex[m_nDetectorIndex].bBatteryEnable) { return false; } int nExist = 0; int nBatteryValue = 0; int nChargingStatus = 0; GetBatteryChargingStatus(nDetectorID, nChargingStatus); if (nChargingStatus) { Debug("Detector is Charging"); m_stDeviceIndex[m_nDetectorIndex].bCharging = true; } else { m_stDeviceIndex[m_nDetectorIndex].bCharging = false; } if (GetBatteryExist(nDetectorID, nExist)) { if (nExist == Enm_On) { GetBatteryRemaining(nPanelID, nBatteryValue); m_nBatteryCapacity = nBatteryValue; StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryValue, "", nDetectorID); } else { Info("Battery is not exist"); StatusFeedback(EVT_STATUS_BATTERY_VALUE, 0, "", nDetectorID); } } else { Fatal("Get Battery Exist Fail"); StatusFeedback(EVT_STATUS_BATTERY_VALUE, 0, "", nDetectorID); return false; } return true; } //读取探测器WIFI,SDK会将WIFI值写入Attr_WifiStatu_WorkingLinkQuality ,从该Attr读取WIFI值 bool IRayCtrl::ReadWifiStatus(int nDetectorID) { if (!m_stDeviceIndex[m_nDetectorIndex].bWifiEnable) { return false; } Debug("Read Wifi"); if (!WaitReady(nDetectorID, 500)) { Fatal("Read Wifi Failed"); return false; } FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_ReadWifiStatus, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Wifi Failed"); return false; } if (WaitRespond(8000)) { Info("Read Wifi success"); return true; } Warn("Read Wifi Timeout"); return false; } bool IRayCtrl::CheckWiFi(int nDetectorID) { int nPanelID = nDetectorID; if (!m_stDeviceIndex[m_nDetectorIndex].bWifiEnable) { return false; } int nConnectInterface = -1; int nWifiValue = 0; if (GetAttr(nPanelID, Attr_NetworkInterface, nConnectInterface)) { if (Enm_NetworkInterface_Wifi == nConnectInterface) { char szLinkedAP[64] = { 0 }; if (GetAttr(nPanelID, Attr_WifiStatu_LinkedAP, szLinkedAP)) { string strFDAP = (szLinkedAP); Info("Detector {$} WifiStatu_LinkedAP {$}", nPanelID, strFDAP.c_str()); m_stDeviceIndex[m_nDetectorIndex].strWifiSSID = strFDAP.c_str(); if (GetWifiLinkQuality(nPanelID, nWifiValue)) { Info("Detector {$} Wifi {$}", nPanelID, nWifiValue); StatusFeedback(EVT_STATUS_WIFI, nWifiValue, "", nDetectorID); } } else { Fatal("Get WifiStatu_LinkedAP Failed"); } } else if (Enm_NetworkInterface_Cable == nConnectInterface) { StatusFeedback(EVT_STATUS_WIFI, 100, "", nDetectorID); } else { Fatal("Connection Status is Unknown"); return false; } } return true; } //读取探测器温度,SDK会将温度值写入Attr_RdResult_T1(静态)/Attr_RdResult_T2(动态) ,从该Attr读取温度值 bool IRayCtrl::ReadTempStatus(int nDetectorID) { Debug("Read Temperture"); int nPanelID = nDetectorID; if (!WaitReady(nPanelID, 500)) { return false; } ResetLock(); Debug("Call Cmd_ReadTemperature"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ReadTemperature, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Temperture Failed"); return false; } if (!WaitRespond(3000)) { Warn("Read Temperture Timeout"); return false; } Debug("Read Temperture Success"); return true; } bool IRayCtrl::CheckTemperature(int nDetectorID) { int nPanelID = nDetectorID; float fTemperature1 = 0.0f; if (GetFPDTempT2(nPanelID, fTemperature1)) { StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", nDetectorID, fTemperature1); m_stDeviceIndex[m_nDetectorIndex].fCurrentTemperValue = fTemperature1; } return true; } //让SDK将PowerOn LifeTime值读取到Attr_FD_LifeTime bool IRayCtrl::ReadLivingTime(int nDetectorID) { if (!WaitReady(nDetectorID, 500)) { return false; } ResetLock(); Info("Call Cmd_QueryLivingTime"); FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_QueryLivingTime, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Query LivingTime Failed"); return false; } if (!WaitRespond(nCMD_TIME)) { Info("Query LivingTime Timeout"); return false; } Info("Query LivingTime Success"); return true; } //获取PowerOn LifeTime值 bool IRayCtrl::CheckLivingTime(int nDetectorID) { int nLifeTime = 0; int nPanelID = nDetectorID; int nPowerOnCount = 0; Info("FD index:{$} LifeTime:{$},PowerOnCount:{$}", nPanelID, nLifeTime, nPowerOnCount); return true; } //WriteROM前,需要清空板内校正的校正选项,否则写入参数可能会失败 bool IRayCtrl::ClearCorrection(int nDetectorID) { Info("Clear Correction Option"); int nPanelIndex = nDetectorID + 1; if (!WaitReady(nPanelIndex, 1000)) { return false; } int nOption = 0; IRayCmdParam param[1]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = nOption; FPDRESULT result = IrayFnInvoke(nPanelIndex, Cmd_SetCorrectOption, param, 1); //Cmd_SetCorrectOption if (TestError(nDetectorID, result)) { Fatal("Call SetCorrectionOption Failed"); return false; } bool bResult = WaitRespond(8000); if (m_stDeviceIndex[m_nDetectorIndex].bSetCorrection) { Info("Clear Correction Success"); } else { Fatal("Clear Correction Failed"); return false; } return true; } //设置探测器校正 bool IRayCtrl::SetDetectorCorrection(int nDetectorID, int nCorrectionType) { Info("Set Detector({$}) correction: {$}", nDetectorID, nCorrectionType); std::string strOffsetType = ""; if (nCorrectionType & Enm_CorrectOp_HW_PreOffset) { strOffsetType = "HW_PreOffset"; } else if (nCorrectionType & Enm_CorrectOp_HW_PostOffset) { strOffsetType = "HW_PostOffset"; } else if (nCorrectionType & Enm_CorrectOp_SW_PreOffset) { strOffsetType = "SW_PreOffset"; } else if (nCorrectionType & Enm_CorrectOp_SW_PostOffset) { strOffsetType = "SW_PostOffset"; } else { strOffsetType = "Undefined Offset"; } std::string strGainDefectType = ""; if ((nCorrectionType & Enm_CorrectOp_HW_Gain) && (nCorrectionType & Enm_CorrectOp_HW_Defect)) { strGainDefectType = "HW_Gain + HW_Defect"; } else if ((nCorrectionType & Enm_CorrectOp_SW_Gain) && (nCorrectionType & Enm_CorrectOp_SW_Defect)) { strGainDefectType = "SW_Gain + SW_Defect"; } else { strGainDefectType = "Undefined Gain, Undefined Defect"; } Info("Detector correction type: {$}", strOffsetType + " + " + strGainDefectType); if (!WaitReady(nDetectorID, 1000)) { return false; } int nOldOption = 0; GetCorrectionOption(nDetectorID, nOldOption); if (nCorrectionType == nOldOption) { Info("Same Correction Option, Omit"); return true; } IRayCmdParam param[1]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = nCorrectionType; FPDRESULT result = IrayFnInvoke(nDetectorID, Cmd_SetCorrectOption, param, 1); //等Cmd_SetCorrectOption if (TestError(nDetectorID, result)) { Fatal("Call SetCorrectionOption Failed"); return false; } bool bResult = WaitRespond(10000); //加载校正策略 if (m_stDeviceIndex[m_nDetectorIndex].bSetCorrection) { Info("SetCorrectionOption Success"); } else { Fatal("SetCorrectionOption Failed"); return false; } return true; } //设置动态探测器内外触发方式 bool IRayCtrl::SetDetectorFluSync(int nDetectorID, int nFluSync) { Info("Set detector({$}) flu sync: {$}", nDetectorID, FluroSyncMode[nFluSync]); if (!WaitReady(nDetectorID, 1000)) { Info("Detector status error"); return false; } int nTempMode = 0; if (GetSyncMode(nDetectorID, nTempMode)) { Info("Current fluro sync mode: {$}", FluroSyncMode[nTempMode]); } else { Error("Get fluro sync mode Failed"); } if (nTempMode != nFluSync) { if (SetAttr(nDetectorID, Attr_UROM_FluroSync_W, nFluSync)) { return WriteRom(nDetectorID); } else { Error("Set fluro sync mode Failed"); return false; } } else { Warn("Same fluro sync mode, Omit"); return true; } return true; } //将设置的各项参数,实际写入探测器端,生效 bool IRayCtrl::WriteRom(int nDetectorID) { Debug("Call Cmd_WriteUserROM"); int nPanelIndex = nDetectorID; FPDRESULT nResult = IrayFnInvoke(nPanelIndex, Cmd_WriteUserROM, NULL, 0); if (TestError(nDetectorID, nResult)) { return false; } if (WaitRespond(80 * 1000)) { Debug("WriteUserROM success"); } else { Fatal("Cmd_WriteUserROM Timeout"); return false; } return true; } //获取系统信息 bool IRayCtrl::GetROMInfo(int nDetectorID) { int nDetectorIndex = nDetectorID - 1; char szSerialNo[64] = { 0 }; string strSNo = ""; if (GetSerialNo(nDetectorID, szSerialNo)) { strSNo = szSerialNo; Info("Detector {$} SN: {$}", nDetectorID, strSNo.c_str()); m_stDeviceIndex[nDetectorIndex].strPanelSerial = strSNo.c_str(); ConfFeedback(EVT_CONF_PANEL_SERIAL, nDetectorID, strSNo.c_str()); } else { Error("Get SN Failed"); } int nProductNo = 0; if (GetProductNo(nDetectorID, nProductNo)) { Info("Detector {$} ProductNo: {$}", nDetectorID, nProductNo); } else { Error("Get ProductNo Failed"); } char szMainVersion[256] = { 0 }; if (GetMainVersion(nDetectorID, szMainVersion)) { string strMainV = szMainVersion; Info("Detector {$} MainVersion: {$}", nDetectorID, strMainV.c_str()); } else { Error("Get MainVersion Failed"); } char szReadVersion[256] = { 0 }; if (GetReadVersion(nDetectorID, szReadVersion)) { string strRV = (szReadVersion); Info("Detector {$} ReadVersion: {$}", nDetectorID, strRV.c_str()); } else { Error("Get ReadVersion Failed"); } char szMcuVersion[256] = { 0 }; if (GetMcuVersion(nDetectorID, szMcuVersion)) { string strMcuV = (szMcuVersion); Info("Detector {$} McuVersion: {$}", nDetectorID, strMcuV.c_str()); } else { Error("Get McuVersion Failed"); } char szArmVersion[256] = { 0 }; if (GetArmVersion(nDetectorID, szArmVersion)) { string strArmV = szArmVersion; m_stDeviceIndex[nDetectorIndex].strFirmware = strArmV.c_str(); Info("Detector {$} ArmVersion: {$}", nDetectorID, strArmV.c_str()); InfoFeedback(EVT_INFO_FIRMWARE, nDetectorID, 0, 0, strArmV.c_str()); } else { Error("Get ArmVersion Failed"); } char szKernalVersion[256] = { 0 }; if (GetKernelVersion(nDetectorID, szKernalVersion)) { string strKernalV = (szKernalVersion); Info("Detector {$} KernelVersion: {$}", nDetectorID, strKernalV.c_str()); } else { Error("Get KernelVersion Failed"); } return true; } bool IRayCtrl::GetHVGSignalStatus(int nDetectorID) { int nXrayEnable = 0; int nXrayOn = 0; int nXraySyncOut = 0; int nXraySyncIn = 0; GetAttr(nDetectorID, Attr_UROM_HvgXRayEnable, nXrayEnable); GetAttr(nDetectorID, Attr_UROM_HvgXRayOn, nXrayOn); GetAttr(nDetectorID, Attr_UROM_HvgXRaySyncOut, nXraySyncOut); GetAttr(nDetectorID, Attr_UROM_HvgXRaySyncIn, nXraySyncIn); Info("XRayEnable signal level: {$}", (nXrayEnable == Enm_SignalLevel_Low) ? "Low" : "High"); Info("XRayOn signal level: {$}", (nXrayOn == Enm_SignalLevel_Low) ? "Low" : "High"); Info("XRaySyncOut signal level: {$}", (nXraySyncOut == Enm_SignalLevel_Low) ? "Low" : "High"); Info("XRaySyncIn signal level: {$}", (nXraySyncIn == Enm_SignalLevel_Low) ? "Low" : "High"); return true; } int IRayCtrl::SetSyncMode(int nDetectorID, int nSetSyncMode) { int nPanelID = nDetectorID; if (!WaitReady(nPanelID, 1000)) { return E_IRAY_SYNCMODE_SETFAILED; } int nTriggerMode = 0; if (GetSyncMode(nPanelID, nTriggerMode)) { Info("Current SyncMode is {$}", TriggerModeName[nTriggerMode]); } else { Error("Get Sync Mode Failed"); } if (nTriggerMode != nSetSyncMode) { Info("Set Sync Mode:{$}", TriggerModeName[nSetSyncMode]); if (SetAttr(nPanelID, Attr_UROM_TriggerMode_W, nSetSyncMode)) { Info("Set Sync Mode Success"); return E_IRAY_SYNCMODE_CHANGED; } else { Error("Set Sync Mode Failed"); return E_IRAY_SYNCMODE_SETFAILED; } } else { Warn("Same Sync Mode,Omit"); return E_IRAY_SYNCMODE_NOCHANGE; } } int IRayCtrl::SetInnerSubFlow(int nDetectorID, int nSetInnerSubFlow) { int nPanelID = nDetectorID; int nInnerSubFlow = 0; Info("Current InnerSubFlow is {$}", InnerSubFlow[nInnerSubFlow]); if (nInnerSubFlow != nSetInnerSubFlow) { Info("Set InnerSubFlow to {$}", InnerSubFlow[nSetInnerSubFlow]); if (!WaitReady(nDetectorID, 500)) { Fatal("Omit InnerSubFlow Setting"); return E_IRAY_SYNCMODE_SETFAILED; } if (!SetInnerSubFlowAttr(nPanelID, nSetInnerSubFlow)) { Fatal("Set InnerSubFlow Failed"); return E_IRAY_SYNCMODE_SETFAILED; } } else { return E_IRAY_SYNCMODE_NOCHANGE; } return E_IRAY_SYNCMODE_CHANGED; } int IRayCtrl::SetCapModeFunc(int nDetectorID, int nSetCapMode) { int nPanelID = nDetectorID; int nPrepCapMode = 0; if (GetPrepCapMode(nPanelID, nPrepCapMode)) { Info("Current PrepCapMode is {$}", PrepCapMode[nPrepCapMode]); if (nPrepCapMode != nSetCapMode) { Info("Set PrepCapMode to {$}", PrepCapMode[nSetCapMode]); if (!SetPrepCapMode(nPanelID, nSetCapMode)) { Error("Set PrepCapMode Failed"); return E_IRAY_SYNCMODE_SETFAILED; } else { return E_IRAY_SYNCMODE_NOCHANGE; } } } else { Error("Get PrepCapMode Failed"); return E_IRAY_SYNCMODE_SETFAILED; } return E_IRAY_SYNCMODE_CHANGED; } //设置iRay探测器该参数 int IRayCtrl::SetFPDCalParam(int nDetectorID, int nSetSelfCapEnable, int nSetSelfClearEnable) { bool bParamChanged = false; int nPanelID = nDetectorID; int nSelfCapEnable = 0; if (GetSelfCapEnable(nPanelID, nSelfCapEnable)) { Info("Current SelfCapEnable is {$}", Enm_Switch[nSelfCapEnable]); if (nSelfCapEnable != nSetSelfCapEnable) { Info("Set SelfCapEnable to {$}", Enm_Switch[nSetSelfCapEnable]); bParamChanged = true; if (!SetSelfCapEnable(nPanelID, nSetSelfCapEnable)) { Error("Set SelfCapEnable Failed"); return E_IRAY_SYNCMODE_SETFAILED; } } } else { Error("Get SelfCapEnable Failed"); return E_IRAY_SYNCMODE_SETFAILED; } int nSelfClearEnable = 0; if (GetSelfClearEnable(nPanelID, nSelfClearEnable)) { Info("Current SelfClearEnable is {$}", Enm_Switch[nSelfClearEnable]); if (nSelfClearEnable != nSetSelfClearEnable) { bParamChanged = true; Info("Set SelfClearEnable to {$}", Enm_Switch[nSetSelfClearEnable]); if (!SetSelfClearEnable(nPanelID, nSetSelfClearEnable)) { Error("Set SelfClearEnable Failed"); return E_IRAY_SYNCMODE_SETFAILED; } } } else { Error("Get SelfClearEnable Failed"); return E_IRAY_SYNCMODE_SETFAILED; } if (bParamChanged) { return E_IRAY_SYNCMODE_CHANGED;//WriteRom(nDetectorID); } return E_IRAY_SYNCMODE_NOCHANGE; } //设置探测器采集的工作模式 bool IRayCtrl::SetDetectorWorkMode(int nDetectorID, int nMode) { Info("Set detector({$}) work mode: {$}", nDetectorID, nMode); string strWorkMode = ""; return true; } //设置探测器窗口和Delay窗口 bool IRayCtrl::SetDetectorXWindow(int nDetectorID, int nDelayTime, int nXWindowTime, int nClearAcqTime) { Info("Set detector {$} XWindow", nDetectorID); int nRomDelayTime = 0; if (GetXWindowDelay(nDetectorID, nRomDelayTime)) { Info("Current DelayTime: {$}", nRomDelayTime); if (nDelayTime != nRomDelayTime) { Info("Set DelayTime: {$}", nDelayTime); WaitReady(nDetectorID, 3000); if (SetXWindowDelay(nDetectorID, nDelayTime)) { Info("Set DelayTime Success"); } else { Error("Write DelayTime Failed"); return false; } } else { Info("Same DelayTime, Omit it"); } } int nRomExpWindow = 0; if (GetExpWindowTime(nDetectorID, nRomExpWindow)) { Info("Current XWindow: {$}", nRomExpWindow); if (nXWindowTime != nRomExpWindow) { Info("Set XWindow: {$}", nXWindowTime); WaitReady(nDetectorID, 3000); if (SetExpWindowTime(nDetectorID, nXWindowTime)) { Info("Set XWindow Success"); } else { Error("Write ExpWindow Failed"); return false; } } else { Info("Same XWindow, Omit it"); } } int nCfgClearAcqTime = 0; if (GetDelayTime(nDetectorID, nCfgClearAcqTime)) { Info("Current ClearAcqTime: {$}", nCfgClearAcqTime); if (nClearAcqTime != nCfgClearAcqTime) { Info("Set ClearAcqTime: {$}", nClearAcqTime); WaitReady(nDetectorID, 3000); if (SetExpWindowTime(nDetectorID, nClearAcqTime)) { Info("Set ClearAcqTime Success"); } else { Error("Set ClearAcqTime Failed"); return false; } } else { Info("Same ClearAcqTime, Omit it"); } } return true; } void IRayCtrl::GetFwName(string strFirmPath, string& strFirmwareName) { WIN32_FIND_DATA lpFindFileData; string strPath = strFirmPath + "\\*.ifrm";//查找指定目录下的所有格式的文件。 Info("{$}", strPath.c_str()); //string strPath1 = CCommonFun::wc2mb(strPath.GetBuffer()); HANDLE hFile = FindFirstFile(strPath.c_str(), &lpFindFileData); if (INVALID_HANDLE_VALUE == hFile) { Info("Cannot find Firmware file"); strFirmwareName = ""; return; } strFirmwareName = lpFindFileData.cFileName; FindClose(hFile); Info("{$}", strFirmwareName.c_str()); } bool IRayCtrl::IsFWNeedUpdate(int nDetectorID) { bool bNeed = false; int nPanelIndex = nDetectorID + 1; char szArmVersion[256] = { 0 }; if (GetArmVersion(nPanelIndex, szArmVersion)) { string strArmV = (szArmVersion); m_stDeviceIndex[m_nDetectorIndex].strFirmware = strArmV.c_str(); Info("Panel {$} ArmVersion:{$}", nPanelIndex, strArmV.c_str()); InfoFeedback(EVT_INFO_FIRMWARE, nDetectorID, 0, 0, strArmV.c_str()); } else { Error("Get ArmVersion Failed"); return false; } string strFirmwareHistoryFiles = g_strAppPath + "FirmwaresHistory_"; strFirmwareHistoryFiles += (m_stDeviceIndex[m_nDetectorIndex].strDeviceName); strFirmwareHistoryFiles += ".xml"; Info("{$}", strFirmwareHistoryFiles.c_str()); int nResult = 0; if (FW_MANDATORY_UPDATE == nResult) { m_stDeviceIndex[m_nDetectorIndex].nFirmwareStatus = FW_MANDATORY_UPDATE; ConfFeedback(EVT_CONF_FIRWARE_UPDATE, nDetectorID, "", FW_MANDATORY_UPDATE); Info("This Firmware must be updated"); //UPDATE bNeed = true; } else if (FW_NEW == nResult) { m_stDeviceIndex[m_nDetectorIndex].nFirmwareStatus = FW_NEW; ConfFeedback(EVT_CONF_FIRWARE_UPDATE, nDetectorID, "", FW_NEW); Info("This Firmware is New"); } else if (FW_NEED_UPDATE == nResult) { m_stDeviceIndex[m_nDetectorIndex].nFirmwareStatus = FW_MANDATORY_UPDATE; ConfFeedback(EVT_CONF_FIRWARE_UPDATE, nDetectorID, "", FW_MANDATORY_UPDATE); Info("This Firmware need to be updated"); //UPDATE bNeed = true; } else if (FW_NOT_SUPPORT == nResult) { m_stDeviceIndex[m_nDetectorIndex].nFirmwareStatus = FW_NOT_SUPPORT; ConfFeedback(EVT_CONF_FIRWARE_UPDATE, nDetectorID, "", FW_NOT_SUPPORT); Info("This Firmware is not supported"); } else if (FW_GET_ERROR == nResult) { m_stDeviceIndex[m_nDetectorIndex].nFirmwareStatus = FW_NEW; ConfFeedback(EVT_CONF_FIRWARE_UPDATE, nDetectorID, "", FW_NEW); Info("Cannot get Firmware List"); } return bNeed; } //----------------------------------------------------------------------------- // 更新FW的指令 // //----------------------------------------------------------------------------- RET_STATUS IRayCtrl::OnUpdateFirmware(nsDPC::FPDDeviceIRay* 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 IRayCtrl::onUpdateFWThread(PVOID pvoid) { IRayCtrl* pOpr = (IRayCtrl*)pvoid; Info("Firmware update thread"); return pOpr->UpdateFirmware(pOpr->m_nUpdateFPDID, true); ; } bool IRayCtrl::UpdateFirmware(int nDetectorID, bool bUpdate) { Info("Update FPD Firmware"); int nPanelIndex = nDetectorID + 1; if (!IsFWNeedUpdate(nDetectorID)) { return true; } if (!bUpdate) { Info("Omit update Firmware "); return true; } if (!m_stDeviceIndex[m_nDetectorIndex].bConnectStatus) { Error("connection lost,Omit firmware update"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_FWU_ERROR_OMIT, "", m_nUpdateFPDID); return false; } if (m_nBatteryCapacity < 50) { Error("Low battery,Omit firmware update Detector battery value<50"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_FWU_ERROR_BATTERY, "", m_nUpdateFPDID); return false; } if (!WaitReady(nPanelIndex, 600)) { Error("wait Ready Failed"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_FWU_ERROR_OMIT, "", m_nUpdateFPDID); return false; } StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_START, "", m_nUpdateFPDID); string strFWPath = g_strAppPath + "SW_Update\\Firmware\\"; strFWPath += m_stDeviceIndex[m_nDetectorIndex].strDeviceName; string strFWName = ""; GetFwName(strFWPath, strFWName); if (strFWPath == "") { Error("Update firmware failed"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID); return false; } strFWPath = strFWPath + "\\" + strFWName; string strFilePath = (strFWPath); Info("Begain update FW : {$}", strFilePath.c_str()); IRayCmdParam param[2]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = Enm_FW_DeviceType_AllInOne; param[1].var.vt = IVT_STR; Info("{$}", strFilePath.length()); strcpy_s(param[1].var.val.strVal, strFilePath.c_str()); m_bFirmwareUpdating = true; m_stDeviceIndex[m_nDetectorIndex].bUpdateFirmware = false; ResetLock(); FPDRESULT nReturn = IrayFnInvoke(nPanelIndex, Cmd_UpdateFirmware, param, 2); if (TestError(nDetectorID, nReturn)) { Error("Call Cmd_UpdateFirmware failed"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID); m_bFirmwareUpdating = false; return false; } bool bResult = WaitRespond(1200000);//20 minutes //等待Cmd_UpdateFirmware 之后再次Cmd_Connect if (bResult) { if (m_stDeviceIndex[m_nDetectorIndex].bUpdateFirmware) { Info("Update firmware Success"); IsFWNeedUpdate(nDetectorID); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_SUCCESS, "", m_nUpdateFPDID); m_bFirmwareUpdating = false; return true; } Info("Update firmware failed"); StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID); m_bFirmwareUpdating = false; return false; } m_bFirmwareUpdating = false; StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID); Info("Update firmware Timeout"); return true; } //从探测器端下载校正文件到本地 bool IRayCtrl::UploadCalibFileFromFD(int nDetectorID, int nIndex, string strFileName, bool bGain) { int nPanelID = nDetectorID + 1; IRayCmdParam param[3]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = Enm_File_Defect; if (bGain) { param[0].var.val.nVal = Enm_File_Gain; } param[1].var.vt = IVT_INT; param[1].var.val.nVal = nIndex; param[2].var.vt = IVT_STR; strcpy_s(param[2].var.val.strVal, strFileName.c_str());// Info("{$}", strFileName.c_str()); m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile = false; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_UploadCaliFile, param, 3); //返回值 Evt_TemplateFileUpload_Result if (TestError(nDetectorID, nResult)) { Error("Upload CaliFile failed"); return false; } ResetLock(); bool bResult = WaitRespond(16000); //defect 6s ,gain 8s。 bug 9494 由10s增加到16s if (bResult) { if (m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile) { Info("Upload CaliFile2 success"); return true; } else { Error("Upload CaliFile2 failed"); return false; } } else { Error("Cmd_UploadCaliFile Timeout"); return false; } } //上传校正文件到探测器端,gain或defect文件 bool IRayCtrl::DownloadCalibrationFileToFD(bool bGainFile, bool bExpMode) { IRayCmdParam param[4]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; int nPanelIndex = m_nDetectorIndex + 1; string strExpMode = "STE"; if (bExpMode) { strExpMode = "LTE"; } string strPath = (m_stDeviceIndex[m_nDetectorIndex].strWorkDir); string strGainFilePath = strPath + "\\Correct\\" + strExpMode + "\\gain_2304x2844.gn"; string strDefectFilePath = strPath + "\\Correct\\" + strExpMode + "\\defect_2304x2844.dft"; string strCalibrationFile = ""; if (bGainFile) { param[0].var.val.nVal = Enm_File_Gain; strCalibrationFile = strGainFilePath; } else { param[0].var.val.nVal = Enm_File_Defect; strCalibrationFile = strDefectFilePath; } param[1].pt = IPT_VARIANT; param[1].var.vt = IVT_INT; param[1].var.val.nVal = 1; if (bExpMode) { param[1].var.val.nVal = 4; //本地合并merge_defect 到FD defect文件中LTE index4 } //else if (m_nSTEExpTime == 800) //{ // param[1].var.val.nVal = 7; //} param[2].pt = IPT_VARIANT; param[2].var.vt = IVT_STR; strcpy_s(param[2].var.val.strVal, strCalibrationFile.c_str()); Info("{$}", strCalibrationFile.c_str()); param[3].pt = IPT_VARIANT; param[3].var.vt = IVT_STR; strcpy_s(param[3].var.val.strVal, ""); ResetLock(); Info("Call Cmd_DownloadCaliFile"); int nResult = IrayFnInvoke(nPanelIndex, Cmd_DownloadCaliFile, param, 4); if (!TestError(m_nDetectorIndex, nResult)) { if (WaitRespond(16000))//bug 9494 由10s增加到16s { Info("Cmd_DownloadCaliFile Success"); } else { Error("Cmd_DownloadCaliFile Failed"); return false; } } return true; } //上传user edit defect文件,到探测器端 bool IRayCtrl::DownloadUserDefectFileToFD(bool bLTE) { int nPanelIndex = m_nDetectorIndex + 1; string strPath = (m_stDeviceIndex[m_nDetectorIndex].strWorkDir); string strEM = "STE"; if (bLTE) { strEM = "LTE"; } string strDefectFilePath = strPath + "\\Correct\\" + strEM + "\\Defect_2304x2844.dft";//useredit_d IRayCmdParam param[4]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; param[0].var.val.nVal = Enm_File_Defect; param[1].pt = IPT_VARIANT; param[1].var.vt = IVT_INT; param[1].var.val.nVal = 1; //本地合并merge_defect 到FD defect文件中STE index1 if (bLTE) { param[1].var.val.nVal = 4; //本地合并merge_defect 到FD defect文件中LTE index4 } //else if (m_bSolefish && m_nSTEExpTime == 800) //{ // param[1].var.val.nVal = 7; //} param[2].pt = IPT_VARIANT; param[2].var.vt = IVT_STR; strcpy_s(param[2].var.val.strVal, strDefectFilePath.c_str()); Info("{$}", strDefectFilePath.c_str()); param[3].pt = IPT_VARIANT; param[3].var.vt = IVT_STR; strcpy_s(param[3].var.val.strVal, ""); ResetLock(); Info("Call Cmd_DownloadCaliFile"); int nResult = IrayFnInvoke(nPanelIndex, Cmd_DownloadCaliFile, param, 4); if (!TestError(m_nDetectorIndex, nResult)) { if (WaitRespond(16000))//bug 9494 由10s增加到16s { Info("Cmd_DownloadCaliFile Success"); } else { Error("Cmd_DownloadCaliFile Failed"); return false; } } return true; } //上传校正报告和Sensitivity文件到FD端, //Cmd_WriteCustomFile 的参数为文件所在的Folder bool IRayCtrl::WriteCumstomFile(int nDetectorID) { int nPanelIndex = nDetectorID + 1; if (!m_stDeviceIndex[m_nDetectorIndex].bWireless) { Error("Omit WriteCustomFile"); return false; } if (!WaitReady(nPanelIndex, 5000)) { Error("Detector isn't Ready"); return false; } string strFilePath = g_strAppPath + "references\\" + m_stDeviceIndex[m_nDetectorIndex].strPanelSerial; string strFileName = (strFilePath); IRayCmdParam param[1]; param[0].var.vt = IVT_STR; strcpy_s(param[0].var.val.strVal, strFileName.c_str()); Info("{$}", strFileName.c_str()); m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile = false; FPDRESULT nResult = IrayFnInvoke(nPanelIndex, Cmd_WriteCustomFile, param, 1); //返回值 if (TestError(nDetectorID, nResult)) { Error("Write CustomFile failed"); return false; } bool bResult = WaitRespond(30000); if (bResult) { if (m_stDeviceIndex[m_nDetectorIndex].bUploadCalibFile) { Info("Write CustomFile2 success"); return true; } else { Error("Write CustomFile2 failed"); return false; } } else { Error("Cmd_ReadCustomFile Timeout"); return false; } } //从校正文件中读取校正日期 bool IRayCtrl::GetCalibrationTime(int nDetectorID, bool bExpMode) { return true; } //从探测器上下载文件:Gain文件,defect文件 bool IRayCtrl::DownloadfromDetector(int nDetectorID) { string strLog; string strWorkDir = m_stDeviceIndex[m_nDetectorIndex].strWorkDir; string strLocalPath = strWorkDir; string strCreatePath = strWorkDir + "\\Correct\\STE"; if (!PathFileExists(strCreatePath.c_str())) { bool bRtn = CreateDirectory(strCreatePath.c_str(), NULL); if (bRtn) { strLog = "create " + strCreatePath + " ok"; Info("{$}", strLog.c_str()); } else { strLog = "create " + strCreatePath + " failed"; Error("{$}", strLog.c_str()); return false; } } else { strLog = strCreatePath + " already exist"; Info("{$}", strLog.c_str()); } strLocalPath += "\\Correct\\STE\\factory_defect_2304x2844.dft"; UploadCalibFileFromFD(nDetectorID, 2, strLocalPath, false); strLocalPath = strWorkDir; strLocalPath += "\\Correct\\STE\\defect_2304x2844.dft"; UploadCalibFileFromFD(nDetectorID, 1, strLocalPath, false); strLocalPath = strWorkDir; strLocalPath += "\\Correct\\STE\\gain_2304x2844.gn"; UploadCalibFileFromFD(nDetectorID, 1, strLocalPath, true); return true; } // 从SDK指定目录拷贝失败的校正文件到CalibrationFailedData中 bool IRayCtrl::SaveFailedCalibFiles(int nDetectorID, bool bExpMode) { Info("SaveCalibrationFailedData"); Info("SaveCalibrationFailedData over"); return true; } bool IRayCtrl::CleanCalibFiles(int nDetectorID, bool bExpMode) { return true; } //----------------------------------------------------------------------------- // 通过 Cmd_QueryLastImageID 检查探测器中是否有未传输成功的图像 //该指令,SDK会返回 Evt_LastImageID ,从该Event 知道图像是否传输成功 //----------------------------------------------------------------------------- bool IRayCtrl::CheckLastImageStatus(int nDetectorID) { ResetLock(); int nPanelID = nDetectorID; if (!WaitReady(nPanelID, 20000)) { Error("CheckLastImageStatus Failed"); return false; } Info("Call Cmd_QueryLastImageID"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_QueryLastImageID, NULL, 0); if (TestError(nDetectorID, nResult)) { Error("Invoke Cmd_QueryLastImageID Failed"); return false; } else { Info("Query LastImageID success"); } bool bResult = false; bResult = WaitRespond(5000); //Evt_LastImageID if (!bResult) { Error("Evt_LastImageID timeout. "); return false; } if (m_stDeviceIndex[m_nDetectorIndex].bImagePending) { if (m_bWindowOn) { Info("need Recover image"); //ErrorFeedback(EVT_ERR_GET_IMAGE, "true");//有图像没拿到,但只有曝光后才能UI弹窗//注释掉,因为连接恢复后多发一个状态给UI,造成多一个弹窗 if (m_bImageRecoverBeCanceled) { Info("Image Recover Be Canceled"); } else { SetEvent(m_hRecoverImage); } } StatusFeedback(EVT_STATUS_IMAGEPENDING, 0, "true");//有图像没拿到 } else { StatusFeedback(EVT_STATUS_IMAGEPENDING, 0, "false");//没有图像没拿到 ErrorFeedback(EVT_ERR_GET_IMAGE, "false");//没有图像没拿到 } return true; } bool IRayCtrl::CancelImageRecover() { Info("Cancel Image Recover"); m_bImageRecoverBeCanceled = true; return true; } //----------------------------------------------------------------------------- // 函数描述 : 恢复图像:将曝光未获取成功的图像,重新获取出来 /* 1. 通过 Cmd_QueryLastImageID 查询到最后一个图像的ID 2. 通过 Cmd_GetImageByImageID ,把这个ID对应的图像获取出来 */ // 返回类型 : // 接口参数 : // //----------------------------------------------------------------------------- bool IRayCtrl::RecoverImage() { int nTryTimes = 0; while (!m_stDeviceIndex[m_nLastExpFDIndex].bConnectStatus && (nTryTimes < 5)) { Info("Waiting detector reconnect"); Sleep(1000); nTryTimes++; } ResetLock(); Info("Call Cmd_QueryLastImageID"); m_stDeviceIndex[m_nLastExpFDIndex].bRecoveringImage = true;//imagerecover 弹框不自动消失。只要走了此流程,后面上图都发一下RCI(Result=0)此消息对UI没有副作用。 m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID = -1; int nPanelID = 1;// m_vecFDRealID[m_nLastExpFDIndex]; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_QueryLastImageID, NULL, 0); if (TestError(m_nLastExpFDIndex, nResult)) { Error("Invoke Cmd_QueryLastImageID Failed"); //SetEvent(m_hRecoverImage); return false; } else { Info("Query LastImageID success"); } bool bResult = false; bResult = WaitRespond(5000); //Evt_LastImageID if (!bResult) { Error("Evt_LastImageID timeout. "); //SetEvent(m_hRecoverImage); return false; } if (!m_stDeviceIndex[m_nLastExpFDIndex].bImagePending) { Warn("this image already be Transfered"); return false; } if (-1 == m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID) { Error("Evt_LastImageID timeout2 "); //SetEvent(m_hRecoverImage); return false; } m_stDeviceIndex[m_nLastExpFDIndex].bConnectStatus = true; IRayCmdParam param; param.var.vt = IVT_INT; param.var.val.nVal = m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID; nResult = IrayFnInvoke(nPanelID, Cmd_GetImageByImageID, ¶m, 1); Info("Call Cmd_GetImageByImageID , ID = {$} , result = {$}", m_stDeviceIndex[m_nLastExpFDIndex].nLastImageID, nResult); if (TestError(m_nLastExpFDIndex, nResult)) { Error("Invoke Cmd_GetImageByImageID Failed"); //SetEvent(m_hRecoverImage); return false; } else { m_stDeviceIndex[m_nLastExpFDIndex].bTaskEnd = false; Info("Get Image ByImageID success"); } return true; } /********************************************************************/ /* 功能:FD Attach过程中,根据有线获取的SN和IP地址,改写iRay SDK的配置文件; 以便在OnConnectFPD时 SDK读取新的配置文件,连接上探测器 /********************************************************************/ bool IRayCtrl::ModifyConfigIni(string strIniPath, string strSN, string strIP) { Info("ModifyConfigIni {$}", strIniPath.c_str()); if (CIniFileCreat(strIniPath.c_str())) //m_IRayInfo.IRayConf[0].strWorkDir + { string strItemData = "Cfg_SN="; strItemData += strSN; Info("{$}", strItemData.c_str()); bool bFindIP = CIniFileSetItemByKey("System", "Cfg_SN", strItemData.c_str()); strItemData = "Cfg_RemoteIP="; strItemData += strIP; Info("{$}", strItemData.c_str()); bFindIP = CIniFileSetItemByKey("Connection", "Cfg_RemoteIP", strItemData.c_str()); CIniFileClose(); } else { Error("Read Pixrad.ini file failed"); CIniFileCloseWithoutWrite(); return false; } Info("ModifyConfigIni ok"); return true; } bool IRayCtrl::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 IRayCtrl::ResetFPD(nsDPC::FPDDeviceIRay* 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 i = 0; i < m_nPanelCount; i++) { if (!m_stDeviceIndex[i].bWifiEnable) { Error("Omit reconnection in fixed FD"); } else { DisconnectFD(i + 1); StartInitFPDThread(); } } return true; } void IRayCtrl::OnProcessPreImg() { if (m_bPreviewEnable) { DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pwPreviewImg); } } void IRayCtrl::OnProcessImg() { if (m_bSaveRaw) { string strImageName = "iRay_" + to_string(m_nFrameID) + ".raw"; SaveRawImage(strImageName.c_str(), m_pwRawImageData, m_nRawImgWidth, m_nRawImgHeight); } //暗场图挡图处理 if (!CheckImageEXI(m_pwRawImageData, m_nRawImgWidth, m_nRawImgHeight, m_nImgBits, m_nExiThreshold, 0.05f)) { Warning("Current frame EXI too low, omit"); return; } m_nFrameID++; DataFeedback(EVT_DATA_RAW_IMAGE, m_pwRawImageData); } // pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度 bool IRayCtrl::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_nHeightOffset) * nInWidth + m_nWidthOffset, 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_nWidthOffset, m_nHeightOffset, m_nBottomOffset); return false; } return true; } bool IRayCtrl::StartHardwareStatusThread() { if (m_pHardwareStatusThread == NULL) { m_hEndHWStatusThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DWORD m_HardwareStatusID; m_pHardwareStatusThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID); if (m_pHardwareStatusThread == NULL) { Fatal("Start HardwareStatus Thread Failed"); return false; } } return true; } DWORD IRayCtrl::HardwareStatusThread(LPVOID pParam) { IRayCtrl* pCurPanel = (IRayCtrl*)pParam; if (pCurPanel == NULL) { return false; } Info("HardwareStatusThread start"); DWORD dwTimer = 5000; DWORD dwCounter = 0; while (true) { DWORD dwResult = WaitForSingleObject(pCurPanel->m_hEndHWStatusThreadEvent, dwTimer); if (dwResult == WAIT_OBJECT_0) { break; } else { if (dwCounter % 60 == 0) //五分钟查一次 { pCurPanel->GetHardwareStatus(); dwCounter = 0; } dwCounter++; } } CloseHandle(pCurPanel->m_hEndHWStatusThreadEvent); SetEvent(pCurPanel->m_hHWStatusThreadEndEvent); Info("HardwareStatusThread stop"); return true; } bool IRayCtrl::GetHardwareStatus() { if (m_bFirmwareUpdating) { int nProgress = 0; int nPanelID = m_nDetectorIndex + 1; GetFWUpdateProgress(nPanelID, nProgress); Info("Firmware update progress:{$}", nProgress); return true; } if (m_bInExposure) { Info("In Exposuring,omit check hw status"); return true; } for (int i = 0; i < m_nPanelCount; i++) { int nDetectorID = i + 1; if (!GetConnectionStatus(nDetectorID)) // 如果检测到平板探测器失去连接,那么要通知DROC { Info("FD {$} is communication error", nDetectorID); m_stDeviceIndex[i].bConnectStatus = false; ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nDetectorID); } else if (m_stDeviceIndex[i].bConnectStatus && !m_bInCalibrating && !m_bInExposure && !m_bSetCorrectFile) { Info("Check FPD {$} Status", nDetectorID); bool bResult = true; if (m_stDeviceIndex[i].bConnectChanged) { m_stDeviceIndex[i].bConnectChanged = false; //CheckLastImageStatus(nDetectorID); } if (ReadTempStatus(nDetectorID)) { CheckTemperature(nDetectorID); } /*if (ReadBatteryStatus(nDetectorID)) { CheckBattery(nDetectorID); } if (ReadWifiStatus(nDetectorID)) { CheckWiFi(nDetectorID); } if (ReadLivingTime(nDetectorID)) { CheckLivingTime(nDetectorID); }*/ } else if (m_stDeviceIndex[i].bConnectStatus) { if (m_stDeviceIndex[i].bConnectChanged) { m_stDeviceIndex[i].bConnectChanged = false; } } } return true; } bool IRayCtrl::GetConnectionStatus(int nDetectorID) { int nConnStates = Enm_ConnState_Unknown; if (GetConnState(nDetectorID, nConnStates)) { switch (nConnStates) { case Enm_ConnState_OK: { return true; } break; default: { Error("Other Connection Status: {$}", nConnStates); } break; } } else { Error("Get connection state fail"); } return false; } //----------------------------------------------------------------------------- // 手动编辑完坏点坏线,将校正文件上传到探测器端,并重新生成校正报告 // //----------------------------------------------------------------------------- bool IRayCtrl::UploadCalibrationFiles(nsDPC::FPDDeviceIRay* pDrvDPC, string strFileName) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return false; } string strExpMode = "STE"; bool bLTE = false; if (!DownloadUserDefectFileToFD(bLTE)) { return 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 IRayCtrl::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 = g_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; } //刷新Offset bool IRayCtrl::StartOffset(bool isAll) { if (!m_stDeviceIndex[m_nDetectorIndex].bConnectStatus) { Warn("Detector communication loss"); return false; } m_bOffsetAll = isAll; Info("Offset mode: {$}", isAll ? "All" : "NoAll"); SetEvent(m_hOffsetEvent); //OffsetCalibration() return true; } //如果是isAll=true, 则刷新全部模式,如果isAll=false, 则刷新当前模式和点片模式 bool IRayCtrl::OffsetCalibration() { Info("OffsetCalibration start"); bool bOffsetFailed = false; StatusFeedback(PANEL_OFFSET_CAL, OFFSET_RUNNING); if (m_bOffsetAll) { /*int nTotalMode = ((*m_pPanelID2DPC)[m_nDetectorIndex])->GetTotalAcqModeNum(); StatusFeedback(PANEL_OFFSET_COUNT, nTotalMode); for (int i = 0; i < nTotalMode; i++) { StatusFeedback(PANEL_OFFSET_PROGRESS, i); if (!OffsetProcess(m_nDetectorID, i + 1)) { Error("Offset mode {$} failed"); bOffsetFailed = true; break; } }*/ int nTotalMode = m_mapLogicModeOperationMode.size(); StatusFeedback(PANEL_OFFSET_COUNT, nTotalMode); int nOffsetProgress = 0; for (map::iterator it = m_mapLogicModeOperationMode.begin(); it != m_mapLogicModeOperationMode.end(); it++) { StatusFeedback(PANEL_OFFSET_PROGRESS, nOffsetProgress); if (!OffsetProcess(m_nDetectorID, it->second)) { Error("Offset mode {$} failed"); bOffsetFailed = true; break; } nOffsetProgress++; } } else { StatusFeedback(PANEL_OFFSET_COUNT, 2); Info("Refresh RAD"); if (!OffsetProcess(m_nDetectorID, 1)) { Error("Offset mode rad failed"); bOffsetFailed = true; } StatusFeedback(PANEL_OFFSET_PROGRESS, 1); Info("Refresh Mode({$})", 2); if (!OffsetProcess(m_nDetectorID, 2)) { Error("Offset mode flu failed"); bOffsetFailed = true; } StatusFeedback(PANEL_OFFSET_PROGRESS, 2); } if (bOffsetFailed) { StatusFeedback(PANEL_OFFSET_CAL, OFFSET_ERROR); } else { StatusFeedback(PANEL_OFFSET_CAL, OFFSET_IDLE); } Info("Offset FINISH"); return true; } //刷新暗场 bool IRayCtrl::OffsetProcess(int nDetectorID, int nMode) { Info("OffsetProcess start"); //先激活对应模式 if (!SetAppMode(nDetectorID, nMode)) { Info("Active offset mode {$} failed"); return false; } if (m_stDeviceIndex[m_nDetectorIndex].nOffsetMode == 0) //SW_Offset { Info("SW_Offset"); FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_OffsetGeneration, NULL, 0); if (TestError(nDetectorID, nResult)) { Error("Cmd_OffsetGeneration Cmd Failed"); return false; } if (!WaitRespond(300000)) { Error("Generate SW Offset Template failed"); } else { Info("Generate SW Offset Template success"); } } else if (m_stDeviceIndex[m_nDetectorIndex].nOffsetMode == 1) //HW_Offset { Info("HW_Offset"); FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_HwGeneratePreOffsetTemplate, NULL, 0); if (TestError(nDetectorID, nResult)) { Error("Cmd_HwGeneratePreOffsetTemplate Cmd Failed"); return false; } if(!WaitRespond(300000)) { Error("Generate HW Offset Template failed"); } else { Info("Generate HW Offset Template success"); } } else { Warn("Undefined offset mode"); return false; } return true; } bool IRayCtrl::AbortOffset() { Info("Abort refresh offset"); m_pfAbort(m_nDetectorID); Info("Abort detector"); StatusFeedback(PANEL_OFFSET_CAL, OFFSET_IDLE); return true; } //检查图像EXI, 返回true: 有射线,返回false: 无射线 bool IRayCtrl::CheckImageEXI(WORD* pImage, int nWidth, int nHeight, int nImageBit, int nThreshold, float fArea) { if (nThreshold == 0) { Info("Omit check EXI"); return true; } Info("Check EXI"); if (!pImage) { Error("Buffer is null"); return false; //图像读入失败。 } int N = 65536; int* Histogram = NULL; Histogram = new int[N]; if (Histogram == NULL) { Error("Alloc buffer failed"); return false; //内存分配失败。 } memset(Histogram, 0, sizeof(int) * N); unsigned long int nCount = 0; unsigned long int temp = 0; int nIdxI = 0; int nIdxJ = 0; for (nIdxJ = 30; nIdxJ < nHeight - 30; nIdxJ = nIdxJ + 4) { for (nIdxI = 30; nIdxI < nWidth - 30; nIdxI = nIdxI + 4) { temp = int(pImage[nIdxJ * nWidth + nIdxI]); Histogram[temp]++; nCount++; } } float fCoe = 0.01f; int nCoeCount = int(fCoe * nCount); int nAreaCount = int((1 - fCoe) * nCount * fArea); long int nIdx = 0; long int nSum = 0; for (nIdx = N - 1; nIdx >= 0; nIdx--) { nSum += Histogram[nIdx]; if (nSum >= nCoeCount) break; } unsigned long int fMean = 0; unsigned long int nflag = 0; for (int i = nIdx; i >= 0; i--) { if (Histogram[nIdx] == 0) { continue; } fMean += nIdx * Histogram[nIdx]; nflag += Histogram[nIdx]; if (nflag >= nAreaCount) { break; } } if (Histogram) { delete[] Histogram; Histogram = NULL; } if (nflag == 0) { Warning("Not have Xray image"); return false; //无x射线 } fMean = unsigned long int(fMean / nflag); Info("Mean count({$})", fMean); if (fMean >= nThreshold) { //LogInfo("Xray image"); return true; } else { //LogInfo("Not have Xray image"); return false; } } bool IRayCtrl::SetOffsetModeScope() { Info("SetModeScope"); int nModeNum = m_pCurrentDPC->GetTotalAcqModeNum(); Info("Mode number: {$}", nModeNum); int nLogicMode = 0; int nOperationMode = 0; for (int i = 0; i < nModeNum; i++) { if ((int)m_ModeConfig["ModeTable"][i]["OffsetEnable"] == 1) { nLogicMode = (int)m_ModeConfig["ModeTable"][i]["LogicMode"]; nOperationMode = (int)m_ModeConfig["ModeTable"][i]["OperationMode"]; m_mapLogicModeOperationMode.insert(pair(nLogicMode, nOperationMode)); } } return true; } bool IRayCtrl::SetFluPPS(float fFluPPS) { if (fFluPPS <= 0.0f) { Warn("Current frame rate is Illegal"); return false; } m_fFrameRate = fFluPPS; return true; } bool IRayCtrl::GetFluPPS(float& fFluPPS) { fFluPPS = m_fFrameRate; return true; }