Detector_TiRayDR.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #pragma once
  2. #include <filesystem>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <variant>
  6. #include <future>
  7. #include "ResDataObject.h"
  8. #include "CCOS.Dev.FPD.TiRayDR.h"
  9. #include "errors.h"
  10. #include "ZSKKCalibration.h"
  11. #include "TiRayApi.h"
  12. #include "TiRayDef.h"
  13. //#include "TirayApiImport.h"
  14. struct image_info {
  15. std::vector<char> data;
  16. int width;
  17. int height;
  18. };
  19. constexpr auto SCAN_EVENT_COUNT = 8;
  20. //typedef void(*ResultCallback)(TiRayVariant argv[], int argc);
  21. using EventListener = std::function<void(TiRayEvent, TiRayVariant[], int)>;
  22. using event_param = std::variant<int, float, long long, std::string, image_info>;
  23. using event_params = std::vector<event_param>;
  24. using event_listener = std::function<void(TiRayEvent, event_params&)>;
  25. #define INT_MAX 2147483647
  26. struct ModelResolveResult {
  27. TiRayModel model;
  28. bool isValid;
  29. };
  30. class Detector_TiRayDR
  31. {
  32. struct scan_result {
  33. std::string sn;
  34. std::string model;
  35. std::string upper_ip;
  36. std::string detector_ip;
  37. };
  38. enum class eDetStatus
  39. {
  40. DetStatus_NotIni,
  41. DetStatus_NotConn,
  42. DetStatus_Sleep,
  43. DetStatus_Standby,
  44. DetStatus_Work,
  45. DetStatus_Acquire,
  46. DetStatus_Offset,
  47. DetStatus_XrayCalibration,
  48. };
  49. //探测器信息
  50. struct CPanelStatus
  51. {
  52. bool bInitOver; //是否初始化完成
  53. bool bConnectState; //是否连接
  54. SYNC_MODE eSyncMode; //同步模式
  55. int nSoftAcqState;
  56. eDetStatus eFPDStatus; //探测器状态
  57. CPanelStatus()
  58. {
  59. bInitOver = false;
  60. bConnectState = false;
  61. eSyncMode = SYNC_SOFTWARE; //暂时使用软同步作为缺省值
  62. nSoftAcqState = 0;
  63. eFPDStatus = eDetStatus::DetStatus_NotIni;
  64. }
  65. };
  66. public:
  67. Detector_TiRayDR();
  68. ~Detector_TiRayDR();
  69. bool ScanDetector(string& strDetectorInfo);
  70. bool DriverEntry(FPDDeviceTiRay* pDrvDPC, ResDataObject& Configuration);
  71. bool Connect(FPDDeviceTiRay* pDrvDPC, const char* szWorkPath);
  72. bool Disconnect();
  73. void EnterExamMode(int nExamMode);
  74. bool SetAcqMode(int nMode);
  75. bool SetSyncMode(int nSyncMode);
  76. bool PrepareAcquisition(FPDDeviceTiRay* pDrvDPC);
  77. bool StartAcquisition(FPDDeviceTiRay* pDrvDPC);
  78. bool StopAcquisition(FPDDeviceTiRay* pDrvDPC);
  79. bool ActiveCalibration(FPDDeviceTiRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType);
  80. bool PrepareCalibration(FPDDeviceTiRay* pDrvDPC);
  81. bool StartCalibration(FPDDeviceTiRay* pDrvDPC);
  82. bool StopCalibration(FPDDeviceTiRay* pDrvDPC);
  83. RET_STATUS AbortCalibration(FPDDeviceTiRay* pDrvDPC);
  84. bool CompleteCalibration(FPDDeviceTiRay* pDrvDPC);
  85. bool SaveCalibrationFile();
  86. bool SetCalibRounds(int nCalibRounds);
  87. bool GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound);
  88. bool AcceptCalibration();
  89. bool RejectCalibration();
  90. CCOS_CALIBRATION_TYPE GetCalibType();
  91. bool UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode);
  92. void SetNotifyStatusTimePeriod(int nTime);
  93. void SetReconnectTimePeriod(int nTime);
  94. int TiRay_GetSdkVersion();
  95. TiRayError TiRay_Execute(int detectorId, int commandId, TiRayVariant argv[], int argc);
  96. TiRayError TiRay_Scan(ResultCallback fn, const char* interfaceIp, int scanDuration);
  97. TiRayError TiRay_SetIp(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp);
  98. TiRayError TiRay_Startup(TiRayModel model, EventCallback fn, const StartupOption* option);
  99. void TiRay_Stop();
  100. TiRayError TiRay_ApplyPreset(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn);
  101. TiRayError TiRay_GenerateTemplate(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize);
  102. void register_event_listener(const EventListener& fn);
  103. void unregister_event_listener(const EventListener& fn);
  104. static bool cropImage(unsigned short* srcData,
  105. int srcWidth, int srcHeight,
  106. unsigned short* destData,
  107. int destWidth, int destHeight);
  108. static std::string saveProcessedImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp);
  109. static void saveRawImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp);
  110. static void cleanOldFiles(const std::string& dirPath, const std::string& filePrefix,size_t maxCount, bool checkSize);
  111. static void handleHardwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]);
  112. static void handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]);
  113. static void handleAedSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[]);
  114. static void handleDarkCalibration(Detector_TiRayDR& detector, TiRayVariant argv[]);
  115. static void handleGainCalibration(Detector_TiRayDR& detector, TiRayVariant argv[]);
  116. static void handleImageReceived(Detector_TiRayDR& detector, TiRayVariant argv[]);
  117. static void on_event_callback(int detectorId, TiRayEvent eventType, TiRayVariant argv[], int argc, void* reservedArg, int reservedArgLen);
  118. static void* onReconnectThread(PVOID pvoid);
  119. int make_notifier_key(int main, int sub) {
  120. return (main << 16) + sub;
  121. }
  122. std::promise<event_params>& add_notifier(int key)
  123. {
  124. std::lock_guard<std::mutex> guard(notifiers_mutex_);
  125. auto& promise = notifiers_[key];
  126. notifiers_[key] = {};
  127. return promise;
  128. }
  129. void remove_notifier(int key) {
  130. std::lock_guard<std::mutex> guard(notifiers_mutex_);
  131. notifiers_.erase(key);
  132. }
  133. enum upload_type : uint8_t {
  134. offset,
  135. gain,
  136. firmware,
  137. };
  138. TiRayError upload(upload_type type, char* data, int size);
  139. template<typename Func>
  140. TiRayError scan(Func fn) {
  141. static std::unique_ptr<Func> callback;
  142. callback = std::make_unique<Func>(std::move(fn));
  143. auto err = TiRay_Scan([](TiRayVariant argv[], int argc) {
  144. (*callback)(scan_result{ argv[0].DataValue, argv[1].DataValue, argv[2].DataValue, argv[3].DataValue });
  145. }, nullptr, 2000);
  146. return err;
  147. }
  148. //template<typename T>
  149. //std::tuple<TiRayError, T> read_attribute(TiRayAttribute attribute, std::chrono::seconds timeout = std::chrono::seconds(2)) {
  150. // TiRayVariant param[1]{};
  151. // param[0].Type = TiRayVariant::TiRayInt;
  152. // param[0].IntValue = attribute;
  153. // // 执行命令
  154. // auto err = Execute(m_nDetectorID, Cmd_ReadAttribute, param, 1);
  155. // if (err != Err_Success) {
  156. // return { err, {} };
  157. // }
  158. // // 处理event_params类型(实际是std::vector<event_param>)
  159. // if constexpr (std::is_same_v<T, event_params>) {
  160. // event_params result;
  161. // // 根据参数类型构造对应的event_param并添加到vector中
  162. // switch (param[0].Type) {
  163. // case TiRayVariant::TiRayInt:
  164. // result.emplace_back(param[0].IntValue);
  165. // break;
  166. // case TiRayVariant::TiRayInt64:
  167. // result.emplace_back(param[0].Int64Value);
  168. // break;
  169. // case TiRayVariant::TiRayFloat:
  170. // result.emplace_back(param[0].FloatValue);
  171. // break;
  172. // case TiRayVariant::TiRayBuffer:
  173. // result.emplace_back(std::string(param[0].DataValue, param[0].DataLen));
  174. // break;
  175. // }
  176. // return { Err_Success, std::move(result) };
  177. // }
  178. // else {
  179. // T result;
  180. // bool typeMismatch = false;
  181. // // 根据参数类型和目标类型进行转换
  182. // if constexpr (std::is_integral_v<T> && sizeof(T) <= 4 || std::is_enum_v<T>) {
  183. // if (param[0].Type == TiRayVariant::TiRayInt) {
  184. // result = static_cast<T>(param[0].IntValue);
  185. // }
  186. // else {
  187. // typeMismatch = true;
  188. // }
  189. // }
  190. // else if constexpr (std::is_integral_v<T> && sizeof(T) > 4) {
  191. // if (param[0].Type == TiRayVariant::TiRayInt64) {
  192. // result = static_cast<T>(param[0].Int64Value);
  193. // }
  194. // else {
  195. // typeMismatch = true;
  196. // }
  197. // }
  198. // else if constexpr (std::is_floating_point_v<T>) {
  199. // if (param[0].Type == TiRayVariant::TiRayFloat) {
  200. // result = static_cast<T>(param[0].FloatValue);
  201. // }
  202. // else {
  203. // typeMismatch = true;
  204. // }
  205. // }
  206. // else {
  207. // // 处理其他类型(如自定义类型)
  208. // typeMismatch = true;
  209. // }
  210. // if (typeMismatch) {
  211. // return { err, {} }; // 假设存在类型不匹配的错误码
  212. // }
  213. // return { Err_Success, result };
  214. // }
  215. //}
  216. template<typename T>
  217. TiRayError write_attribute(TiRayAttribute attribute, T value, std::chrono::seconds timeout = std::chrono::seconds(2)) {
  218. std::cout << "--TiRay Function-- write_attribute Start" << std::endl;
  219. std::cout << "Writing attribute: " << static_cast<int>(attribute)
  220. << ", Timeout: " << timeout.count() << "s" << std::endl;
  221. std::unique_ptr<char[]> buffer;
  222. TiRayVariant param[2]{};
  223. param[0].Type = TiRayVariant::TiRayInt;
  224. param[0].IntValue = attribute;
  225. if constexpr (std::is_integral_v<T> && sizeof(T) <= 4 || std::is_enum_v<T>) {
  226. param[1].Type = TiRayVariant::TiRayInt;
  227. param[1].IntValue = value;
  228. std::cout << "Using TiRayInt type, value: " << value << std::endl;
  229. }
  230. else if constexpr (std::is_integral_v<T> && sizeof(T) > 4) {
  231. param[1].Type = TiRayVariant::TiRayInt64;
  232. param[1].Int64Value = value;
  233. std::cout << "Using TiRayInt64 type, value: " << value << std::endl;
  234. }
  235. else if constexpr (std::is_floating_point_v<T>) {
  236. param[1].Type = TiRayVariant::TiRayFloat;
  237. param[1].FloatValue = value;
  238. std::cout << "Using TiRayFloat type, value: " << value << std::endl;
  239. }
  240. else if constexpr (std::is_same_v<T, std::string>) {
  241. param[1].Type = TiRayVariant::TiRayBuffer;
  242. buffer = std::make_unique<char[]>(param[1].DataLen);
  243. param[1].DataLen = static_cast<int>(value.size());
  244. param[1].DataValue = buffer.get();
  245. memcpy(param[1].DataValue, value.c_str(), param[1].DataLen);
  246. std::cout << "Using TiRayBuffer type, string length: " << param[1].DataLen
  247. << ", value: " << value << std::endl;
  248. }
  249. else {
  250. static_assert(!std::is_same_v<T, T>, "Unsupported type T");
  251. }
  252. auto err = TiRay_Execute(m_nDetectorID, Cmd_WriteAttribute, param, 2);
  253. if (err != Err_Success) {
  254. std::cout << "Error: TiRay_Execute failed with code: " << static_cast<int>(err) << std::endl;
  255. return err;
  256. }
  257. std::cout << "Success: Attribute " << static_cast<int>(attribute) << " written successfully" << std::endl;
  258. return Err_Success;
  259. }
  260. std::vector<image_info> m_gainCalibImages; // 存储Gain模式下的所有30张图像
  261. std::vector<image_info> m_currentDoseImages; // 存储当前剂量组的6张图像
  262. std::vector<image_info> m_gainV2MeanImages; // 存储每个剂量组生成的均值图
  263. int m_currentDoseIndex = 0; // 当前处理的剂量组索引(0-4,共5组)
  264. private:
  265. map<FPDDeviceTiRay*, int>* m_pDPC2PanelID;
  266. map<int, FPDDeviceTiRay*>* m_pPanelID2DPC;
  267. std::list<EventListener> m_listeners;
  268. ResDataObject m_ModeConfig; //保存DPC模块下发的配置
  269. CPanelStatus* m_pStPanelStatus[2]; //
  270. void* m_hTiRayDRModule;
  271. APP_STATUS m_nAppStatus; //记录软件状态
  272. CCOS_CALIBRATION_TYPE m_eCaliType; // 记录当前校正类型
  273. CCOS_CALIBRATION_MODE m_nCalibrationMode;//校正模式 ecom校正/厂商校正
  274. CZSKKCalibrationCtrl* m_pZSKKCalib;
  275. std::map<int32_t, std::promise<event_params>> notifiers_;
  276. std::mutex notifiers_mutex_;
  277. int m_nPanelCount; //探测器数量
  278. int m_nDetectorID;
  279. int m_nCurrentPanelID;
  280. int m_nSyncMode; //记录选择模式时使用的同步模式
  281. int m_nImageWidth;
  282. int m_nImageHeight;
  283. int m_nWidthOffset;
  284. int m_nHeightOffset;
  285. int m_nRawImgWidth; //SDK反馈的图像宽
  286. int m_nRawImgHeight; //SDK反馈的图像高
  287. int m_nCalibrationRounds;//校正轮数
  288. int m_nCalibCurrentCalibrationRound;//当前校正轮数
  289. int m_nCalibCurrentExposureIndex;//当前轮次曝光第几次
  290. int m_nExposureNumCurrentRound;//当前轮次需要曝光的总次数
  291. int m_nImageNum;
  292. int m_nReconnectTimePeriod;
  293. int m_nNotifyStatusTimePeriod;
  294. bool m_bSaveRaw;
  295. bool m_bConnected;
  296. bool m_bExitRadAcqStatus;
  297. bool m_bAEDReady;
  298. bool m_bAEDWorkFlag;
  299. bool m_bMonitorFlag;
  300. bool m_bUseGainV2 = false;
  301. std::string m_strWorkPath; //保存工作路径,用于加载SDK和配置
  302. std::string m_strDetectorType; //探测器类型
  303. std::string m_strWiredIP;
  304. std::string m_strWirelessIP;
  305. std::string m_strLocalIP;
  306. std::string m_strSerialNum;
  307. WORD* m_pRawImgBuffer; //原始图
  308. WORD* m_pImgBuffer; //裁剪后图像
  309. //辅助线程事件
  310. std::shared_ptr<LinuxEvent> m_hInitEvent;
  311. std::shared_ptr<LinuxEvent> m_hExitEvent; //退出辅助线程事件
  312. std::shared_ptr<LinuxEvent> m_hReConnectEvent;
  313. std::shared_ptr<LinuxEvent> m_hRadEvent;
  314. std::vector<std::shared_ptr<LinuxEvent>> m_hArrayEvent;
  315. pthread_t m_hReconnectThread = 0;
  316. bool m_bReconnectThreadRunning = false;
  317. std::shared_ptr<LinuxEvent> m_hToggleEvent; //辅助线程退出通知事件
  318. pthread_t m_hFPDScanThread = 0; //辅助线程
  319. pthread_t m_hRadAcquisitionThread = 0;
  320. pthread_t m_hStatusMonitorThread = 0;
  321. std::shared_ptr<LinuxEvent> m_hExitRadAcqStatus;
  322. ModelResolveResult ResolveModelType(const std::string& detectorType);
  323. bool LoadDll(string strWorkPath);
  324. bool ReleaseDll();
  325. bool OpenDetector();
  326. bool CheckConnect(string strIP);
  327. bool OpenStatusMonitor();
  328. static void* TiRayStatusMonitorThread(PVOID pvoid);
  329. bool StatusMonitor();
  330. bool CloseStatusMonitor();
  331. bool CloseDetectorScan();
  332. bool LoadCalibrationFiles(int nCalibrationMode);
  333. bool TestError(TiRayError nErrorCode);
  334. //辅助线程
  335. static void* onFPDScanThread(PVOID pvoid);
  336. void OnReconnectFPD();
  337. void OnProcessInitFPD();
  338. int DarkAcquisition();
  339. bool GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth);
  340. eDetStatus GetTiRayDPCStatus(int nDetectorIndex = -1);
  341. bool SetTiRayDPCStatus(eDetStatus status, int nDetectorIndex = -1);
  342. bool IsConnected(string strIP);
  343. bool CheckConnection();
  344. bool ReConnectFPD();
  345. bool OpenRadAcquisition();
  346. static void* RadAcquisitionThread(void* pParam);
  347. bool PerformRadAcquisition();
  348. bool CloseRadAcquisition();
  349. void ConfFeedback(int nEventID, int nDetectorID = -1, const char* pszMsg = "", int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL);
  350. void InfoFeedback(int nEventID, int nDetectorID = -1, int nParam1 = 0, float fParam2 = 0, const char* pszMsg = "", int nPtrParamLen = 0, void* pParam = NULL);
  351. void StatusFeedback(int nEventID, int nParam1 = 0, const char* pszMsg = "", int nDetectorID = -1, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL);
  352. void DataFeedback(int nEventID, void* pParam = NULL, int nParam1 = 0, float fParam2 = 0, const char* pszMsg = "", int nPtrParamLen = 0, int nDetectorID = -1);
  353. void WarnFeedback(int nEventID, const char* pszMsg = "", int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL, int nDetectorID = -1);
  354. void ErrorFeedback(int nEventID, const char* pszMsg = "", int nDetectorID = -1, int nParam1 = 0, float fParam2 = 0, int nPtrParamLen = 0, void* pParam = NULL);
  355. };