#include "stdafx.h" #include "AxsCtrl.h" #include "CCOS.Dev.FPD.AxsDM.h" #include "common_api.h" #include "PacketAnalizer.h" CAXSCtrl* g_pDetector = nullptr; #define LOAD_PROC_ADDRESS(handle,func) \ if ((API_##func = (AXS_##func)GetProcAddress(handle, #func)) == NULL) { printf("Error occurs while loading entry point!!! \n'%s'\n", #func); }\ CAXSCtrl::CAXSCtrl() { m_pDPC2PanelID = new map(); m_pPanelID2DPC = new map(); m_nPanelCount = 0;//最少一个板 m_nCurrentPanelID = 0; m_strWorkPath = ""; m_strTplDarkPath = ""; m_strTplFloodPath = ""; m_ePZDPCstate = PZDPC_STATE_INIT; m_bHavePreview = false; m_nImageMode = 0; m_nAecImageWidth = 0; m_nAecImageHeight = 0; m_nAecImageSize = 0; m_nAecImageBits = 16; m_nAecPixelSize = 4; m_nRawImgWidth = 0; m_nRawImgHeight = 0; m_nRawImageSize = 0; m_nRawImageBits = 16; m_nRawPixelSize = 2; m_nLeftOffset = 0; m_nTopOffset = 0; m_nRightOffset = 0; m_nBottomOffset = 0; m_nImageWidth = 0; m_nImageHeight = 0; m_nImageSize = 0; m_nImageBits = 16; m_nImagePixelSize = 2; m_pAecImgBuffer = nullptr; m_pRawImgBuffer = nullptr; m_pImgBuffer = nullptr; m_nPixelPitch = 85;//单位:um m_nSequenceId = 0; m_nImageIndex = 0; m_nSaveRaw = 0; m_nExamMode = APP_STATUS_IDLE; m_nCalibrationMode = CCOS_CALIBRATION_MODE_ZSKK; m_eType = CCOS_CALIBRATION_TYPE_NONE; m_eCalState = PZ_CALIBRATION_ORIGINAL; m_bCalibrationOver = false; m_detectorState = PEGASUS_SERVICE_STATE; m_pZSKKCalib = nullptr; m_strPanelType = ""; m_strSerialNumber = ""; m_bLoadedSDK = false; m_bInitializedSDK = false; m_nCalibrationRounds = 0; m_nCalibCurrentCalibrationRound = 0; m_nExposureNumCurrentRound = 0; m_nCalibCurrentExposureIndex = 0; m_bOnlyHaveFpd = false; m_context = PEGASUS_CONTEXT_CONTACT; m_nCurrentAcqMode = ACQ_UNKNOWN; m_targetFilter = PEGASUS_TARGET_FILTER_0; memset(&m_ResultImage, 0, sizeof(m_ResultImage)); m_bReadyForExp = false; m_bChangeAcqProperties = false; m_nTimerHardWare = 0; m_bShutDownFlag = false; m_bTimeOutFlag = false; string temp = "AxsDetectorCtrl"; temp = temp + std::to_string(getpid()); m_pAcqUnitCient = new LogicClient(temp, "", "", false); if (m_pAcqUnitCient->Open("ccosChannel", ALL_ACCESS)) { m_pAcqUnitCient->SubScribeTopic("CCOS/DEVICE/Generator/+/+/+/Notify/GENERATORSYNCSTATE"); } m_hPZSDKModule = nullptr; m_hRespond = CreateEvent(NULL, FALSE, FALSE, NULL); m_bExitGetInfoThread = false; m_hDetectorInfoThread = nullptr; m_bExitFpdScanThread = false; m_hFPDScanThread = nullptr; //1-一般为NULL 2-是否自动复位 true-人工复位 false-自动复位 3-初始状态 true-有信号 false-无信号 4-事件名称 m_hStopScanEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hAecImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hCorrectedImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hXWinOnEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hInitFPDEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hReInitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hRecoverImage = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hStopScanEvent; m_hArrayEvent[1] = m_hAecImgEvent; m_hArrayEvent[2] = m_hCorrectedImgEvent; m_hArrayEvent[3] = m_hXWinOnEvent; m_hArrayEvent[4] = m_hInitFPDEvent; m_hArrayEvent[5] = m_hReInitEvent; m_hArrayEvent[6] = m_hRecoverImage; m_hArrayEvent[7] = m_pAcqUnitCient->GetNotifyHandle(); //校正线程 m_bExitCalibrationThread = false; m_hCalibrationThread = nullptr; m_hStopCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hPZMStartOffset = CreateEvent(NULL, FALSE, FALSE, NULL); m_hPZMInOffset = CreateEvent(NULL, FALSE, FALSE, NULL); m_hPZMStartGain = CreateEvent(NULL, FALSE, FALSE, NULL); m_hPZMInGain = CreateEvent(NULL, FALSE, FALSE, NULL); m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hPZMCalibration[0] = m_hStopCalibEvent; m_hPZMCalibration[1] = m_hPZMStartOffset; m_hPZMCalibration[2] = m_hPZMInOffset; m_hPZMCalibration[3] = m_hPZMStartGain; m_hPZMCalibration[4] = m_hPZMInGain; m_hPZMCalibration[5] = m_hEndCalibEvent; API_PEGASUS_RegisterProgressionCallback = nullptr; API_PEGASUS_Initialize = nullptr; API_PEGASUS_QuickInitialize = nullptr; API_PEGASUS_Shutdown = nullptr; API_PEGASUS_LoadContext = nullptr; API_PEGASUS_DetailedInformation = nullptr; API_PEGASUS_Information = nullptr; API_PEGASUS_SystemDetailedInformation = nullptr; API_PEGASUS_CalibrationInformation = nullptr; API_PEGASUS_GetCalibrationInformation = nullptr; API_PEGASUS_GetCalibrationInformationUsingType = nullptr; API_PEGASUS_IsReadyForExposure = nullptr; API_PEGASUS_Acquire = nullptr; API_PEGASUS_AbortAcquire = nullptr; API_PEGASUS_StartContinuousAcquisition = nullptr; //API_PEGASUS_StartContinuousAcquisitionEx = nullptr; API_PEGASUS_ChangeContinuousAcquisitionProperties = nullptr; //API_PEGASUS_ChangeContinuousAcquisitionPropertiesEx = nullptr; API_PEGASUS_GetContinuousAcquisitionProperties = nullptr; //API_PEGASUS_GetContinuousAcquisitionPropertiesEx = nullptr; API_PEGASUS_OverrideTargetFilter = nullptr; API_PEGASUS_GetAecImage = nullptr; API_PEGASUS_GetCorrectedImage = nullptr; API_PEGASUS_GetInformationOfFirstAvailableImage = nullptr; API_PEGASUS_StartSingleAcquisition = nullptr; API_PEGASUS_PrepareForExposure = nullptr; API_PEGASUS_TriggerAcquisition = nullptr; API_PEGASUS_RecoverImage = nullptr; //API_PEGASUS_RecoverImageEx = nullptr; API_PEGASUS_CancelImageRecovery = nullptr; API_PEGASUS_RecoverLastSequenceID = nullptr; API_PEGASUS_Calibrate = nullptr; //API_PEGASUS_CalibrateEx = nullptr; API_PEGASUS_GetNbrCalImagesLeft = nullptr; API_PEGASUS_AbortCalibration = nullptr; API_PEGASUS_AddImageToCalibration = nullptr; API_PEGASUS_RejectCalibrationImage = nullptr; API_PEGASUS_AutoCalibrate = nullptr; API_PEGASUS_CalibrateUsingType = nullptr; API_PEGASUS_StopComServer = nullptr; API_PEGASUS_GetLogLevel = nullptr; API_PEGASUS_SetLogLevel = nullptr; API_PEGASUS_SelfTest = nullptr; API_PEGASUS_Sleep = nullptr; API_PEGASUS_ServiceImageInformation = nullptr; API_PEGASUS_GetServiceImage = nullptr; API_PEGASUS_UpdateDefectMap = nullptr; API_PEGASUS_GetWeakDefect = nullptr; API_PEGASUS_UpdateWeakDefect = nullptr; API_PEGASUS_GetErrorDescription = nullptr; API_PEGASUS_GetEventDescription = nullptr; API_PEGASUS_GetMultiEventDescription = nullptr; API_PEGASUS_GetDebugDump = nullptr; API_PEGASUS_GetDetectorTypeDescription = nullptr; API_PEGASUS_GetProductTypeDescription = nullptr; API_PEGASUS_GetContextCodeDescription = nullptr; API_PEGASUS_GetDetectorStateDescription = nullptr; API_PEGASUS_GetPegasusStateDescription = nullptr; API_PEGASUS_GetLogLevelCodeDescription = nullptr; API_PEGASUS_GetSelfTestTypeDescription = nullptr; API_PEGASUS_GetTargetFilterTypeDescription = nullptr; API_PEGASUS_GetFocusTypeDescription = nullptr; API_PEGASUS_GetServiceImageTypeDescription = nullptr; API_PEGASUS_GetPixelFormatDescription = nullptr; API_PEGASUS_GetDefectTypeDescription = nullptr; API_PEGASUS_GetCalibrationTypeDescription = nullptr; API_PEGASUS_GetAvailableContext = nullptr; API_PEGASUS_Entry = nullptr; API_PEGASUS_Exit = nullptr; API_PEGASUS_TerminateAcquisition = nullptr; } CAXSCtrl::~CAXSCtrl() { if (m_nPanelCount != 0) { for (int i = 0; i < m_nPanelCount; i++) { delete[]m_pStPanelStatus[i]; } } m_bExitGetInfoThread = true;//退出获取探测器温度和状态线程 m_bExitFpdScanThread = true; m_bExitCalibrationThread = true; if (m_pAecImgBuffer) { delete[]m_pAecImgBuffer; m_pAecImgBuffer = nullptr; } if (m_pRawImgBuffer) { delete[]m_pRawImgBuffer; m_pRawImgBuffer = nullptr; } if (m_pImgBuffer != nullptr) { delete[]m_pImgBuffer; m_pImgBuffer = nullptr; } if (nullptr != m_pDPC2PanelID) { delete m_pDPC2PanelID; m_pDPC2PanelID = nullptr; } if (nullptr != m_pPanelID2DPC) { delete m_pPanelID2DPC; m_pPanelID2DPC = nullptr; } if (m_pZSKKCalib) { delete m_pZSKKCalib; m_pZSKKCalib = nullptr; } if (m_hRespond) { CloseHandle(m_hRespond); m_hRespond = nullptr; } if (m_hStopScanEvent) { CloseHandle(m_hStopScanEvent); m_hStopScanEvent = nullptr; } if (m_hAecImgEvent) { CloseHandle(m_hAecImgEvent); m_hAecImgEvent = nullptr; } if (m_hCorrectedImgEvent) { CloseHandle(m_hCorrectedImgEvent); m_hCorrectedImgEvent = nullptr; } if (m_hXWinOnEvent) { CloseHandle(m_hXWinOnEvent); m_hXWinOnEvent = nullptr; } if (m_hInitFPDEvent) { CloseHandle(m_hInitFPDEvent); m_hInitFPDEvent = nullptr; } if (m_hReInitEvent) { CloseHandle(m_hReInitEvent); m_hReInitEvent = nullptr; } if (m_hRecoverImage) { CloseHandle(m_hRecoverImage); m_hRecoverImage = nullptr; } if (m_hStopCalibEvent) { CloseHandle(m_hStopCalibEvent); m_hStopCalibEvent = nullptr; } if (m_hPZMStartOffset) { CloseHandle(m_hPZMStartOffset); m_hPZMStartOffset = nullptr; } if (m_hPZMInOffset) { CloseHandle(m_hPZMInOffset); m_hPZMInOffset = nullptr; } if (m_hPZMStartGain) { CloseHandle(m_hPZMStartGain); m_hPZMStartGain = nullptr; } if (m_hPZMInGain) { CloseHandle(m_hPZMInGain); m_hPZMInGain = nullptr; } if (m_hEndCalibEvent) { CloseHandle(m_hEndCalibEvent); m_hEndCalibEvent = nullptr; } } //获取探测器温度和Pegasus的状态 DWORD __stdcall CAXSCtrl::OnGetFpdInfo(PVOID pvoid) { CAXSCtrl* pOpr = (CAXSCtrl*)pvoid; FINFO("Enter Get Detector Info Thread"); PEGASUS_ErrorCode err; PEGASUS_Info info; char shortDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; while (!pOpr->m_bExitGetInfoThread) { //这里没有考虑探测器的状态,可能某些状态时探测器是不支持获取info的,这些后续在加 FINFO("Call API_PEGASUS_Information"); err = pOpr->API_PEGASUS_Information(&info); if (!pOpr->TestError(err,"GetInformation")) { FERROR("Fail to get detector info!"); } else { float fTemperature = info.temperature; pOpr->StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", pOpr->m_nCurrentPanelID, fTemperature); pOpr->m_detectorState = info.pegasusState; memset(shortDescription,0, PEGASUS_MAX_STRING_LENGTH); pOpr->API_PEGASUS_GetPegasusStateDescription(pOpr->m_detectorState,shortDescription); FINFO("OnGetFpdInfo pegasus state:{$},description:{$}", (int)info.pegasusState,shortDescription); if (pOpr->m_pStPanelStatus[pOpr->m_nCurrentPanelID]->bConnectStatus == false) { if (info.pegasusState >= PEGASUS_SHUTDOWN_STATE && info.pegasusState <= PEGASUS_RECOVERY_STATE) { pOpr->m_pStPanelStatus[pOpr->m_nCurrentPanelID]->bConnectStatus = true; pOpr->ErrorFeedback(EVT_ERR_COMMUNICATE, "false", pOpr->m_nCurrentPanelID); pOpr->StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_OK);//通知连接成功 } } if (info.pegasusState == PEGASUS_RECOVERY_STATE) { FINFO("need to recover image..."); } } FINFO("Get Fpd Info Thread Sleep 3s"); Sleep(3000); } FINFO("Exit Get Detector Info Thread"); return 0; } void onEventCallback(PEGASUS_EventType myEvent, PEGASUS_ErrorCode err, void* pContext) { g_pDetector->eventCallback(myEvent,err,pContext); } void CAXSCtrl::eventCallback(PEGASUS_EventType myEvent, PEGASUS_ErrorCode err, void* pContext) { CString strLog; strLog.Format("eventCallback EventType: %d", myEvent); FINFO(strLog.GetString()); PEGASUS_ErrorCode nRet = PEGASUS_SUCCESS; PEGASUS_ExposureData* pExpData = static_cast(pContext); //校正用的曝光参数KV MAS PEGASUS_ExposureData m_CalExpData; char eventDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char errShortDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char errLongDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; API_PEGASUS_GetEventDescription(myEvent, eventDescription); strLog.Format("eventCallback Event: %d, Description: %s", myEvent, eventDescription); FINFO(strLog.GetString()); if (err != PEGASUS_SUCCESS) { API_PEGASUS_GetErrorDescription(err, errShortDescription, errLongDescription); strLog.Format("eventCallback err: %d, errShortDescription: %s, errLongDescription: %s ", err, errShortDescription, errLongDescription); FERROR(strLog.GetString()); } switch (myEvent) { case PEGASUS_NO_EVENT: { FINFO("PEGASUS_NO_EVENT Arrived"); break; } case PEGASUS_ERROR_EVENT: { FERROR("PEGASUS_ERROR_EVENT Arrived,Please Abort DROC and Check For the Problem"); StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); if (err == PEGASUS_MAJOR_TIMEOUT_WAITING_FOR_EXPOSURE) { FERROR("err is PEGASUS_MAJOR_TIMEOUT_WAITING_FOR_EXPOSURE"); } else { if (err == PEGASUS_MAJOR_COMMUNICATION_ERROR) { //m_bExitGetInfoThread = true; } if (!m_bShutDownFlag) { FINFO("PEGASUS_ERROR_EVENT Call API_PEGASUS_Shutdown"); API_PEGASUS_Shutdown();//探测器出现error时 } } break; } case PEGASUS_INITIALIZATION_EVENT: //初始化事件到来 { FINFO("PEGASUS_INITIALIZATION_EVENT Arrived"); if (err == PEGASUS_SUCCESS) { FINFO("Initial success"); StopWaiting("Init"); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK);//通知初始化成功 ErrorFeedback(EVT_ERR_COMMUNICATE, "false", m_nCurrentPanelID); StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_OK);//通知连接成功 m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus = true; //在这里调用开始采集函数,因为校正时也会用到这里的回调,如果不在初始化成功后就开始采集, //那么如果用户一打开软件就进入校正页面,没有进检查界面,那么校正流程就无法进行了 bool ret = StartContinuousAcquisition(); if (!ret) { FERROR("fail to start acq!"); } //开启线程循环获取探测器的信息 detail info 或者 info DWORD dwThreadId; if (m_hDetectorInfoThread == nullptr) { m_hDetectorInfoThread = CreateThread(NULL, 0, OnGetFpdInfo, this, 0, &dwThreadId); //启动辅助线程 } } else { FINFO("Initial detector fail!"); if (err == PEGASUS_WARNING_IMAGE_RECOVERY_IS_NEEDED) { FERROR("need to recover image..."); } } break; } case PEGASUS_SHUTDOWN_EVENT: //关闭探测器事件来到 { FINFO("PEGASUS_SHUTDOWN_EVENT Arrived"); m_bShutDownFlag = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); if (err == PEGASUS_WARNING_IMAGE_RECOVERY_IS_NEEDED)//需要恢复图像,此时并不是真正的shutdown状态 { FERROR("need to recover image..."); SetEvent(m_hRecoverImage);//恢复图像流程 } else { SetEvent(m_hReInitEvent); } break; } case PEGASUS_CONTEXT_CHANGE_EVENT: //改变CONTEXT模式,DROC中无法手动改变 { FINFO("PEGASUS_CONTEXT_CHANGE_EVENT Arrived"); if (pContext) { m_context = *((PEGASUS_Context*)pContext); API_PEGASUS_GetContextCodeDescription(m_context, errShortDescription); FINFO("Context Code Description:{$}",errShortDescription); } break; } case PEGASUS_SELF_TEST_EVENT: { FINFO("PEGASUS_SELF_TEST_EVENT Arrived"); break; } case PEGASUS_AEC_DATA_EVENT: { FINFO("PEGASUS_AEC_DATA_EVENT Arrived"); //原来V2在这里通知APP进行读图 CCOS不用通知 APP收到出线通知就会显示进度条 break; } case PEGASUS_CORRECTED_IMAGE_EVENT: { FINFO("PEGASUS_CORRECTED_IMAGE_EVENT Arrived"); //原来V2在这里通知APP进行读图 CCOS不用通知 APP收到出线通知就会显示进度条 break; } case PEGASUS_ACQUIRE_DONE_EVENT: //采集完成 { FINFO("PEGASUS_ACQUIRE_DONE_EVENT Arrived"); //::PostMessage(g_CurPanel->m_hWnd, MSG_PANEL_STATUS, PNL_READY, NULL); //StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); break; } case PEGASUS_ACQUIRE_ABORT_EVENT: //采集终止 { FINFO("PEGASUS_ACQUIRE_ABORT_EVENT Arrived"); //StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); break; } case PEGASUS_CALIBRATION_ACQUIRE_READY_EVENT: //校正开始,准备SC校正曝光 { FINFO("PEGASUS_CALIBRATION_ACQUIRE_READY_EVENT Arrived"); //::PostMessage(g_CurPanel->m_hWnd, MSG_PANEL_STATUS, PNL_READY, NULL); StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); StopWaiting("CalibrationAcquire"); memcpy(&m_CalExpData, pExpData, sizeof(m_CalExpData)); ShowExposureParam(m_CalExpData); // 写日志记录曝光参数 break; } case PEGASUS_CALIBRATION_CORRECTED_IMAGE_EVENT: // 这个事件 LAM2 不再使用 { FINFO("PEGASUS_CALIBRATION_CORRECTED_IMAGE_EVENT Arrived"); break; } case PEGASUS_CALIBRATION_DONE_EVENT: //校正结束 { FINFO("PEGASUS_CALIBRATION_DONE_EVENT Arrived,One time Finished"); //::PostMessage(g_CurPanel->m_hWnd, MSG_PANEL_STATUS, PNL_COMP_CAL_END, NULL); //StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); break; } case PEGASUS_CALIBRATION_ABORT_EVENT: //校正终止 { FINFO("PEGASUS_CALIBRATION_ABORT_EVENT Arrived,Calibration Abort"); //::PostMessage(g_CurPanel->m_hWnd, MSG_PANEL_STATUS, PNL_READY, NULL); //StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); SetEvent(m_hEndCalibEvent); break; } case PEGASUS_READY_FOR_EXPOSURE_EVENT: //平板ready事件 { //SDK2.19.0.0不会回调此事件 FINFO("PEGASUS_READY_FOR_EXPOSURE_EVENT Arrived,Detector is ready for exposure"); m_bReadyForExp = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); break; } default: break; } strLog.Format("End to Get Event: %d", myEvent); FINFO(strLog.GetString()); } void CAXSCtrl::ShowExposureParam(PEGASUS_ExposureData& expData) { CString strLog; FINFO("ShowExposureParam start"); char targetFilterDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char focusTypeDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char contextDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char pegasusStateDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; strLog.Format(_T(" imageLeft : %i"), expData.imageLeft); FINFO(strLog.GetString()); strLog.Format(_T(" mas : %f"), expData.mas); FINFO(strLog.GetString()); strLog.Format(_T(" kv : %i"), expData.kv); FINFO(strLog.GetString()); strLog.Format(_T(" use_grid : %s"), (expData.use_grid ? "YES" : "NO")); FINFO(strLog.GetString()); strLog.Format(_T(" use_AEC : %s"), (expData.use_AEC ? "YES" : "NO")); FINFO(strLog.GetString()); API_PEGASUS_GetTargetFilterTypeDescription(expData.targetFilter, targetFilterDescription); strLog.Format(_T(" targetFilter: %s"), targetFilterDescription); FINFO(strLog.GetString()); API_PEGASUS_GetFocusTypeDescription(expData.focus, focusTypeDescription); strLog.Format(_T(" focusType : %s"), focusTypeDescription); FINFO(strLog.GetString()); API_PEGASUS_GetContextCodeDescription(expData.context, contextDescription); strLog.Format(_T(" context : %s"), contextDescription); FINFO(strLog.GetString()); API_PEGASUS_GetPegasusStateDescription(expData.pegasusState, pegasusStateDescription); strLog.Format(_T(" pegasusState: %s"), pegasusStateDescription); FINFO(strLog.GetString()); FINFO("ShowExposureParam end"); } void onMultiEventCallback(PEGASUS_MultiEventType myEvent, PEGASUS_ErrorCode err, int sequenceId, int imageIndex) { g_pDetector->multiEventCallback(myEvent,err,sequenceId,imageIndex); } void CAXSCtrl::multiEventCallback(PEGASUS_MultiEventType myEvent, PEGASUS_ErrorCode err, int sequenceId, int imageIndex) { CString strLog; char eventDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char errShortDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; char errLongDescription[PEGASUS_MAX_STRING_LENGTH] = { 0 }; API_PEGASUS_GetMultiEventDescription(myEvent, eventDescription); strLog.Format("multiEventCallback Event is %d,Event Description is %s", myEvent, eventDescription); FINFO(strLog.GetString()); m_nSequenceId = sequenceId; // 序列ID m_nImageIndex = imageIndex; strLog.Format("Current SequenceID is %d,ImageIndex is %d", sequenceId, imageIndex); FINFO(strLog.GetString()); if (err != PEGASUS_SUCCESS) { API_PEGASUS_GetErrorDescription(err, errShortDescription, errLongDescription); strLog.Format("multiEventCallback err: %d, errShortDescription: %s, errLongDescription: %s ", err, errShortDescription, errLongDescription); FERROR(strLog.GetString()); } switch (myEvent) { case PEGASUS_MULTI_READY_FOR_EXPOSURE_EVENT: //探测器ready,可按下手闸曝光 { FINFO("PEGASUS_MULTI_READY_FOR_EXPOSURE_EVENT Arrived,detector is ready,Start to exposure"); m_bReadyForExp = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP); //if (!m_bChangeAcqProperties) //在ready前会执行setAcqMode,如果没有切换成功,在READY后再切换一次 //{ // ChangeAcqProperties(m_nCurrentAcqMode); //采集模式选择 AEC或者NORMAL //} break; } case PEGASUS_MULTI_SEQUENCE_STARTED_EVENT: //手闸按下 激发此事件 { FINFO("PEGASUS_MULTI_SEQUENCE_STARTED_EVENT Arrived,Hand brake pressed"); m_bReadyForExp = false; //如果环境中只有探测器为真实设备,手闸按下后主动通知射线来了否则状态机不能从FrameReady跳转到FrameStart if (m_bOnlyHaveFpd) { FINFO("notify XRAY ON"); StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON); } FINFO("Call TerminateAcquisition"); API_PEGASUS_TerminateAcquisition(); break; } case PEGASUS_MULTI_AEC_DATA_EVENT: //若是AEC模式,AEC图像准备好后激发此事件 { FINFO("PEGASUS_MULTI_AEC_DATA_EVENT Arrived"); if (err == PEGASUS_SUCCESS) { FINFO("set event to get AEC image"); SetEvent(m_hAecImgEvent);//getImage } else { FERROR("err occured is {$}",(int)err); } break; } case PEGASUS_MULTI_CORRECTED_IMAGE_EVENT: //正常图像准备好后,激发此事件 { FINFO("PEGASUS_MULTI_CORRECTED_IMAGE_EVENT Arrived"); if (m_bOnlyHaveFpd) { FINFO("notify XRAY OFF"); StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_OFF); } if (err == PEGASUS_SUCCESS) { FINFO("set event to get corrected image"); //SetEvent(m_hCorrectedImgEvent);//getImage OnProcessCorrectedImg(); StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK); } else { if (err == PEGASUS_MAJOR_IMAGE_LOST_ERROR) { FERROR("image lost, have to recover image!"); } } break; } case PEGASUS_MULTI_SEQUENCE_DONE_EVENT: //获取图像完成或者在规定时间内没有进行曝光 { FINFO("PEGASUS_MULTI_SEQUENCE_DONE_EVENT Arrived"); //断开重连之后,探测器会把这个消息回调过来,如果错误码为PEGASUS_MAJOR_IMAGE_LOST_ERROR需要恢复图像 if (err == PEGASUS_MAJOR_IMAGE_LOST_ERROR) { FERROR("Image lost,have to shutdown and recover image"); if (!m_bShutDownFlag) { FINFO("PEGASUS_MULTI_SEQUENCE_DONE_EVENT PEGASUS_MAJOR_IMAGE_LOST_ERROR Call API_PEGASUS_Shutdown"); API_PEGASUS_Shutdown();//这里的shutdown会有错误码,根据错误码进入恢复图像流程 } } if (err == PEGASUS_MAJOR_TIMEOUT_WAITING_FOR_EXPOSURE)//曝光超时先shutdown再init { m_bTimeOutFlag = true; StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); FERROR("exposure time out current sequence has been aborted. "); //发送关窗 StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF); //曝光超时需要先shutdown,再重新init if (!m_bShutDownFlag) { FINFO("PEGASUS_MULTI_SEQUENCE_DONE_EVENT PEGASUS_MAJOR_TIMEOUT_WAITING_FOR_EXPOSURE Call API_PEGASUS_Shutdown"); API_PEGASUS_Shutdown();//曝光超时 } } break; } case PEGASUS_MULTI_SEQUENCE_NOT_READY_EVENT: { FINFO("PEGASUS_MULTI_SEQUENCE_NOT_READY_EVENT Arrived,Detector not ready"); //::PostMessage(g_CurPanel->m_hWnd, MSG_PANEL_STATUS, PNL_PREPARE, NULL); break; } case PEGASUS_MULTI_READY_FOR_PREPARE_FOR_EXPOSURE_EVENT: { FINFO("PEGASUS_MULTI_READY_FOR_PREPARE_FOR_EXPOSURE_EVENT Arrived,Detector wait for prepare to ready!"); //如果此事件到来时客户端处于检查界面,那么需要重新调用API_PEGASUS_PrepareForExposure让探测器ready FINFO("m_bShutDownFlag:{$}, m_bTimeOutFlag:{$}", m_bShutDownFlag, m_bTimeOutFlag); if (m_bShutDownFlag || m_bTimeOutFlag) { if (m_ePZDPCstate == PZDPC_STATE_WORK || m_ePZDPCstate == PZDPC_STATE_CALIBRATION) { FINFO("Call API_PEGASUS_IsReadyForExposure"); bool readyFlag = API_PEGASUS_IsReadyForExposure(); if (readyFlag) { FINFO("the detector is ready"); } else { FINFO("the detector is not ready!"); int nTimeout = 20; //ready后等待曝光的时间,超时会报错 try { nTimeout = (int)m_objFPDConfig["ReadyTimeout"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); } //等待ready时间为nTimeout,超过这个时间探测器将结束此次采集,下次采集必须重新调用prepareforexposure FINFO("PEGASUS_MULTI_SEQUENCE_DONE_EVENT Call API_PEGASUS_PrepareForExposure"); PEGASUS_ErrorCode ret = API_PEGASUS_PrepareForExposure(nTimeout); if (!TestError(ret, "PrepareForExposure")) { FERROR("Prepare for exposure is fail!"); } } } m_bShutDownFlag = false; m_bTimeOutFlag = false; } break; } default: break; } } bool CAXSCtrl::StartContinuousAcquisition() { FINFO("Enter into StartContinuousAcquisition"); PEGASUS_ErrorCode l_error; bool bAEC = false; if (AEC == m_nCurrentAcqMode) { bAEC = true; } FINFO("Call API_PEGASUS_StartContinuousAcquisition"); l_error = API_PEGASUS_StartContinuousAcquisition(m_targetFilter, bAEC, m_context, onMultiEventCallback); if (!TestError(l_error,"StartContinuousAcquisition")) { FERROR("PEGASUS_StartContinuousAcquisition Failed!"); return false; } FINFO("StartContinuousAcquisition End"); return true; } bool CAXSCtrl::DriverEntry(CFPDDeviceAXS* pDrvDPC, ResDataObject & Configuration) { printf("--Func-- DriverEntry %p \n", pDrvDPC); FINFO("--Func-- 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_objFPDConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储 m_pStPanelStatus[m_nPanelCount]->objPanelConfig = Configuration; m_nPanelCount++; //增加校正模式的赋值操作-后续在进行初始化的时候用到 m_nCalibrationMode = (CCOS_CALIBRATION_MODE)(int)m_objFPDConfig["CalibMode"]; return true; } /// /// 设备连接,启动辅助线程,初始化平板,此时已获取到配置信息 /// /// /// /// bool bool CAXSCtrl::Connect(CFPDDeviceAXS* pDrvDPC, const char* szWorkPath) { printf("--Func-- Connect begin...\n"); FINFO("--Func-- Connect. work path:{$}", szWorkPath); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return true; } //初始化失败错误,基本不可以恢复了,直接返回false if (m_pStPanelStatus[m_nCurrentPanelID]->bInitError) { printf("\n Connect detector over(err_init) \n"); FINFO("Connect detector over(err_init)"); return false; } //初始化阶段出现连接错误,这种状态下不再执行下面的流程 if (m_pStPanelStatus[m_nCurrentPanelID]->bConnErrorInInit) { if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { printf("\n Connect detector over(err_connect) \n"); FINFO("Connect detector over(err_connect)"); return false; } else { printf("\n Connect detector over \n"); FINFO("Connect detector over"); return true; } } //输出一次日期,看日志方便 //SYSTEMTIME st; //GetLocalTime(&st); //FINFO("Date: [%04d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay); //FERROR("Date: [%04d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay); //end if (m_strWorkPath == "") { m_strWorkPath = szWorkPath; } if (!m_pZSKKCalib) { m_pZSKKCalib = new CZSKKCalibrationCtrl(); } DWORD dwThreadId; if (m_hFPDScanThread == nullptr) { m_hFPDScanThread = CreateThread(NULL, 0, onFPDScanThread, this, 0, &dwThreadId); //启动辅助线程 } SetPZDPCState(PZDPC_STATE_INIT); //进入初始化状态 SetEvent(m_hInitFPDEvent); return true; } bool CAXSCtrl::Disconnect() { FINFO("--Func-- Disconnect"); //先退出线程,避免重连流程和调用关闭接口冲突 SetEvent(m_hStopScanEvent); //关闭辅助线程 SetEvent(m_hStopCalibEvent);//关闭校正线程 m_bExitGetInfoThread = true;//关闭获取探测器信息线程 if (m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus = false; } if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Unload ZSKK Reference file"); m_pZSKKCalib->UnLoadZSKKGainMap(); m_pZSKKCalib->UnLoadZSKKPixMap(); } FINFO("Disconnect over"); return true; } void CAXSCtrl::EnterExamMode(int nExamMode) { switch (nExamMode) { case APP_STATUS_WORK_BEGIN: FINFO("Enter into Exam Windows"); m_nExamMode = APP_STATUS_WORK_BEGIN; break; case APP_STATUS_WORK_END: FINFO("Quit Exam Windows set detector state standby"); m_nExamMode = APP_STATUS_WORK_END; SetPZDPCState(PZDPC_STATE_STANDBY); break; case APP_STATUS_DETSHARE_BEGIN: FINFO("Enter into Detector Share Windows"); m_nExamMode = APP_STATUS_DETSHARE_BEGIN; break; case APP_STATUS_DETSHAR_END: m_nExamMode = APP_STATUS_IDLE; FINFO("Quit Detector Share Windows"); m_nExamMode = APP_STATUS_DETSHAR_END; break; case APP_STATUS_CAL_BEGIN: FINFO("Enter into Calibration Windows"); m_nExamMode = APP_STATUS_CAL_BEGIN; break; case APP_STATUS_CAL_END: FINFO("Quit Calibration Windows"); m_nExamMode = APP_STATUS_CAL_END; break; case APP_STATUS_WORK_IN_SENSITIVITY: FINFO("Enter into sensitivity test interface"); m_nExamMode = APP_STATUS_WORK_IN_SENSITIVITY; break; default: break; } } //设置同步模式 void CAXSCtrl::SetSynMode(int nMode) { FINFO("SetSynMode: {$}", nMode); m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)nMode; } void CAXSCtrl::SetCalibMode(CCOS_CALIBRATION_MODE eCalibMode) { FINFO("SetCalibMode: {$}", (int)eCalibMode); m_nCalibrationMode = eCalibMode; } bool CAXSCtrl::PrepareAcquisition(CFPDDeviceAXS* pDrvDPC) { FINFO("CAXSCtrl::PrepareAcquisition"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } SetPZDPCState(PZDPC_STATE_WORK); //此时进入检查 if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FERROR("There is no detector connected, return"); return false; } //在调接口让探测器ready之前先判断探测器是否ready,如果已经ready那么不调接口prepare FINFO("Call API_PEGASUS_IsReadyForExposure"); bool bRet = API_PEGASUS_IsReadyForExposure(); if (bRet) { FINFO("the detector is ready! return"); return true; } int nTimeout = 20; //ready后等待曝光的时间,超时会报错 try { nTimeout = (int)m_objFPDConfig["ReadyTimeout"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); } //等待ready时间为nTimeout,超过这个时间探测器将结束此次采集,下次采集必须重新调用prepareforexposure FINFO("PrepareAcquisition Call API_PEGASUS_PrepareForExposure"); PEGASUS_ErrorCode ret = API_PEGASUS_PrepareForExposure(nTimeout); if (!TestError(ret, "PrepareForExposure")) { FERROR("Prepare for exposure is fail!"); return false; } StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START); return true; } bool CAXSCtrl::StartAcquisition(CFPDDeviceAXS* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } FINFO("NotifyXWindowOn"); printf("NotifyXWindowOn\n"); SetEvent(m_hXWinOnEvent); return true; } /*** ** 调用api,结束采集 ** LMAM3-IZ85c一般情况下不会调用stop ***/ bool CAXSCtrl::StopAcquisition(CFPDDeviceAXS* pDrvDPC) { FINFO("CAXSCtrl::StopAcquisition"); if (nullptr != pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } } return true; } /*** ** 说明:激活校正 ***/ bool CAXSCtrl::ActiveCalibration(CFPDDeviceAXS* pDrvDPC, CCOS_CALIBRATION_TYPE eType) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FERROR("There is no detector connected, return"); return false; } StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START); DWORD dwThreadId; if (m_hCalibrationThread == nullptr) { m_hCalibrationThread = CreateThread(NULL, 0, onCalibrationThread, this, 0, &dwThreadId); } else { FERROR("The calibration process is ongoing"); } if (nullptr == m_hCalibrationThread) { FERROR("Start calibration thread failed"); return false; } m_eType = eType; SetPZDPCState(PZDPC_STATE_CALIBRATION); m_eCalState = PZ_CALIBRATION_INIT; //参考trixellDR 流程 if (CCOS_CALIBRATION_TYPE_DARK == eType) { FINFO("Active Dark Calibration"); } else if (CCOS_CALIBRATION_TYPE_XRAY == eType) { FINFO("Active Xray Calibration"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { if (!m_pZSKKCalib) { FERROR("ZSKK Calibration object is undefined"); } else { //反馈Dose信息 DataFeedback(EVT_DATA_DOSEPARAM, NULL, 0, 25.0); //加载ZSKK的校正文件 m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "\\rawdata\\"; m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "\\references\\"; m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth; m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight; m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds; m_pZSKKCalib->m_nSaturationValue = 50000; m_pZSKKCalib->LoadZSKKGainMap(false, m_strPanelType); m_pZSKKCalib->LoadZSKKPixelMap(false, m_strPanelType); FINFO("Start ZSKK Gain!"); FINFO("references file path: {$}", m_pZSKKCalib->m_strRefFilePath.c_str()); } } } else { FINFO("Active not supported calibration({$}), return!", (int)eType); } return true; } /*** ** 说明:准备校正(状态机FramePrep) ***/ bool CAXSCtrl::PrepareCalibration(CFPDDeviceAXS* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FERROR("There is no detector connected, return"); return false; } if (CCOS_CALIBRATION_TYPE_XRAY == m_eType) { FINFO("PrepareCalibration type = {$}", (int)CCOS_CALIBRATION_TYPE_XRAY); m_eCalState = PZ_CALIBRATION_GAIN; if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("PrepareCalibration ZSKK"); FINFO("Call API_PEGASUS_IsReadyForExposure"); bool ret = API_PEGASUS_IsReadyForExposure(); if (ret) { FINFO("The detector is ready!"); StatusFeedback(EVT_STATUS_PANEL, PANEL_GAIN_READY_EXP);//notify detector is ready } else { FERROR("Ther detector is not ready!"); //如果不ready该如何处理后续再加 return false; } } else { FINFO("PrepareCalibration OTHER"); FINFO("Call API_PEGASUS_CalibrateUsingType"); PEGASUS_ErrorCode ret = API_PEGASUS_CalibrateUsingType(PEGASUS_CALIBRATION_TYPE_GAIN, m_nExposureNumCurrentRound); if (!TestError(ret, "PEGASUS_CalibrateUsingType")) { FERROR("Pegasus Start Calibration Failed!"); return false; } //等待ready通知 int nTimeout = 15; try { nTimeout = (int)m_objFPDConfig["ReadyTimeout"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); } if (!WaitRespond(nTimeout, "PrepareCalibration Going to ready")) //没有等到ready回调,返回失败 { return false; } printf("PrepareCalibration wait end...\n"); FINFO("PrepareCalibration wait end..."); StatusFeedback(EVT_STATUS_PANEL, PANEL_GAIN_READY_EXP);//notify detector is ready } } else { //LMAM3-IZ85c不用暗场校正直接返回成功即可(暗场走个流程,没有实质性的动作) FINFO("PrepareCalibration type = {$}", (int)CCOS_CALIBRATION_TYPE_DARK); m_eCalState = PZ_CALIBRATION_OFFSET; } return true; } bool CAXSCtrl::StartCalibration(CFPDDeviceAXS* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FERROR("There is no detector connected, return"); printf("the detector is not connected\n"); return false; } if (CCOS_CALIBRATION_TYPE_DARK == m_eType) { printf("开始 DARK 校正 \n"); FINFO("start dark calibration"); m_eCalState = PZ_CALIBRATION_OFFSET; //SetEvent(m_hPZMStartOffset); SetEvent(m_hPZMInOffset); } else if(CCOS_CALIBRATION_TYPE_XRAY == m_eType) { printf("开始 GAIN 校正 \n"); FINFO("start gain calibration"); m_eCalState = PZ_CALIBRATION_GAIN; //SetEvent(m_hPZMStartGain); } return true; } bool CAXSCtrl::StopCalibration(CFPDDeviceAXS* pDrvDPC) { if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { printf("Not current DPC, return\n"); FERROR("Not current DPC, return"); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FERROR("There is no detector connected, return"); return false; } if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { m_bCalibrationOver = false; //用户停止校正 } return true; } /// /// 动态加载设备厂商SDK DLL /// bool CAXSCtrl::LoadSdkDll() { string strSDKPath = ""; string strDllpath = ""; try { strSDKPath = (string)m_objFPDConfig["SDKPath"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); return false; } strSDKPath = m_strWorkPath + "\\" + strSDKPath; strDllpath = strSDKPath + "\\Pegasus.dll"; FINFO("Load SDK path: {$}", strDllpath.c_str()); //将SDK路径加入环境变量 char* pathvar; pathvar = getenv("Path"); printf("pathvar = %s \n\n", pathvar); string strPath = "Path="; strPath += pathvar; strPath += ";"; strPath += strSDKPath; printf("strPath:%s \n\n", strPath.c_str()); if (_putenv(strPath.c_str()) != 0) { DWORD dw = GetLastError(); printf("Add dll failed: %d \n", dw); return false; } //pathvar = getenv("Path"); //test //printf("pathvar = %s \n\n", pathvar); m_hPZSDKModule = LoadLibraryEx(strDllpath.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (m_hPZSDKModule == nullptr) { DWORD dw = GetLastError(); FERROR("Load {$} failed: {$} \n", strDllpath.c_str(), dw); return false; } LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_RegisterProgressionCallback); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Initialize); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_QuickInitialize); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Shutdown); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_LoadContext); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_DetailedInformation); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Information); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_SystemDetailedInformation); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_CalibrationInformation); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetCalibrationInformation); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetCalibrationInformationUsingType); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_IsReadyForExposure); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Acquire); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_AbortAcquire); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_StartContinuousAcquisition); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_StartContinuousAcquisitionEx); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_ChangeContinuousAcquisitionProperties); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_ChangeContinuousAcquisitionPropertiesEx); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetContinuousAcquisitionProperties); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetContinuousAcquisitionPropertiesEx); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_OverrideTargetFilter); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetAecImage); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetCorrectedImage); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetInformationOfFirstAvailableImage); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_StartSingleAcquisition); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_PrepareForExposure); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_TriggerAcquisition); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_RecoverImage); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_RecoverImageEx); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_CancelImageRecovery); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_RecoverLastSequenceID); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Calibrate); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_CalibrateEx); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetNbrCalImagesLeft); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_AbortCalibration); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_AddImageToCalibration); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_RejectCalibrationImage); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_AutoCalibrate); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_CalibrateUsingType); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_StopComServer); //LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetLogLevel); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_SetLogLevel); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_SelfTest); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Sleep); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_ServiceImageInformation); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetServiceImage); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_UpdateDefectMap); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetWeakDefect); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_UpdateWeakDefect); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetErrorDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetEventDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetMultiEventDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetDebugDump); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetDetectorTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetProductTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetContextCodeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetDetectorStateDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetPegasusStateDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetLogLevelCodeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetSelfTestTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetTargetFilterTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetFocusTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetServiceImageTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetPixelFormatDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetDefectTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetCalibrationTypeDescription); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_GetAvailableContext); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Entry); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_Exit); LOAD_PROC_ADDRESS(m_hPZSDKModule, PEGASUS_TerminateAcquisition); m_bLoadedSDK = true; FINFO("Load SDK over"); return true; } /// /// 初始化 SDK初始化接口中会连接探测器 /// [DONE.CHECKED.] /// /// PEGASUS_ErrorCode CAXSCtrl::InitSDK() { printf("Begin initialize SDK \n"); FINFO("Begin initialize SDK\n"); PEGASUS_ErrorCode nRet = PEGASUS_SUCCESS; bool bQuickFlag = true; // 是否快速初始化 bool isSkipEoConfig = false; // 是否跳过EO初始化 if (bQuickFlag) { FINFO("Enter into QuickInitialize"); //从关闭模式恢复(如果15分钟没有动作探测器进入关闭模式,相当于省电模式)时使用quick initial if (isSkipEoConfig) { FINFO("QuickInitialize Pegasus w/o reading the EOs."); FINFO(" This operation takes less than one minute to complete."); } else { FINFO("QuickInitialize Pegasus with EOs reading."); FINFO(" This operation takes less than one minute to complete if the EOs are not expired"); FINFO(" Otherwise it could take a couple of minutes."); } nRet = API_PEGASUS_QuickInitialize(onEventCallback, m_context, isSkipEoConfig); if (!TestError(nRet, "PEGASUS_QuickInitialize")) { FERROR("Quick Initialize fail!"); } } else { FINFO("Enter into Initialize"); nRet = API_PEGASUS_Initialize(onEventCallback); if (!TestError(nRet, "PEGASUS_Initialize")) { FERROR("Initialize fail!"); } } if (PEGASUS_SUCCESS == nRet) { //等待初始化成功通知 int nTimeout = 30000; //缺省等30s try { nTimeout = (int)m_objFPDConfig["ConnectTimeout"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); } if (!WaitRespond(nTimeout, "Initialize Going to connect")) //没有等到初始化成功的回调,返回失败 { nRet = PEGASUS_MAJOR_TIMEOUT_ERROR; goto my_error; } printf("Initialize wait end...\n"); FINFO("Initialize wait end..."); if (m_ePZDPCstate == PZDPC_STATE_INIT) { m_pStPanelStatus[m_nCurrentPanelID]->bConnErrorInInit = false; } //调用接口获取探测器信息并打印到日志中 nRet = GetDetectorInfo(); if (nRet) { FERROR("InitSDK GetDetectorInfo fail!"); } } my_error: //根据最后一次的返回值判断 if (PEGASUS_SUCCESS != nRet) { StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); FERROR("Initialize error,code:{$}", (int)nRet); if (PEGASUS_MAJOR_COMMUNICATION_ERROR == nRet) { //m_bExitGetInfoThread = true; if (m_ePZDPCstate == PZDPC_STATE_INIT) { m_pStPanelStatus[m_nCurrentPanelID]->bConnErrorInInit = true; StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END); } } else { FINFO("InitSDK other error"); if (m_ePZDPCstate == PZDPC_STATE_INIT) { m_pStPanelStatus[m_nCurrentPanelID]->bInitError = true; ErrorFeedback(EVT_ERR_INIT_FAILED, "true"); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR); } } } printf("Initialize SDK over \n"); FINFO("Initialize SDK over\n"); return nRet; } bool CAXSCtrl::LoadZskkMap() { FINFO("Begin LoadZskkMap"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Load ZSKK Reference file"); if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strPanelType)) { FERROR("Load ZSKK Gain Map failed!"); } if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_strPanelType)) { FERROR("Load ZSKK Defect Map failed!"); } } FINFO("LoadZskkMap over"); return true; } void CAXSCtrl::GetConfigParam() { FINFO("GetConfigParam start"); //从配置文件中读取当前环境中是否只有一个探测器是真实设备的配置项 m_bOnlyHaveFpd = ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[m_nCurrentPanelID])->GetOnlyHaveFpd(); if (m_bOnlyHaveFpd) { FINFO("Current system only have FPD other is demo!"); } FINFO("GetConfigParam end"); } //获取SDK版本信息,获取探测器信息 PEGASUS_ErrorCode CAXSCtrl::GetDetectorInfo() { FINFO("===== Get Detailed Information Start====="); CString strLog; PEGASUS_ErrorCode err; PEGASUS_DetailedInfo l_di; char description[PEGASUS_MAX_STRING_LENGTH] = {0}; // Get Pegasus detailed information FINFO("Call PEGASUS_DetailedInformation"); err = API_PEGASUS_DetailedInformation(&l_di); if (!TestError(err,"GetDetailedInformation")) { FERROR("Pegasus failed to return Pegasus detailed information during Acquire"); return err; } else { //DetectorType API_PEGASUS_GetDetectorTypeDescription(l_di.detector_type, description); strLog.Format("Detector Type %d : %s", l_di.detector_type, description); FINFO(strLog.GetString()); //Current Context API_PEGASUS_GetContextCodeDescription(l_di.current_context, description); strLog.Format("Current Context %d : %s", l_di.current_context, description); FINFO(strLog.GetString()); //FirmwareInfo----------- //DetectorID strLog.Format( "Detector's DetectorID : %s",l_di.firmwareInfo.detectorID); FINFO(strLog.GetString()); //TFT panel ID strLog.Format( "Detector's Panel ID : %s",l_di.firmwareInfo.panelId); FINFO(strLog.GetString()); //system configuration release strLog.Format( "Detector's system configuration release : %s",l_di.firmwareInfo.sysRelease); FINFO(strLog.GetString()); //cpuBootVer strLog.Format( "Detector's cpuBootVer : %s",l_di.firmwareInfo.cpuBootVer); FINFO(strLog.GetString()); //cpuVer strLog.Format( "Detector's cpuVer : %s",l_di.firmwareInfo.cpuVer); FINFO(strLog.GetString()); //FPGAVer firmware version strLog.Format("Detector's firmware version : %s", l_di.firmwareInfo.fpgaVer); FINFO(strLog.GetString()); //FPGA Top 0 firmware version strLog.Format("Detector's Top 0 firmware version : %s", l_di.firmwareInfo.fpgaT0); FINFO(strLog.GetString()); //FPGA Top 1 firmware version strLog.Format("Detector's Top 1 firmware version : %s", l_di.firmwareInfo.fpgaT1); FINFO(strLog.GetString()); //FPGA Top 2 firmware version strLog.Format("Detector's Top 2 firmware version : %s", l_di.firmwareInfo.fpgaT2); FINFO(strLog.GetString()); //FPGA Top 3 firmware version strLog.Format("Detector's Top 3 firmware version : %s", l_di.firmwareInfo.fpgaT3); FINFO(strLog.GetString()); //FPBA Bottom 0 firmware version strLog.Format("Detector's Bottom 0 firmware version : %s", l_di.firmwareInfo.fpgaB0); FINFO(strLog.GetString()); //FPBA Bottom 1 firmware version strLog.Format("Detector's Bottom 1 firmware version : %s", l_di.firmwareInfo.fpgaB1); FINFO(strLog.GetString()); //FPBA Bottom 2 firmware version strLog.Format("Detector's Bottom 2 firmware version : %s", l_di.firmwareInfo.fpgaB2); FINFO(strLog.GetString()); //FPBA Bottom 3 firmware version strLog.Format("Detector's Bottom 3 firmware version : %s", l_di.firmwareInfo.fpgaB3); FINFO(strLog.GetString()); //FirmwareInfo----------- //ImageInfo--------- //imagingMode m_nImageMode = l_di.imageInfo.imagingMode; strLog.Format("Image Mode : %d", m_nImageMode); FINFO(strLog.GetString()); //rawWidth //m_nRawImgWidth = l_di.imageInfo.rawWidth;//2816 strLog.Format("Raw Image Width : %d", l_di.imageInfo.rawWidth); FINFO(strLog.GetString()); //rawHeight //m_nRawImgHeight = l_di.imageInfo.rawHeight;//3650 strLog.Format("Raw Image Height : %d", l_di.imageInfo.rawHeight); FINFO(strLog.GetString()); //rawSize //m_nRawImageSize = l_di.imageInfo.rawSize;//20556800 strLog.Format("Raw Image Size : %d", l_di.imageInfo.rawSize); FINFO(strLog.GetString()); //rawPixelSize //m_nRawPixelSize = l_di.imageInfo.rawPixelSize;//2 strLog.Format("Raw Image Pixel Size : %d", l_di.imageInfo.rawPixelSize); FINFO(strLog.GetString()); //width m_nRawImgWidth = l_di.imageInfo.width;//2816 m_nImageWidth = l_di.imageInfo.width;//2816 strLog.Format("Normal Image Width : %d", m_nImageWidth); FINFO(strLog.GetString()); //height m_nRawImgHeight = l_di.imageInfo.height;//3584 m_nImageHeight = l_di.imageInfo.height;//3584 strLog.Format("Normal Image Height : %d", m_nImageHeight); FINFO(strLog.GetString()); //size m_nRawImageSize = l_di.imageInfo.size;//20185088 m_nImageSize = l_di.imageInfo.size;//20185088 strLog.Format("Normal Image Size : %d", m_nImageSize); FINFO(strLog.GetString()); //pixelSize m_nRawPixelSize = l_di.imageInfo.pixelSize;//2 m_nImagePixelSize = l_di.imageInfo.pixelSize;//2 strLog.Format("Normal Image Pixel Size : %d", m_nImagePixelSize); FINFO(strLog.GetString()); //aec image ===== pre view //aecWidth m_nAecImageWidth = l_di.imageInfo.aecWidth;//22 strLog.Format("Aec Image Width : %d", m_nAecImageWidth); FINFO(strLog.GetString()); //aecHeight m_nAecImageHeight = l_di.imageInfo.aecHeight;//28 strLog.Format("Aec Image Height : %d", m_nAecImageHeight); FINFO(strLog.GetString()); //aecSize m_nAecImageSize = l_di.imageInfo.aecSize;//2464 strLog.Format("Aec Image Size : %d", m_nAecImageSize); FINFO(strLog.GetString()); //aecPixelSize m_nAecPixelSize = l_di.imageInfo.aecPixelSize;//4 strLog.Format("Aec Image Pixel Size : %d", m_nAecPixelSize); FINFO(strLog.GetString()); //temperature strLog.Format("Temperature : %.2f C", l_di.temperature); FINFO(strLog.GetString()); StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nCurrentPanelID, l_di.temperature); //pegasusState API_PEGASUS_GetPegasusStateDescription( l_di.pegasusState, description); strLog.Format( "Pegasus State %d : %s", l_di.pegasusState, description ); FINFO(strLog.GetString()); //detectorState API_PEGASUS_GetDetectorStateDescription( l_di.detectorState, description); strLog.Format( "Detector State %d : %s", l_di.detectorState, description ); FINFO(strLog.GetString()); //eclipseVersion strLog.Format( "Eclipse Eclipse Version : %s", l_di.eclipseVersion ); FINFO(strLog.GetString()); //pegasusVersion strLog.Format("Eclipse Pegasus Version : %s", l_di.pegasusVersion); FINFO(strLog.GetString()); } /*FINFO("Call PEGASUS_GetLogLevel"); PEGASUS_LogLevel logLevel; err = API_PEGASUS_GetLogLevel(&logLevel); if (!TestError(err,"GetLogLevel")) { FERROR("failed get log level"); return err; } API_PEGASUS_GetLogLevelCodeDescription(logLevel, description); strLog.Format("log level is: %d description: %s", logLevel, description); FINFO(strLog.GetString());*/ FINFO("===== Get Detailed Information Over ====="); return err; } /*** ** 设置校正文件路径 ** 说明:device\references\xxxxxx\dark是暗场校正过程文件 ** device\references\xxxxxx\flood是亮场校正过程文件 ** 校正完成后校正文件会生成到device\references\路径,strPanelSerial表示探测器序列号 ***/ bool CAXSCtrl::SetFPDTplPath() { FINFO("SetFPDTplPath start"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("calibration is ZSKK,return"); return true; } string strTplRootPath = m_strWorkPath + "\\references"; string strPanelSerial = ""; string strDarkTplPath = ""; string strFloodTplPath = ""; try { strPanelSerial = (string)m_objFPDConfig["SerialNumber"]; } catch (ResDataObjectExption& e) { FERROR("Read configuration failed, Error code: {$}", e.what()); return false; } strDarkTplPath = strTplRootPath + "\\" + strPanelSerial + "\\dark\\"; strFloodTplPath = strTplRootPath + "\\" + strPanelSerial + "\\flood\\"; // 创建dark文件路径 if (CreateFileDirectory(strDarkTplPath)) { FINFO("Create Directory: {$}", strDarkTplPath.c_str()); m_strTplDarkPath = strDarkTplPath; } else { FERROR("Create Directory: {$} failed", strDarkTplPath.c_str()); return false; } // 创建flood文件路径 if (CreateFileDirectory(strFloodTplPath)) { FINFO("Create Directory: {$}", strFloodTplPath.c_str()); m_strTplFloodPath = strFloodTplPath; } else { FERROR("Create Directory: {$} failed", strFloodTplPath.c_str()); return false; } //将references路径设置给SDK /*char* szTplRootPath = const_cast(strTplRootPath.c_str()); FINFO("Call TplPathSet, Template Root Path : {$}", szTplRootPath); nRet = API_COM_TplPathSet(szTplRootPath); if (!TestError(nRet, "TplPathSet")) { return false; }*/ FINFO("SetFPDTplPath end"); return true; } DWORD __stdcall CAXSCtrl::onFPDScanThread(PVOID pvoid) { CAXSCtrl* pOpr = (CAXSCtrl*)pvoid; FINFO("Enter Scan Thread"); DWORD dwTimeOut = 5000; while (!pOpr->m_bExitFpdScanThread) { DWORD dwRet = WaitForMultipleObjects(ASSIST_EVENT_COUNT, pOpr->m_hArrayEvent, FALSE, dwTimeOut); if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent { FINFO("Exit fpd scan thread!"); pOpr->m_bExitFpdScanThread = true; } else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hAecImgEvent { pOpr->OnProcessAecImg(); } else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hCorrectedImgEvent { pOpr->OnProcessCorrectedImg(); } else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hXWinOnEvent { DWORD dwXrayOnTime, dwXrayOffTime; dwXrayOnTime = dwXrayOffTime = GetTickCount(); FINFO("XWindowOn: {$}", dwXrayOnTime); printf("XWindowOn \n"); pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON); /*while (dwXrayOffTime - dwXrayOnTime < 750) { dwXrayOffTime = GetTickCount(); } FINFO("XWindowOff: {$}", dwXrayOffTime); printf("XWindowOff \n"); pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);*/ } else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hInitFPDEvent { pOpr->OnProcessInitFPD(); } else if (WAIT_OBJECT_0 + 5 == dwRet) //m_hReInitEvent { pOpr->OnReInitFPD(); } else if (WAIT_OBJECT_0 + 6 == dwRet) //m_hRecoverImage { pOpr->OnRecoverImage(); } else if (WAIT_OBJECT_0 + 7 == dwRet) //m_pAcqUnitCient { pOpr->OnProcessGenNotify(); } } FINFO("Exit Scan Thread"); pOpr->m_hFPDScanThread = nullptr; return 0; } /*** ** 处理AEC图像 ***/ void CAXSCtrl::OnProcessAecImg() { printf("Here Come AEC Image.....\n"); FINFO("Here Come AEC Image"); CString strLog; PEGASUS_ErrorCode ret; if (m_pAecImgBuffer) { memset(m_pAecImgBuffer, 0, m_nRawImgWidth * m_nAecImageHeight * 2); } m_ResultImage.cropInfo.cropOffsetRow = 0; m_ResultImage.cropInfo.cropOffsetCol = 0; m_ResultImage.cropInfo.cropWidth = m_nAecImageWidth; m_ResultImage.cropInfo.cropHeight = m_nAecImageHeight; m_nAecImageSize = m_nAecImageWidth * m_nAecImageHeight * m_nAecPixelSize; strLog.Format("AEC Image Width:%d,Height:%d,PixelSize:%d,Aec image size:%d", m_nAecImageWidth, m_nAecImageHeight, m_nAecPixelSize, m_nAecImageSize); FINFO(strLog.GetString()); if (nullptr != m_ResultImage.pImage) { FINFO("Free Last Image Buffer"); free(m_ResultImage.pImage); m_ResultImage.pImage = nullptr; } m_ResultImage.pImage = malloc(m_nAecImageSize); if (m_ResultImage.pImage) { memset(m_ResultImage.pImage, 0, m_nAecImageSize); } else { FERROR("malloc fail!"); return; } FINFO("Begin to Get AEC Image"); ret = API_PEGASUS_GetAecImage(m_nSequenceId, &m_ResultImage); if (!TestError(ret, "GetAecImage")) { FERROR("Acquire AEC Image Failed"); return; } if (m_pAecImgBuffer) { memcpy(m_pAecImgBuffer, m_ResultImage.pImage, m_nAecImageSize); } if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nAecImageHeight, m_nAecImageWidth, m_pAecImgBuffer); } if (m_nSaveRaw) { SaveRawFunc(m_pAecImgBuffer, m_nAecImageWidth *2, m_nAecImageHeight); } DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pAecImgBuffer); } /*** ** 处理Normal图像 ***/ void CAXSCtrl::OnProcessCorrectedImg() { printf("Here Come Corrected Image.....\n"); FINFO("Here Come Corrected Image"); CString strLog; PEGASUS_ErrorCode ret; if (m_pRawImgBuffer) { memset(m_pRawImgBuffer, 0, m_nRawImgHeight * m_nRawImgWidth); } m_ResultImage.cropInfo.cropOffsetRow = 0; m_ResultImage.cropInfo.cropOffsetCol = 0; m_ResultImage.cropInfo.cropWidth = m_nRawImgWidth; m_ResultImage.cropInfo.cropHeight = m_nRawImgHeight; m_nRawImageSize = m_nRawImgWidth * m_nRawImgHeight * m_nRawPixelSize; strLog.Format("Raw Image Width:%d,Height:%d,PixelSize:%d", m_nRawImgWidth, m_nRawImgHeight, m_nRawPixelSize); FINFO(strLog.GetString()); if (nullptr != m_ResultImage.pImage) { FINFO("Free Last Image Buffer"); free(m_ResultImage.pImage); m_ResultImage.pImage = nullptr; } FINFO("m_nRawImageSize:{$}", m_nRawImageSize); m_ResultImage.pImage = malloc(m_nRawImageSize); if (m_ResultImage.pImage) { memset(m_ResultImage.pImage, 0, m_nRawImageSize); } else { FERROR("malloc fail!"); return; } FINFO("Begin to Get Corrected Image "); ret = API_PEGASUS_GetCorrectedImage(m_nSequenceId, m_nImageIndex, &m_ResultImage); if (!TestError(ret, "GetCorrectedImage")) { strLog.Format("Acquire Corrected Image Failed,Error Code: %d", ret); FERROR(strLog.GetString()); return; } if (m_pRawImgBuffer) { memcpy(m_pRawImgBuffer, m_ResultImage.pImage, m_nRawImageSize); } if (m_nLeftOffset != 0 || m_nTopOffset != 0 || m_nRightOffset != 0 || m_nBottomOffset != 0) { if (CropImageMargin(m_pImgBuffer, m_nImageWidth, m_nImageHeight, m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight, m_nRawImageBits, m_nLeftOffset, m_nTopOffset, m_nRightOffset, m_nBottomOffset)) { FERROR("Crop Image Error!"); } else { FINFO("After crop image width:{$},image height:{$}", m_nImageWidth, m_nImageHeight); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer); } if (m_nSaveRaw) { SaveRawFunc(m_pImgBuffer, m_nImageWidth, m_nImageHeight); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer); } } else { FINFO("m_nLeftOffset and m_nTopOffset and m_nRightOffset and m_nBottomOffset is 0"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Apply ZSKK Calibration File"); m_pZSKKCalib->m_nGridSuppressed = 6; m_pZSKKCalib->ApplyZSKKReference(m_nRawImgHeight, m_nRawImgWidth, m_pRawImgBuffer); } if (m_nSaveRaw) { SaveRawFunc(m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight); } DataFeedback(EVT_DATA_RAW_IMAGE, m_pRawImgBuffer); } } void CAXSCtrl::SaveRawFunc(WORD* pInImg, int nImgWidth, int nImgHeight) { FILE* fp; SYSTEMTIME st; GetLocalTime(&st); //FINFO("Date: [%04d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay); char filename[256]; //sprintf(filename, "\\Image\\Raw%02d-%02d-%02d-%02d-%02d.raw", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); sprintf(filename, "\\rawdata\\Raw.raw"); string strFileName = m_strWorkPath + filename; if ((fp = fopen(strFileName.c_str(), "wb+")) == NULL) { DWORD dw = GetLastError(); FERROR("fopen {$} failed, {$}", strFileName.c_str(), dw); return; } fwrite(pInImg, sizeof(WORD), nImgWidth * nImgHeight, fp); fclose(fp); FINFO("Save image over"); } /*** ** 裁剪图像 ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度 ***/ //参照RFOC康众动态代码整理的图像裁剪功能 int CAXSCtrl::CropImageMargin(LPVOID pDstData, int& nDstWidth, int& nDstHeight, LPVOID pScrData, int nSrcWidth, int nSrcHeight, int nBits, int nLeftMargin, int nTopMargin, int nRightMargin, int nBottomMargin) { FINFO("CropImageMargin start"); if ((pDstData == NULL) || (pScrData == NULL) || (nSrcWidth <= 0) || (nSrcHeight <= 0) || (nBits <= 0)) return -1; if ((nLeftMargin >= nSrcWidth) || (nTopMargin >= nSrcHeight)) return -1; int nBitsToBYTE = (int)((nBits + 7) * 0.125); if (nBitsToBYTE < 1) return -1; int nXL, nXR, nYL, nYR; nXL = nLeftMargin;//32 nYL = nTopMargin; if (nSrcWidth - nRightMargin < 0) return -1; nXR = nSrcWidth - nRightMargin - 1; //2783 if (nXR < nXL) return -1; if (nSrcHeight - nBottomMargin < 0) return -1; nYR = nSrcHeight - nBottomMargin - 1; if (nYR < nYL) return -1; nDstWidth = nXR - nXL + 1; nDstHeight = nYR - nYL + 1; FINFO("TopCrop:{$};Bottom:{$},nDstWidth:{$},nDstHeight:{$},Bits:{$}", nYL, nYR, nDstWidth, nDstHeight, nBitsToBYTE); int i = 0; #pragma omp parallel private(i) { #pragma omp for for (i = nYL; i <= nYR; i++) { ::memcpy((WORD*)pDstData + (i - nYL) * nDstWidth, (WORD*)pScrData + (i * nSrcWidth + nXL), nDstWidth * nBitsToBYTE); } } FINFO("CropImageMargin end"); return 0; } /// /// 实际探测器初始化,事件触发 /// 连接探测器并进行初始化操作 /// void CAXSCtrl::OnProcessInitFPD() { FINFO("OnProcessInitFPD start..."); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START);//初始化成功的回调中会有end PEGASUS_ErrorCode nRet = PEGASUS_SUCCESS; if (m_bLoadedSDK) { FINFO("Already load sdk dll"); } else { //加载SDK DLL if (!LoadSdkDll()) { FERROR("OnProcessInitFPD LoadSdkDll fail"); return; } } //获取配置信息 GetConfigParam(); //加载ZSKK校正文件 LoadZskkMap(); if (m_bInitializedSDK) { FINFO("Already init sdk"); } else { //调用SDK接口进行初始化,等待初始化成功事件通知再向上通知初始化成功 nRet = InitSDK(); if (nRet) { FERROR("OnProcessInitFPD InitSDK fail"); m_bInitializedSDK = false; } else { //AXS2430没有专门的连接探测器接口,能初始化成功就认为是连接成功了 m_bInitializedSDK = true; //调用SDK设置SDK需要的校正文件路径,当前探测器没有设置校正文件路径的接口,故此处没作用 SetFPDTplPath(); } } FINFO("OnProcessInitFPD end..."); } /*** ** 说明:重新初始化探测器,SDK初始化时会连接探测器(重连功能使用) ***/ void CAXSCtrl::OnReInitFPD() { FINFO("OnReInitFPD start..."); //设备掉线后睡1秒,避免太频繁初始化 Sleep(1000); StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START); PEGASUS_ErrorCode nRet = InitSDK(); if (nRet) { FERROR("OnReInitFPD InitSDK fail!"); } FINFO("OnReInitFPD end..."); } /*** ** 说明:重新初始化探测器,SDK初始化时会连接探测器(重连功能使用) ***/ void CAXSCtrl::OnRecoverImage() { FINFO("OnRecoverImage start..."); PEGASUS_ErrorCode ret = PEGASUS_SUCCESS; int nSequenceId = 0; FINFO("Call API_PEGASUS_RecoverLastSequenceID"); ret = API_PEGASUS_RecoverLastSequenceID(&nSequenceId); if (!TestError(ret,"RecoverLastSequenceID")) { FERROR("recover last sequence id fail!"); return; } FINFO("get last sequence id:{$}", nSequenceId); if (nSequenceId < m_nSequenceId) { FERROR("don't have to recover image!"); return; } // In screening mode, this value is one. In tomosynthesis mode this value is 1 or more if (m_nImageIndex > 0) { FINFO("{$} image have to recover!", m_nImageIndex); for (int i = 0; i < m_nImageIndex; i++) { FINFO("Call API_PEGASUS_RecoverImage,sequence id:{$}", m_nSequenceId + i); ret = API_PEGASUS_RecoverImage(m_nSequenceId + i, m_targetFilter, m_context, onMultiEventCallback); if (!TestError(ret, "Recover image")) { FERROR("recover image fail! sequence id:{$}", m_nSequenceId + i); } } } else { FINFO("OnRecoverImage m_nImageIndex:{$}", m_nImageIndex); } FINFO("OnRecoverImage end..."); } void CAXSCtrl::OnProcessGenNotify() { ResDataObject ResNotify, NotifyData; PACKET_CMD Cmd; ResDataObject ResContext; string m_strCurTransaction; while (m_pAcqUnitCient->IsDataArrived()) { FINFO("Detector Get Notify"); Cmd = m_pAcqUnitCient->ReadNotify(ResNotify); FINFO("CMD:{$}", (int)Cmd); PacketAnalizer::GetPacketTransaction(&ResNotify, m_strCurTransaction); string strKey = PacketAnalizer::GetPacketKey(&ResNotify); string path = PacketAnalizer::GetPacketPublisher(&ResNotify); FINFO("Detector recv notify from [{$}] Key {$} Cmd : {$}", path, strKey, (int)Cmd); if (Cmd == PACKET_CMD_NONE) { FERROR("Notify:Cmd type is NONE"); return; } else if (Cmd == PACKET_CMD_UPDATE) { FINFO("Get PACKET_CMD_UPDATE"); ResContext.clear(); PacketAnalizer::GetPacketContext(&ResNotify, ResContext); FINFO("GENERATORSYNCSTATE {$}", (int)ResContext); } else { FINFO("Other CMD!"); return; } /*if ((int)ResContext == 3) { FINFO("Call TerminateAcquisition"); API_PEGASUS_TerminateAcquisition(); }*/ } } DWORD __stdcall CAXSCtrl::onCalibrationThread(PVOID pvoid) { CAXSCtrl* pOpr = (CAXSCtrl*)pvoid; if (pOpr->OnProcessCalibration()) { FINFO("Calibration process over"); } else { pOpr->StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); FERROR("Quit calibration over(with error)"); } CloseHandle(pOpr->m_hCalibrationThread); pOpr->m_hCalibrationThread = nullptr; FINFO("Quit calibration process"); return 0; } /*** ** 校正过程 ** 说明:校正辅助线程,结合校正process的阶段和SDK回调完成校正流程 ** (ActiveCalibration)停止采集,进入idle状态(set prepare event)[CalibINIT process] ** 修改配置 ** == dark == ** 1.(StartCalibration)调用api,进入hst状态(set offset event) ** 2.调用api,开始采集dark图像(image callback) ** 3.保存8张dark图像,停止采集,进入idle状态(set endcalib/aed event)[CalibOFFSET process] ** (上aed图过程目前只在aed同步模式下进行) ** 4.接收10张aed图像,上传数据,停止采集,进入idle状态(set endcalib event)[CalibAED process] ** == flood == ** 1.(PrepareCalibration)调用api,进入hst或aed状态 ** 2.(StartCalibration)调用api,采集flood图像(image callback) ** 3.修改配置,进入hst或aed模式,采集亮场图像 ** 4.重复1、2、3,采集8张flood图像,停止采集,进入idle状态(set endcalib event)[CalibGAIN process] ** (endcalib event)生成校正文件,恢复配置 ***/ bool CAXSCtrl::OnProcessCalibration() { FINFO("calibration process start"); while (!m_bExitCalibrationThread) { DWORD dwSignal = WaitForMultipleObjects(CALIBRATION_EVENT_COUNT, m_hPZMCalibration, FALSE, INFINITE); if (dwSignal == WAIT_OBJECT_0) //退出校正线程 m_hStopCalibEvent { FINFO("Exit Calibration Thread!"); m_bExitCalibrationThread = true; } else if (dwSignal == WAIT_OBJECT_0 + 1) //暗场校正开始 m_hPZMStartOffset { FINFO("Start Offset Calibration"); } else if (dwSignal == WAIT_OBJECT_0 + 2) //暗场校正结束 m_hPZMInOffset { FINFO("Offset calibraion end"); } else if (dwSignal == WAIT_OBJECT_0 + 3) //亮场校正开始 m_hPZMStartGain { FINFO("Start Gain Calibration"); } else if (dwSignal == WAIT_OBJECT_0 + 4) // 停止采集亮场图 m_hPZMInGain { //亮场图采集完毕就认为是校正流程完成->正常结束校正 //亮场校正完成后停止校正状态,让探测器进入idle状态,同时告诉app校正结束 printf("XRAY 校正 结束 \r\n"); FINFO("xray calibraion end"); StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); m_bExitCalibrationThread = true; NotifyCalibrationTime(); //如果上层不主动调用SaveCalibrationFile时在自己调用 //StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_START); //StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END); } else if (dwSignal == WAIT_OBJECT_0 + 5)// 异常结束校正 m_hEndCalibEvent { m_bExitCalibrationThread = true; FERROR("Calibration End Abnormal!!!"); } } FINFO("calibration process stop"); return true; } void CAXSCtrl::SetPZDPCState(PZDPC_State ePZDPCstate) { string strlog = "Unknown"; switch (ePZDPCstate) { case PZDPC_STATE_INIT: strlog = "INIT"; break; case PZDPC_STATE_STANDBY: strlog = "STANDBY"; break; case PZDPC_STATE_WORK: strlog = "WORK"; break; case PZDPC_STATE_CALIBRATION: strlog = "CALIBRATION"; break; case PZDPC_STATE_EXIT: strlog = "EXIT"; break; case PZDPC_STATE_MAX: break; default: break; } FINFO("Set PZ DPC state {$}", strlog.c_str()); m_ePZDPCstate = ePZDPCstate; } PZDPC_State CAXSCtrl::GetPZDPCState() { string strlog = "Unknown"; switch (m_ePZDPCstate) { case PZDPC_STATE_INIT: strlog = "INIT"; break; case PZDPC_STATE_STANDBY: strlog = "STANDBY"; break; case PZDPC_STATE_WORK: strlog = "WORK"; break; case PZDPC_STATE_CALIBRATION: strlog = "CALIBRATION"; break; case PZDPC_STATE_EXIT: strlog = "EXIT"; break; case PZDPC_STATE_MAX: break; default: break; } FINFO("Get state, {$}", strlog.c_str()); return m_ePZDPCstate; } /*** * 执行失败,返回false;执行成功,返回true ***/ bool CAXSCtrl::TestError(PEGASUS_ErrorCode nRet, const char* szFuncName) { PEGASUS_ErrorCode ret; if (nRet < PEGASUS_SUCCESS && nRet > PEGASUS_MAJOR_IMAGE_SATURATED_ERROR) { FERROR("error code[{$}] is out of range.",(int)nRet); return false; } if (nRet == PEGASUS_SUCCESS) { FINFO("{$} returned OK", szFuncName); return true; } else { CString strLog; char errShortDescription[PEGASUS_MAX_STRING_LENGTH]; char errLongDescription[PEGASUS_MAX_STRING_LENGTH]; API_PEGASUS_GetErrorDescription(nRet, errShortDescription, errLongDescription); strLog.Format("TestError error code: %d, Short Description: %s, Long Description: %s", nRet, errShortDescription, errLongDescription); FERROR(strLog.GetString()); //MAJOR错误 if (nRet >= PEGASUS_MAJOR_PARAMETER_OUT_OF_RANGE_ERROR && nRet <= PEGASUS_MAJOR_EO_RAMPUP_FAIL) { FERROR("The system should try to re-initialize PEGASUS by calling PEGASUS_Shutdown and then PEGASUS_Initialize or PEGASUS_QuickInitialize"); m_bReadyForExp = false; StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); if (nRet == PEGASUS_MAJOR_COMMUNICATION_ERROR) { //m_bExitGetInfoThread = true;//退出获取探测器温度和状态线程,避免调用接口时重复报这个错,重复shutdown造成问题 m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus = false; ErrorFeedback(EVT_ERR_COMMUNICATE, "true", m_nCurrentPanelID); StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_DISCONNECT_SUCCESS); } if (!m_bShutDownFlag) { FINFO("TestError Call API_PEGASUS_Shutdown"); API_PEGASUS_Shutdown();//以上错误时 } } else if (nRet >= PEGASUS_FATAL_HARDWARE_ERROR && nRet <= PEGASUS_FATAL_IMAGE_TRANSFER_TEST_FAIL_ERROR) { FERROR("Fatal error,should restart the detector system!"); m_bReadyForExp = false; StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE); FINFO("Call API_PEGASUS_Exit"); ret = API_PEGASUS_Exit(); if (ret) { FERROR("execute exit fail!"); } } return false; } } bool CAXSCtrl::WaitRespond(int nTimeOut, const char* szPosition) { FINFO("--- {$} WaitRespond, {$}ms ---", szPosition, nTimeOut); ResetEvent(m_hRespond); DWORD dwRet = WaitForSingleObject(m_hRespond, nTimeOut); if (dwRet == WAIT_TIMEOUT) { FERROR("Timeout in wait respond"); return false; } return true; } void CAXSCtrl::StopWaiting(const char* szPosition) { FINFO("--- Stop waiting respond, {$} ---", szPosition); SetEvent(m_hRespond); } /// /// 配置反馈通知 @SDK /// /// /// /// /// /// /// /// void CAXSCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /// /// Info消息反馈通知 @SDK /// /// /// /// /// /// /// /// void CAXSCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /// /// 设备状态改变通知 @SDK /// /// 事件ID 属于部件或者子系统 /// 事件状态值,不同事件有不同的取值说明 /// 事件附带文本消息 /// 探测器ID,单板系统 默认值 -1 /// 浮点参数2 /// 附加参数内存长度 /// 附加参数内存地址 void CAXSCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /// /// 数据反馈通知 @SDK /// /// 采集数据事件ID,EVT_DATA_RAW_IMAGE /// 图像内存地址 /// 参数1,默认值0 /// 参数2,浮点,默认值0.0 /// 附带文本消息 /// 图像内存长度,默认值0,固定大小 /// 探测器ID,单板模式 默认值-1 void CAXSCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /// /// 告警事件反馈通知 @SDK /// /// /// /// /// /// /// /// void CAXSCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /// /// 内部错误通知 @SDK /// /// 事件ID /// 事件消息文本内容 /// 探测器ID,单板模式默认值-1 /// 参数1,整型,默认值0 /// 参数2,浮点数,默认值0.0 /// 附加参数内存长度 /// 附加参数内存地址 void CAXSCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam) { if (-1 == nDetectorID) { nDetectorID = m_nCurrentPanelID; } ((CFPDDeviceAXS*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam); } /*** * 设置校正轮数 ***/ bool CAXSCtrl::SetReferenceNum(int nReferenceNum) { m_nCalibrationRounds = nReferenceNum; FINFO("Set reference number: {$}", m_nCalibrationRounds); return true; } /*** ** 说明:根据配置文件配置的图像大小动态申请内存 ** 参数:nLogicMode,从配置文件读取当前mode 相关参数 ***/ bool CAXSCtrl::SelectExamMode(int nLogicMode, CFPDDeviceAXS* pDrvDPC) { FINFO("SelectExamMode start"); if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID) { FINFO("panel id {$} != {$} return...",(*m_pDPC2PanelID)[pDrvDPC], m_nCurrentPanelID); return false; } if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus) { FINFO("Current detector is not connect, return"); return false; } FINFO("SelectExamMode:{$}", nLogicMode); if (nLogicMode < 0 || nLogicMode > 9) //sdk 最多9个mode { FERROR("Invalid acq mode!"); return false; } //if (m_nCurrentAcqMode == nLogicMode) //同样appmode下没必要再次走下面的流程 //{ // FINFO("Same acq mode, return true"); // return true; //} m_ModeConfig = m_pStPanelStatus[m_nCurrentPanelID]->objPanelConfig; int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode"); bool bInitBuffer = false; for (int i = 0; i < nModeCount; i++) { if (nLogicMode == (int)m_ModeConfig["ModeTable"][i]["LogicMode"]) { try { m_bHavePreview = (int)m_ModeConfig["ModeTable"][i]["HavePreview"]; m_nAecImageWidth = (int)m_ModeConfig["ModeTable"][i]["PreviewImageWidth"]; m_nAecImageHeight = (int)m_ModeConfig["ModeTable"][i]["PreviewImageHeight"]; m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][i]["RawImgWidth"]; m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][i]["RawImgHeight"]; m_nImageWidth = (int)m_ModeConfig["ModeTable"][i]["ImageWidth"]; m_nImageHeight = (int)m_ModeConfig["ModeTable"][i]["ImageHeight"]; m_nLeftOffset = (int)m_ModeConfig["ModeTable"][i]["CropImageLeft"]; m_nTopOffset = (int)m_ModeConfig["ModeTable"][i]["CropImageTop"]; m_nRightOffset = (int)m_ModeConfig["ModeTable"][i]["CropImageRight"]; m_nBottomOffset = (int)m_ModeConfig["ModeTable"][i]["CropImageBottom"]; m_nRawImageBits = (int)m_ModeConfig["ModeTable"][i]["PhySizeInfoBit"];//原始图和有效图图像位数 m_nImageBits = (int)m_ModeConfig["ModeTable"][i]["PhySizeInfoBit"]; m_nPixelPitch = (int)m_ModeConfig["ModeTable"][i]["PixelPitch"];//像素间距 m_nSaveRaw = (int)m_ModeConfig["ModeTable"][i]["IsSaveRaw"]; if (m_bHavePreview) { if (m_pAecImgBuffer) { delete m_pAecImgBuffer; m_pAecImgBuffer = NULL; } //因为AEC的像素大小是4,故用WORD new时需要乘2 m_pAecImgBuffer = new WORD[m_nAecImageWidth * m_nAecImageHeight *2]; } if (m_pRawImgBuffer) { delete m_pRawImgBuffer; m_pRawImgBuffer = NULL; } //RAW图像素大小是2,直接用WORD new m_pRawImgBuffer = new WORD[m_nRawImgWidth * m_nRawImgHeight]; if (m_pImgBuffer) { delete m_pImgBuffer; m_pImgBuffer = NULL; } //有效图和RAW图一样,图像素大小是2,直接用WORD new m_pImgBuffer = new WORD[m_nImageWidth * m_nImageHeight]; FINFO("Image Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$} {$} {$}), Bits({$}), PixelPitch({$}), SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nLeftOffset, m_nTopOffset, m_nRightOffset, m_nBottomOffset, m_nRawImageBits, m_nPixelPitch, m_nSaveRaw); bInitBuffer = true; if (m_bHavePreview) { ConfFeedback(EVT_CONF_PREVIEW_WIDTH, m_nCurrentPanelID, "", m_nAecImageWidth); ConfFeedback(EVT_CONF_PREVIEW_HIGHT, m_nCurrentPanelID, "", m_nAecImageHeight); } ConfFeedback(EVT_CONF_RAW_WIDTH, m_nCurrentPanelID, "", m_nImageWidth); ConfFeedback(EVT_CONF_RAW_HIGHT, m_nCurrentPanelID, "", m_nImageHeight); ConfFeedback(EVT_CONF_RAW_BITS, m_nCurrentPanelID, "", m_nImageBits); ConfFeedback(EVT_CONF_PIXELSPACE, m_nCurrentPanelID, "", 0, (float)m_nPixelPitch); break; } catch (ResDataObjectExption& exp) { FERROR("Get config failed: {$}", exp.what()); } } } if (!bInitBuffer) { FERROR("Image buffer is NULL"); return false; } FINFO("SelectExamMode end"); return true; } //切换采集模式(普通模式/AEC模式) bool CAXSCtrl::SetAcqMode(int nLogicMode, CFPDDeviceAXS* pDrvDPC) { FINFO("CAXSCtrl SetAcqMode start, mode:{$}",nLogicMode); if (nLogicMode == m_nCurrentAcqMode) { CString strLog; strLog.Format("Same Exposure Mode:%d", nLogicMode); FINFO(strLog.GetString()); return true; } m_nCurrentAcqMode = (eAcqMode)nLogicMode; m_bChangeAcqProperties = false;//切换采集模式之前重置为false if (m_bReadyForExp) { ChangeAcqProperties(m_nCurrentAcqMode); //采集模式选择 AEC或者Manual } FINFO("CAXSCtrl SetAcqMode end"); return true; } bool CAXSCtrl::ChangeAcqProperties(int nAcqMode) { FINFO("Change Acq Properties, acq mode:{$}", nAcqMode); bool l_bSetAec = false; if (AEC == nAcqMode) { FINFO("Enter into AEC Exposure Mode"); l_bSetAec = true; } else if (RAD == nAcqMode) { FINFO("Enter into Normal Exposure Mode"); l_bSetAec = false; } bool isAecMode; int currentSequenceId; PEGASUS_ErrorCode l_error; FINFO("Get Continuous Acquisition Properties:"); l_error = API_PEGASUS_GetContinuousAcquisitionProperties(&m_targetFilter, &isAecMode, &m_context, ¤tSequenceId); if (!TestError(l_error,"GetContinuousAcquisitionProperties")) { FERROR("GetContinuousAcquisitionProperties Failed"); return false; } CString strLog; strLog.Format("Target Filter:%d", m_targetFilter); FINFO(strLog.GetString()); strLog.Format("Is AEC Mode:%d", isAecMode); FINFO(strLog.GetString()); strLog.Format("Context:%d", m_context); FINFO(strLog.GetString()); strLog.Format("Current Sequence Id:%d", currentSequenceId); FINFO(strLog.GetString()); FINFO("Change Continuous Acquisition Properties"); l_error = API_PEGASUS_ChangeContinuousAcquisitionProperties(m_targetFilter, l_bSetAec, m_context); if (!TestError(l_error,"ChangeContinuousAcquisitionProperties")) { FERROR("Change Acquisition Properties Failed"); m_bChangeAcqProperties = false; return false; } else { m_bChangeAcqProperties = true; } FINFO("Change Acquisition Properties Success"); return true; } /*** * 接受曝光图像 ***/ bool CAXSCtrl::AcceptCalibration() { FINFO("Accept calibration exposure result"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_OEM)//厂商校正 { FINFO("Call AddImageToCalibration"); PEGASUS_ErrorCode l_err = API_PEGASUS_AddImageToCalibration(); if (!TestError(l_err,"AddImageToCalibration")) { FERROR("Add image to calibration fail!"); return false; } } else //ZSKK校正 { if (m_nCalibCurrentExposureIndex == 1) { m_pZSKKCalib->AddImageToPixMap(m_pRawImgBuffer); m_pZSKKCalib->AverageZSKKGainMap(m_pRawImgBuffer, m_nCalibCurrentCalibrationRound - 1, true); } else { m_pZSKKCalib->AverageZSKKGainMap(m_pRawImgBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮 } } FINFO("Accept calibration exposure over"); return true; } /*** * 拒绝曝光图像 ***/ bool CAXSCtrl::RejectCalibration() { FINFO("RejectCalibration start"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_OEM) { FINFO("Call PEGASUS_RejectCalibrationImage"); // This call takes a couple of seconds PEGASUS_ErrorCode l_err = API_PEGASUS_RejectCalibrationImage(); if (!TestError(l_err, "RejectCalibrationImage")) { FERROR("Reject Image To Calibration Failed"); return false; } } FINFO("RejectCalibration end"); return true; } //只有ZSKK校正时调用 bool CAXSCtrl::SaveCalibrationFile() { FINFO("Save Calibration File"); if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { FINFO("Save ZSKK Calibration File"); m_pZSKKCalib->StoreZSKKGainMap(m_strPanelType); m_pZSKKCalib->StoreZSKKPixMap(m_strPanelType); } //更新配置文件中校正日期和时间 SYSTEMTIME stCurrentTime = { 0 }; GetLocalTime(&stCurrentTime); CString strLog; strLog.Format("Current time: %04d/%02d/%02d %02d:%02d:%02d:%03d", stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay, stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds); FINFO(strLog.GetString()); FINFO("Save Calibration File over"); return true; } //只有ZSKK校正会调用这个函数 bool CAXSCtrl::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; } /*** ** 说明:结束校正 ** DPC处理完校正报告后调用,此处上传map、报告等文件 ***/ bool CAXSCtrl::CompleteCalibration(CFPDDeviceAXS* pDrvDPC) { FINFO("CompleteCalibration calib type {$}",(int)m_eType); if (m_eType == CCOS_CALIBRATION_TYPE_DARK) { printf("DARK 校正 结束\n"); FINFO("DARK 校正 结束"); } else if (m_eType == CCOS_CALIBRATION_TYPE_XRAY) { printf("GAIN 校正 结束\n"); FINFO("GAIN 校正 结束"); m_eCalState = PZ_CALIBRATION_ORIGINAL; if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_ZSKK) { SetEvent(m_hPZMInGain); m_bCalibrationOver = true; } } return true; } /*** ** 说明:获取校正时间 ***/ bool CAXSCtrl::NotifyCalibrationTime(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; } /*** ** 说明:终止校正 ***/ bool CAXSCtrl::AbortCalibration() { FINFO("AbortCalibration start"); m_eType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值 if (m_nCalibrationMode == CCOS_CALIBRATION_MODE_OEM) //厂商校正 { //厂商校正在收到回调事件PEGASUS_CALIBRATION_ABORT_EVENT后再退出校正线程 FINFO("Call PEGASUS_AbortCalibration"); PEGASUS_ErrorCode ret = API_PEGASUS_AbortCalibration(); if (!TestError(ret, "AbortCalibration")) { FERROR("Abort Calibration fail!"); return false; } } else { SetEvent(m_hEndCalibEvent);//终止校正退出校正线程 if (!m_bCalibrationOver) { FINFO("AbortCalibration,reload previous calibration map"); m_pZSKKCalib->LoadZSKKGainMap(true, m_strPanelType); //重新加载增益校正文件 m_pZSKKCalib->AbortZSKKPixMap(m_strPanelType); //放弃坏点校正并重新加载原来的坏点校正文件 } } FINFO("AbortCalibration over"); return true; } /*** * 保存RAW图像 ***/ bool CAXSCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight) { FINFO("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight); if (pRawImg == NULL || pImgName == NULL) { return false; } string strImagePath = ""; strImagePath = m_strWorkPath + "\\rawdata\\" + pImgName; 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 Image"); return true; } CCOS_CALIBRATION_TYPE CAXSCtrl::GetCAXSCtrlCalibType() { FINFO("Get CAXSCtrl Calib Type {$}",(int)m_eType); return m_eType; } //慎重调用,可能会导致板出问题,硬reset需要很长时间 bool CAXSCtrl::ResetDetector(CFPDDeviceAXS* pDrvDPC) { bool nRet = true; /*nRet = API_COM_ResetFP(); if (!TestError(nRet, "ResetFP")) { printf("Reset Detector fail!\n"); FERROR("Reset Detector fail!"); return false; }*/ return nRet; } int CAXSCtrl::GetCalImagesLeftCount() { FINFO("GetCalImagesLeftCount"); int nNbrCalImagesLeft = 0; PEGASUS_ErrorCode l_err = API_PEGASUS_GetNbrCalImagesLeft(&nNbrCalImagesLeft); if (!TestError(l_err,"GetNbrCalImagesLeft")) { FERROR("Get Nbr Cal Image Left Failed"); nNbrCalImagesLeft = 4; //假值 } if (nNbrCalImagesLeft == 0) { nNbrCalImagesLeft = 4; } FINFO("Cal Image Left Count:{$}",nNbrCalImagesLeft); return nNbrCalImagesLeft; }