#include "stdafx.h" #include #include "sys\stat.h" #include //文件流库函数 #include #include "IRayCtrl.h" #include "common_api.h" #include "MyPingip.h" extern Log4CPP::Logger* gLogger; #include #pragma comment(lib,"Shlwapi.lib") //如果没有这行,会出现link错误 #pragma comment(lib, "Version.lib") const int BUFFER_NUM = 10; const int BUFFER_LENGTH = 4000 * 4000; const int ID_TIMER_REFRESH_HARDWARE = 1; const int ID_TIMER_TEMPERCHECK = 2; const int ID_TIMER_RESET_SNLIST = 3; const int ID_TIMER_RECONNECT = 4; const int ID_TIMER_CHECK_CALIBRTION = 5; const int nINIT_TIME = 50000; 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); } void FpdScanResult(DetectorProfile* pDetectorProfile) { g_pIRayCtrl->ScanResult(pDetectorProfile); } #define MAX_STRING 1024 IRayCtrl::IRayCtrl() : g_strAppPath("") , m_nPanelCount(0) , m_nDetectorID(1) , m_nDetectorIndex(0) , m_nCalibrationMode(CCOS_CALIBRATION_MODE_ZSKK) , m_pZSKKCalib(nullptr) , m_nCalibCurrentCalibrationRound(0) , m_nCalibrationRounds(0) , m_nCalibCurrentExposureIndex(0) , m_nExposureNumCurrentRound(0) , m_bSaveCalibrationRaw(0) , m_hExitEvent(nullptr) , m_hRecoverImage(nullptr) , m_hOffsetEvent(nullptr) , m_hCofirmCalib(nullptr) , m_hEndCalibEvent(nullptr) , m_eCaliType(CCOS_CALIBRATION_TYPE_NONE) , m_nStatusPeriod(10000) , m_bInitialing(false) , m_bDetectorReady(false) { m_hInitThread = NULL; m_hScanEventThread = NULL; m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); //m_pImageBuffer = NULL; m_strWorkPath = ""; m_eAppStatus = APP_STATUS_IDLE; m_nCurrentMode = -1; m_nImageWidth = 0; m_nImageHeight = 0; m_nRawImgWidth = 0; m_nRawImgHeight = 0; m_nWidthOffset = 0; m_nHeightOffset = 0; m_pImgBuffer = NULL; m_nImgBits = 16; m_nPixelPitch = 150; m_bPreviewEnable = false; m_nPreviewWidth = 0; m_nPreviewHeight = 0; m_nDoseParam = 0; m_fCurrentDose = 0; m_nCaliFailedCount = 0; m_bGainPreparing = false; m_bGainProcess = false; m_bConfirmCaliRst = false; //m_nGainNodeCount = 0; //m_nGainNodeIndex = 0; //m_nGainExpCount = 0; //m_nGainExpIndex = 0; m_bModuleConnecting = false; m_bUpdateFirmwareDirect = false; m_nUpdateFPDID = -1; m_bIsImageRecovering = false; m_bInCalibrating = false; m_bFDAttaching = false; m_pwPreviewImg = NULL; m_pwRawImageData = NULL; m_pHardwareStatusThread = NULL; m_pXWindowoffThread = NULL; m_bFirmwareUpdating = false; m_bInExposure = false; m_nRecoverImageTimes = 0; m_bImageRecoverBeCanceled = false; m_bSetCorrectFile = false; } IRayCtrl::~IRayCtrl() { OnEXIT(); if (m_pImgBuffer) { delete[] m_pImgBuffer; m_pImgBuffer = NULL; } if (m_pZSKKCalib) { delete m_pZSKKCalib; m_pZSKKCalib = nullptr; } delete m_pDPC2PanelID; m_pDPC2PanelID = NULL; delete m_pPanelID2DPC; m_pPanelID2DPC = NULL; } 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 = NULL; } if (m_hExitEvent) { CloseHandle(m_hExitEvent); m_hExitEvent = NULL; } if (m_hRecoverImage) { CloseHandle(m_hRecoverImage); m_hRecoverImage = NULL; } if (m_hOffsetEvent) { CloseHandle(m_hOffsetEvent); m_hOffsetEvent = NULL; } if (m_hCofirmCalib) { CloseHandle(m_hCofirmCalib); m_hCofirmCalib = NULL; } if (m_hEndCalibEvent) { CloseHandle(m_hEndCalibEvent); m_hEndCalibEvent = NULL; } if (m_hIRayScanEnd) { CloseHandle(m_hIRayScanEnd); m_hIRayScanEnd = NULL; } if (m_hHWStatusThreadEndEvent) { CloseHandle(m_hHWStatusThreadEndEvent); m_hHWStatusThreadEndEvent = NULL; } if (m_pwPreviewImg) { delete[] m_pwPreviewImg; m_pwPreviewImg = NULL; } if (m_pwRawImageData) { delete[] m_pwRawImageData; m_pwRawImageData = NULL; } } 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; } bool IRayCtrl::ScanResult(DetectorProfile* pDetectorProfile) { Info("Scan Product No:{$}", pDetectorProfile->nProdNo); string strIP = pDetectorProfile->szIP; Info("Scan Detector IP:{$}", strIP.c_str()); string strSN = pDetectorProfile->szSN; Info("Scan Detector SN:{$}", strSN.c_str()); if (m_nPanelCount > 0)//SDK 会自动恢复连接,不需要再调用connect,反而会影响SDK的动作 { for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) //先连接多板 { if (!m_stDeviceIndex[nDetectorID].bConnectStatus && !m_stDeviceIndex[nDetectorID].bInitOK && !m_bInitialing && !m_bModuleConnecting) { Info("Have unConnect Detector SN:{$}", m_stDeviceIndex[nDetectorID].strPanelSerial.c_str()); if (m_stDeviceIndex[nDetectorID].strPanelSerial == strSN && m_stDeviceIndex[nDetectorID].bActived) { Info("Reconnecting FPD {$} now", nDetectorID); DetectorInitProcess(nDetectorID); } } } } return true; } //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 ]"); if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { Info("Offset..."); return; } if ((TRIGGER_INNER2 == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) || (TRIGGER_FREESYNC == m_stDeviceIndex[m_nDetectorIndex].nSyncMode)) { StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_ON); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } } break; case Evt_Exp_Prohibit: { Info("[ Event:Evt_Exp_Prohibit ]"); } break; case Evt_Exp_Enable: { Info("[ Event:Evt_Exp_Enable ]"); m_bDetectorReady = true; if (TRIGGER_SOFT == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) { 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 ]"); } //break; case Evt_Image: { Info("[ Event:Evt_Image ],Image ReadOut = true"); IRayImage* pstImg = (IRayImage*)pParam; if (pstImg == NULL) { Fatal("Image Data is NULL"); return; } for (size_t i = 0; i < pstImg->propList.nItemCount; i++) { switch (pstImg->propList.pItems[i].nMapKey) { case Enm_ImageTag_AvgValue: { int nAvgValue = pstImg->propList.pItems[i].varMapVal.val.nVal; Info("Image Avg Value:{$}", nAvgValue); break; } case Enm_ImageTag_CenterValue: { int nCenterValue = pstImg->propList.pItems[i].varMapVal.val.nVal; Info("Image Center Value : {$}", nCenterValue); break; } } } if (m_bInCalibrating) { SetEvent(m_hCofirmCalib); return; } if (m_stDeviceIndex[nDetectorID - 1].bRecoveringImage) { if (m_nRecoverImageTimes > 0) { StatusFeedback(EVT_STATUS_IMAGERECOVERAUTO, 0, "true"); } else { StatusFeedback(EVT_STATUS_IMAGEPENDING, 0, "false");//没有图像没拿到 ErrorFeedback(EVT_ERR_GET_IMAGE, "false"); } m_nRecoverImageTimes = 0; m_stDeviceIndex[nDetectorID - 1].bRecoveringImage = false; m_stDeviceIndex[nDetectorID - 1].bImagePending = false; } int nRawImgHeight = pstImg->nHeight; int nRawImgWidth = pstImg->nWidth; Info("Image Height:{$}, Width:{$}", nRawImgHeight, nRawImgWidth); if (m_pwRawImageData) { delete[] m_pwRawImageData; m_pwRawImageData = NULL; } m_pwRawImageData = new WORD[nRawImgHeight * nRawImgWidth]; if (m_pwRawImageData == NULL) { Fatal("Allocate Raw Image Failed"); return; } memcpy(m_pwRawImageData, pstImg->pData, nRawImgHeight * nRawImgWidth * sizeof(WORD)); if (m_stDeviceIndex[nDetectorID - 1].strDeviceName.find("Mars") != std::string::npos) { FlipX(m_pwRawImageData, nRawImgWidth, nRawImgHeight); } else { FlipXRotate90(m_pwRawImageData, nRawImgWidth, nRawImgHeight); } OnProcessImg(); } break; case Evt_Prev_Image: { Info("[ Event:Evt_Prev_Image ]"); if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { Info("Offset..."); return; } if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { Info("XRay Calibration..."); return; } 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("Mars") != std::string::npos) { 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 nPanelID, int nParam1, int nParam2, bool bResult) { int nDetectorID = 0; 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; } } void IRayCtrl::OnProcessTaskResult(int nPanelID, int nParam1, int nParam2, bool bResult) { int nDetectorID = nPanelID - 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", nPanelID); SendNotify(); m_stDeviceIndex[nDetectorID].bInitOK = false; m_stDeviceIndex[nDetectorID].bConnectStatus = false; ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nDetectorID); } break; case Cmd_Connect: { Info("[ Cmd_Connect ]"); if (bResult) { Info("FPD {$} is Connected", nPanelID); m_stDeviceIndex[nDetectorID].bInitOK = true;//已经连接成功过了,后面不需要在connect了,等待SDK自动connect就可以了。 m_stDeviceIndex[nDetectorID].bConnectStatus = true; //m_stDeviceIndex[nDetectorID].bConnectChanged = true; //连接恢复之后,都要先查询一次有没有未传输成功的图像 m_nCmdConnectResult = nParam2; ErrorFeedback(EVT_ERR_COMMUNICATE, "false", nDetectorID); } else { m_stDeviceIndex[nDetectorID].bConnectStatus = false; Fatal("FPD {$} connect failed", nPanelID); 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: { 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[nDetectorID].bUpdateFirmware = bResult; if (TestError(nDetectorID, nParam2)) {//失败时,发notify结束超时等待 SendNotify(); } //else 不发,等探测器重启后,由SDK callback Cmd_connect时发notify结束 } break; case Cmd_ReadTemperature: { Info("Cmd_ReadTemperature{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bReadTemperature = bResult; SendNotify(); } break; case Cmd_ReadBatteryStatus: { Info("Cmd_ReadBatteryStatus{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bReadBattery = bResult; SendNotify(); } break; case Cmd_QueryLivingTime: { Info("Cmd_QueryLivingTime {$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bLivingTime = bResult; SendNotify(); } break; case Cmd_ReadWifiStatus: { Info("Cmd_ReadWifiStatus{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bReadWifi = bResult; SendNotify(); } break; case Cmd_SetCorrectOption: { Info("Cmd_SetCorrectOption{$}", strTaskResult.c_str()); 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[nDetectorID].bTaskEnd = true; if (!bResult) { //SetEvent(m_hRecoverImage); } } break; case Cmd_ReadHallSensor: { Info("Cmd_ReadHallSensor{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bHallSensor = bResult; SendNotify(); } break; case Cmd_ClearAcq: { Info("Cmd_ClearAcq{$}", strTaskResult.c_str()); m_bInExposure = false; m_stDeviceIndex[nDetectorID].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; } } } 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()); if (TRIGGER_INNER2 == m_stDeviceIndex[m_nDetectorIndex].nSyncMode && !bResult) { m_bDetectorReady = false; } } 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[nDetectorID].bUploadCalibFile = bResult; Info("Cmd_UploadCaliFile{$}", strTaskResult.c_str()); SendNotify(); break; } case Cmd_SelectCaliFile: { m_stDeviceIndex[nDetectorID].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"); m_bDetectorReady = false; } break; case Cmd_ReadCustomFile: { Info("Cmd_ReadCustomFile{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].bUploadCalibFile = bResult; SendNotify(); } break; case Cmd_WriteCustomFile: { Info("Cmd_WriteCustomFile{$}", strTaskResult.c_str()); m_stDeviceIndex[nDetectorID].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\\iRayDR\\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_hIRayScanEnd = CreateEvent(NULL, FALSE, FALSE, NULL); m_hWindowOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hRecoverImage = CreateEvent(NULL, FALSE, FALSE, NULL); m_hOffsetEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hCofirmCalib = CreateEvent(NULL, FALSE, FALSE, NULL); m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hHWStatusThreadEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hExitEvent; m_hArrayEvent[1] = m_hRecoverImage; m_hArrayEvent[2] = m_hOffsetEvent; m_hArrayEvent[3] = m_hCofirmCalib; m_hArrayEvent[4] = m_hEndCalibEvent; Info("Call RegisterScanNotify"); int nRet = m_pRegisterScanNotify(FpdScanResult); if (TestError(0, nRet)) { Info("Register ScanNotify Failed"); return false; } Info("IRayCtrl::Init over\n"); return true; } //启动初始化线程 void IRayCtrl::StartInitFPDThread() { Info("Start Init Thread"); DWORD unThreadID; if (m_hInitThread == NULL) { m_hInitThread = CreateThread(0, 0, onInitPanel, this, 0, &unThreadID); if (m_hInitThread == NULL) { Fatal("Start Init Thread Error"); } } //endif } //初始化 DWORD IRayCtrl::onInitPanel(void* pParam) { IRayCtrl* pInstance = (IRayCtrl*)pParam; pInstance->Action_Init(); pInstance->m_hInitThread = NULL; return true; } void IRayCtrl::Action_Init() { Info("IRayCtrl::Action_Init"); m_bInitialing = true; for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) //连接多板 { string strWorkDir = (m_stDeviceIndex[nDetectorID].strWorkDir); Info("Start Register Detector: {$}", strWorkDir.c_str()); int nPanelID = 0; int nRet = m_fpCreate(strWorkDir.c_str(), SDKCallbackProxy, &nPanelID); if (TestError(nPanelID, nRet, false)) { Error("Register Detector {$} Callback Failed", nPanelID); continue; } Info("Register Detector {$} Callback Success", nPanelID); bool bRet = DetectorInitProcess(nDetectorID); if (!bRet) { Error("Init process failed"); } } if (!m_pZSKKCalib) { m_pZSKKCalib = new CZSKKCalibrationCtrl(); } if (CCOS_CALIBRATION_MODE_ZSKK == m_nCalibrationMode) //ZSKK校正 { Info("Load ZSKK Reference file"); m_pZSKKCalib->m_strRawImgPath = g_strAppPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = g_strAppPath + "\\references\\"; m_pZSKKCalib->m_nFullImgWidth = m_stDeviceIndex[m_nDetectorIndex].nFullImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_stDeviceIndex[m_nDetectorIndex].nFullImageHeight; m_pZSKKCalib->m_nSaturationValue = 50000; if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_stDeviceIndex[m_nDetectorIndex].strDetectorModel)) { Warn("Load ZSKK Gain calibration failed"); } if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_stDeviceIndex[m_nDetectorIndex].strDetectorModel)) { Warn("Load ZSKK Defect calibration failed"); } } iRayScanEventThread(); StartHardwareStatusThread(); m_bInitialing = false; Info("Action init over\n"); } //初始化连接探测器 bool IRayCtrl::DetectorInitProcess(int nDetectorID, bool bFDAttach) { bool bPingSucces = false; int nPingTotalTime = 30; //ping不通,一次约2s,共30次,1分钟左右超时 for (int nPingTimes = 0; nPingTimes < nPingTotalTime; nPingTimes++) { bPingSucces = IsConnected(m_stDeviceIndex[nDetectorID].strWiredIP); if (bPingSucces) { Info("Ping Detector successfully"); break; } Sleep(2000); } //ping不通就不用连接了 if (!bPingSucces) { Error("Ping detector failed, timeout!!!"); ErrorFeedback(EVT_ERR_COMMUNICATE, "true"); return false; } OnInitStatus(nDetectorID, PANEL_EVENT_START); int nPanelID = nDetectorID + 1; int nDetectorIndex = nPanelID - 1; Info("Call FnInvoke:Connect"); int nRet = IrayFnInvoke(nPanelID, Cmd_Connect, NULL, 0); //wait Cmd_Connect if (TestError(nDetectorID, nRet)) { Error("Connect Detector {$} Failed", nPanelID); if (m_stDeviceIndex[nDetectorID].bActived) { m_stDeviceIndex[nDetectorID].bExisted = true; m_stDeviceIndex[nDetectorID].bConnectStatus = false; } return false; } ResetLock(); if (!WaitRespond(nINIT_TIME)) { Error("Connect Detector {$} timeout", nPanelID); } if (m_stDeviceIndex[nDetectorID].bConnectStatus) { Info("Connect Detector {$} Success", nPanelID); } 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[nDetectorID].bActived) { m_stDeviceIndex[nDetectorID].bExisted = true; } return false; } } GetROMInfo(nDetectorID); SyncTimePC2FD(nDetectorID); SetDetectorWorkMode(nDetectorID, m_stDeviceIndex[nDetectorID].strDetectorModel, m_stDeviceIndex[nDetectorID].nSyncMode); if (bFDAttach) //特殊需求,同步校正文件 { DownloadfromDetector(nDetectorID); } //SetLTEMode(false); SetDetectorXWindow(nPanelID, 500, m_stDeviceIndex[nDetectorIndex].nXWindow, m_stDeviceIndex[nDetectorIndex].nXWindow); //SetMarsCorrection(nPanelID); SetDetectorCorrection(nPanelID, m_stDeviceIndex[nDetectorIndex].nCorrectionType); ////读取WIFI电量温度 /*if (ReadWifiStatus(nDetectorID)) { CheckWiFi(nDetectorID); }*/ /*if (ReadTempStatus(nDetectorID)) { CheckTemperature(nDetectorID); }*/ /*if (ReadLivingTime(nDetectorID)) { CheckLivingTime(nDetectorID); }*/ m_nCalibrationMode = CCOS_CALIBRATION_MODE(m_stDeviceIndex[nDetectorID].nCalibMode); m_stDeviceIndex[nDetectorID].bExisted = true; m_stDeviceIndex[nDetectorID].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[nDetectorID].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::iRayScanEventThread() { if (m_hScanEventThread != NULL) { Info("ScanEvent Thread already run\n"); return; } Info("Start ScanEvent Thread"); DWORD unThreadID; m_hScanEventThread = (HANDLE)CreateThread(NULL, 0, onScanEvent, (LPVOID)this, 0, &unThreadID); if (m_hScanEventThread == NULL) { Fatal("Start Scan Event Error"); } else { Info("Start ScanEvent Thread ok"); } //endif } /************************************************************************************ 功能:启动线程,处理一些异步消息 ************************************************************************************/ 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"); } } else if (WAIT_OBJECT_0 + 2 == dwResult) //m_hOffsetEvent { Info("Get Offset Event"); pInstance->OffsetProcess(); } else if (WAIT_OBJECT_0 + 3 == dwResult) //m_hCofirmCalib { Info("Get Cofirm Calibration Event"); pInstance->ConfirmCalibration(); } else if (WAIT_OBJECT_0 + 4 == dwResult) //m_hEndCalibEvent { Info("Get EndCalibraion Event"); pInstance->OnEndCalibraion(); } } 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::GetInnerSubFlow(int nDetectorID, int& nInnerSubFlow) { return GetAttr(nDetectorID, Attr_FROM_InnerSubFlow, nInnerSubFlow); } 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); } bool IRayCtrl::GetFPDTempT1(int nDetectorID, float& fTempT1) { return GetAttr(nDetectorID, Attr_RdResult_T1, fTempT1); } 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) { 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()); } 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_stDeviceIndex[m_nPanelCount] = DeviceStruct; m_ObjFPDsInfo[m_nPanelCount] = Configuration; Info("AddDPCs, {$} {$} ", m_stDeviceIndex[m_nPanelCount].strDetectorModel, m_stDeviceIndex[m_nPanelCount].strDeviceName); m_pDPC2PanelID->insert(pair(pDrvDPC, m_nPanelCount)); m_pPanelID2DPC->insert(pair(m_nPanelCount, pDrvDPC)); m_ModeConfig = m_ObjFPDsInfo[m_nDetectorIndex]; m_nPanelCount++; Info("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)[nDetectorID])->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)[nDetectorID])->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)[nDetectorID])->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)[nDetectorID])->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)[nDetectorID])->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)[nDetectorID])->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]; Info("ActivePanel over: {$}, DetectorIndex {$}", 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"; m_bModuleConnecting = false; 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); } 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); } Info("Call Destroy"); nResult = m_fpDestroy(nPanelID); TestError(m_nDetectorIndex, nResult); ErrorFeedback(EVT_ERR_MAX_NUMBER, "false", m_nDetectorIndex); Info("DisConnect Over"); return true; } RET_STATUS IRayCtrl::SetSyncMode(SYNC_MODE nSyncMode, HARDWARE_TRIGGER_MODE TriggerMode) { return RET_STATUS::RET_SUCCEED; } /*** ** 说明:设置当前的曝光模式 ** 参数:nLogicMode,从配置文件读取,与SDK配置application mode对应 ***/ bool IRayCtrl::SelectExamMode(int nLogicMode, nsDPC::FPDDeviceIRay* pDrvDPC) { Info("IRayCtrl::SelectExamMode start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC {$}, {$} != {$} ,return", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nDetectorIndex); return false; } if (m_stDeviceIndex[m_nDetectorIndex].bConnectStatus == false) { Error("Current detector {$} is not connect, return\n", m_nDetectorIndex); return false; } Info("SelectExamMode({$})", nLogicMode); if (m_nCurrentMode == nLogicMode) //同样appmode下没必要再次走下面的流程 { Info("Same appmode, return true"); return true; } m_nCurrentMode = nLogicMode; try { m_nRawImgHeight = m_stDeviceIndex[m_nDetectorIndex].nRawHeight; m_nRawImgWidth = m_stDeviceIndex[m_nDetectorIndex].nRawWidth; m_nImageWidth = m_stDeviceIndex[m_nDetectorIndex].nFullImageWidth; m_nImageHeight = m_stDeviceIndex[m_nDetectorIndex].nFullImageHeight; m_nWidthOffset = m_stDeviceIndex[m_nDetectorIndex].nImageLeftOffset; m_nRightOffset = m_stDeviceIndex[m_nDetectorIndex].nImageRightOffset; m_nHeightOffset = m_stDeviceIndex[m_nDetectorIndex].nImageTopOffset; m_nBottomOffset = m_stDeviceIndex[m_nDetectorIndex].nImageBottomOffset; m_nImgBits = m_stDeviceIndex[m_nDetectorIndex].nImageBits; m_nPixelPitch = m_stDeviceIndex[m_nDetectorIndex].nPixelSpace; m_nSaveRaw = m_stDeviceIndex[m_nDetectorIndex].nSaveRaw; Info("Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$} {$} {$}), Bits({$}), PixelPitch({$}), SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nHeightOffset, m_nBottomOffset, m_nWidthOffset, m_nRightOffset, m_nImgBits, m_nPixelPitch, m_nSaveRaw); string strCoef = (string)m_ModeConfig["Sensitivity"]; Info("Sensitivity: {$}", strCoef.c_str()); m_nPreviewWidth = m_stDeviceIndex[m_nDetectorIndex].nPreviewWidth; m_nPreviewHeight = m_stDeviceIndex[m_nDetectorIndex].nPreviewHeight; m_bPreviewEnable = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable; Info("Preview size(W*H {$}*{$}), PreviewEnable({$})", m_nPreviewWidth, m_nPreviewHeight, m_bPreviewEnable); } catch (ResDataObjectExption& exp) { Error("Get config failed: {$}", exp.what()); } if (m_pImgBuffer) { delete m_pImgBuffer; m_pImgBuffer = NULL; } m_pImgBuffer = new WORD[m_nImageHeight * m_nImageWidth]; ConfFeedback(EVT_CONF_RAW_WIDTH, m_nDetectorIndex, "", m_nImageWidth); ConfFeedback(EVT_CONF_RAW_HIGHT, m_nDetectorIndex, "", m_nImageHeight); ConfFeedback(EVT_CONF_RAW_BITS, m_nDetectorIndex, "", m_nImgBits); ConfFeedback(EVT_CONF_PIXELSPACE, m_nDetectorIndex, "", m_nPixelPitch); ConfFeedback(EVT_CONF_PREVIEW_WIDTH, m_nDetectorIndex, "", m_nPreviewWidth); ConfFeedback(EVT_CONF_PREVIEW_HIGHT, m_nDetectorIndex, "", m_nPreviewHeight); Info("selectExamMode {$} over \n", m_nCurrentMode); //加载校正文件,暂时先放到初始化流程中,同探测器多模式还需要考虑 //LoadReference(nLogicMode); return true; } bool IRayCtrl::OffsetProcess() { //先检查状态 if (!WaitReady(m_nDetectorIndex + 1, 1000)) { Error("Detector isn't Ready"); return false; } Info("Call Cmd_OffsetGeneration"); FPDRESULT nResult = IrayFnInvoke(m_nDetectorIndex + 1, Cmd_OffsetGeneration, NULL, 0); if (TestError(m_nDetectorIndex, nResult)) { Error("Cmd_OffsetGeneration Cmd Failed"); StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FAILED); return false; } ResetLock(); if (WaitRespond(600000)) //10分钟超时时间 { Info("Generate PreOffset Template success"); StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FINISH); } else { Error("Generate PreOffset Template failed"); StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FAILED); } 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].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::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; } if (m_bInitialing) { Warn("Current detector in init process, disable exposure"); return RET_STATUS::RET_FAILED; } int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Software sync mode"); } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { Info("Inner Call Cmd_StartAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StartAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StartAcq Failed"); } else { Info("Cmd_StartAcq over"); } } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { if (m_bDetectorReady) { Info("Detector already ready, omit"); return RET_STATUS::RET_SUCCEED; } Info("Inner2 Call Cmd_StartAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StartAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StartAcq Failed"); } else { Info("Cmd_StartAcq over"); } } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } return RET_STATUS::RET_SUCCEED; } RET_STATUS IRayCtrl::StartAcquisition(nsDPC::FPDDeviceIRay* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return RET_STATUS::RET_FAILED; } m_bImageRecoverBeCanceled = false; RET_STATUS Ret = RET_STATUS::RET_FAILED; //如果当前探测器断连,则不开始采集,直接返回失败 if (!m_stDeviceIndex[m_nDetectorIndex].bConnectStatus) { Warn("Detector not in connection when start acq, return failed"); return RET_STATUS::RET_FAILED; } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START); m_bInExposure = true; m_nLastExpFDIndex = m_nDetectorIndex; m_bAbortRecover = false; int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Call Cmd_ClearAcq"); 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_ACQUISITION, PANEL_EVENT_END_ERROR); return Ret; } else { m_stDeviceIndex[m_nDetectorIndex].bTaskEnd = false; Info("Send BeginCapture message"); } } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { // } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_ON); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_ON); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } 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; } int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Software sync mode"); } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { Info("Inner Call Cmd_StopAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StopAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StopAcq Failed"); } else { Info("Cmd_StopAcq over"); } } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { Info("Inner2 Call Cmd_StopAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StopAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StopAcq Failed"); } else { Info("Cmd_StopAcq over"); } } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } m_bInExposure = false; return RET_STATUS::RET_SUCCEED; } 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; Info("InitCalibration Current Active FD Index:{$}", m_nDetectorIndex); if (m_nPanelCount < 0) { return false; } string strMode = "STE"; int Xwindow = 500; int nPanelID = m_nDetectorIndex + 1; Info("Set Xwindow to {$}", Xwindow); if (SetDelayTime(nPanelID, Xwindow)) { Info("Panel {$} goto {$} mode ok", nPanelID, strMode.c_str()); } else { Info("Panel {$} goto {$} mode failed", nPanelID, strMode.c_str()); return false; } if (SetAppMode(nPanelID)) { Info("Panel {$} goto {$} FPDAPPmode ok", nPanelID, strMode.c_str()); } else { Info("Panel {$} goto {$} FPDAPPmode failed", nPanelID, strMode.c_str()); return false; } m_bCalibResultFailed = false; m_fCalibTemperature1 = m_stDeviceIndex[m_nDetectorIndex].fCurrentTemperValue; m_bInCalibrating = true; bool ret = GetiRayPanelCalibItem(); if (!ret) { Error("GetPanelCalibItem failed\n"); return false; } list::iterator iter; for (iter = m_listCalibItem.begin(); iter != m_listCalibItem.end(); iter++) { Info("Calibration dose:{$},Number:{$}", iter->nReferDose, iter->nAvgNum); } m_iterCalibDose = m_listCalibItem.begin(); m_nDoseParam = m_iterCalibDose->nReferDose; DataFeedback(EVT_DATA_DOSEPARAM, NULL, m_nDoseParam); Info("First Calibration dose:{$},Number:{$},m_nDoseParam = {$}", m_iterCalibDose->nReferDose, m_iterCalibDose->nAvgNum, m_nDoseParam); 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_FAILED; StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); if (CCOS_CALIBRATION_TYPE_DARK == Type) { Info("ActiveDarkCalibration"); Ret = RET_STATUS::RET_SUCCEED; } else if (CCOS_CALIBRATION_TYPE_XRAY == Type) { Info("ActiveXrayCalibration"); if (m_nCalibrationMode) //iRay 校正 { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); if (!InitCalibration()) { StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); return RET_STATUS::RET_FAILED; } } else //ZSKK校正 { if (!m_pZSKKCalib) { Error("ZSKK Calibration object is undefined"); Ret = RET_STATUS::RET_FAILED; } else { //反馈Dose信息 DataFeedback(EVT_DATA_DOSEPARAM, NULL, 2000, 0); //加载ZSKK的校正文件 m_pZSKKCalib->m_strRawImgPath = g_strAppPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = g_strAppPath + "\\references\\"; m_pZSKKCalib->m_nFullImgWidth = m_stDeviceIndex[m_nDetectorIndex].nFullImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_stDeviceIndex[m_nDetectorIndex].nFullImageHeight; m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds; m_pZSKKCalib->m_nSaturationValue = 50000; m_pZSKKCalib->LoadZSKKGainMap(false, m_stDeviceIndex[m_nDetectorIndex].strDetectorModel); m_pZSKKCalib->LoadZSKKPixelMap(false, m_stDeviceIndex[m_nDetectorIndex].strDetectorModel); Info("Load ZSKK map successful"); Info("References: {$}", m_pZSKKCalib->m_strRefFilePath); Ret = RET_STATUS::RET_SUCCEED; } } } else { Error("Active not supported calibration({$}), return! \n", (int)Type); Ret = RET_STATUS::RET_NOSUPPORT; return Ret; } m_eCaliType = Type; 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; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) //offset校正直接返回 { Warn("Preparing generate HW post offset template"); return RET_STATUS::RET_SUCCEED; } RET_STATUS Ret = RET_STATUS::RET_FAILED; if (m_nCalibrationMode) //iRay校正 { Info("Manual trigger next calibration exposure"); } else //ZSKK校正 { int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Software sync mode"); } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { Info("Inner Call Cmd_StartAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StartAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StartAcq Failed"); } else { Info("Cmd_StartAcq over"); } } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { Info("Inner2 Call Cmd_StartAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StartAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StartAcq Failed"); } else { Info("Cmd_StartAcq over"); } } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } Ret = RET_STATUS::RET_SUCCEED; } Ret = RET_STATUS::RET_SUCCEED; Debug("PrepareCalibration Over"); 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); //OffsetProcess() Ret = RET_STATUS::RET_SUCCEED; } else { Info("StartXrayCalibration \n"); int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; m_bInExposure = true; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Call Cmd_ClearAcq"); int nPanelID = m_nDetectorIndex + 1; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ClearAcq, NULL, 0); if (TestError(m_nDetectorIndex, nResult)) { Error("Invoke Cmd_ClearAcq Failed"); StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR); return Ret; } else { m_stDeviceIndex[m_nDetectorIndex].bTaskEnd = false; Info("Send BeginCapture message"); } } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { // } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { // } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } 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() { Info("Accept calibration exposure result"); if (m_nCalibrationMode) //iRay校正 { 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); } else //ZSKK校正 { Info("Accept ZSKK calibration exposure"); if (m_nCalibCurrentExposureIndex == 1) { m_pZSKKCalib->AddImageToPixMap(m_pImgBuffer); m_pZSKKCalib->AverageZSKKGainMap(m_pImgBuffer, m_nCalibCurrentCalibrationRound - 1, true); } else { m_pZSKKCalib->AverageZSKKGainMap(m_pImgBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮 } } 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; } 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) { m_bCalibResultFailed = false; } return Ret; } bool bResult = WaitRespond(120 * 1000); // Evt_TaskResult_Canceled if (bResult) { Info("Abort Calibration Success"); } else { Error("Abort Calibration Timeout"); } SetMarsCorrection(m_nDetectorIndex); } else { Info("Omit Abort Calibration"); } Ret = RET_STATUS::RET_SUCCEED; return Ret; } /*** ** 说明:结束校正 ** 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); SetMarsCorrection(m_nDetectorIndex); string szTemp; if (bLTE) { szTemp = m_stDeviceIndex[m_nDetectorIndex].strCalibrationLTEDate; } else { szTemp = m_stDeviceIndex[m_nDetectorIndex].strCalibrationDate; } WriteCumstomFile(m_nDetectorIndex);//上传校正报告,sensitivity BackupCalibFiles(m_nDetectorIndex, true, bLTE);//备份校正defect map/ if (bRet) { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END); } else { StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END_ERROR); } Info("Calibration completed!"); return; } bool IRayCtrl::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound) { m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound; m_nCalibrationRounds = nCalibrationRounds; m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex; m_nExposureNumCurrentRound = nExposureNumCurrentRound; Info("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds, nCalibCurrentExposureIndex, nExposureNumCurrentRound); return true; } bool IRayCtrl::SaveCalibrationFile() { Info("Save Calibration File"); if (m_nCalibrationMode)//iRay校正 { //不做处理 } else { Info("Save ZSKK Calibration File"); m_pZSKKCalib->StoreZSKKGainMap(m_stDeviceIndex[m_nDetectorIndex].strDetectorModel); m_pZSKKCalib->StoreZSKKPixMap(m_stDeviceIndex[m_nDetectorIndex].strDetectorModel); } //更新配置文件中校正日期和时间 SYSTEMTIME stCurrentTime = { 0 }; GetLocalTime(&stCurrentTime); Info("Current calibration time: {$d04}/{$d02}/{$d02} {$d02}:{$d02}:{$d02}:{$d02}", stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay, stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds); m_stDeviceIndex[m_nDetectorIndex].strCalibrationDate = std::to_string(stCurrentTime.wYear) + "-" + std::to_string(stCurrentTime.wMonth) + "-" + std::to_string(stCurrentTime.wDay); m_stDeviceIndex[m_nDetectorIndex].strCalibrationTime = std::to_string(stCurrentTime.wHour) + ":" + std::to_string(stCurrentTime.wMinute) + ":" + std::to_string(stCurrentTime.wSecond) + "." + std::to_string(stCurrentTime.wMilliseconds); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值 Info("Save Calibration File over"); return true; } //------------------------------------------------------------------------------------------------------------------- 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 bLTE) //{ // bool bRet = true; // // Info("Active gain calibration files"); // 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; // // if (bLTE) // { // param[1].var.val.nVal = 4; // } // // int nPanelID = m_nDetectorIndex + 1; // FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_SelectCaliFile, param, 2); // if (!TestError(m_nDetectorIndex, nResult)) // { // if (WaitRespond(16000)) // { // Info("Cmd_SelectCaliFile Success"); // } // else // { // Error("Cmd_SelectCaliFile Failed"); // bRet &= false; // } // } // // Info("Active defect calibration files"); // 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; // if (bLTE) // { // param[1].var.val.nVal = 4; // } // // nResult = IrayFnInvoke(nPanelID, Cmd_SelectCaliFile, param, 2); // if (!TestError(m_nDetectorIndex, nResult)) // { // if (WaitRespond(16000)) // { // Info("Cmd_SelectCaliFile Success"); // } // else // { // Error("Cmd_SelectCaliFile Failed"); // bRet &= false; // } // } // // return bRet; //} 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; if ((m_stDeviceIndex[m_nDetectorIndex].strCalibrationDate != " ") && (m_stDeviceIndex[m_nDetectorIndex].strCalibrationLTEDate != " ")) { param[1].var.val.nVal = 10; } else { Info("no Calibration files can be set"); return false; } 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::SetLTEMode(bool bEnable) { return true; } 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; } /* 功能:将本地系统时间和探测器端系统时间进行同步,探测器端会记录log,同步时间有利于日志分析 */ bool IRayCtrl::SyncTimePC2FD(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!WaitReady(nPanelID, 600)) { Fatal("Wait ready Failed"); return false; } Info("Call Cmd_SetTimeByDiff"); IRayCmdParam param[1]; param[0].pt = IPT_VARIANT; param[0].var.vt = IVT_INT; param[0].var.val.nVal = 0; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_SetTimeByDiff, param, 1); if (TestError(nDetectorID, nResult, false)) { Info("Cmd_SetTimeByDiff failed"); return false; } if (WaitRespond(5000)) { Info("Cmd_SetTimeByDiff Success"); } else { Fatal("Cmd_SetTimeByDiff Failed"); return false; } return true; } bool IRayCtrl::ReadBatteryStatus(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bWireless) { return false; } Info("Begin to Read Battery"); if (!WaitReady(nPanelID, 600)) { Fatal("Read Battery Failed"); return false; } FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ReadBatteryStatus, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Battery Failed"); return false; } bool bResult = WaitRespond(3000); if (bResult) { if (m_stDeviceIndex[nDetectorID].bReadBattery) { Info("Read Battery Success"); return true; } return false; } Info("Read Battery Timeout"); return false; } bool IRayCtrl::CheckBattery(int nDetectorID, bool bLog) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bBatteryEnable) { Info("Battery disable"); return true; } if (!m_stDeviceIndex[nDetectorID].bWireless) { return false; } int nExist = 0; int nBatteryValue = 0; int nChargingStatus = 0; GetBatteryChargingStatus(nPanelID, nChargingStatus); if (nChargingStatus) { if (bLog) { Info("Detector is Charging battery"); } m_stDeviceIndex[nDetectorID].bCharging = true; } else { m_stDeviceIndex[nDetectorID].bCharging = false; } if (GetBatteryExist(nPanelID, 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) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bWireless) { return false; } Info("Read Wifi"); if (!WaitReady(nPanelID, 500)) { Fatal("Read Wifi Failed"); return false; } FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ReadWifiStatus, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Wifi Failed"); return false; } bool bResult = WaitRespond(8000); if (bResult) { if (m_stDeviceIndex[nDetectorID].bReadWifi) { Info("Read Wifi Success"); return true; } return false; } Info("Read Wifi Timeout"); return false; } bool IRayCtrl::CheckWiFi(int nDetectorID, bool bLog) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bWifiEnable) { Info("Wifi disable"); return true; } if (!m_stDeviceIndex[nDetectorID].bWireless) { 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)) { if (bLog) { string strFDAP = (szLinkedAP); Info("Detector {$} WifiStatu_LinkedAP {$}", nPanelID, strFDAP.c_str()); m_stDeviceIndex[nDetectorID].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; } bool IRayCtrl::CheckTemperature(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bTemperatureEnable) { Info("Temperature disable"); return true; } float fTemperature1 = 0.0f; if (GetFPDTempT1(nPanelID, fTemperature1)) { StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", nDetectorID, fTemperature1); m_stDeviceIndex[m_nDetectorIndex].fCurrentTemperValue = fTemperature1; } return true; } //读取探测器温度,SDK会将温度值写入Attr_RdResult_T1 ,从该Attr读取温度值 bool IRayCtrl::ReadTempStatus(int nDetectorID) { Info("Read Temperture"); int nPanelID = nDetectorID + 1; if (!WaitReady(nPanelID, 500)) { return false; } ResetLock(); Info("Call Cmd_ReadTemperature"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_ReadTemperature, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Read Temperture Failed"); return false; } bool bResult = WaitRespond(3000); if (bResult) { if (m_stDeviceIndex[nDetectorID].bReadTemperature) { Info("Read Temperture Success"); return true; } return false; } Info("Read Temperture Timeout"); return false; } //让SDK将PowerOn LifeTime值读取到Attr_FD_LifeTime bool IRayCtrl::ReadLivingTime(int nDetectorID) { int nPanelID = nDetectorID + 1; if (!WaitReady(nPanelID, 500)) { return false; } ResetLock(); Info("Call Cmd_QueryLivingTime"); m_stDeviceIndex[nDetectorID].bLivingTime = false; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_QueryLivingTime, NULL, 0); if (TestError(nDetectorID, nResult)) { Fatal("Query LivingTime Failed"); return false; } bool bResult = WaitRespond(3000); if (bResult) { if (m_stDeviceIndex[nDetectorID].bLivingTime) { Info("Query LivingTime Success"); return true; } return false; } Info("Query LivingTime Timeout"); return false; } //获取PowerOn LifeTime值 bool IRayCtrl::CheckLivingTime(int nDetectorID) { int nLifeTime = 0; int nPanelID = nDetectorID + 1; GetLifeTime(nPanelID, nLifeTime); if (nLifeTime != m_stDeviceIndex[nDetectorID].nLifeTime) { m_stDeviceIndex[nDetectorID].nLifeTime = nLifeTime; Info("Life Time: {$}", nLifeTime); ConfFeedback(EVT_CONF_LIFETIME, nDetectorID, "", nLifeTime); } int nPowerOnCount = 0; GetPowerOnCount(nPanelID, nPowerOnCount); if (nPowerOnCount != m_stDeviceIndex[nDetectorID].nPowerOn) { //string strMessage = ""; //strMessage.Format("PowerOn Counter:{$}", nPowerOnCount); InfoFeedback(EVT_INFO_POWER_ON, nDetectorID, nPowerOnCount); m_stDeviceIndex[nDetectorID].nPowerOn = nPowerOnCount; } Info("FD index:{$} LifeTime:{$},PowerOnCount:{$}", nPanelID, nLifeTime, nPowerOnCount); return true; } //WriteROM前,需要清空板内校正的校正选项,否则写入参数可能会失败 bool IRayCtrl::ClearCorrection(int nDetectorID) { Info("Clear Correction Option"); int nPanelID = nDetectorID + 1; if (!WaitReady(nPanelID, 1000)) { return false; } int nOption = 0; IRayCmdParam param[1]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = nOption; FPDRESULT result = IrayFnInvoke(nPanelID, Cmd_SetCorrectOption, param, 1); //Cmd_SetCorrectOption if (TestError(nDetectorID, result)) { Fatal("Call SetCorrectionOption Failed"); return false; } if (WaitRespond(8000)) { Info("Clear Correction Success"); } else { Fatal("Clear Correction Failed"); return false; } return true; } //探测器是板内校正 // 设置探测器端校正参数,加载校正文件 bool IRayCtrl::SetMarsCorrection(int nDetectorID) { Info("Set Mars Correction Option"); int nPanelID = nDetectorID; if (!WaitReady(nPanelID, 1000)) { return false; } int nOption = 0; nOption = nOption | Enm_CorrectOp_HW_PostOffset; nOption = nOption | Enm_CorrectOp_HW_Gain; nOption = nOption | Enm_CorrectOp_HW_Defect; int nOldOption = 0; GetCorrectionOption(nPanelID, nOldOption); if (nOption == nOldOption) { Info("Same Correction Option,Omit"); return true; } if (22 == nOption) { Info("Set FPD {$} Correction Option: PostOffset+All", nPanelID); } else { Info("Set FPD {$} Correction Option: {$}", nPanelID, nOption); } IRayCmdParam param[1]; param[0].var.vt = IVT_INT; param[0].var.val.nVal = nOption; FPDRESULT result = IrayFnInvoke(nPanelID, Cmd_SetCorrectOption, param, 1); //Cmd_SetCorrectOption if (TestError(nDetectorID, result)) { Fatal("Call SetCorrectionOption Failed"); return false; } //加载校正策略,多状态(初始化、重连、校正正常或错误结束)都调用。 if (WaitRespond(10000)) { Info("SetCorrectionOption Success"); } else { Fatal("SetCorrectionOption 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; } if (WaitRespond(10000)) //加载校正策略 { Info("SetCorrectionOption Success"); } else { Fatal("SetCorrectionOption Failed"); return false; } return true; } //将设置的各项参数,实际写入探测器端,生效 bool IRayCtrl::WriteRom(int nDetectorID) { Info("Call Cmd_WriteUserROM"); int nPanelID = nDetectorID; FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_WriteUserROM, NULL, 0); if (TestError(nPanelID, nResult)) { return false; } bool bResult = WaitRespond(80 * 1000); if (bResult) { } else { Fatal("Cmd_WriteUserROM Timeout"); return false; } return true; } bool IRayCtrl::GetROMInfo(int nDetectorID) { int nPanelIndex = nDetectorID + 1; char szSerialNo[64] = { 0 }; string strSNo = ""; if (GetSerialNo(nPanelIndex, szSerialNo)) { strSNo = (szSerialNo); Info("Panel {$} SN:{$}", nPanelIndex, strSNo.c_str()); m_stDeviceIndex[nDetectorID].strPanelSerial = strSNo.c_str(); m_stDeviceIndex[nDetectorID].strPartNumber = strSNo.substr(0, 6).c_str(); string strDC = "20"; strDC = strDC + strSNo.substr(13, 2) + strSNo.substr(9, 2) + strSNo.substr(11, 2); m_stDeviceIndex[nDetectorID].strDateCode = strDC.c_str(); ConfFeedback(EVT_CONF_PANEL_SERIAL, nDetectorID, m_stDeviceIndex[nDetectorID].strPanelSerial.c_str()); ConfFeedback(EVT_CONF_DATECODE, nDetectorID, strDC.c_str()); ConfFeedback(EVT_CONF_PART_NUMBER, nDetectorID, m_stDeviceIndex[nDetectorID].strPartNumber.c_str()); } else { Error("Get SN Failed"); } Info("PartNumber:{$},DateCode:{$}", m_stDeviceIndex[nDetectorID].strPartNumber.c_str(), m_stDeviceIndex[nDetectorID].strDateCode.c_str()); int nProductNo = 0; if (GetProductNo(nPanelIndex, nProductNo)) { Info("Panel {$} ProductNo:{$}", nPanelIndex, nProductNo); } else { Error("Get ProductNo Failed"); } { m_stDeviceIndex[nDetectorID].bWireless = true; } char szBatterySN[256] = { 0 }; if (GetBatterySN(nPanelIndex, szBatterySN)) { Info("Panel {$} BatterySN:{$}", nPanelIndex, szBatterySN); ConfFeedback(EVT_CONF_BATTERY_SN, nDetectorID, szBatterySN); } else { Info("Get BatterySN Failed."); } if (ReadBatteryStatus(nDetectorID)) //先查询个电量,固件升级需要 { CheckBattery(nDetectorID); } char szMainVersion[256] = { 0 }; if (GetMainVersion(nPanelIndex, szMainVersion)) { string strMainV = (szMainVersion); Info("Panel {$} MainVersion:{$}", nPanelIndex, strMainV.c_str()); } else { Error("Get MainVersion Failed"); } char szReadVersion[256] = { 0 }; if (GetReadVersion(nPanelIndex, szReadVersion)) { string strRV = (szReadVersion); Info("Panel {$} ReadVersion:{$}", nPanelIndex, strRV.c_str()); } else { Error("Get ReadVersion Failed"); } char szMcuVersion[256] = { 0 }; if (GetMcuVersion(nPanelIndex, szMcuVersion)) { string strMcuV = (szMcuVersion); Info("Panel {$} McuVersion:{$}", nPanelIndex, strMcuV.c_str()); } else { Error("Get McuVersion Failed"); } char szArmVersion[256] = { 0 }; if (GetArmVersion(nPanelIndex, szArmVersion)) { string strArmV = (szArmVersion); m_stDeviceIndex[nDetectorID].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"); } char szKernalVersion[256] = { 0 }; if (GetKernelVersion(nPanelIndex, szKernalVersion)) { string strKernalV = (szKernalVersion); Info("Panel {$} KernelVersion:{$}", nPanelIndex, strKernalV.c_str()); } else { Error("Get KernelVersion Failed"); } return true; } int IRayCtrl::SetSyncMode(int nDetectorID, int nSetSyncMode) { int nPanelID = nDetectorID + 1; 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 { Info("Same Sync Mode,Omit"); return E_IRAY_SYNCMODE_NOCHANGE; } } int IRayCtrl::SetInnerSubFlow(int nDetectorID, int nSetInnerSubFlow) { int nPanelID = nDetectorID + 1; int nInnerSubFlow = 0; if (GetInnerSubFlow(nPanelID, nInnerSubFlow)) { Info("Current InnerSubFlow is {$}", InnerSubFlow[nInnerSubFlow]); if (nInnerSubFlow != nSetInnerSubFlow) { Info("Set InnerSubFlow to {$}", InnerSubFlow[nSetInnerSubFlow]); if (!WaitReady(nPanelID, 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; } } else { Fatal("Get InnerSubFlow Failed"); return E_IRAY_SYNCMODE_SETFAILED; } return E_IRAY_SYNCMODE_CHANGED; } int IRayCtrl::SetCapModeFunc(int nDetectorID, int nSetCapMode) { int nPanelID = nDetectorID + 1; 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 + 1; 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, string strFPDType, int nTriggerMode) { Info("Set detector work mode: {$} trigger mode: {$}", strFPDType, nTriggerMode); int nModeChanged = 0; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)nTriggerMode; if ((strFPDType.find("Mars") != std::string::npos) && (strFPDType.find("X") != std::string::npos)) { if (TRIGGER_SOFT == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Soft); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER2 == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_CycleAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else if (TRIGGER_FREESYNC == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_FreeSync); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else if (TRIGGER_PREP == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Prep); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_On, Enm_Off); } else { Warn("Undefined trigger mode!"); } } else if ((strFPDType.find("Mars") != std::string::npos) && (strFPDType.find("V3") != std::string::npos)) { if (TRIGGER_SOFT == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Soft); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER2 == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_CycleAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else if (TRIGGER_FREESYNC == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_FreeSync); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else if (TRIGGER_PREP == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Prep); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_Acq2); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_On, Enm_Off); } else { Warn("Undefined trigger mode!"); } } else if (strFPDType.find("Luna") != std::string::npos) { if (TRIGGER_SOFT == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Soft); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_FREESYNC == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_FreeSync); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else { Warn("Undefined trigger mode!"); } } else if (strFPDType.find("Venu") != std::string::npos) { if (TRIGGER_SOFT == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Soft); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_INNER == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Inner); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_On); } else if (TRIGGER_FREESYNC == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_FreeSync); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_ClearAcq); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_Off, Enm_Off); } else if (TRIGGER_PREP == nTempTriggerMode) { nModeChanged = SetSyncMode(nDetectorID, Enm_TriggerMode_Prep); nModeChanged |= SetInnerSubFlow(nDetectorID, Enm_InnerSubFlow_ClearAcq); nModeChanged |= SetCapModeFunc(nDetectorID, Enm_PrepCapMode_Acq2); nModeChanged |= SetFPDCalParam(nDetectorID, Enm_On, Enm_Off); } else { Warn("Undefined trigger mode!"); } } if (nModeChanged == E_IRAY_SYNCMODE_CHANGED) { ClearCorrection(nDetectorID); WriteRom(nDetectorID + 1); } 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()); 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) { return false; } //----------------------------------------------------------------------------- // 更新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_nDetectorIndex; 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[nDetectorID].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[nDetectorID].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[nDetectorID].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[nDetectorID].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[nDetectorID].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) { return true; } //上传user edit defect文件,到探测器端 bool IRayCtrl::DownloadUserDefectFileToFD(bool bLTE) { return true; } //从探测器端读取Sensitivity和校正报告文件 //下载到CalibrationData目录 bool IRayCtrl::ReadCumstomFile(int nDetectorID) { return true; } //上传校正报告和Sensitivity文件到FD端, //Cmd_WriteCustomFile 的参数为文件所在的Folder bool IRayCtrl::WriteCumstomFile(int nDetectorID) { int nPanelIndex = nDetectorID + 1; if (!m_stDeviceIndex[nDetectorID].bWireless) { Error("Omit WriteCustomFile"); return false; } if (!WaitReady(nPanelIndex, 5000)) { Error("Detector isn't Ready"); return false; } string strFilePath = g_strAppPath + "references\\" + m_stDeviceIndex[nDetectorID].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[nDetectorID].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[nDetectorID].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 ((nsDPC::FPDDeviceIRay*)(*m_pPanelID2DPC)[nDetectorID])->GetCalibrationTime(bExpMode); } ////从探测器上下载文件: //Gain文件,defect文件,sensitivity,校正报告文件; bool IRayCtrl::DownloadfromDetector(int nDetectorID) { return true; } // 从SDK指定目录拷贝失败的校正文件到CalibrationFailedData中 bool IRayCtrl::SaveFailedCalibFiles(int nDetectorID, bool bExpMode) { return true; } bool IRayCtrl::BackupCalibFiles(int nDetectorID, bool bBackupOrRestore, bool bExpMode) { return true; } bool IRayCtrl::CleanCalibFiles(int nDetectorID, bool bExpMode) { return true; } bool IRayCtrl::CleanCalibReport(int nDetectorID, bool bExpMode) { return true; } // 从CalibrationData中恢复校正报告文件 bool IRayCtrl::RestoreCalibReport(int nDetectorID, bool bExpMode) { return true; } // 从CalibrationData中恢复Sensitivity文件 bool IRayCtrl::RestoreSensitivity(int nDetectorID) { return true; } //----------------------------------------------------------------------------- // 通过 Cmd_QueryLastImageID 检查探测器中是否有未传输成功的图像 //该指令,SDK会返回 Evt_LastImageID ,从该Event 知道图像是否传输成功 //----------------------------------------------------------------------------- bool IRayCtrl::CheckLastImageStatus(int nDetectorID) { ResetLock(); int nPanelID = nDetectorID + 1; 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[nDetectorID].bImagePending) { 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; 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; } 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 nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) { if (!m_stDeviceIndex[nDetectorID].bWireless) { Error("Omit reconnection in fixed FD"); } else { DisconnectFD(nDetectorID); StartInitFPDThread(); } } return true; } void IRayCtrl::OnProcessPreImg() { if (m_bPreviewEnable) { DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pwPreviewImg); } } void IRayCtrl::OnProcessImg() { if (m_nSaveRaw) { SaveRawImage("0_Original.raw", m_pImgBuffer, m_nImageWidth, m_nImageHeight); } if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { Debug("Begin get effect image, m_nRawImgWidth {$}\n", m_nRawImgWidth); if (!GetEffectiveImage(m_pImgBuffer, m_pwRawImageData, m_nRawImgWidth)) { Error("Get effect image failed"); return; } if (m_nSaveRaw) { SaveRawImage("1_After_Crop.raw", m_pImgBuffer, m_nImageWidth, m_nImageHeight); } Debug("Get effect image over"); } else { memcpy(m_pImgBuffer, m_pwRawImageData, m_nImageHeight * m_nImageWidth * sizeof(WORD)); } if (m_nCalibrationMode) //iRay校正 { //跳过 } else if (APP_STATUS_CAL_BEGIN != m_eAppStatus) { Info("Apply ZSKK Reference"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); if (m_nSaveRaw) { SaveRawImage("2_After_Reference.raw", m_pImgBuffer, m_nImageWidth, m_nImageHeight); } } if (APP_STATUS_CAL_BEGIN == m_eAppStatus && m_nSaveRaw) { string strImageName = "Calibration_Image_" + to_string(m_nCalibCurrentCalibrationRound) + "_" + to_string(m_nCalibCurrentExposureIndex) + ".raw"; SaveRawImage(strImageName.c_str(), m_pImgBuffer, m_nImageWidth, m_nImageHeight); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); if ((TRIGGER_INNER2 == m_stDeviceIndex[m_nDetectorIndex].nSyncMode) || (TRIGGER_FREESYNC == m_stDeviceIndex[m_nDetectorIndex].nSyncMode)) { StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_OFF); } StartXWindowOffThread(); } // 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 = pCurPanel->m_nStatusPeriod; while (true) { DWORD dwResult = WaitForSingleObject(pCurPanel->m_hEndHWStatusThreadEvent, dwTimer); if (dwResult == WAIT_OBJECT_0) { break; } else { pCurPanel->GetHardwareStatus(); } } CloseHandle(pCurPanel->m_hEndHWStatusThreadEvent); SetEvent(pCurPanel->m_hHWStatusThreadEndEvent); Info("HardwareStatusThread stop"); return true; } bool IRayCtrl::GetHardwareStatus() { if (m_bInExposure) { Info("In Exposuring,omit check hw status"); return true; } for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++) { if (!GetConnectionStatus(nDetectorID)) // 如果检测到平板探测器失去连接,那么要通知DROC { Info("FD {$} is communication error", nDetectorID); m_stDeviceIndex[nDetectorID].bConnectStatus = false; ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nDetectorID); } else if (m_stDeviceIndex[nDetectorID].bConnectStatus && !m_bInCalibrating && !m_bInExposure && !m_bSetCorrectFile) { Info("Check FPD {$} Status", nDetectorID); bool bResult = true; if (m_stDeviceIndex[nDetectorID].bConnectChanged) { m_stDeviceIndex[nDetectorID].bConnectChanged = false; //ReadTempStatus(nDetectorID); CheckLastImageStatus(nDetectorID); } bResult = CheckBattery(nDetectorID, false); bResult = CheckWiFi(nDetectorID, false) && bResult; bResult = CheckTemperature(nDetectorID) && bResult; } else if (m_stDeviceIndex[nDetectorID].bConnectStatus) { if (m_stDeviceIndex[nDetectorID].bConnectChanged) { m_stDeviceIndex[nDetectorID].bConnectChanged = false; } } } return true; } bool IRayCtrl::GetConnectionStatus(int nDetectorID) { CString strLog = L""; int nConnStates = Enm_ConnState_Unknown; int nPanelID = m_nDetectorIndex + 1; if (GetConnState(nPanelID, 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"; Info("UploadCalibrationFiles over"); return true; } //解析Defect校正文件,并生成ZSKK defect map int IRayCtrl::ParseDefectFile(int nPanelIndex, bool bExpMode, bool bManualDefect) { string strPath = m_stDeviceIndex[nPanelIndex].strWorkDir; if (!m_stDeviceIndex[nPanelIndex].bWireless) { strPath = m_stDeviceIndex[nPanelIndex].strFPDConfFilePath; } string strExpMode = "STE"; Info("{$}", strPath.c_str()); if (!PathFileExists(strPath.c_str())) { Error("Defect Calibration File isn't Existed"); return 0; } Info("Begin to Create Defect Map"); return 0; } //解析完defect文件,关闭解析函数 bool IRayCtrl::CloseDefectTemplateFile(void* pHandler) { FPDRESULT nResult = m_pfCloseDefectTemplateFile(pHandler); if (TestError(m_nDetectorIndex, nResult)) { Error("CloseDefectTemplateFile Failed"); return false; } else { Info("CloseDefectTemplateFile Success"); 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 + "\\rawdata\\" + pImgName; FILE* fp; if ((fp = fopen(strImagePath.c_str(), "wb")) == NULL) { DWORD dw = GetLastError(); Error("fopen {$} failed, {$}", strImagePath.c_str(), dw); return false; } fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp); fclose(fp); Info("End to Save Raw Image"); return true; } //设置同步模式 bool IRayCtrl::ActiveSyncMode(nsDPC::FPDDeviceIRay* pDrvDPC, int nSyncMode) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex) { Warn("Not current DPC, return"); return false; } if (m_stDeviceIndex[m_nDetectorIndex].nSyncMode == nSyncMode) { Info("Same sync mode, omit set sync mode"); return true; } const char* szDetectorID = m_stDeviceIndex[m_nDetectorIndex].strDetectorModel.c_str(); if (SetDetectorWorkMode(m_nDetectorIndex, szDetectorID, nSyncMode)) { m_stDeviceIndex[m_nDetectorIndex].nSyncMode = nSyncMode; Info("Set detector sync mode into {$}", nSyncMode); } else { Error("Set detector sync mode failed!"); } return true; } /*** * 设置校正点数 ***/ bool IRayCtrl::SetReferenceNum(int nReferenceNum) { m_nCalibrationRounds = nReferenceNum; Info("Set reference number: {$}", m_nCalibrationRounds); return true; } /*终止指令*/ bool IRayCtrl::CancelOperation() { Info("CancelOperation"); if (m_bInExposure) { int nPanelID = m_nDetectorIndex + 1; IRAY_TRIGGER_MODE nTempTriggerMode = (IRAY_TRIGGER_MODE)m_stDeviceIndex[m_nDetectorIndex].nSyncMode; if (TRIGGER_SOFT == nTempTriggerMode) //软同步 { Info("Software sync mode"); } else if (TRIGGER_INNER == nTempTriggerMode) //手动同步 { Info("Inner Call Cmd_StopAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StopAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StopAcq Failed"); } else { Info("Cmd_StopAcq over"); } } else if (TRIGGER_INNER2 == nTempTriggerMode) //自动inner2同步 { Info("Inner2 Call Cmd_StopAcq"); FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_StopAcq, NULL, 0); if (TestError(nPanelID, nResult)) { Error("Invoke Cmd_StopAcq Failed"); } else { Info("Cmd_StopAcq over"); } } else if (TRIGGER_FREESYNC == nTempTriggerMode) //Free同步 { Info("Free sync mode"); } else if (TRIGGER_PREP == nTempTriggerMode) //软同步或者AED { Info("Prep sync mode"); } else { Error("The detector get undefined sync mode"); return RET_STATUS::RET_FAILED; } m_bInExposure = false; } Info("Call m_pfAbort"); int ret = m_pfAbort(m_nDetectorIndex + 1); if (TestError(m_nDetectorIndex, ret, false)) { Info("Abort Cmd Failed"); m_bCalibResultFailed = false; return false; } if (WaitRespond(1000)) // Evt_TaskResult_Canceled { Info("Abort Calibration Success"); } else { Error("Abort Calibration Timeout"); } return true; }