Detector_TiRayDR.h 15 KB

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