#include "stdafx.h" #include "Detector_CareRayDR.h" #include "CCOS.Dev.FPD.CareRayDR.h" #include "MyPingip.h" Detector_CareRayDR* g_pDetector = nullptr; extern Log4CPP::Logger* gLogger; #define LOAD_PROC_ADDRESS(handle,func) \ if ((API_##func = (CB_##func)GetProcAddress(handle, #func)) == NULL) \ { \ FERROR("Error occurs while loading entry point!!! {$}", #func);\ }\ const int nBuffSize = 1024 * 1024 * 64; const int FLUORO_IMAGE_HEADER_SIZE = 256; void __stdcall CREventCallback(int eventID, Event * eventData) { if (nullptr != g_pDetector) { g_pDetector->CallBackEvent(eventID, eventData); } } Detector_CareRayDR::Detector_CareRayDR() { m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); m_nPanelCount = 0; m_nCurrentPanelID = 0; m_nCurrentDetectorType = Unkown_Type; m_hCareRayDRModule = nullptr; m_nSyncMode = SYNC_SOFTWARE; m_nSdkSyncMode = UNDEF_SYNC; m_pRawImgBuffer = nullptr; m_pPreImgBuffer = nullptr; m_pImgBuffer = nullptr; m_nImageWidth = 0; m_nImageHeight = 0; m_nWidthOffset = 0; m_nHeightOffset = 0; m_nRawImgWidth = 0; m_nRawImgHeight = 0; m_nPreviewEnable = 0; m_nPreImgWidth = 0; m_nPreImgHeight = 0; m_nAppStatus = APP_STATUS_IDLE; m_nSaveRaw = 0; m_bCancelFlag = false; m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; m_nImageSize = 0; m_nXwindow = 2000; m_nDelayTime = 100; m_nWaitTime = 5; m_nCheckMode = CheckMode::MODE_UNDEFINED; m_nCurrentLogicMode = AcqMode::NONE; m_nLastCheckMode = CheckMode::MODE_UNDEFINED; m_bFetchable = false; m_nCalibrationMode = CCOS_CALIBRATION_MODE_ZSKK; m_pFluFrameData = nullptr; m_nFluLastExpStatus = -1; m_nFluCurrentExpStatus = 0; m_nMaxFrameId = 0; m_nReceivedFrameId = 0; m_nCalibrationRounds = 0; m_nCalibCurrentCalibrationRound = 0; m_nCalibCurrentExposureIndex = 0; m_nExposureNumCurrentRound = 0; m_pZSKKCalib = nullptr; m_strDetectorType = ""; m_bGetImageByCallBack = false; m_nNotifyStatusTimePeriod = 10000;//默认10秒推一次 m_nReconnectTimePeriod = 5000; m_hRespond = CreateEvent(NULL, FALSE, FALSE, NULL); m_hStopScanEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hAcqEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hProcessImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hXWinOnEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hDarkEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hGainEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hInitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hStopScanEvent; m_hArrayEvent[1] = m_hAcqEvent; m_hArrayEvent[2] = m_hProcessImgEvent; m_hArrayEvent[3] = m_hXWinOnEvent; m_hArrayEvent[4] = m_hDarkEvent; m_hArrayEvent[5] = m_hGainEvent; m_hArrayEvent[6] = m_hInitEvent; m_hToggleEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hFPDScanThread = nullptr; m_hFPDStatusThread = nullptr; m_bExit = false; m_hReconnectThread = nullptr; InitSdkInterface(); } void Detector_CareRayDR::InitSdkInterface() { API_CR_connect_detector = nullptr; API_CR_disconnect_detector = nullptr; API_CR_reset_detector = nullptr; API_CR_set_check_mode = nullptr; API_CR_set_sync_mode = nullptr; API_CR_set_cycle_time = nullptr; API_CR_set_normal_power = nullptr; API_CR_set_save_power = nullptr; API_CR_permit_exposure = nullptr; API_CR_start_acq_full_image = nullptr; API_CR_start_acq_dark_full_image = nullptr; API_CR_start_acq_prev_image = nullptr; API_CR_start_acq_dark_prev = nullptr; API_CR_start_acq_def_image = nullptr; API_CR_start_acq_fluoro_image = nullptr; API_CR_start_acq_fluoro_dark_image = nullptr; API_CR_stop_acq_frame = nullptr; API_CR_stop_acq_frame_cleanup = nullptr; API_CR_set_user_correction = nullptr; API_CR_get_user_correction = nullptr; API_CR_set_dose = nullptr; API_CR_get_active_detector_ID = nullptr; API_CR_set_active_detector = nullptr; API_CR_get_dual_detector_state = nullptr; API_CR_set_smart_hand_switch = nullptr; API_CR_get_SHS_status = nullptr; API_CR_get_wireless_ip = nullptr; API_CR_set_wireless_ip = nullptr; API_CR_get_station_mode_conf = nullptr; API_CR_set_station_mode_conf = nullptr; API_CR_get_temperature_cal_data = nullptr; API_CR_check_temperature_slot = nullptr; API_CR_get_API_Version = nullptr; API_CR_get_conn_state = nullptr; API_CR_get_detector_type = nullptr; API_CR_get_detector_info = nullptr; API_CR_get_mode_info = nullptr; API_CR_get_status_info = nullptr; API_CR_get_status_info_Ex = nullptr; API_CR_get_image_attr = nullptr; API_CR_get_image = nullptr; API_CR_get_preview_image = nullptr; API_CR_get_unuploaded_img_info = nullptr; API_CR_query_prog_info = nullptr; API_CR_inpaint_bad_pixels = nullptr; API_CR_select_cal_type = nullptr; API_CR_get_cal_params = nullptr; API_CR_set_offset_correction = nullptr; API_CR_cal_offset = nullptr; API_CR_linear_calibration = nullptr; API_CR_portable_calibration = nullptr; API_CR_execute_linear_cal = nullptr; API_CR_execute_portable_cal = nullptr; API_CR_stop_cal_procedure = nullptr; API_CR_start_fluoro_calibration = nullptr; API_CR_query_calibration_status = nullptr; API_CR_do_gridpattern_filtration = nullptr; API_CR_register_callback = nullptr; API_CR_send_exp_request = nullptr; API_CR_ready_state_request = nullptr; API_CR_start_soft_acquisition = nullptr; API_CR_set_AEC_integ_time = nullptr; API_CR_register_AEC_callback = nullptr; API_CR_start_AEC_acquire_process = nullptr; API_CR_get_one_key_cal = nullptr; API_CR_check_img_for_factory_cal = nullptr; API_CR_download_factory_cal_files = nullptr; API_CR_execute_one_key_cal = nullptr; API_CR_start_acq_NDT_dark_image = nullptr; API_CR_execute_NDT_CAL = nullptr; API_CR_correct_NDT_image = nullptr; API_CR_set_NDT_frame_num = nullptr; API_CR_finish_NDT_acquisition = nullptr; API_CR_check_NDT_CAL_Files = nullptr; } Detector_CareRayDR::~Detector_CareRayDR() { if (m_hStopScanEvent) { CloseHandle(m_hStopScanEvent); m_hStopScanEvent = nullptr; } if (m_hAcqEvent) { CloseHandle(m_hAcqEvent); m_hAcqEvent = nullptr; } if (m_hGainEvent) { CloseHandle(m_hGainEvent); m_hGainEvent = nullptr; } if (m_hDarkEvent) { CloseHandle(m_hDarkEvent); m_hDarkEvent = nullptr; } if (m_hRespond) { CloseHandle(m_hRespond); m_hRespond = nullptr; } if (m_hToggleEvent) { CloseHandle(m_hToggleEvent); m_hToggleEvent = nullptr; } if (m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } if (m_pPreImgBuffer) { delete[]m_pPreImgBuffer; m_pPreImgBuffer = nullptr; } if (m_pImgBuffer) { delete[]m_pImgBuffer; m_pImgBuffer = nullptr; } if (m_pDarkImage) { delete[]m_pDarkImage; m_pDarkImage = nullptr; } if (m_pFluFrameData) { delete[] m_pFluFrameData; m_pFluFrameData = nullptr; } if (m_pZSKKCalib) { delete m_pZSKKCalib; m_pZSKKCalib = nullptr; } if (m_hFPDScanThread) { CloseHandle(m_hFPDScanThread); m_hFPDScanThread = nullptr; } if (m_hFPDStatusThread) { CloseHandle(m_hFPDStatusThread); m_hFPDStatusThread = nullptr; } if (m_hReconnectThread) { CloseHandle(m_hReconnectThread); m_hReconnectThread = nullptr; } } bool Detector_CareRayDR::DriverEntry(FPDDeviceCareRay* pDrvDPC, ResDataObject& Configuration) { printf("======== DriverEntry %p\n", pDrvDPC); FINFO("======== DriverEntry {$}", pDrvDPC); map::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC); if (DPCsIter != m_pDPC2PanelID->end()) { printf("This DPC already exist\n"); FERROR("This DPC already exist"); return false; } CPanelStatus* p = new CPanelStatus(); m_pStPanelStatus[m_nPanelCount] = p; m_pDPC2PanelID->insert(pair(pDrvDPC, m_nPanelCount)); m_pPanelID2DPC->insert(pair(m_nPanelCount, pDrvDPC)); m_nPanelCount++; m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储 //FINFO("Config: {$}", m_ModeConfig.encode()); try { m_nCalibrationMode = (CCOS_CALIBRATION_MODE)(int)m_ModeConfig["CalibMode"]; m_nNotifyStatusTimePeriod = (int)m_ModeConfig["NotifyStatusTimePeriod"]; m_nReconnectTimePeriod = (int)m_ModeConfig["ReConnectTimePeriod"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); } if (!m_pZSKKCalib) { m_pZSKKCalib = new CZSKKCalibrationCtrl(); } if (nullptr == m_hFPDScanThread) { unsigned uThreadId; _beginthreadex(NULL, 0, onFPDScanThread, this, 0, &uThreadId); m_hFPDScanThread = OpenThread(THREAD_ALL_ACCESS, TRUE, uThreadId); } SetEvent(m_hInitEvent); return true; } bool Detector_CareRayDR::Connect(FPDDeviceCareRay* pDrvDPC, const char* szWorkPath) { FINFO("======== Connect detector begin"); printf("======== Connect detector begin \r\n"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { FINFO("Not current DPC, return true"); printf("Not current DPC, return true \r\n"); return true; } FINFO("szWorkPath:{$}", szWorkPath); m_strCtrlWorkPath = szWorkPath; bool bRet = ConnectDetector(); if (!bRet) { return false; } FINFO("======== Connect over"); printf("======== Connect over \r\n"); return true; } void Detector_CareRayDR::EnterExamMode(int nExamMode) { switch (nExamMode) { case APP_STATUS_WORK_BEGIN: FINFO("Enter into Exam Windows"); m_nAppStatus = APP_STATUS_WORK_BEGIN; break; case APP_STATUS_WORK_END: FINFO("Quit Exam Windows"); m_nAppStatus = APP_STATUS_WORK_END; break; case APP_STATUS_DETSHARE_BEGIN: FINFO("Enter into Detector Share Windows"); m_nAppStatus = APP_STATUS_DETSHARE_BEGIN; break; case APP_STATUS_DETSHAR_END: m_nAppStatus = APP_STATUS_IDLE; FINFO("Quit Detector Share Windows"); m_nAppStatus = APP_STATUS_DETSHAR_END; break; case APP_STATUS_CAL_BEGIN: FINFO("Enter into Calibration Windows"); m_nAppStatus = APP_STATUS_CAL_BEGIN; break; case APP_STATUS_CAL_END: FINFO("Quit Calibration Windows"); m_nAppStatus = APP_STATUS_CAL_END; break; case APP_STATUS_WORK_IN_SENSITIVITY: FINFO("Enter into sensitivity test interface"); m_nAppStatus = APP_STATUS_WORK_IN_SENSITIVITY; break; default: break; } if (nExamMode == APP_STATUS_WORK_END || nExamMode == APP_STATUS_CAL_END) { m_bCancelFlag = true; //退出检查界面,停止查询 prog info m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Standby; } } /*** ** 根据采集模式申请图像buffer ***/ bool Detector_CareRayDR::SetAcqMode(int nMode) { FINFO("======== Detector_CareRayDR::SetAcqMode mode:{$}", nMode); if (m_nCurrentLogicMode == nMode) { FINFO("Same acq mode,return"); return true; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } try { int nModeCount = (int)m_ModeConfig["ModeTable"].size(); for (int i = 0; i < nModeCount; i++) { int nAppModeID = (int)m_ModeConfig["ModeTable"][i]["LogicMode"]; if (nAppModeID == nMode) { //设置采集模式,根据不同的场景设置不同的采集模式 if (nMode == AcqMode::RAD) { m_nCheckMode = CheckMode::MODE_RAD; } else if (nMode == AcqMode::DUALENERGY) { m_nCheckMode = CheckMode::MODE_DUAL_ENERGY; } else if (nMode == AcqMode::DDR) { //MODE_FLU_ROI_A_BIN11 = 0x1B, //1280 x 1280, 1-bin 这俩当时测试的时候有问题,故先用 MODE_FLU_FULLSIZE_BIN22 //MODE_FLU_ROI_A_BIN22 = 0x1C, //640 x 640, 2-bin m_nCheckMode = CheckMode::MODE_FLU_FULLSIZE_BIN22;//1408 x 1152, 2-bin } m_nImageWidth = (int)m_ModeConfig["ModeTable"][i]["ImageWidth"]; m_nImageHeight = (int)m_ModeConfig["ModeTable"][i]["ImageHeight"]; m_nWidthOffset = (int)m_ModeConfig["ModeTable"][i]["WidthOffset"]; m_nHeightOffset = (int)m_ModeConfig["ModeTable"][i]["HeightOffset"]; FINFO("After crop image width: {$}, height: {$}, WidthOffset: {$}, HeightOffset: {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset); m_nPreviewEnable = (int)m_ModeConfig["ModeTable"][i]["PreviewEnable"]; m_nPreImgWidth = (int)m_ModeConfig["ModeTable"][i]["PreviewWidth"]; m_nPreImgHeight = (int)m_ModeConfig["ModeTable"][i]["PreviewHeight"]; FINFO("m_nPreviewEnable:{$},m_nPreImgWidth:{$},m_nPreImgHeight:{$}", m_nPreviewEnable, m_nPreImgWidth, m_nPreImgHeight); if (nullptr != m_pImgBuffer) { delete[] m_pImgBuffer; m_pImgBuffer = nullptr; } m_pImgBuffer = new WORD[m_nImageWidth * m_nImageHeight]; if (m_nPreviewEnable) { if (nullptr != m_pPreImgBuffer) { delete[] m_pPreImgBuffer; m_pPreImgBuffer = nullptr; } m_pPreImgBuffer = new WORD[m_nPreImgWidth * m_nPreImgHeight]; } m_nXwindow = (int)m_ModeConfig["ModeTable"][i]["XWindow"]; m_nDelayTime = (int)m_ModeConfig["ModeTable"][i]["DelayTime"]; m_nWaitTime = (int)m_ModeConfig["ModeTable"][i]["WaitTime"]; m_nSaveRaw = (int)m_ModeConfig["ModeTable"][i]["IsSaveRaw"]; FINFO("m_nXwindow:{$},m_nDelayTime:{$},m_nWaitTime:{$},m_nSaveRaw:{$}", m_nXwindow, m_nDelayTime, m_nWaitTime, m_nSaveRaw); m_nCurrentLogicMode = nMode; break; } } } catch (ResDataObjectExption& e) { FERROR("Get config error: {$}", e.what()); return false; } return true; } bool Detector_CareRayDR::SetSyncMode(int nSyncMode) { FINFO("======== Detector_CareRayDR::SetSyncMode nSyncMode:{$}", nSyncMode); m_nSyncMode = nSyncMode; switch (m_nSyncMode) { case SYNC_MANUAL: m_nSdkSyncMode = MANUAL_SYNC; break; case SYNC_SOFTWARE: m_nSdkSyncMode = SOFT_SYNC; break; case SYNC_HARDWARE: m_nSdkSyncMode = EXT_SYNC; break; case SYNC_AED: m_nSdkSyncMode = AED_SYNC; break; case SYNC_HARDWARE_DIRECT: m_nSdkSyncMode = EXT_SYNC; break; default: FERROR("Invalid Sync Mode!"); return false; } m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)m_nSyncMode; return true; } bool Detector_CareRayDR::PrepareAcquisition(FPDDeviceCareRay* pDrvDPC) { FINFO("======== PrepareAcquisition start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } //未初始化、未连接 不执行 if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } FINFO("Call API_CR_set_check_mode m_nCheckMode:{$}", m_nCheckMode); int nRet = API_CR_set_check_mode(m_nCheckMode); if (TestError(nRet, "API_CR_set_check_mode")) { FERROR("Set check mode failed"); return false; } if (ShowModeInfo() != CR_NO_ERR) { return false; } FINFO("PrepareAcquisition m_nSdkSyncMode:{$}", m_nSdkSyncMode); if (!SetSdkSyncModeAndTime(m_nSdkSyncMode)) { return false; } //根据校正配置,加载不同的校正文件 if (pDrvDPC->m_stDeviceConfig.nCalibMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("ZSKK calibration file"); } else { FINFO("Manufacture calibration file"); SetUserCorrection(true); } FINFO("Call set normal power"); nRet = API_CR_set_normal_power();//切换到高功耗模式 if (TestError(nRet, "API_CR_set_normal_power")) { FERROR("Set normal power failed"); return false; } m_bCancelFlag = false; //准备采集前恢复初值 //AED就提前开始采集,软同步在StartAcquisition再开始采集 if (m_nCurrentLogicMode == AcqMode::RAD && m_nSdkSyncMode == AED_SYNC) { SetEvent(m_hAcqEvent);//PrepareAcquisition m_bGetImageByCallBack = false; } if (m_nCurrentLogicMode == AcqMode::RAD && m_nSdkSyncMode == SOFT_SYNC) { //开始采集后如果不及时曝光探测器就自动推暗场图,故需要在这里通知一个假ready StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); m_bGetImageByCallBack = true; } if (m_nCurrentLogicMode == AcqMode::DUALENERGY && m_nSdkSyncMode == SOFT_SYNC) { StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); m_bGetImageByCallBack = false; } if (m_nCurrentLogicMode == AcqMode::DDR && m_nSdkSyncMode == AED_SYNC) { SetEvent(m_hAcqEvent);//PrepareAcquisition m_bGetImageByCallBack = false; } FINFO("m_bGetImageByCallBack:{$}", m_bGetImageByCallBack); m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Work; m_nLastCheckMode = m_nCheckMode; FINFO("======== PrepareAcquisition end"); return true; } bool Detector_CareRayDR::StartAcquisition(FPDDeviceCareRay* pDrvDPC) { FINFO("======== StartAcquisition start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } //未初始化、未连接 不执行 if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } //软同步在这里开始,AED在Prepare时就开始 if (m_nSdkSyncMode == SOFT_SYNC) { SetEvent(m_hAcqEvent);//StartAcquisition } m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Acquire; FINFO("======== StartAcquisition end"); return true; } bool Detector_CareRayDR::StopAcquisition(FPDDeviceCareRay* pDrvDPC) { FINFO("======== StopAcquisition start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } m_bCancelFlag = true;//StopAcquisition int nRet = -1; if (m_nLastCheckMode >= CheckMode::MODE_FLU_ROI_A_BIN11) { FINFO("Call stop acq frame cleanup"); nRet = API_CR_stop_acq_frame_cleanup(); //用于停止曝光流程 if (TestError(nRet, "API_CR_stop_acq_frame_cleanup")) { FERROR("Stop acq frame cleanup failed!"); return false; } } else { //双能不调用停止采集接口 if (m_nCheckMode == CheckMode::MODE_DUAL_ENERGY) { FINFO("DualEnergy don't call stop acq frame,just set save power"); } else { FINFO("Call stop acq frame"); nRet = API_CR_stop_acq_frame(); //用于停止曝光流程 if (TestError(nRet, "API_CR_stop_acq_frame")) { FERROR("Stop acq frame failed!"); return false; } } } FINFO("Call set save power"); nRet = API_CR_set_save_power(); if (TestError(nRet, "API_CR_set_save_power")) { FERROR("Set save power failed"); return false; } m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Standby; FINFO("======== StopAcquisition end"); return true; } bool Detector_CareRayDR::ActiveCalibration(FPDDeviceCareRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType) { FINFO("======== ActiveCalibration start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); m_nAppStatus = APP_STATUS_CAL_BEGIN; //激活校正,置为校正界面 m_eCaliType = eType; if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("Active Dark Calibration"); } if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("Active Xray Calibration"); if (m_nCalibrationMode) //厂商校正ActiveCalibration { } else //ZSKK校正 { if (!m_pZSKKCalib) { FERROR("ZSKK Calibration object is undefined"); } else { //加载ZSKK的校正文件 m_pZSKKCalib->m_strRawImgPath = m_strCtrlWorkPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = m_strCtrlWorkPath + "\\references\\"; m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight; m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds; m_pZSKKCalib->m_nSaturationValue = 50000; //LoadZSKKGainMap 参数为false,意思是开始增益校正 m_pZSKKCalib->LoadZSKKGainMap(false, m_strDetectorType); m_pZSKKCalib->LoadZSKKPixelMap(false, m_strDetectorType); FINFO("Load ecom gain and pixel map, references file path: {$}", m_pZSKKCalib->m_strRefFilePath); } } } FINFO("======== ActiveCalibration end"); return true; } /*** * 接受曝光图像 ***/ bool Detector_CareRayDR::AcceptCalibration() { FINFO("======== AcceptCalibration"); if (m_nCalibrationMode)//厂商校正AcceptCalibration { //不做处理 } else //ZSKK校正 { WORD* pImageBuffer = nullptr; //这里要注意使用的image buffer是哪个,裁剪和不裁剪是不一样的 if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { pImageBuffer = m_pImgBuffer; } else { pImageBuffer = m_pRawImgBuffer; } if (m_nCalibCurrentExposureIndex == 1) { m_pZSKKCalib->AddImageToPixMap(pImageBuffer); m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, true); } else { m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮 } } return true; } /*** * 拒绝曝光图像 ***/ bool Detector_CareRayDR::RejectCalibration() { FINFO("======== RejectCalibration"); return true; } /*** * 设置校正轮数 ***/ void Detector_CareRayDR::SetCalibRounds(int nCalibRounds) { m_nCalibrationRounds = nCalibRounds; FINFO("======== Set CalibrationRounds: {$}", m_nCalibrationRounds); } bool Detector_CareRayDR::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound) { m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound; m_nCalibrationRounds = nCalibrationRounds; m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex; m_nExposureNumCurrentRound = nExposureNumCurrentRound; FINFO("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds, nCalibCurrentExposureIndex, nExposureNumCurrentRound); return true; } //使探测器ready bool Detector_CareRayDR::PrepareCalibration(FPDDeviceCareRay* pDrvDPC) { FINFO("======== PrepareCalibration start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("PrepareCalibration CCOS_CALIBRATION_TYPE_DARK == m_eCaliType"); //由于前端没有测试过暗场校正上图的情况,故此处不进行暗场上图 //DarkAcquisition(); StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); } else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("PrepareCalibration CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType"); m_bCancelFlag = false; //准备校正前恢复初值 bool ret = PrepareAcquisition(pDrvDPC); if (ret) { FINFO("PrepareCalibration PrepareAcquisition success!"); } else { FERROR("PrepareCalibration PrepareAcquisition fail!"); return false; } } FINFO("======== PrepareCalibration end"); return true; } //软同步调用接口,其它同步模式没有动作 bool Detector_CareRayDR::StartCalibration(FPDDeviceCareRay* pDrvDPC) { FINFO("======== StartCalibration start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } //未初始化、未连接 不执行 if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType) { FINFO("StartCalibration DARK"); Sleep(2000);//不结束的太快,否则状态机反应不过来 StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Offset; } else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType) { FINFO("StartCalibration XRAY"); bool ret = StartAcquisition(pDrvDPC); if (!ret) { return false; } m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_XrayCalibration; } FINFO("======== StartCalibration end"); return true; } /*** ** 说明:终止校正 ***/ bool Detector_CareRayDR::AbortCalibration(FPDDeviceCareRay* pDrvDPC) { FINFO("======== AbortCalibration start"); m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值 if (m_nCalibrationMode) //厂商校正AbortCalibration { } else { FINFO("Reload Gain Map And Pixel Map"); //重新加载增益校正文件 if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strDetectorType)) { Warn("Load ZSKK Gain calibration failed"); } //放弃坏点校正并重新加载原来的坏点校正文件 m_pZSKKCalib->AbortZSKKPixMap(m_strDetectorType); } m_nAppStatus = APP_STATUS_CAL_END; FINFO("======== AbortCalibration over"); return true; } bool Detector_CareRayDR::StopCalibration(FPDDeviceCareRay* pDrvDPC) { FINFO("======== StopCalibration"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } m_bCancelFlag = true;//中止校正 m_nAppStatus = APP_STATUS_CAL_END; return true; } /*** ** 说明:获取校正时间 ** 连接成功后,校正完成后 获取 ***/ bool Detector_CareRayDR::GetCalibrationTime(int nDetectorID) { if (nDetectorID == -1) { nDetectorID = m_nCurrentPanelID; } else { InfoFeedback(EVT_INFO_CALIBRATIOIN_TIME, nDetectorID, 0, 0, "0"); InfoFeedback(EVT_INFO_CALIBRATIOIN_TIMEL, nDetectorID, 0, 0, "0"); } return true; } /*** ** 说明:结束校正 ** DPC处理完校正报告后调用,此处上传map、报告等文件 ***/ bool Detector_CareRayDR::CompleteCalibration(FPDDeviceCareRay* pDrvDPC) { FINFO("======== CompleteCalibration calib type {$}", (int)m_eCaliType); if (m_eCaliType == CCOS_CALIBRATION_TYPE_DARK) { printf("DARK DARK Calib over \r\n"); FINFO("DARK Calib over"); } else if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY) { printf("XRAY Calib over \r\n"); FINFO("XRAY Calib over"); GetCalibrationTime(); m_nAppStatus = APP_STATUS_CAL_END; } return true; } bool Detector_CareRayDR::SaveCalibrationFile() { FINFO("======== Save Calibration File"); StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_START); if (m_nCalibrationMode)//厂商校正SaveCalibrationFile { //不做处理 } else { FINFO("Save ZSKK Calibration File"); m_pZSKKCalib->StoreZSKKGainMap(m_strDetectorType); m_pZSKKCalib->StoreZSKKPixMap(m_strDetectorType); } StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END); SYSTEMTIME stCurrentTime = { 0 }; GetLocalTime(&stCurrentTime); FINFO("save calib file time: {$04d}/{$02d}/{$02d} {$02d}:{$02d}:{$02d}:{$03d}", stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay, stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds); FINFO("======== Save Calibration File over"); return true; } CCOS_CALIBRATION_TYPE Detector_CareRayDR::GetCalibType() { FINFO("======== GetCalibType {$}", (int)m_eCaliType); return m_eCaliType; } bool Detector_CareRayDR::LoadDll(string strWorkPath) { FINFO("LoadDll start"); string strSDKPath = ""; try { strSDKPath = (string)m_ModeConfig["SDKPath"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed! reason: {$}", e.what()); return false; } string workpath = strWorkPath + strSDKPath; string drvpath = workpath + "\\CrApi.dll"; FINFO("SDK path:{$}", drvpath); SetDllDirectory(workpath.c_str()); m_hCareRayDRModule = LoadLibrary(drvpath.c_str()); if (m_hCareRayDRModule == nullptr) { DWORD dw = GetLastError(); FERROR("Load {$} failed! error code: {$}", drvpath.c_str(), dw); return false; } LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_connect_detector); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_disconnect_detector); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_reset_detector); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_check_mode); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_sync_mode); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_cycle_time); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_normal_power); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_save_power); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_permit_exposure); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_full_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_dark_full_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_prev_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_dark_prev); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_def_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_fluoro_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_fluoro_dark_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_stop_acq_frame); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_stop_acq_frame_cleanup); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_user_correction); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_user_correction); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_dose); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_active_detector_ID); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_active_detector); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_dual_detector_state); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_smart_hand_switch); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_SHS_status); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_wireless_ip); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_wireless_ip); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_station_mode_conf); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_station_mode_conf); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_temperature_cal_data); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_check_temperature_slot); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_API_Version); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_conn_state); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_detector_type); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_detector_info); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_mode_info); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_status_info); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_status_info_Ex); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_image_attr); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_preview_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_unuploaded_img_info); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_query_prog_info); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_inpaint_bad_pixels); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_select_cal_type); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_cal_params); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_offset_correction); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_cal_offset); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_linear_calibration); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_portable_calibration); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_execute_linear_cal); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_execute_portable_cal); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_stop_cal_procedure); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_fluoro_calibration); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_query_calibration_status); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_do_gridpattern_filtration); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_register_callback); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_send_exp_request); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_ready_state_request); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_soft_acquisition); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_AEC_integ_time); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_register_AEC_callback); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_AEC_acquire_process); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_get_one_key_cal); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_check_img_for_factory_cal); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_download_factory_cal_files); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_execute_one_key_cal); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_start_acq_NDT_dark_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_execute_NDT_CAL); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_correct_NDT_image); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_set_NDT_frame_num); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_finish_NDT_acquisition); LOAD_PROC_ADDRESS(m_hCareRayDRModule, CR_check_NDT_CAL_Files); FINFO("LoadDll end"); return true; } /*** ** 连接探测器 ***/ bool Detector_CareRayDR::ConnectDetector() { FINFO("ConnectDetector start"); string strSDKPath = ""; int nRet = -1; try { strSDKPath = (string)m_ModeConfig["SDKPath"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); return false; } string strWorkpath = m_strCtrlWorkPath + strSDKPath + "\\CareRay"; FINFO("ConnectDetector strWorkpath:{$}", strWorkpath); char* szWorkpath = const_cast(strWorkpath.c_str()); if (API_CR_connect_detector) { FINFO("Call API_CR_connect_detector"); nRet = API_CR_connect_detector(szWorkpath); if (CR_NO_ERR != nRet && CR_ALREADY_CONN_ERR != nRet) { TestError(nRet, "API_CR_connect_detector"); FERROR("Connect detector failed!!!"); return false; } } else { FWARN("API_CR_connect_detector is nullptr!"); return false; } m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT); //测试发现,注册回调需要放在连接成功之后 FINFO("Call Register callback"); nRet = API_CR_register_callback(CREventCallback); if (TestError(nRet,"API_CR_register_callback")) { FERROR("register call back fail!"); return false; } //如果是双板环境,输出两个平板的信息 FINFO("m_nPanelCount:{$}", m_nPanelCount); if (m_nPanelCount > 1) { DetectorActiveState das; FINFO("Call get dual detector state"); nRet = API_CR_get_dual_detector_state(&das); if (TestError(nRet, "API_CR_get_dual_detector_state")) { FERROR("get dual detector state fail!"); return false; } FINFO("Current Active Detector ID = {$}", das.activeDetectorID); FINFO("Detector Number = {$}, Detector A type = {$}, Detector B type = {$}", das.detectorNum, das.detectorAType, das.detectorBType); FINFO("Detector A connect state = {$}, Detector B connect state = {$}", das.detectorAstate, das.detectorBstate); if (das.detectorAstate) { m_pStPanelStatus[0]->bConnectState = true; } if (das.detectorBstate) { m_pStPanelStatus[1]->bConnectState = true; } if (0 != das.activeDetectorID) { //双板时,若第一块板不连接,API会自动切换到第二块探测器 //此处暂不处理 } } FINFO("ConnectDetector end"); return true; } /*** ** 初始化探测器 ***/ bool Detector_CareRayDR::InitDetector() { FINFO("InitDetector start"); int nRet = -1; //初始化时先reset,恢复缺省状态 FINFO("Call reset detector"); nRet = API_CR_reset_detector(FALSE); if (TestError(nRet, "API_CR_reset_detector")) { FERROR("reset detector fail!"); return false; } //获取实际的探测器类型 FINFO("Call get detector type"); m_nCurrentDetectorType = API_CR_get_detector_type(); GetDetectorType((DetectorType)m_nCurrentDetectorType, m_strDetectorType); FINFO("Detector type: {$} {$}", m_nCurrentDetectorType, m_strDetectorType);//CareView_1800CwE CareView_1500CwII //输出探测器版本信息、序列号等 ShowDetectorInfo(); //开启单独的线程每隔一段时间调一下接口读取探测器的温度和电量和wifi信号 if (nullptr == m_hFPDStatusThread) { unsigned uThreadId; _beginthreadex(NULL, 0, onFPDStatusThread, this, 0, &uThreadId); m_hFPDStatusThread = OpenThread(THREAD_ALL_ACCESS, TRUE, uThreadId); } //申请DDR使用内存 if (m_pFluFrameData) { delete[] m_pFluFrameData; m_pFluFrameData = nullptr; } m_pFluFrameData = new WORD[nBuffSize]; memset(m_pFluFrameData, 0, nBuffSize); try { int nModeCount = (int)m_ModeConfig["ModeTable"].size(); for (int i = 0; i < nModeCount; i++) { int nAppModeID = (int)m_ModeConfig["ModeTable"][i]["LogicMode"]; if (nAppModeID == AcqMode::RAD) { m_nImageWidth = (int)m_ModeConfig["ModeTable"][i]["ImageWidth"]; m_nImageHeight = (int)m_ModeConfig["ModeTable"][i]["ImageHeight"]; break; } } } catch (ResDataObjectExption& e) { FERROR("Get config error: {$}", e.what()); return false; } if (m_nCalibrationMode)//厂商校正InitDetector { } else { Info("Load ZSKK Reference file"); m_pZSKKCalib->m_strRawImgPath = m_strCtrlWorkPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = m_strCtrlWorkPath + "\\references\\"; //读取配置文件中RAD模式的高和宽 m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight; m_pZSKKCalib->m_nSaturationValue = 50000; if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strDetectorType)) { Warn("Load ZSKK Gain calibration failed"); } if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_strDetectorType)) { Warn("Load ZSKK Defect calibration failed"); } } FINFO("InitDetector end"); return true; } int Detector_CareRayDR::ShowDetectorInfo() { FINFO("Getting Detector Info"); DetectorInfo detectorInfo; FINFO("Call API_CR_get_detector_info"); int nRet = API_CR_get_detector_info(&detectorInfo); if (TestError(nRet,"API_CR_get_detector_info")) { FERROR("Get Detector Info Failed"); } else { FINFO("RawImageWidth is: {$}", detectorInfo.rawImageWidth); FINFO("RawImageHeight is: {$}", detectorInfo.rawImageHeight); FINFO("MaxPixelValue is: {$}", detectorInfo.maxPixelValue); FINFO("BitsPerPixel is: {$}", detectorInfo.bitsPerPixel); FINFO("HardWareVersion is: {$}", detectorInfo.hardWareVersion); FINFO("SoftWareVersion is: {$}", detectorInfo.softWareVersion); FINFO("SerialNumber is: {$}", detectorInfo.serialNumber); FINFO("DetectorDescription is: {$}", detectorInfo.detectorDescription); } return nRet; } bool Detector_CareRayDR::ActiveDetector(FPDDeviceCareRay* pDrvDPC, bool bActive) { FINFO("========ActiveDetector bActive:{$}", bActive); if (bActive) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } //未初始化、未连接 不执行 if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState) { FERROR("bConnectState is false, Detector not connected, return"); return false; } FINFO("Call set normal power"); int nRet = API_CR_set_normal_power();//切换到高功耗模式 if (TestError(nRet, "API_CR_set_normal_power")) { FERROR("Set normal power failed"); return false; } } else { bool bRet = StopAcquisition(pDrvDPC); if (bRet) { FERROR("StopAcquisition fail!"); return false; } } return true; } /*** ** 显示当前采集模式的图像信息 ***/ int Detector_CareRayDR::ShowModeInfo() { ModeInfo stModeInfo; FINFO("Call API_CR_get_mode_info"); int nRet = API_CR_get_mode_info(m_nCheckMode, &stModeInfo); if (TestError(nRet,"API_CR_get_mode_info")) { FERROR("Get Mode Info Failed"); } else { //1800Cwe-m 双能的时候 stModeInfo.imageSize = stModeInfo.imageWidth * stModeInfo.imageHeight *2 + 65536(头) FINFO("ImageWidth = {$}, ImageHeight = {$}, ImageSize = {$}", stModeInfo.imageWidth, stModeInfo.imageHeight, stModeInfo.imageSize); m_nRawImgWidth = stModeInfo.imageWidth; m_nRawImgHeight = stModeInfo.imageHeight; if (nullptr != m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } m_pRawImgBuffer = new WORD[m_nRawImgWidth * m_nRawImgHeight]; //stModeInfo.linesPerPixel或者stModeInfo.colsPerPixel大于1时表示开启BINNING模式 FINFO("modeId:{$}, acqType:{$}, LinesPerPixel:{$}, ColsPerPixel:{$}, maxFrameRate:{$}, modeDescription:{$}", stModeInfo.modeId, stModeInfo.acqType, stModeInfo.linesPerPixel, stModeInfo.colsPerPixel, stModeInfo.maxFrameRate, stModeInfo.modeDescription); } return nRet; } /*** ** 设置同步模式、采集窗口 ***/ bool Detector_CareRayDR::SetSdkSyncModeAndTime(int nSyncMode) { FINFO("SetSdkSyncModeAndTime ({$})", nSyncMode); FINFO("Call API_CR_set_sync_mode"); int nResult = API_CR_set_sync_mode(nSyncMode); if ((CR_NO_ERR != nResult) && (ERR_NO_CONFIGFILE != nResult)) { TestError(nResult, "API_CR_set_sync_mode"); FERROR("Set sync mode failed"); return false; } //因为不同的探测器不同的同步模式,康众推荐了不同的积分时间,在文档中有,故这俩接口放在一起调用 FINFO("Call set cycle time nXwindowTime:{$},nDelayTime:{$},nWaitTime:{$}", m_nXwindow, m_nDelayTime, m_nWaitTime); nResult = API_CR_set_cycle_time(m_nXwindow, m_nDelayTime, m_nWaitTime); if (TestError(nResult,"API_CR_set_cycle_time")) { FERROR("Set cycle time failed"); return false; } FINFO("Set cycle time success"); return true; } unsigned __stdcall Detector_CareRayDR::onFPDScanThread(PVOID pvoid) { Detector_CareRayDR* pOpr = (Detector_CareRayDR*)pvoid; FINFO("Start FPD scan thread"); printf("Start FPD scan thread \r\n"); DWORD dwTimeOut = INFINITE; while (!pOpr->m_bExit) { FINFO("onFPDScanThread Waiting for signal..."); DWORD dwRet = WaitForMultipleObjects(SCAN_EVENT_COUNT, pOpr->m_hArrayEvent, FALSE, dwTimeOut); if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent { pOpr->m_bExit = true; } else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hAcqEvent { pOpr->OnStartAcquisition(); } else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hProcessImgEvent { pOpr->OnProcessImg(); } else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hXWinOnEvent { ULONGLONG dwXrayOnT, dwXrayOffT; dwXrayOnT = dwXrayOffT = GetTickCount64(); FINFO("Xwindowon: {$}", dwXrayOnT); pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); while (dwXrayOffT - dwXrayOnT < 500) //窗口暂时写死 { dwXrayOffT = GetTickCount64(); } FINFO("Xwindowoff: {$}", dwXrayOffT); pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); } else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hDarkEvent { pOpr->StartDarkCalibration(); } else if (WAIT_OBJECT_0 + 5 == dwRet) //m_hGainEvent { pOpr->StartGainCalibration(); } else if (WAIT_OBJECT_0 + 6 == dwRet) //m_hInitEvent { pOpr->InitFPD(); } } SetEvent(pOpr->m_hToggleEvent); FINFO("Leave scan thread"); printf("Leave scan thread \r\n"); return 0; } /*** ** 说明:检查探测器状态线程 ***/ unsigned __stdcall Detector_CareRayDR::onFPDStatusThread(PVOID pvoid) { printf("Start scan detector status thread \r\n"); FINFO("Start scan detector status thread"); Detector_CareRayDR* pOpr = (Detector_CareRayDR*)pvoid; int nRet = 0; StatusInfo stInfo; while (!pOpr->m_bExit) { if (!pOpr->m_pStPanelStatus[pOpr->m_nCurrentPanelID]->bConnectState) { FERROR("Detector is not connected!"); Sleep(pOpr->m_nNotifyStatusTimePeriod); continue; } FINFO("Call API_CR_get_status_info"); nRet = pOpr->API_CR_get_status_info(&stInfo); if (pOpr->TestError(nRet, "API_CR_get_status_info")) { FERROR("get status info fail!"); } else { FINFO("checkMode:{$},detectorState:{$},frameRate:{$}", stInfo.checkMode, stInfo.detectorState, stInfo.frameRate); FINFO("Current detector maxTemperature:{$:f3},aveTemperature:{$:f3},overhot_flag:{$}", stInfo.temperature.maxTemperature, stInfo.temperature.aveTemperature, stInfo.temperature.overhot_flag); pOpr->StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", pOpr->m_nCurrentPanelID, stInfo.temperature.maxTemperature); bool bCharging = false; if (stInfo.batInfo.ave_current > 0.00001) { bCharging = true; } FINFO("Current detector battery: {$} {$}", stInfo.batInfo.relative_state_of_charge * 100, bCharging ? "Charging" : "Not charging"); pOpr->StatusFeedback(EVT_STATUS_BATTERY_VALUE, (int)(stInfo.batInfo.relative_state_of_charge * 100), "", pOpr->m_nCurrentPanelID); FINFO("Current detector wifi link quality: {$}, essid:{$}, mode:{$}, freq:{$}, signal_level:{$}", stInfo.wireless_info.link_quality, stInfo.wireless_info.essid, stInfo.wireless_info.mode, stInfo.wireless_info.freq, stInfo.wireless_info.signal_level); int nLinkQuality = atoi(stInfo.wireless_info.link_quality); pOpr->StatusFeedback(EVT_STATUS_WIFI, nLinkQuality, "", pOpr->m_nCurrentPanelID); } Sleep(pOpr->m_nNotifyStatusTimePeriod); } FINFO("Leave scan thread"); printf("Leave scan thread \r\n"); return 0; } void Detector_CareRayDR::OnStartAcquisition() { FINFO("OnStartAcquisition m_nSyncMode:{$},m_nCurrentLogicMode:{$}", m_nSyncMode, m_nCurrentLogicMode); if (m_nCurrentLogicMode == RAD) { if (SYNC_SOFTWARE == m_nSyncMode)//通过回调函数通知 { PerformSoftSyncAcq(); } else if (SYNC_MANUAL == m_nSyncMode || SYNC_HARDWARE == m_nSyncMode || SYNC_AED == m_nSyncMode)//主动查询状态 { RadAcquisition(); } } else if (m_nCurrentLogicMode == DUALENERGY) { PerformDualEnergyAcquisition(); } else if(m_nCurrentLogicMode == DDR)//康众1500cwII只支持AED模式下的DDR { if (SYNC_SOFTWARE == m_nSyncMode)//通过回调函数通知 { FluAcquisitionByCallBack(); } else if (SYNC_HARDWARE == m_nSyncMode || SYNC_AED == m_nSyncMode)//主动查询状态 { FluAcquisitionByGetImage(); } } } void Detector_CareRayDR::PerformDualEnergyAcquisition() { int result = CR_NO_ERR; ExpProgress expProg = { 0 }; int nXrayOutTime = 0; FINFO("Call API_CR_start_acq_full_image"); result = API_CR_start_acq_full_image(); if (TestError(result,"API_CR_start_acq_full_image")) { return; } FINFO("start acq full image success!"); bool bHadSentExpReq = false;//是否发送过API_CR_send_exp_request bool bHaveSendAcqStatus = false;//是否发送过采集状态 bool bReadyFlag = false;//控制日志打印 bool bExposeFlag = false;//控制日志打印 bool bComplete = false;//控制日志打印 do { Sleep(5); result = API_CR_query_prog_info(CR_RAD_PROG, &expProg); if (CR_NO_ERR != result) { TestError(result, "API_CR_query_prog_info"); return; } switch (expProg.expStatus) { case CR_EXP_READY: { //FINFO("Detector is ready status!"); //only send exposure request for the first image if (!bHadSentExpReq && SOFT_SYNC == m_nSdkSyncMode) { FINFO("SOFT_SYNC == m_nSdkSyncMode Call API_CR_send_exp_request"); result = API_CR_send_exp_request(); if (TestError(result, "API_CR_send_exp_request")) { FINFO("Call API_CR_stop_acq_frame"); API_CR_stop_acq_frame(); return; } bHadSentExpReq = true; } if (!bReadyFlag) { FINFO("Detector is ready then need trans to EXPOSE status"); bReadyFlag = true; bExposeFlag = false; bComplete = false; } break; } case CR_EXP_EXPOSE: { if (!bHaveSendAcqStatus) { StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);//DualEnergy bHaveSendAcqStatus = true; } //FINFO("Detector is expose ready status!"); if (m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus == eDetStatus::DetStatus_Acquire) { if (!bExposeFlag) { FINFO("Detector is expose ready for Rad Acquisition, press x-ray hand switch now..."); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); nXrayOutTime++; bReadyFlag = false; bExposeFlag = true; bComplete = false; Sleep(700); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); } } break; } case CR_EXP_COMPLETE: { if (!bComplete) { FINFO("get Detector complete status!"); bReadyFlag = false; bExposeFlag = false; bComplete = true; } break; } default: FINFO("default status! {$}", expProg.expStatus); break; } //do not to get image when fetchable the first time to be true if (expProg.fetchable && nXrayOutTime == 2) { FINFO("nXrayOutTime is 2 and can get image from detector"); break; } } while (true); //从探测器中获取拍摄的2张图(一次性获取图像内存在一起呢) FrameAttr obj; FINFO("Call API_CR_get_image_attr"); result = API_CR_get_image_attr(&obj); if (TestError(result, "API_CR_get_image_attr")) { return; } //imageSize = headSize(if needed) + width * height * sizeof(WORD) //For 1500 series, width: 2816, height: 2304, headSize: 65536 (byte) //For 500 series, width: 3072, height: 2560, headSize: 65536 (byte) //For 1800 series, width: 3072, height: 3072, headSize: 65536 (byte) FINFO("image width:{$},height:{$},pixel_bits:{$}", obj.image_width, obj.image_height, obj.pixel_bits); int imgSize = 2 * (obj.image_width * obj.image_height * (obj.pixel_bits / 8)); WORD* pImage = (WORD*)malloc(imgSize); if (NULL == pImage) { result = CR_ALCATE_BUFF_ERR; TestError(result); return; } FINFO("Call API_CR_get_image"); //第二个参数TRUE 带头文件 FALSE 不带头文件 RAD 65536 bytes flu 256 bytes result = API_CR_get_image(imgSize, FALSE, pImage); if (TestError(result, "API_CR_get_image")) { return; } for (size_t i = 0; i < 2; i++) { FINFO("imgSize:{$},pImage:{$},m_pRawImgBuffer:{$}", imgSize, pImage, m_pRawImgBuffer); memcpy(m_pRawImgBuffer, pImage + i * imgSize / 4, imgSize / 2); FINFO("Begin get effect image"); if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, obj.image_width)) { return; } FINFO("Get effect image over"); //非校正状态才应用校正文件 校正时不使用校正文件 if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); if (m_nSaveRaw) { SaveRawFunc(m_pImgBuffer, m_nImageWidth, m_nImageHeight,to_string(i)); } } if (pImage) { free(pImage); pImage = NULL; } StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); } int Detector_CareRayDR::FluAcquisitionByCallBack() { FINFO("FluAcquisitionByCallBack start"); int result = CR_NO_ERR; //exposure and frame event would be notified by callback m_nFluCurrentExpStatus = 0; m_nFluLastExpStatus = -1; m_nMaxFrameId = 0; m_nReceivedFrameId = 0; if (!m_pFluFrameData) { m_pFluFrameData = new WORD[nBuffSize]; if (NULL == m_pFluFrameData) { FERROR("new memory failed..."); return ERR_MEM_ALLOC; } } memset(m_pFluFrameData, 0, nBuffSize); FINFO("Call CR_start_acq_fluoro_image"); result = API_CR_start_acq_fluoro_image(m_pFluFrameData, nBuffSize); if (TestError(result,"CR_start_acq_fluoro_image")) { FERROR("CR_start_acq_fluoro_image error, reason: {$}", CrErrStrList(result)); return result; } FINFO("FluAcquisitionByCallBack end"); return result; } int Detector_CareRayDR::FluAcquisitionByGetImage() { FINFO("========FluAcquisitionByGetImage"); int result = CR_NO_ERR; int nFrameSize = 0; int nLastFrameNumAcquiredInDetr = -1; char* pFrameData = NULL; ModeInfo oModeInfo = { 0 }; ExpProgress oExpInfo = { 0 }; //loop interfaces to get exposure and frame information m_nFluCurrentExpStatus = 0; m_nFluLastExpStatus = -1; m_nMaxFrameId = 0; m_nReceivedFrameId = 0; bool bExposureFinishedInDetr = false; bool bFlag = false; FINFO("Call API_CR_get_mode_info"); result = API_CR_get_mode_info(m_nCheckMode, &oModeInfo); if (TestError(result,"API_CR_get_mode_info")) { return result; } nFrameSize = oModeInfo.imageWidth * oModeInfo.imageHeight * 2 + FLUORO_IMAGE_HEADER_SIZE; pFrameData = (char*)malloc(nFrameSize); if (NULL == pFrameData) { FERROR("Allocate memory failed..."); return ERR_MEM_ALLOC; } memset(pFrameData, 0x0, nFrameSize); //pass NULL and -1 to disable the callback to notify fluoro frames FINFO("Call API_CR_start_acq_fluoro_image"); result = API_CR_start_acq_fluoro_image(NULL, -1); if (TestError(result, "API_CR_start_acq_fluoro_image")) { return result; } do { result = API_CR_query_prog_info(CR_RAD_PROG, &oExpInfo); if (CR_NO_ERR != result) { TestError(result,"API_CR_query_prog_info"); break; } m_nFluCurrentExpStatus = oExpInfo.expStatus >> 16; if (oExpInfo.expose_flag) { if (!bFlag) { FINFO("Ready, start x-ray now..."); StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); bFlag = true; } } if (m_nFluLastExpStatus != m_nFluCurrentExpStatus) { if (6 == m_nFluCurrentExpStatus) { FINFO("X-Ray detected..."); StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON); } else if(7 == m_nFluCurrentExpStatus) { FINFO("No X-Ray detected..."); } } if (nLastFrameNumAcquiredInDetr != oExpInfo.frame_number) { FINFO("Total {$} frames will be send inside detector", oExpInfo.frame_number); nLastFrameNumAcquiredInDetr = oExpInfo.frame_number; } if (7 == m_nFluCurrentExpStatus && 6 == m_nFluLastExpStatus) { bExposureFinishedInDetr = true; m_nMaxFrameId = oExpInfo.expStatus & 0xffff; FINFO("Detected x-ray stopped, the max frame number inside detector is {$}", m_nMaxFrameId); break; } if (m_bCancelFlag) { FINFO("Cancel Acq"); break; } m_nFluLastExpStatus = m_nFluCurrentExpStatus; } while (true); while (bExposureFinishedInDetr) { StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); FINFO("Call API_CR_get_image"); result = API_CR_get_image(nFrameSize, TRUE, pFrameData); if (result == CR_NO_ERR) { //收到一张图 FINFO("result == CR_NO_ERR"); m_nReceivedFrameId = *(int*)(pFrameData + 8); FINFO("frame id = {$}", m_nReceivedFrameId); //向上推图 if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(oModeInfo.imageHeight, oModeInfo.imageWidth, (WORD*)pFrameData + FLUORO_IMAGE_HEADER_SIZE); } DataFeedback(EVT_DATA_RAW_IMAGE, pFrameData + FLUORO_IMAGE_HEADER_SIZE); if (m_nSaveRaw) { SaveRawFunc((WORD*)pFrameData + FLUORO_IMAGE_HEADER_SIZE, oModeInfo.imageWidth, oModeInfo.imageHeight, to_string(m_nReceivedFrameId)); } StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); if (m_nReceivedFrameId >= m_nMaxFrameId) { FINFO("Flu acquisition finished, ready to exit the acquisition..."); //DDR结束通知standby让状态跳转FrameEnd StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); break; } } else if(result == ERR_NO_FETCHABLE_FRAME)//没收到过此推送 { FINFO("result == ERR_NO_FETCHABLE_FRAME"); FINFO("All the frames achieved,no fetchable frame"); StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); break; } else if (result == CR_RECV_ERR) { FINFO("result == CR_RECV_ERR"); break; } else { FERROR("get image error! code:{$}", result); TestError(result,"API_CR_get_image"); break; } } if (pFrameData) { free(pFrameData); pFrameData = nullptr; } return result; } void Detector_CareRayDR::OnProcessImg() { FINFO("OnProcessImg start"); Sleep(200); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); int nRet = -1; FrameAttr stImgInfo; FINFO("Call get image attr"); nRet = API_CR_get_image_attr(&stImgInfo); if (TestError(nRet, "API_CR_get_image_attr")) { return; } m_nImageSize = stImgInfo.image_width * stImgInfo.image_height * (stImgInfo.pixel_bits / 8); FINFO("get image attr, W: {$}, H: {$}, bits: {$}, size:{$}", stImgInfo.image_width, stImgInfo.image_height, stImgInfo.pixel_bits, m_nImageSize); FINFO("Call get image"); nRet = API_CR_get_image(m_nImageSize, FALSE, m_pRawImgBuffer); if (TestError(nRet, "API_CR_get_image")) { FERROR("Get image failed"); return; } if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { FINFO("Begin get effect image"); printf("Begin get effect image \r\n"); if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, m_nRawImgWidth)) { return; } FINFO("Get effect image over"); printf("Get effect image over \r\n"); //非校正状态才应用校正文件 校正时不使用校正文件 if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); if (m_nSaveRaw) { SaveRawFunc(m_pImgBuffer, m_nImageWidth, m_nImageHeight); } } else { if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nRawImgHeight, m_nRawImgWidth, m_pRawImgBuffer); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pRawImgBuffer); if (m_nSaveRaw) { SaveRawFunc(m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight); } } StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); FINFO("OnProcessImg end"); } void Detector_CareRayDR::StartDarkCalibration() { FINFO("dark calibration start"); int nRet = -1; FINFO("Call stop cal procedure(FALSE)"); nRet = API_CR_stop_cal_procedure(FALSE); //参照SDK demo流程,在开始前调用这个接口 if (TestError(nRet,"API_CR_stop_cal_procedure")) { FERROR("Get stop cal procedure Failed"); return; } FINFO("Call cal offset"); nRet = API_CR_cal_offset(m_nCheckMode); if (TestError(nRet,"API_CR_cal_offset")) { FERROR("Start offset failed"); return; } FINFO("Query status"); int nFrameNum = 0; ExpProgress calProg; do { FINFO("Call query prog info"); nRet = API_CR_query_prog_info(CR_CAL_PROG, &calProg); if (TestError(nRet, "API_CR_query_prog_info")) { FERROR("Query Prog Info Failed"); FINFO("Call reset detector"); nRet = API_CR_reset_detector(FALSE); if (TestError(nRet, "API_CR_reset_detector")) { FERROR("reset detector fail!"); } return; } Sleep(100); if (CR_NO_ERR != calProg.errorCode) { TestError(calProg.errorCode); break; } if (calProg.frame_number > nFrameNum) { FINFO("Now received {$} dark images ", calProg.frame_number); nFrameNum = calProg.frame_number; } } while (FALSE == calProg.calComplete); if (TRUE == calProg.calComplete) { FINFO("Offset calibration finished!"); StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); } else { FERROR("Error occurred in offset calibration!"); } FINFO("dark calibration end"); } void Detector_CareRayDR::StartGainCalibration() { FINFO("StartGainCalibration start"); FINFO("StartGainCalibration end"); } void Detector_CareRayDR::InitFPD() { FINFO("InitFPD start"); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START); if (!LoadDll(m_strCtrlWorkPath)) { ErrorFeedback(EVT_ERR_INIT_FAILED, "true"); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR); //初始化失败 return; } else { if (!InitDetector()) { printf("Init detector failed, Connect failed \r\n"); FINFO("Init detector failed, Connect failed"); ErrorFeedback(EVT_ERR_INIT_FAILED, "true"); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR); //初始化失败 } else { m_pStPanelStatus[m_nCurrentPanelID]->bInitOver = true; StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK); } } FINFO("InitFPD end"); } /*** ** 启动软同步采集 ** 通过回调反馈进度 ***/ int Detector_CareRayDR::PerformSoftSyncAcq() { FINFO("PerformSoftSyncAcq start"); int nRet = -1; FINFO("Call start soft acquisition"); nRet = API_CR_start_soft_acquisition(); if (TestError(nRet,"API_CR_start_soft_acquisition")) { FERROR("Start soft acq failed"); return nRet; } FINFO("Call ready state request"); nRet = API_CR_ready_state_request(); if (TestError(nRet,"API_CR_ready_state_request")) { FERROR("Request ready state failed"); return nRet; } //软同步时此函数在SDK内部已经调用了API_CR_get_image_attr和API_CR_get_image了,所以在回调中直接把回调的图片数据直接拷贝过来就可以了 FINFO("Call start acq fullimg"); nRet = API_CR_start_acq_full_image(); if (TestError(nRet, "API_CR_start_acq_full_image")) { FERROR("Start acq fullimg failed"); return nRet; } FINFO("PerformSoftSyncAcq end"); return nRet; } //AED和硬同步 int Detector_CareRayDR::RadAcquisition() { FINFO("RadAcquisition start"); int nRet = -1; //在探测器处于硬同步、AED、手动模式的时候此函数在SDK内部不会主动调用API_CR_get_image_attr和API_CR_get_image,需要后续查询状态为fetchable时再调用 FINFO("Call start acq fullimg"); nRet = API_CR_start_acq_full_image(); if (TestError(nRet,"API_CR_start_acq_full_image")) { FERROR("Start acq fullimg failed"); return nRet; } if (SYNC_MANUAL == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode || SYNC_AED == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode) { nRet = QueryAutoProgInfo(); } else if(SYNC_HARDWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode) { nRet = QueryRadProgInfo(); } //轮询采集状态没有返回图像或终止了采集 if (CR_NO_ERR != nRet) { FERROR("query auto prog info fail!"); return nRet; } //如果是通过取消采集退出来的,那么不需要上图,否则需要上图 if (!m_bCancelFlag) { SetEvent(m_hProcessImgEvent); } FINFO("RadAcquisition end"); return nRet; } /*** ** 获取一帧暗场图 ***/ int Detector_CareRayDR::DarkAcquisition() { int nRet = -1; int printOver = 0, awaitOver = 0; ExpProgress expProg; FINFO("Call set normal power"); nRet = API_CR_set_normal_power(); if (TestError(nRet,"API_CR_set_normal_power")) { FERROR("Set normal power failed"); return false; } FINFO("Call start acq dark fullimg"); nRet = API_CR_start_acq_dark_full_image(); if (TestError(nRet,"API_CR_start_acq_dark_full_image")) { FERROR("Acquire dark image failed"); return nRet; } memset(&expProg, 0x0, sizeof(ExpProgress)); FINFO("Query Detector Status"); do { Sleep(50); FINFO("Call API_CR_query_prog_info"); nRet = API_CR_query_prog_info(CR_RAD_PROG, &expProg); if (TestError(nRet,"API_CR_query_prog_info")) { FERROR("Error occurred when query detector status info!"); return nRet; } if (expProg.fetchable) { FINFO("Dark Image will Arrive"); break; } } while (TRUE); FrameAttr stImgInfo; FINFO("Call get image attr"); nRet = API_CR_get_image_attr(&stImgInfo); if (TestError(nRet,"API_CR_get_image_attr")) { FERROR("Get image attr failed"); return nRet; } FINFO("Image attr, H: {$}, W: {$}, bits: {$}", stImgInfo.image_height, stImgInfo.image_width, stImgInfo.pixel_bits); if (nullptr == m_pDarkImage) { m_pDarkImage = new WORD[stImgInfo.image_height * stImgInfo.image_width]; } FINFO("Call get image"); nRet = API_CR_get_image(stImgInfo.image_height * stImgInfo.image_width * (stImgInfo.pixel_bits / 8), FALSE, m_pDarkImage); if (TestError(nRet,"API_CR_get_image")) { FERROR("Get image failed"); return nRet; } return nRet; } /*** ** 轮询Manual(SDK的半aed模式)、aed模式采集状态 ***/ int Detector_CareRayDR::QueryAutoProgInfo(bool bIsAED) { FINFO("Begin query auto exposure progress info"); ExpProgress expProg; memset(&expProg, 0x0, sizeof(ExpProgress)); int nResult = CR_NO_ERR; bool bFlag = true;//取消重复动作标志 do { Sleep(50); nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg); if (CR_NO_ERR != nResult) { TestError(nResult, "API_CR_query_prog_info"); break; } if (expProg.expose_flag)//可以曝光 { if (bFlag) { FINFO("Detector is ready for Rad Acquisition, press x-ray hand switch now..."); StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY); bFlag = false; } } if (expProg.fetchable) { FINFO("Can get image from detector"); //这里的消息只有环境中只有一个探测器的时候配合工作流才会生效 StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON); break; } if (m_bCancelFlag) { FINFO("Cancel Acq"); break; } } while (true); return nResult; } /*** ** 轮询硬同步模式采集状态 ***/ int Detector_CareRayDR::QueryRadProgInfo() { FINFO("Begin query rad exposure progress info"); ExpProgress expProg; memset(&expProg, 0, sizeof(ExpProgress)); bool bExpError = false; bool bExpInit = false; bool bExpReady = false; bool bExpPermission = false; bool bExpPermitted = false; bool bExpExpose = false; bool bExpComplete = false; int nResult = CR_NO_ERR; do { Sleep(50); FINFO("Call query prog info"); nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg); if (CR_NO_ERR != nResult) { TestError(nResult, "API_CR_query_prog_info"); return nResult; } switch (expProg.expStatus) { case CR_EXP_ERROR: if (!bExpError) { bExpError = true; FINFO("CR_EXP_ERROR(-1)"); } break; case CR_EXP_INIT: if (!bExpInit) { bExpInit = true; FINFO("CR_EXP_INIT(0)"); } break; case CR_EXP_READY: if (!bExpReady) { bExpReady = true; FINFO("CR_EXP_READY(1)"); } break; case CR_EXP_WAIT_PERMISSION: if (!bExpPermission) { FINFO("CR_EXP_WAIT_PERMISSION(2)"); bExpPermission = true; FINFO("Call permit exposure"); nResult = API_CR_permit_exposure(); if (TestError(nResult,"API_CR_permit_exposure")) { FERROR("Permit Exposure Failed!"); return nResult; } } break; case CR_EXP_PERMITTED: if (!bExpPermitted) { bExpPermitted = true; FINFO("CR_EXP_PERMITTED(3)"); } break; case CR_EXP_EXPOSE: if (!bExpExpose) { bExpExpose = true; FINFO("CR_EXP_EXPOSE(4)"); } break; case CR_EXP_COMPLETE: if (!bExpComplete) { bExpComplete = true; FINFO("CR_EXP_COMPLETE(5)"); } break; default: break; }//end for switch if (expProg.fetchable) { FINFO("Can get image from detector"); break; } if (m_bCancelFlag) { FINFO("Cancel Acq"); break; } } while (true); return nResult; } void Detector_CareRayDR::SaveRawFunc(WORD* pInImg, int nImgWidth, int nImgHeight, string strFrameID) { FILE* fp; string strFileName = ""; if (strFrameID == "") { strFileName = m_strCtrlWorkPath + "\\rawdata\\Raw.raw"; } else { strFileName = m_strCtrlWorkPath + "\\rawdata\\Frame" + strFrameID + ".raw"; } FINFO("image file name:{$}", strFileName); if ((fp = fopen(strFileName.c_str(), "wb")) == NULL) { DWORD dw = GetLastError(); FERROR("fopen {$} failed, error code:{$}", strFileName, dw); return; } fwrite(pInImg, sizeof(WORD), (size_t)nImgWidth * (size_t)nImgHeight, fp); fclose(fp); FINFO("Save image over"); } /*** * 保存RAW图像 ***/ bool Detector_CareRayDR::SaveRawWithName(const char* pRawName, const WORD* pRawImg, int nWidth, int nHeight) { FINFO("========SaveRaw RawName:{$}", pRawName); if (pRawImg == NULL || pRawName == NULL) { return false; } string strImagePath = m_strCtrlWorkPath + "\\rawdata\\" + pRawName; FILE* fp; if ((fp = fopen(strImagePath.c_str(), "wb")) == NULL) { DWORD dw = GetLastError(); FERROR("fopen {$} failed, {$}", strImagePath.c_str(), dw); return false; } fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp); fclose(fp); FINFO("End to Save Raw"); return true; } /*** ** 裁剪图像 ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度 ***/ bool Detector_CareRayDR::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth) { if (pOutImg == NULL || pInImg == NULL || nInWidth < 0) { FERROR("Illegal parameter, can not get effective image"); return false; } try { for (int i = 0; i < m_nImageHeight; i++) { memcpy(pOutImg + i * m_nImageWidth, pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset, m_nImageWidth * sizeof(WORD)); } } catch (...) { FERROR("Get effective image crashed"); return false; } return true; } //设置校正选项,选择是否加载校正文件 bool Detector_CareRayDR::SetUserCorrection(bool bLoad) { UserCorrection corr; memset(&corr, 0x0, sizeof(UserCorrection)); if (bLoad) { switch (m_nCurrentDetectorType) { case CareView_1500R: case CareView_500M: case CareView_1800R: case CareView_1800I: case CareView_1800L: case CareView_750M: case CareView_1500L: case CareView_1800RV2: case CareView_1800LE: case AniView_D4343: FINFO("Load Fixed Correction Files"); corr.fixedCorr = TRUE; break; case CareView_500P: case CareView_1500P: case CareView_1500Rm: case CareView_1500C: case CareView_1500Cw: case CareView_300P: case CareView_1500PV2: case CareView_750Cw: case CareView_1800Cw: case CareView_1800CwE: case CareView_1500CwE: case CareView_1500CwII: FINFO("Load Portable Correction Files"); corr.portableCorr = TRUE; break; default: corr.fixedCorr = TRUE; break; } } FINFO("Call API_CR_set_user_correction"); int nResult = API_CR_set_user_correction(&corr); if (TestError(nResult,"API_CR_set_user_correction")) { if (CR_OFFSET_CAL_FILE_NOT_MATCH_ERR == nResult) { FERROR("Offset Calibration Files are not match!"); } else { FERROR("Set user correction Failed"); } return false; } else { FINFO("Set user correction Success"); } return true; } /*** ** 计算一键校正曝光的图像灰度 ***/ double Detector_CareRayDR::GetMean(WORD* imgNoHeader, int pixelNum) { double imgMean = 0; for (int i = 0; i < pixelNum; i++) { imgMean += imgNoHeader[i]; } imgMean = imgMean / pixelNum; return imgMean; } Detector_CareRayDR::eDetStatus Detector_CareRayDR::GetCareRayDPCStatus(int nDetectorIndex) { if (-1 == nDetectorIndex) { nDetectorIndex = m_nCurrentPanelID; } string strStatus = "Unknown"; switch (m_pStPanelStatus[nDetectorIndex]->eFPDStatus) { case eDetStatus::DetStatus_NotIni: strStatus = "NotIni"; break; case eDetStatus::DetStatus_NotConn: strStatus = "NotConn"; break; case eDetStatus::DetStatus_Sleep: strStatus = "Sleep"; break; case eDetStatus::DetStatus_Standby: strStatus = "Standby"; break; case eDetStatus::DetStatus_Work: strStatus = "Work"; break; case eDetStatus::DetStatus_Acquire: strStatus = "Acquire"; break; case eDetStatus::DetStatus_Offset: strStatus = "Offset"; break; case eDetStatus::DetStatus_XrayCalibration: strStatus = "XrayCalibration"; break; default: break; } FINFO("Driver status: {$}", strStatus.c_str()); return m_pStPanelStatus[nDetectorIndex]->eFPDStatus; } bool Detector_CareRayDR::SetCareRayDPCStatus(eDetStatus status, int nDetectorIndex) { if (-1 == nDetectorIndex) { nDetectorIndex = m_nCurrentPanelID; } string strStatus = "Unknown"; bool bSetStatus = true; switch (status) { case eDetStatus::DetStatus_NotIni: strStatus = "NotIni"; break; case eDetStatus::DetStatus_NotConn: strStatus = "NotConn"; break; case eDetStatus::DetStatus_Sleep: strStatus = "Sleep"; break; case eDetStatus::DetStatus_Standby: strStatus = "Standby"; break; case eDetStatus::DetStatus_Work: strStatus = "Work"; break; case eDetStatus::DetStatus_Acquire: strStatus = "Acquire"; break; case eDetStatus::DetStatus_Offset: strStatus = "Offset"; break; case eDetStatus::DetStatus_XrayCalibration: strStatus = "XrayCalibration"; break; default: bSetStatus = false; break; } if (bSetStatus) { m_pStPanelStatus[nDetectorIndex]->eFPDStatus = status; FINFO("Set driver status: {$}", strStatus.c_str()); } else { FERROR("{$} {$} is a illegal status", strStatus, (int)status); } return bSetStatus; } bool Detector_CareRayDR::IsConnected(string strIP) { FINFO("Check ping {$}", strIP); CMyPingip obPingIp; //StatusFeedback(EVT_STATUS_PING, 0, "true"); if (!obPingIp.PingFunction(strIP.c_str())) { FINFO("ping {$} Failed", strIP); //StatusFeedback(EVT_STATUS_PING, 0, "false"); return false; } return true; } /*** ** 等待探测器操作执行完毕 ***/ bool Detector_CareRayDR::WaitRespond(int nTimeOut, const char* szAction) { FINFO("--- WaitRespond({$}), {$}ms ---", szAction, nTimeOut); DWORD dwRet = WaitForSingleObject(m_hRespond, nTimeOut); if (dwRet == WAIT_TIMEOUT) { FERROR("time out in wait response, action:{$}", szAction); return false; } return true; } void Detector_CareRayDR::StopWaiting(const char* szAction) { FINFO("--- Stop waiting respond, {$} ---", szAction); SetEvent(m_hRespond); } /*** ** 检测接口是否有错误,true:有错;false:没错 ***/ bool Detector_CareRayDR::TestError(int nRet, const char* szFuncName, bool bShowTrue) { if (nRet == CR_NO_ERR) { if (bShowTrue) { FINFO("{$} executed successfully", szFuncName); } return false; } else { FERROR("{$} return error {$}, reason: {$}", szFuncName, nRet, CrErrStrList(nRet)); printf("%s return error %d, reason: %s \r\n", szFuncName, nRet, CrErrStrList(nRet)); return true; } } void Detector_CareRayDR::GetDetectorType(DetectorType eType, string& szType) { string strType = "Unkown_Type"; switch (eType) { case CareView_1500R: strType = "CareView_1500R"; break; case CareView_1500Rm: strType = "CareView_1500Rm"; break; case CareView_1500P: strType = "CareView_1500P"; break; case CareView_1500C: strType = "CareView_1500C"; break; case CareView_1800R: strType = "CareView_1800R"; break; case CareView_500M: strType = "CareView_500M"; break; case CareView_500I: strType = "CareView_500I"; break; case CareView_500P: strType = "CareView_500P"; break; case CareView_900F: strType = "CareView_900F"; break; case CareView_1800I: strType = "CareView_1800I"; break; case CareView_1500L: strType = "CareView_1500L"; break; case CareView_1500Cw: strType = "CareView_1500Cw"; break; case CareView_300P: strType = "CareView_300P"; break; case CareView_750M: strType = "CareView_750M"; break; case CareView_1800L: strType = "CareView_1800L"; break; case CareView_1800RV2: strType = "CareView_1800RV2"; break; case CareView_1500PV2: strType = "CareView_1500PV2"; break; case CareView_750Cw: strType = "CareView_750Cw"; break; case CareView_0331IF: strType = "CareView_0331IF"; break; case CareView_750I: strType = "CareView_750I"; break; case CareView_1800IF: strType = "CareView_1800IF"; break; case CareView_750C: strType = "CareView_750C"; break; case CareView_1800Cw: strType = "CareView_1800Cw"; break; case CareView_1500S: strType = "CareView_1500S"; break; case CareView_750S: strType = "CareView_750S"; break; case CareView_750Mc: strType = "CareView_750Mc"; break; case CareView_240I: strType = "CareView_240I"; break; case CareView_1800RF: strType = "CareView_1800RF"; break; case CareView_1800LE: strType = "CareView_1800LE"; break; case CareView_1800CwE: strType = "CareView_1800CwE"; break; case AniView_D4343: strType = "AniView_D4343"; break; case CareView_1500CwE: strType = "CareView_1500CwE"; break; case CareView_1500Sf: strType = "CareView_1500Sf"; break; case CareView_750Sf: strType = "CareView_750Sf"; break; case CareView_1500CwII: strType = "CareView_1500CwII"; break; case Unkown_Type: break; default: break; } szType = strType; } bool Detector_CareRayDR::IsPortableFPD() { if (CareView_1500Rm == m_nCurrentDetectorType || CareView_1500P == m_nCurrentDetectorType || CareView_500P == m_nCurrentDetectorType || CareView_1500C == m_nCurrentDetectorType || CareView_1500PV2 == m_nCurrentDetectorType || CareView_1500Cw == m_nCurrentDetectorType || CareView_750Cw == m_nCurrentDetectorType || CareView_1800Cw == m_nCurrentDetectorType || CareView_1800CwE == m_nCurrentDetectorType || CareView_1500CwE == m_nCurrentDetectorType) { return true; } else { return false; } } void Detector_CareRayDR::CallBackEvent(int eventID, Event* eventData) { FINFO("Call back event ID: {$}", eventID); switch (eventID) { case EVT_DISCONNECT: { FINFO("Callback EVT_DISCONNECT"); m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = false; StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); /*if (nullptr == m_hReconnectThread) { unsigned uThreadId; _beginthreadex(NULL, 0, onReconnectThread, this, 0, &uThreadId); m_hReconnectThread = OpenThread(THREAD_ALL_ACCESS, TRUE, uThreadId); }*/ break; } case EVT_READY: { FINFO("Callback EVT_READY m_nSdkSyncMode:{$}", m_nSdkSyncMode); if (SOFT_SYNC == m_nSdkSyncMode) { int result = API_CR_send_exp_request(); if (TestError(result, "API_CR_send_exp_request")) { printf("CR_send_exp_request error,reason: %s\n", CrErrStrList(result)); FERROR("CR_send_exp_request error,reason: {$}", CrErrStrList(result)); return; } } StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);//EVT_READY break; } case EVT_EXP_EN://请求曝光状态 { FINFO("Callback EVT_EXP_EN"); StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);//EVT_EXP_EN break; } case EVT_IMAGE_ARRIVE: { FINFO("Callback EVT_IMAGE_ARRIVE"); FINFO("Image Arrived, width: {$}, height: {$}, bits:{$}", eventData->width, eventData->height, eventData->bits); m_nImageSize = eventData->width * eventData->height * (eventData->bits / 8); FINFO("m_nImageSize:{$}", m_nImageSize); memcpy(m_pRawImgBuffer, eventData->data, m_nImageSize); FINFO("m_nWidthOffset:{$},m_nHeightOffset:{$}", m_nWidthOffset, m_nHeightOffset); if (m_nWidthOffset != 0 || m_nHeightOffset != 0) { FINFO("Begin get effect image"); printf("Begin get effect image \r\n"); if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, m_nRawImgWidth)) { return; } FINFO("Get effect image over"); printf("Get effect image over \r\n"); if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); if (m_nSaveRaw) { SaveRawFunc(m_pImgBuffer, m_nImageWidth, m_nImageHeight); } } else { if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nRawImgHeight, m_nRawImgWidth, m_pRawImgBuffer); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pRawImgBuffer); if (m_nSaveRaw) { SaveRawFunc(m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight); } } StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); break; } case EVT_AEC_PREV_MODE_READY: FINFO("Callback EVT_AEC_PREV_MODE_READY"); break; case EVT_AEC_RAD_MODE_READY: FINFO("Callback EVT_AEC_RAD_MODE_READY"); break; case EVT_AEC_PREV_IMG_ARRIVE: FINFO("Callback EVT_AEC_PREV_IMG_ARRIVE"); break; case EVT_AEC_RAD_IMG_ARRIVE: FINFO("Callback EVT_AEC_RAD_IMG_ARRIVE"); break; case EVT_DETECTOR_ERROR: FINFO("Callback EVT_DETECTOR_ERROR"); break; case EVT_EXPOSE_FLAG_FALSE: FINFO("Callback EVT_EXPOSE_FLAG_FALSE"); break; case EVT_EXPOSE_FLAG_TRUE: FINFO("Callback EVT_EXPOSE_FLAG_TRUE"); break; case EVT_INITIAL: FINFO("Callback EVT_INITIAL"); break; case EVT_UNUPLOADED_IMG_EXIST: FINFO("Callback EVT_UNUPLOADED_IMG_EXIST"); break; case EVT_CONNECTED: FINFO("Callback EVT_CONNECTED"); m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT); break; case EVT_SECOND_PANEL_CONNECTED: FINFO("Callback EVT_SECOND_PANEL_CONNECTED"); break; case EVT_SECOND_PANEL_DISCONNECTED: FINFO("Callback EVT_SECOND_PANEL_DISCONNECTED"); break; case EVT_SHS_STATUS_CHANGED: FINFO("Callback EVT_SHS_STATUS_CHANGED"); break; case EVT_IMAGE_TRANSFER_FAILED: FINFO("Callback EVT_IMAGE_TRANSFER_FAILED"); break; case EVT_TEMPERATURE_SLOT_MISSING: { FINFO("Callback EVT_TEMPERATURE_SLOT_MISSING"); TemperatureSlotWarnMsg* oTempSlotWarnMsg = (TemperatureSlotWarnMsg*)eventData->data; FINFO("Temperature slot warn message, DetectorID = {$},MissingExpTime = {$} ms,MissingTemperature = {$:f1} Celsius,CurrentTemperature = {$:f1} Celsius,ToleranceTemperature = {$:f1} Celsius", oTempSlotWarnMsg->nDetectorID, oTempSlotWarnMsg->nMissingExpTime, oTempSlotWarnMsg->fMissingTemperature, oTempSlotWarnMsg->fCurrentTemperature, oTempSlotWarnMsg->fToleranceTemperature); break; } case EVT_TEMPERATURE_SLOT_TRAIN_START: { FINFO("Callback EVT_TEMPERATURE_SLOT_TRAIN_START"); TemperatureSlotTrainMsg* oTempSlotTrainMsg = (TemperatureSlotTrainMsg*)eventData->data; FINFO("One temperature slot train start, DetectorID = {$},ExpTime of training slot = {$} ms,Temperature of training slot = {$:f1} Celsius", oTempSlotTrainMsg->nDetectorID, oTempSlotTrainMsg->nExpTimeOfSlot, oTempSlotTrainMsg->fTemperatureOfSlot); break; } case EVT_TEMPERATURE_SLOT_TRAIN_FINISH: { FINFO("Callback EVT_TEMPERATURE_SLOT_TRAIN_FINISH"); TemperatureSlotTrainMsg* oTempSlotTrainMsg = (TemperatureSlotTrainMsg*)eventData->data; FINFO("One temperature slot train finished,DetectorID = {$},ExpTime of slot = {$} ms,Temperature of slot = {$:f1} Celsius", oTempSlotTrainMsg->nDetectorID, oTempSlotTrainMsg->nExpTimeOfSlot, oTempSlotTrainMsg->fTemperatureOfSlot); break; } case EVT_TEMPERATURE_SLOT_TRAIN_ABORT: { FINFO("Callback EVT_TEMPERATURE_SLOT_TRAIN_ABORT"); TemperatureSlotTrainMsg* oTempSlotTrainMsg = (TemperatureSlotTrainMsg*)eventData->data; FINFO("One temperature slot train aborted,DetectorID = {$},ExpTime of aborted slot = {$} ms,Temperature of aborted slot = {$:f1} Celsius", oTempSlotTrainMsg->nDetectorID, oTempSlotTrainMsg->nExpTimeOfSlot, oTempSlotTrainMsg->fTemperatureOfSlot); break; } case EVT_USELESS_IMAGE: //康众新加的aed误触发回调 FINFO("Callback EVT_USELESS_IMAGE"); break; case EVT_EXP_PROGRESS: { if (!m_bGetImageByCallBack) { break; } FINFO("Callback EVT_EXP_PROGRESS"); ExpProgress* pExpProgress = (ExpProgress*)eventData->data; m_nFluCurrentExpStatus = pExpProgress->expStatus >> 16; if (pExpProgress->expose_flag) { //ready了,可以曝光 FINFO("Flu acq is ready"); } else { //不ready FINFO("Flu acq is not ready"); } if (m_nFluLastExpStatus != m_nFluCurrentExpStatus) { if (6 == m_nFluCurrentExpStatus) { FINFO("X-Ray detected..."); } else if (7 == m_nFluCurrentExpStatus) { FINFO("No X-Ray detected..."); } } FINFO("Total {$} frames will be send inside detector", pExpProgress->frame_number); if (7 == m_nFluCurrentExpStatus && 6 == m_nFluLastExpStatus) { m_nMaxFrameId = pExpProgress->expStatus & 0xffff; FINFO("Detected x-ray stopped, the max frame number inside detector is {$}", m_nMaxFrameId); } m_nFluLastExpStatus = m_nFluCurrentExpStatus; break; } case EVT_NEW_FRAME: { FINFO("Callback EVT_NEW_FRAME"); int nBuffIndex = *(int*)eventData->data; FINFO("nBuffIndex:{$}, image width:{$},height:{$},bits:{$}", nBuffIndex, eventData->width, eventData->height, eventData->bits); int nFrameSize = eventData->width * eventData->height * (eventData->bits / 8) + FLUORO_IMAGE_HEADER_SIZE; char* pCurrentFrameData = (char*)m_pFluFrameData + nBuffIndex * nFrameSize; m_nReceivedFrameId = *(int*)(pCurrentFrameData + 8); FINFO("frame size = {$}, m_nReceivedFrameId = {$}, ", nFrameSize, m_nReceivedFrameId); //把图推上去 if (m_nAppStatus != APP_STATUS_CAL_BEGIN && m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(eventData->height, eventData->width, (WORD*)pCurrentFrameData); } DataFeedback(EVT_DATA_RAW_IMAGE, pCurrentFrameData); if (m_nSaveRaw) { SaveRawFunc((WORD*)pCurrentFrameData, eventData->width, eventData->height, to_string(m_nReceivedFrameId)); } if (m_nReceivedFrameId >= m_nMaxFrameId) { FINFO("Flu acquisition finished, ready to exit the acquisition..."); } break; } case EVT_CALIB_IN_PROGRESS: FINFO("Callback EVT_CALIB_IN_PROGRESS"); break; case EVT_CALIB_FINISHED: FINFO("Callback EVT_CALIB_FINISHED"); break; case EVT_PREV_IMAGE_ARRIVED: FINFO("Callback EVT_PREV_IMAGE_ARRIVED"); //如果PreviewEnable是1 并且是CareRay1800Cw 系列的探测器 则获取预览图 if (m_nPreviewEnable && m_strDetectorType.find("1800Cw") != std::string::npos) { FINFO("Call get preview image"); int result = API_CR_get_preview_image(m_nImageSize, FALSE, m_pPreImgBuffer); DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pPreImgBuffer); if (m_nSaveRaw) { SaveRawWithName("Preview.raw",m_pPreImgBuffer, m_nPreImgWidth, m_nPreImgHeight); } Sleep(300); } break; case EVT_CALIB_FILES_DOWNLOAD_FAILED: FINFO("Callback EVT_CALIB_FILES_DOWNLOAD_FAILED"); break; default: FERROR("not support current event ID:{$}", eventID); break; } } void Detector_CareRayDR::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_CareRayDR::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_CareRayDR::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_CareRayDR::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_CareRayDR::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } void Detector_CareRayDR::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } bool Detector_CareRayDR::UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode) { FINFO("========UpdateCalibMode eCalibMode:{$}", (int)eCalibMode); m_nCalibrationMode = eCalibMode; return true; } void Detector_CareRayDR::SetNotifyStatusTimePeriod(int nTime) { FINFO("========SetNotifyStatusTimePeriod nTime:{$}", nTime); m_nNotifyStatusTimePeriod = nTime; } void Detector_CareRayDR::SetReconnectTimePeriod(int nTime) { FINFO("========SetReconnectTimePeriod nTime:{$}", nTime); m_nReconnectTimePeriod = nTime; } /*** ** 说明:重连探测器线程 ***/ unsigned __stdcall Detector_CareRayDR::onReconnectThread(PVOID pvoid) { FINFO("Reconnect detector thread start"); Detector_CareRayDR* pOpr = (Detector_CareRayDR*)pvoid; while (!pOpr->m_pStPanelStatus[pOpr->m_nCurrentPanelID]->bConnectState) { pOpr->ConnectDetector(); Sleep(pOpr->m_nReconnectTimePeriod); } FINFO("Leave reconnect detector thread"); return 0; }