#pragma once #include #include #include #include #include #include "ResDataObject.h" #include "CCOS.Dev.FPD.TiRayDR.h" #include "errors.h" #include "ZSKKCalibration.h" #include "TiRayApi.h" #include "TiRayDef.h" //#include "TirayApiImport.h" struct image_info { std::vector data; int width; int height; }; constexpr auto SCAN_EVENT_COUNT = 8; //typedef void(*ResultCallback)(TiRayVariant argv[], int argc); using EventListener = std::function; using event_param = std::variant; using event_params = std::vector; using event_listener = std::function; #define INT_MAX 2147483647 struct ModelResolveResult { TiRayModel model; bool isValid; }; class Detector_TiRayDR { struct scan_result { std::string sn; std::string model; std::string upper_ip; std::string detector_ip; }; enum class eDetStatus { DetStatus_NotIni, DetStatus_NotConn, DetStatus_Sleep, DetStatus_Standby, DetStatus_Work, DetStatus_Acquire, DetStatus_Offset, DetStatus_XrayCalibration, }; //探测器信息 struct CPanelStatus { bool bInitOver; //是否初始化完成 bool bConnectState; //是否连接 SYNC_MODE eSyncMode; //同步模式 int nSoftAcqState; eDetStatus eFPDStatus; //探测器状态 CPanelStatus() { bInitOver = false; bConnectState = false; eSyncMode = SYNC_SOFTWARE; //暂时使用软同步作为缺省值 nSoftAcqState = 0; eFPDStatus = eDetStatus::DetStatus_NotIni; } }; public: Detector_TiRayDR(); ~Detector_TiRayDR(); bool ScanDetector(string& strDetectorInfo); bool DriverEntry(FPDDeviceTiRay* pDrvDPC, ResDataObject& Configuration); bool Connect(FPDDeviceTiRay* pDrvDPC, const char* szWorkPath); bool Disconnect(); void EnterExamMode(int nExamMode); bool SetAcqMode(int nMode); bool SetSyncMode(int nSyncMode); bool PrepareAcquisition(FPDDeviceTiRay* pDrvDPC); bool StartAcquisition(FPDDeviceTiRay* pDrvDPC); bool StopAcquisition(FPDDeviceTiRay* pDrvDPC); bool ActiveCalibration(FPDDeviceTiRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType); bool PrepareCalibration(FPDDeviceTiRay* pDrvDPC); bool StartCalibration(FPDDeviceTiRay* pDrvDPC); bool StopCalibration(FPDDeviceTiRay* pDrvDPC); RET_STATUS AbortCalibration(FPDDeviceTiRay* pDrvDPC); bool CompleteCalibration(FPDDeviceTiRay* pDrvDPC); bool SaveCalibrationFile(); bool SetCalibRounds(int nCalibRounds); bool GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound); bool AcceptCalibration(); bool RejectCalibration(); CCOS_CALIBRATION_TYPE GetCalibType(); bool UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode); void SetNotifyStatusTimePeriod(int nTime); void SetReconnectTimePeriod(int nTime); int TiRay_GetSdkVersion(); TiRayError TiRay_Execute(int detectorId, int commandId, TiRayVariant argv[], int argc); TiRayError TiRay_Scan(ResultCallback fn, const char* interfaceIp, int scanDuration); TiRayError TiRay_SetIp(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp); TiRayError TiRay_Startup(TiRayModel model, EventCallback fn, const StartupOption* option); void TiRay_Stop(); TiRayError TiRay_ApplyPreset(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn); TiRayError TiRay_GenerateTemplate(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize); void register_event_listener(const EventListener& fn); void unregister_event_listener(const EventListener& fn); bool cropImage(unsigned short* srcData, int srcWidth, int srcHeight, unsigned short* destData, int destWidth, int destHeight); static std::string saveProcessedImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp); static void saveRawImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp); static void cleanOldFiles(const std::string& dirPath, const std::string& filePrefix,size_t maxCount, bool checkSize); static void handleHardwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]); static void handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]); static void handleAedSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]); static void handleDarkCalibration(Detector_TiRayDR& detector, TiRayVariant argv[]); static void handleGainCalibration(Detector_TiRayDR& detector, TiRayVariant argv[]); static void handleImageReceived(Detector_TiRayDR& detector, TiRayVariant argv[]); static void on_event_callback(int detectorId, TiRayEvent eventType, TiRayVariant argv[], int argc, void* reservedArg, int reservedArgLen); static void* onReconnectThread(PVOID pvoid); int make_notifier_key(int main, int sub) { return (main << 16) + sub; } std::promise& add_notifier(int key) { std::lock_guard guard(notifiers_mutex_); auto& promise = notifiers_[key]; notifiers_[key] = {}; return promise; } void remove_notifier(int key) { std::lock_guard guard(notifiers_mutex_); notifiers_.erase(key); } enum upload_type : uint8_t { offset, gain, firmware, }; TiRayError upload(upload_type type, char* data, int size); template TiRayError scan(Func fn) { static std::unique_ptr callback; callback = std::make_unique(std::move(fn)); auto err = TiRay_Scan([](TiRayVariant argv[], int argc) { (*callback)(scan_result{ argv[0].DataValue, argv[1].DataValue, argv[2].DataValue, argv[3].DataValue }); }, nullptr, 2000); return err; } //template //std::tuple read_attribute(TiRayAttribute attribute, std::chrono::seconds timeout = std::chrono::seconds(2)) { // TiRayVariant param[1]{}; // param[0].Type = TiRayVariant::TiRayInt; // param[0].IntValue = attribute; // // 执行命令 // auto err = Execute(m_nDetectorID, Cmd_ReadAttribute, param, 1); // if (err != Err_Success) { // return { err, {} }; // } // // 处理event_params类型(实际是std::vector) // if constexpr (std::is_same_v) { // event_params result; // // 根据参数类型构造对应的event_param并添加到vector中 // switch (param[0].Type) { // case TiRayVariant::TiRayInt: // result.emplace_back(param[0].IntValue); // break; // case TiRayVariant::TiRayInt64: // result.emplace_back(param[0].Int64Value); // break; // case TiRayVariant::TiRayFloat: // result.emplace_back(param[0].FloatValue); // break; // case TiRayVariant::TiRayBuffer: // result.emplace_back(std::string(param[0].DataValue, param[0].DataLen)); // break; // } // return { Err_Success, std::move(result) }; // } // else { // T result; // bool typeMismatch = false; // // 根据参数类型和目标类型进行转换 // if constexpr (std::is_integral_v && sizeof(T) <= 4 || std::is_enum_v) { // if (param[0].Type == TiRayVariant::TiRayInt) { // result = static_cast(param[0].IntValue); // } // else { // typeMismatch = true; // } // } // else if constexpr (std::is_integral_v && sizeof(T) > 4) { // if (param[0].Type == TiRayVariant::TiRayInt64) { // result = static_cast(param[0].Int64Value); // } // else { // typeMismatch = true; // } // } // else if constexpr (std::is_floating_point_v) { // if (param[0].Type == TiRayVariant::TiRayFloat) { // result = static_cast(param[0].FloatValue); // } // else { // typeMismatch = true; // } // } // else { // // 处理其他类型(如自定义类型) // typeMismatch = true; // } // if (typeMismatch) { // return { err, {} }; // 假设存在类型不匹配的错误码 // } // return { Err_Success, result }; // } //} template TiRayError write_attribute(TiRayAttribute attribute, T value, std::chrono::seconds timeout = std::chrono::seconds(2)) { std::cout << "--TiRay Function-- write_attribute Start" << std::endl; std::cout << "Writing attribute: " << static_cast(attribute) << ", Timeout: " << timeout.count() << "s" << std::endl; std::unique_ptr buffer; TiRayVariant param[2]{}; param[0].Type = TiRayVariant::TiRayInt; param[0].IntValue = attribute; if constexpr (std::is_integral_v && sizeof(T) <= 4 || std::is_enum_v) { param[1].Type = TiRayVariant::TiRayInt; param[1].IntValue = value; std::cout << "Using TiRayInt type, value: " << value << std::endl; } else if constexpr (std::is_integral_v && sizeof(T) > 4) { param[1].Type = TiRayVariant::TiRayInt64; param[1].Int64Value = value; std::cout << "Using TiRayInt64 type, value: " << value << std::endl; } else if constexpr (std::is_floating_point_v) { param[1].Type = TiRayVariant::TiRayFloat; param[1].FloatValue = value; std::cout << "Using TiRayFloat type, value: " << value << std::endl; } else if constexpr (std::is_same_v) { param[1].Type = TiRayVariant::TiRayBuffer; buffer = std::make_unique(param[1].DataLen); param[1].DataLen = static_cast(value.size()); param[1].DataValue = buffer.get(); memcpy(param[1].DataValue, value.c_str(), param[1].DataLen); std::cout << "Using TiRayBuffer type, string length: " << param[1].DataLen << ", value: " << value << std::endl; } else { static_assert(!std::is_same_v, "Unsupported type T"); } auto err = TiRay_Execute(m_nDetectorID, Cmd_WriteAttribute, param, 2); if (err != Err_Success) { std::cout << "Error: TiRay_Execute failed with code: " << static_cast(err) << std::endl; return err; } std::cout << "Success: Attribute " << static_cast(attribute) << " written successfully" << std::endl; return Err_Success; } std::vector m_gainCalibImages; // 存储Gain模式下的所有30张图像 std::vector m_currentDoseImages; // 存储当前剂量组的6张图像 std::vector m_gainV2MeanImages; // 存储每个剂量组生成的均值图 int m_currentDoseIndex = 0; // 当前处理的剂量组索引(0-4,共5组) private: map* m_pDPC2PanelID; map* m_pPanelID2DPC; std::list m_listeners; ResDataObject m_ModeConfig; //保存DPC模块下发的配置 CPanelStatus* m_pStPanelStatus[2]; // void* m_hTiRayDRModule; APP_STATUS m_nAppStatus; //记录软件状态 CCOS_CALIBRATION_TYPE m_eCaliType; // 记录当前校正类型 CCOS_CALIBRATION_MODE m_nCalibrationMode;//校正模式 ecom校正/厂商校正 CZSKKCalibrationCtrl* m_pZSKKCalib; std::map> notifiers_; std::mutex notifiers_mutex_; int m_nPanelCount; //探测器数量 int m_nDetectorID; int m_nCurrentPanelID; int m_nSyncMode; //记录选择模式时使用的同步模式 int m_nImageWidth; int m_nImageHeight; int m_nWidthOffset; int m_nHeightOffset; int m_nRawImgWidth; //SDK反馈的图像宽 int m_nRawImgHeight; //SDK反馈的图像高 int m_nCalibrationRounds;//校正轮数 int m_nCalibCurrentCalibrationRound;//当前校正轮数 int m_nCalibCurrentExposureIndex;//当前轮次曝光第几次 int m_nExposureNumCurrentRound;//当前轮次需要曝光的总次数 int m_nImageNum; int m_nReconnectTimePeriod; int m_nNotifyStatusTimePeriod; bool m_bSaveRaw; bool m_bConnected; bool m_bExitRadAcqStatus; bool m_bAEDReady; bool m_bAEDWorkFlag; bool m_bMonitorFlag; bool m_bUseGainV2 = false; std::string m_strWorkPath; //保存工作路径,用于加载SDK和配置 std::string m_strDetectorType; //探测器类型 std::string m_strWiredIP; std::string m_strWirelessIP; std::string m_strLocalIP; std::string m_strSerialNum; WORD* m_pRawImgBuffer; //原始图 WORD* m_pImgBuffer; //裁剪后图像 //辅助线程事件 std::shared_ptr m_hInitEvent; std::shared_ptr m_hExitEvent; //退出辅助线程事件 std::shared_ptr m_hReConnectEvent; std::shared_ptr m_hRadEvent; std::vector> m_hArrayEvent; pthread_t m_hReconnectThread = 0; bool m_bReconnectThreadRunning = false; std::shared_ptr m_hToggleEvent; //辅助线程退出通知事件 pthread_t m_hFPDScanThread = 0; //辅助线程 pthread_t m_hRadAcquisitionThread = 0; pthread_t m_hStatusMonitorThread = 0; std::shared_ptr m_hExitRadAcqStatus; ModelResolveResult ResolveModelType(const std::string& detectorType); bool LoadDll(string strWorkPath); bool ReleaseDll(); bool OpenDetector(); bool CheckConnect(string strIP); bool OpenStatusMonitor(); static void* TiRayStatusMonitorThread(PVOID pvoid); bool StatusMonitor(); bool CloseStatusMonitor(); bool CloseDetectorScan(); bool LoadCalibrationFiles(int nCalibrationMode); bool TestError(TiRayError nErrorCode); //辅助线程 static void* onFPDScanThread(PVOID pvoid); void OnReconnectFPD(); void OnProcessInitFPD(); int DarkAcquisition(); bool GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth); eDetStatus GetTiRayDPCStatus(int nDetectorIndex = -1); bool SetTiRayDPCStatus(eDetStatus status, int nDetectorIndex = -1); bool IsConnected(string strIP); bool CheckConnection(); bool ReConnectFPD(); bool OpenRadAcquisition(); static void* RadAcquisitionThread(void* pParam); bool PerformRadAcquisition(); bool CloseRadAcquisition(); void ConfFeedback(int nEventID, int nDetectorID = -1, const char* pszMsg = "", int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL); void InfoFeedback(int nEventID, int nDetectorID = -1, int nParam1 = 0, float fParam2 = 0, const char* pszMsg = "", int nPtrParamLen = 0, void* pParam = NULL); void StatusFeedback(int nEventID, int nParam1 = 0, const char* pszMsg = "", int nDetectorID = -1, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL); void DataFeedback(int nEventID, void* pParam = NULL, int nParam1 = 0, float fParam2 = 0, const char* pszMsg = "", int nPtrParamLen = 0, int nDetectorID = -1); void WarnFeedback(int nEventID, const char* pszMsg = "", int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL, int nDetectorID = -1); void ErrorFeedback(int nEventID, const char* pszMsg = "", int nDetectorID = -1, int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL); };