CareRayCtrl.cpp 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263
  1. #include "stdafx.h"
  2. #include "CareRayCtrl.h"
  3. #include "CCOS.Dev.FPD.CareRay.h"
  4. extern Log4CPP::Logger* gLogger;
  5. CareRayCtrl* g_pDetector = nullptr;
  6. #define LOAD_PROC_ADDRESS(handle,func) \
  7. if ((API_##func = (Func_##func)GetProcAddress(handle, #func)) == NULL) { FERROR("Error occurs while loading entry point!!! \r\n'{$}'\n", #func); }\
  8. void __stdcall CREventCallback(int eventID, Event* eventData)
  9. {
  10. if (nullptr != g_pDetector)
  11. {
  12. g_pDetector->ProcessCREvent(eventID, eventData);
  13. }
  14. }
  15. CareRayCtrl::CareRayCtrl()
  16. {
  17. m_nExposureMode = DEFAULTMODE;
  18. m_nXWindowTime = 500;
  19. m_bDetectorReady = false;
  20. m_bIsAcqStatus = false;
  21. m_pDPC2PanelID = new map<FPDDeviceCareRay*, int>();
  22. m_pPanelID2DPC = new map<int, FPDDeviceCareRay*>();
  23. m_nPanelCount = 0;
  24. m_strWorkPath = "";
  25. m_nCurrentPanelID = 0;
  26. m_nCurrentDetectorType = Unkown_Type;
  27. m_pStPanelStatus[0] = nullptr;
  28. m_pStPanelStatus[1] = nullptr;
  29. m_nSyncMode = SYNC_HARDWARE;
  30. m_nCurSyncMode = 0;
  31. m_nRawImgWidth = 0;
  32. m_nRawImgHeight = 0;
  33. m_pRawImgBuffer = nullptr;
  34. m_pImgBuffer = nullptr;
  35. m_pDarkImage = nullptr;
  36. m_nExamMode = APP_STATUS_IDLE;
  37. m_nSaveRaw = 0;
  38. m_bGetImage = true;
  39. m_bCancelFlag = false;
  40. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
  41. m_bAbortOffset = false;
  42. m_bOneKeyConf = false;
  43. m_bOneKeyCalibration = false;
  44. m_calparams = { 0 };
  45. m_nGainNodeCount = 0;
  46. m_nGainNodeIndex = 0;
  47. m_nGainExpCount = 0;
  48. m_nGainExpIndex = 0;
  49. m_nImageSize = 0;
  50. m_nCurrentMode = MODE_RAD;
  51. m_hRespond = CreateEvent(NULL, FALSE, FALSE, NULL);
  52. m_hFPDScanThread = nullptr;
  53. m_hStopScanEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  54. m_hAcqEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  55. m_hProcessImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  56. m_hXWinOnEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  57. m_hDarkEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  58. m_hGainEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  59. m_hArrayEvent[0] = m_hStopScanEvent;
  60. m_hArrayEvent[1] = m_hAcqEvent;
  61. m_hArrayEvent[2] = m_hProcessImgEvent;
  62. m_hArrayEvent[3] = m_hXWinOnEvent;
  63. m_hArrayEvent[4] = m_hDarkEvent;
  64. m_hArrayEvent[5] = m_hGainEvent;
  65. m_hNotifyDetectorInfoThread = nullptr;
  66. m_bExitNotify = false;
  67. m_hCareRayModule = nullptr;
  68. API_CR_connect_detector = nullptr;
  69. API_CR_disconnect_detector = nullptr;
  70. API_CR_reset_detector = nullptr;
  71. API_CR_set_check_mode = nullptr;
  72. API_CR_set_sync_mode = nullptr;
  73. API_CR_set_cycle_time = nullptr;
  74. API_CR_set_normal_power = nullptr;
  75. API_CR_set_save_power = nullptr;
  76. API_CR_permit_exposure = nullptr;
  77. API_CR_start_acq_full_image = nullptr;
  78. API_CR_start_acq_prev_image = nullptr;
  79. API_CR_start_acq_def_image = nullptr;
  80. API_CR_stop_acq_frame = nullptr;
  81. API_CR_stop_acq_frame_cleanup = nullptr;
  82. API_CR_set_user_correction = nullptr;
  83. API_CR_get_user_correction = nullptr;
  84. API_CR_set_dose = nullptr;
  85. API_CR_get_API_Version = nullptr;
  86. API_CR_get_conn_state = nullptr;
  87. API_CR_get_detector_type = nullptr;
  88. API_CR_get_detector_info = nullptr;
  89. API_CR_get_mode_info = nullptr;
  90. API_CR_get_status_info = nullptr;
  91. API_CR_get_image_attr = nullptr;
  92. API_CR_get_image = nullptr;
  93. API_CR_get_unuploaded_img_info = nullptr;
  94. API_CR_query_prog_info = nullptr;
  95. API_CR_inpaint_bad_pixels = nullptr;
  96. API_CR_get_cal_params = nullptr;
  97. API_CR_set_offset_correction = nullptr;
  98. API_CR_cal_offset = nullptr;
  99. API_CR_linear_calibration = nullptr;
  100. API_CR_portable_calibration = nullptr;
  101. API_CR_get_active_detector_ID = nullptr;
  102. API_CR_execute_linear_cal = nullptr;
  103. API_CR_execute_portable_cal = nullptr;
  104. API_CR_stop_cal_procedure = nullptr;
  105. API_CR_set_active_detector = nullptr;
  106. API_CR_get_dual_detector_state = nullptr;
  107. API_CR_register_callback = nullptr;
  108. API_CR_send_exp_request = nullptr;
  109. API_CR_ready_state_request = nullptr;
  110. API_CR_start_soft_acquisition = nullptr;
  111. API_CR_get_one_key_cal = nullptr;
  112. API_CR_download_factory_cal_files = nullptr;
  113. API_CR_start_acq_dark_full_image = nullptr;
  114. API_CR_check_img_for_factory_cal = nullptr;
  115. API_CR_execute_one_key_cal = nullptr;
  116. }
  117. CareRayCtrl::~CareRayCtrl()
  118. {
  119. if (m_pRawImgBuffer)
  120. {
  121. delete[]m_pRawImgBuffer;
  122. m_pRawImgBuffer = nullptr;
  123. }
  124. if (m_pImgBuffer != nullptr)
  125. {
  126. delete[]m_pImgBuffer;
  127. m_pImgBuffer = nullptr;
  128. }
  129. if (m_pDarkImage != nullptr)
  130. {
  131. delete[]m_pDarkImage;
  132. m_pDarkImage = nullptr;
  133. }
  134. if (m_hRespond)
  135. {
  136. CloseHandle(m_hRespond);
  137. m_hRespond = nullptr;
  138. }
  139. if (m_hStopScanEvent)
  140. {
  141. CloseHandle(m_hStopScanEvent);
  142. m_hStopScanEvent = nullptr;
  143. }
  144. if (m_hAcqEvent)
  145. {
  146. CloseHandle(m_hAcqEvent);
  147. m_hAcqEvent = nullptr;
  148. }
  149. if (m_hProcessImgEvent)
  150. {
  151. CloseHandle(m_hProcessImgEvent);
  152. m_hProcessImgEvent = nullptr;
  153. }
  154. if (m_hXWinOnEvent)
  155. {
  156. CloseHandle(m_hXWinOnEvent);
  157. m_hXWinOnEvent = nullptr;
  158. }
  159. if (m_hDarkEvent)
  160. {
  161. CloseHandle(m_hDarkEvent);
  162. m_hDarkEvent = nullptr;
  163. }
  164. if (m_hGainEvent)
  165. {
  166. CloseHandle(m_hGainEvent);
  167. m_hGainEvent = nullptr;
  168. }
  169. m_bExitNotify = true;
  170. }
  171. bool CareRayCtrl::DriverEntry(FPDDeviceCareRay* pDrvDPC, ResDataObject& Configuration)
  172. {
  173. FINFO("--Func-- DriverEntry {$}", pDrvDPC);
  174. map<FPDDeviceCareRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  175. if (DPCsIter != m_pDPC2PanelID->end())
  176. {
  177. printf("This DPC already exist\n");
  178. FERROR("This DPC already exist");
  179. return false;
  180. }
  181. CPanelStatus* p = new CPanelStatus();
  182. m_pStPanelStatus[m_nPanelCount] = p;
  183. m_pDPC2PanelID->insert(pair<FPDDeviceCareRay*, int>(pDrvDPC, m_nPanelCount));
  184. m_pPanelID2DPC->insert(pair<int, FPDDeviceCareRay*>(m_nPanelCount, pDrvDPC));
  185. m_nPanelCount++;
  186. m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储
  187. //FINFO("Config: {$}", m_ModeConfig.encode());
  188. return true;
  189. }
  190. bool CareRayCtrl::Connect(FPDDeviceCareRay* pDrvDPC, const char* szWorkPath)
  191. {
  192. FINFO("Connect detector begin");
  193. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  194. {
  195. FERROR("Not current DPC, return true");
  196. return true;
  197. }
  198. m_strWorkPath = szWorkPath;
  199. if (!LoadDll(szWorkPath))
  200. {
  201. return false;
  202. }
  203. if (!OpenDetector())
  204. {
  205. FERROR("Open detector failed, Connect failed");
  206. return false;
  207. }
  208. if (!InitDetector())
  209. {
  210. FERROR("Init detector failed, Connect failed");
  211. return false;
  212. }
  213. if (nullptr == m_hFPDScanThread)
  214. {
  215. unsigned uThreadId;
  216. _beginthreadex(NULL, 0, onFPDScanThread, this, 0, &uThreadId);
  217. m_hFPDScanThread = OpenThread(THREAD_ALL_ACCESS, TRUE, uThreadId);
  218. }
  219. if (nullptr == m_hNotifyDetectorInfoThread)
  220. {
  221. unsigned uThreadId;
  222. m_hNotifyDetectorInfoThread = (HANDLE)_beginthreadex(NULL, 0, onNotifyDetectorInfoThread, this, 0, &uThreadId);
  223. }
  224. FINFO("Connect over");
  225. return true;
  226. }
  227. void CareRayCtrl::Reconnect()
  228. {
  229. FINFO("Reconnect detector begin");
  230. FINFO("Reconnect detector end");
  231. }
  232. bool CareRayCtrl::GetDetectorAcqStatus()
  233. {
  234. FINFO("GetDetectorAcqStatus m_bIsAcqStatus:{$}", m_bIsAcqStatus);
  235. return m_bIsAcqStatus;
  236. }
  237. void CareRayCtrl::SetAcqStatus(bool bAcqStatus)
  238. {
  239. FINFO("SetAcqStatus bAcqStatus:{$}", bAcqStatus);
  240. m_bIsAcqStatus = bAcqStatus;
  241. }
  242. void CareRayCtrl::SetCanelFlag(bool bCancelFlag)
  243. {
  244. FINFO("SetCanelFlag bCancelFlag:{$}", bCancelFlag);
  245. m_bCancelFlag = bCancelFlag;
  246. }
  247. bool CareRayCtrl::Disconnect()
  248. {
  249. FINFO("Disconnect detector begin");
  250. SetEvent(m_hStopScanEvent); //关闭Scan线程
  251. m_bExitNotify = true;//退出通知探测器信息线程
  252. FINFO("Call API_CR_disconnect_detector");
  253. int nRet = API_CR_disconnect_detector();
  254. if (TestError(nRet,"API_CR_disconnect_detector"))
  255. {
  256. FERROR("disconnect detector failed!");
  257. return false;
  258. }
  259. FINFO("Disconnect over");
  260. return true;
  261. }
  262. void CareRayCtrl::EnterExamMode(int nExamMode)
  263. {
  264. switch (nExamMode)
  265. {
  266. case APP_STATUS_WORK_BEGIN:
  267. FINFO("Enter into Exam Windows");
  268. m_nExamMode = APP_STATUS_WORK_BEGIN;
  269. break;
  270. case APP_STATUS_WORK_END:
  271. FINFO("Quit Exam Windows");
  272. m_nExamMode = APP_STATUS_WORK_END;
  273. break;
  274. case APP_STATUS_DETSHARE_BEGIN:
  275. FINFO("Enter into Detector Share Windows");
  276. m_nExamMode = APP_STATUS_DETSHARE_BEGIN;
  277. break;
  278. case APP_STATUS_DETSHAR_END:
  279. m_nExamMode = APP_STATUS_IDLE;
  280. FINFO("Quit Detector Share Windows");
  281. m_nExamMode = APP_STATUS_DETSHAR_END;
  282. break;
  283. case APP_STATUS_CAL_BEGIN:
  284. FINFO("Enter into Calibration Windows");
  285. m_nExamMode = APP_STATUS_CAL_BEGIN;
  286. break;
  287. case APP_STATUS_CAL_END:
  288. FINFO("Quit Calibration Windows");
  289. m_nExamMode = APP_STATUS_CAL_END;
  290. break;
  291. case APP_STATUS_WORK_IN_SENSITIVITY:
  292. FINFO("Enter into sensitivity test interface");
  293. m_nExamMode = APP_STATUS_WORK_IN_SENSITIVITY;
  294. break;
  295. default:
  296. break;
  297. }
  298. if (APP_STATUS_WORK_END == nExamMode)
  299. {
  300. m_bCancelFlag = true; //退出检查,将标记位置为true
  301. //软同步在此处调用停止采集,其它同步模式在query过程调用
  302. if (EVT_READY == m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState)
  303. {
  304. //int nRet = -1;
  305. //FINFO("Call stop acq");
  306. //nRet = API_CR_stop_acq_frame(); //用于终止曝光流程
  307. //if (TestError(nRet, "API_CR_stop_acq_frame"))
  308. //{
  309. // FERROR("Stop acq failed");
  310. //}
  311. //else
  312. //{
  313. // m_bDetectorReady = false;
  314. // m_bIsAcqStatus = false;
  315. //}
  316. }
  317. }
  318. }
  319. /***
  320. * 激活探测器
  321. ***/
  322. bool CareRayCtrl::ActiveDetector(int nDetectorID)
  323. {
  324. FINFO("ActiveDetector ID: {$}", nDetectorID);
  325. //每一次选择一个view都要激活一次探测器。
  326. return true;
  327. }
  328. /***
  329. ** 根据采集模式申请图像buffer
  330. ***/
  331. bool CareRayCtrl::SetAcqMode(DetModeInfoStruct DetModeInfo, DetCalibInfo DetCalibInfo, int nMode)
  332. {
  333. FINFO("SetAcqMode[{$}]", nMode);
  334. m_stModeInfo = DetModeInfo;
  335. m_stCalibInfo = DetCalibInfo;
  336. //申请图像buffer
  337. if (nullptr != m_pImgBuffer)
  338. {
  339. delete[] m_pImgBuffer;
  340. m_pImgBuffer = nullptr;
  341. }
  342. m_pImgBuffer = new WORD[(size_t)m_stModeInfo.nImageHeight * (size_t)m_stModeInfo.nImageWidth];
  343. FINFO("SetAcqMode, image width: {$}, image height:{$}",m_stModeInfo.nImageWidth, m_stModeInfo.nImageHeight);
  344. FINFO("Offset width: {$}, Offset height: {$}",m_stModeInfo.nWidthOffset, m_stModeInfo.nHeightOffset);
  345. //step 1
  346. int nRet = -1;
  347. if(nMode == RAD)
  348. {
  349. nRet = API_CR_set_check_mode(MODE_RAD);
  350. m_nExposureMode = RAD;
  351. }
  352. else if (nMode == AEC)
  353. {
  354. nRet = API_CR_set_check_mode(MODE_PREV);
  355. m_nExposureMode = AEC;
  356. }
  357. if (TestError(nRet, "API_CR_set_check_mode"))
  358. {
  359. FERROR("Set check mode failed");
  360. return false;
  361. }
  362. m_nSyncMode = m_stModeInfo.nSyncType;
  363. FINFO("m_nSyncMode:{$}", m_nSyncMode);
  364. //step2
  365. int nSdkSyncMode = SOFT_SYNC;
  366. string strTemp = "SOFT_SYNC";
  367. switch (m_nSyncMode)
  368. {
  369. case SYNC_MANUAL:
  370. nSdkSyncMode = MANUAL_SYNC;
  371. strTemp = "MANUAL_SYNC";
  372. break;
  373. case SYNC_SOFTWARE:
  374. nSdkSyncMode = SOFT_SYNC;
  375. strTemp = "SOFT_SYNC";
  376. break;
  377. case SYNC_HARDWARE:
  378. nSdkSyncMode = EXT_SYNC;
  379. strTemp = "EXT_SYNC";
  380. break;
  381. case SYNC_AED:
  382. nSdkSyncMode = AUTO_SYNC;
  383. strTemp = "AUTO_SYNC";
  384. break;
  385. case SYNC_HARDWARE_DIRECT:
  386. nSdkSyncMode = EXT_SYNC;
  387. strTemp = "EXT_SYNC";
  388. break;
  389. default:
  390. break;
  391. }
  392. FINFO("nSdkSyncMode: {$} {$}", nSdkSyncMode, strTemp.c_str());
  393. if (!SetSyncMode(nSdkSyncMode, m_stModeInfo.nXwindow))
  394. {
  395. return false;
  396. }
  397. else
  398. {
  399. m_nCurSyncMode = m_nSyncMode;
  400. m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)m_nCurSyncMode;
  401. }
  402. //step 3
  403. LoadCareCalibration(true);
  404. m_nSaveRaw = m_stModeInfo.nIsSaveRaw;
  405. FINFO("SetAcqMode m_nSaveRaw:{$}", m_nSaveRaw);
  406. return true;
  407. }
  408. bool CareRayCtrl::PrepareAcquisition(FPDDeviceCareRay* pDrvDPC)
  409. {
  410. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  411. {
  412. FERROR("Not current DPC, return");
  413. return false;
  414. }
  415. FINFO("m_bIsAcqStatus:{$},m_bDetectorReady:{$}", m_bIsAcqStatus, m_bDetectorReady);
  416. //如果是采集状态那么就判断是不是ready了,如果不是采集状态就不判断是否ready了
  417. if (m_bIsAcqStatus)
  418. {
  419. if (m_bDetectorReady)
  420. {
  421. FINFO("Detector already in ready status, return true");
  422. return true;
  423. }
  424. }
  425. m_bCancelFlag = false; //准备采集前恢复初值
  426. FINFO("SetEvent(m_hAcqEvent)");
  427. SetEvent(m_hAcqEvent); //准备采集
  428. return true;
  429. }
  430. bool CareRayCtrl::StartAcquisition(FPDDeviceCareRay* pDrvDPC)
  431. {
  432. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  433. {
  434. FERROR("Not current DPC, return");
  435. return false;
  436. }
  437. //未初始化、未连接 不执行
  438. int nRet = -1;
  439. if (SYNC_SOFTWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  440. && EVT_READY == m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState)
  441. //在ready时调用api,避免api时序混乱
  442. {
  443. FINFO("Call exp request");
  444. nRet = API_CR_send_exp_request();
  445. if (TestError(nRet, "API_CR_send_exp_request"))
  446. {
  447. FERROR("Send exp request failed");
  448. return false;
  449. }
  450. }
  451. return true;
  452. }
  453. bool CareRayCtrl::StopAcquisition(FPDDeviceCareRay* pDrvDPC)
  454. {
  455. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  456. {
  457. FERROR("Not current DPC, return");
  458. return false;
  459. }
  460. int nRet = -1;
  461. FINFO("Call stop acq");
  462. nRet = API_CR_stop_acq_frame(); //用于终止曝光流程
  463. if (TestError(nRet, "API_CR_stop_acq_frame"))
  464. {
  465. FERROR("Stop acq failed");
  466. return false;
  467. }
  468. m_bDetectorReady = false;
  469. m_bIsAcqStatus = false;
  470. return true;
  471. }
  472. bool CareRayCtrl::ActiveCalibration(FPDDeviceCareRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType)
  473. {
  474. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  475. {
  476. FERROR("Not current DPC, return");
  477. return false;
  478. }
  479. int nRet = -1;
  480. //启动后直接开始校正,需要设置一次同步模式
  481. if (m_nCurSyncMode != m_nSyncMode)
  482. {
  483. int nSyncMode = SOFT_SYNC;
  484. string strTemp = "SOFT_SYNC";
  485. switch (m_nSyncMode)
  486. {
  487. case SYNC_MANUAL:
  488. nSyncMode = MANUAL_SYNC;
  489. strTemp = "MANUAL_SYNC";
  490. break;
  491. case SYNC_SOFTWARE:
  492. nSyncMode = SOFT_SYNC;
  493. strTemp = "SOFT_SYNC";
  494. break;
  495. case SYNC_HARDWARE:
  496. nSyncMode = EXT_SYNC;
  497. strTemp = "EXT_SYNC";
  498. break;
  499. case SYNC_AED:
  500. nSyncMode = MANUAL_SYNC; //探测器aed模式不支持校正,需要用manual
  501. strTemp = "MANUAL_SYNC(replace AUTO_SYNC in calibration)";
  502. break;
  503. case SYNC_HARDWARE_DIRECT:
  504. nSyncMode = EXT_SYNC;
  505. strTemp = "EXT_SYNC";
  506. break;
  507. default:
  508. break;
  509. }
  510. FINFO("Set SyncMode: {$} {$}", nSyncMode, strTemp.c_str());
  511. if (!SetSyncMode(nSyncMode))
  512. {
  513. return false;
  514. }
  515. else
  516. {
  517. m_nCurSyncMode = m_nSyncMode;
  518. m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)m_nCurSyncMode;
  519. }
  520. }
  521. else
  522. {
  523. //探测器aed模式不支持校正,需要用manual
  524. if (SYNC_AED == m_nSyncMode)
  525. {
  526. FINFO("Set SyncMode: 4 MANUAL_SYNC(replace AUTO_SYNC in calibration)");
  527. if (!SetSyncMode(MANUAL_SYNC))
  528. {
  529. return false;
  530. }
  531. }
  532. }
  533. m_nExamMode = APP_STATUS_CAL_BEGIN; //激活校正,置为校正界面
  534. m_eCaliType = eType;
  535. if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
  536. {
  537. m_nGainNodeIndex = 0; //激活校正,恢复初值
  538. m_nGainExpIndex = 0; //激活校正,恢复初值
  539. //下载一键校正文件
  540. FINFO("Call download factory cal files");
  541. nRet = API_CR_download_factory_cal_files();
  542. if (TestError(nRet, "API_CR_download_factory_cal_files"))
  543. {
  544. if (ERR_NO_CONFIGFILE == nRet || CR_SEND_ERR == nRet || CR_RECV_ERR == nRet)
  545. {
  546. //v2 DROC中下载失败也执行一键校正,和SDK demo不符
  547. //m_bOneKeyCalibration = true;
  548. FERROR("Failed to download calibration files from detector");
  549. }
  550. else
  551. {
  552. FERROR("Cannot find factory-calibrated files.");
  553. }
  554. m_bOneKeyCalibration = false;
  555. }
  556. //设置不应用校正
  557. LoadCareCalibration(false);
  558. //获取SDK校正参数
  559. FINFO("Call get cal params");
  560. nRet = API_CR_get_cal_params(&m_calparams);
  561. if (TestError(nRet, "API_CR_get_cal_params"))
  562. {
  563. FERROR("get cal params failed!");
  564. }
  565. else
  566. {
  567. FINFO("gain image dir: {$}", m_calparams.gain_image_dir);
  568. FINFO("num per dose: {$}", m_calparams.linear_num_per_dose);
  569. FINFO("dose: {$}", m_calparams.linear_dose_num);
  570. }
  571. }
  572. return true;
  573. }
  574. //使探测器ready
  575. bool CareRayCtrl::PrepareCalibration(FPDDeviceCareRay* pDrvDPC)
  576. {
  577. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  578. {
  579. FERROR("Not current DPC, return");
  580. return false;
  581. }
  582. if (m_bOneKeyCalibration)
  583. {
  584. PerformDarkAcquisition();
  585. }
  586. m_bCancelFlag = false; //准备校正前恢复初值
  587. SetEvent(m_hAcqEvent); //准备校正
  588. return true;
  589. }
  590. //软同步调用接口,其它同步模式没有动作
  591. bool CareRayCtrl::StartCalibration(FPDDeviceCareRay* pDrvDPC)
  592. {
  593. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  594. {
  595. FERROR("Not current DPC, return");
  596. return false;
  597. }
  598. //未初始化、未连接 不执行
  599. if (CCOS_CALIBRATION_TYPE_DARK)
  600. {
  601. SetEvent(m_hDarkEvent);
  602. }
  603. else if (CCOS_CALIBRATION_TYPE_XRAY)
  604. {
  605. int nRet = -1;
  606. if (SYNC_SOFTWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  607. && EVT_READY == m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState)
  608. //在ready时调用api,避免api时序混乱
  609. {
  610. FINFO("Call exp request");
  611. nRet = API_CR_send_exp_request();
  612. if (TestError(nRet, "API_CR_send_exp_request"))
  613. {
  614. FERROR("Send exp request failed");
  615. return false;
  616. }
  617. }
  618. }
  619. return true;
  620. }
  621. bool CareRayCtrl::StopCalibration(FPDDeviceCareRay* pDrvDPC)
  622. {
  623. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  624. {
  625. FERROR("Not current DPC, return");
  626. return false;
  627. }
  628. m_bCancelFlag = true;
  629. Sleep(500);
  630. //探测器aed模式不支持校正,需要用manual,校正结束后切换回来
  631. if (SYNC_AED == m_nSyncMode)
  632. {
  633. FINFO("Set SyncMode: 3 AUTO_SYNC(restore AUTO_SYNC in calibration)");
  634. SetSyncMode(AUTO_SYNC);
  635. }
  636. LoadCareCalibration(true);
  637. return true;
  638. }
  639. bool CareRayCtrl::ConfirmCalExposure()
  640. {
  641. m_nGainExpIndex++;
  642. if (!m_bOneKeyCalibration)
  643. {
  644. char* path = m_calparams.gain_image_dir;
  645. char strImageName[STRLEN];
  646. sprintf_s(strImageName, STRLEN, "70kv-%d%s%d%s", m_nGainExpIndex, "-", m_nGainExpCount, ".raw");
  647. //70kv-1-15.raw 。。。 70kv-15-15.raw
  648. FILE* fp;
  649. if ((fp = fopen(path, "wb")) == NULL)
  650. {
  651. DWORD dw = GetLastError();
  652. FERROR("fopen {$} failed, {$}", path, dw);
  653. return false;
  654. }
  655. fwrite(m_pRawImgBuffer, sizeof(WORD), (size_t)m_nRawImgWidth * (size_t)m_nRawImgHeight, fp);
  656. fclose(fp);
  657. FINFO("writeImageToDisk success.");
  658. }
  659. //处理已接受和未曝光的标记位
  660. if (m_nGainExpIndex == m_nGainExpCount) //当前剂量点的曝光次数已经够了
  661. {
  662. m_nGainNodeIndex++;
  663. if (m_nGainNodeIndex == m_nGainNodeCount) //所有剂量点已经曝光完成
  664. {
  665. //校正结束的处理
  666. if (m_bOneKeyCalibration)
  667. {
  668. double dMean = GetMean(m_pRawImgBuffer, m_nImageSize / sizeof(WORD));
  669. if (dMean > 20000 * 1.25 || dMean < 20000 * 0.75)
  670. {
  671. FINFO("Call check image");
  672. int nRet = API_CR_check_img_for_factory_cal(m_pRawImgBuffer);
  673. if (TestError(nRet, "API_CR_check_img_for_factory_cal"))
  674. {
  675. FERROR("It is strongly recommended to reject this image");
  676. }
  677. }
  678. SurfaceFitResult fitResult;
  679. FINFO("CALL CR_execute_one_key_cal");
  680. int nRet = API_CR_execute_one_key_cal(m_pRawImgBuffer, m_pDarkImage, &fitResult); //根据输入的亮场图像和暗场图像计算一键校准文件
  681. if (TestError(nRet, "API_CR_execute_one_key_cal"))
  682. {
  683. FERROR("CR_execute_one_key_cal Failed");
  684. }
  685. else
  686. {
  687. FINFO("CR_execute_one_key_cal Success");
  688. }
  689. }
  690. FINFO("Gain calibration finished! set exammode to cali end");
  691. m_bCancelFlag = true; //校正结束曝光流程
  692. m_nExamMode = APP_STATUS_CAL_END; //增益结束,置为end
  693. //探测器aed模式不支持校正,需要用manual,校正结束后切换回来
  694. if (SYNC_AED == m_nSyncMode)
  695. {
  696. FINFO("Set SyncMode: 3 AUTO_SYNC(restore AUTO_SYNC in calibration)");
  697. SetSyncMode(AUTO_SYNC);
  698. }
  699. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  700. }
  701. }
  702. FINFO("Exp index and count({$} {$}), note index and count({$} {$})", m_nGainExpIndex, m_nGainExpCount, m_nGainNodeIndex, m_nGainNodeCount);
  703. return true;
  704. }
  705. void CareRayCtrl::RejectCalExposure()
  706. {
  707. //暂时什么都不处理
  708. }
  709. bool CareRayCtrl::LoadDll(string strWorkPath)
  710. {
  711. string strSDKPath = "";
  712. try
  713. {
  714. strSDKPath = (string)m_ModeConfig["SDKPath"];
  715. }
  716. catch (ResDataObjectExption& e)
  717. {
  718. FERROR("Read configuration failed, Error code: {$}", e.what());
  719. return false;
  720. }
  721. string workpath = strWorkPath + "\\" + strSDKPath;
  722. string drvpath = workpath + "\\CrApi.dll";
  723. //SetDllDirectory(workpath.c_str());
  724. //将SDK路径加入环境变量
  725. char* pathvar;
  726. pathvar = getenv("Path");
  727. printf("pathvar = %s \n\n", pathvar);
  728. string strPath = "Path=";
  729. strPath += pathvar;
  730. strPath += ";";
  731. strPath += workpath;
  732. printf("strPath:%s \n\n", strPath.c_str());
  733. if (_putenv(strPath.c_str()) != 0)
  734. {
  735. DWORD dw = GetLastError();
  736. printf("put env failed! last error:%ld \n", dw);
  737. return false;
  738. }
  739. m_hCareRayModule = LoadLibrary(drvpath.c_str());
  740. if (m_hCareRayModule == nullptr)
  741. {
  742. DWORD dw = GetLastError();
  743. FERROR("Load {$} failed: {$}", drvpath.c_str(), dw);
  744. return false;
  745. }
  746. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_register_callback);
  747. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_connect_detector);
  748. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_disconnect_detector);
  749. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_reset_detector);
  750. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_dual_detector_state);
  751. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_detector_type);
  752. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_detector_info);
  753. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_status_info);
  754. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_check_mode);
  755. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_mode_info);
  756. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_sync_mode);
  757. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_cycle_time);
  758. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_normal_power);
  759. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_save_power);
  760. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_soft_acquisition);
  761. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_ready_state_request);
  762. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_send_exp_request);
  763. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_full_image);
  764. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_image_attr);
  765. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_image);
  766. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_query_prog_info);
  767. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_permit_exposure);
  768. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_stop_acq_frame);
  769. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_stop_cal_procedure);
  770. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_cal_offset);
  771. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_download_factory_cal_files);
  772. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_user_correction);
  773. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_cal_params);
  774. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_check_img_for_factory_cal);
  775. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_execute_one_key_cal);
  776. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_dark_full_image);
  777. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_prev_image);
  778. //共32个
  779. return true;
  780. }
  781. /***
  782. ** 连接探测器
  783. ***/
  784. bool CareRayCtrl::OpenDetector()
  785. {
  786. string strSDKPath = "";
  787. try
  788. {
  789. strSDKPath = (string)m_ModeConfig["SDKPath"];
  790. }
  791. catch (ResDataObjectExption& e)
  792. {
  793. FERROR("Read configuration failed, Error code: {$}", e.what());
  794. return false;
  795. }
  796. string strWorkpath = m_strWorkPath + "\\" + strSDKPath + "\\CareRay";
  797. char* szWorkpath = const_cast<char*>(strWorkpath.c_str());
  798. int nRet = -1;
  799. FINFO("Call connect({$})", szWorkpath);
  800. nRet = API_CR_connect_detector(szWorkpath);
  801. if (CR_NO_ERR != nRet && CR_ALREADY_CONN_ERR != nRet)
  802. {
  803. FERROR("Connect return failed! reson:{$}", CrErrStrList(nRet));
  804. return false;
  805. }
  806. FINFO("Connect executed successfully");
  807. //测试发现,注册回调需要放在连接成功之后
  808. FINFO("Register callback");
  809. nRet = API_CR_register_callback(CREventCallback);
  810. if (TestError(nRet, "API_CR_register_callback"))
  811. {
  812. FERROR("register callback failed!");
  813. }
  814. //如果是双板环境,输出两个平板的信息
  815. if (m_nPanelCount > 1)
  816. {
  817. DetectorActiveState das;
  818. API_CR_get_dual_detector_state(&das);
  819. FINFO("Current Active Detector ID = {$}", das.activeDetectorID);
  820. FINFO("Detector Number = {$}, Detector A type = {$}, Detector B type = {$}",
  821. das.detectorNum, das.detectorAType, das.detectorBType);
  822. FINFO("Detector A connect state = {$}, Detector B connect state = {$}",
  823. das.detectorAstate, das.detectorBstate);
  824. if (das.detectorAstate)
  825. {
  826. m_pStPanelStatus[0]->bConnectState = true;
  827. }
  828. if (das.detectorBstate)
  829. {
  830. m_pStPanelStatus[1]->bConnectState = true;
  831. }
  832. if (0 != das.activeDetectorID)
  833. {
  834. //双板时,若第一块板不连接,API会自动切换到第二块探测器
  835. //此处暂不处理
  836. }
  837. }
  838. else
  839. {
  840. m_pStPanelStatus[0]->bConnectState = true;
  841. }
  842. return true;
  843. }
  844. /***
  845. ** 初始化探测器
  846. ***/
  847. bool CareRayCtrl::InitDetector()
  848. {
  849. int nRet = -1;
  850. //初始化时先reset,恢复缺省状态
  851. FINFO("Call reset");
  852. nRet = API_CR_reset_detector(FALSE);
  853. if (TestError(nRet, "API_CR_reset_detector"))
  854. {
  855. FERROR("reset detector failed!");
  856. }
  857. //获取实际的探测器类型
  858. FINFO("Call gettype");
  859. m_nCurrentDetectorType = API_CR_get_detector_type();
  860. string strType = "";
  861. GetDetectorType((DetectorType)m_nCurrentDetectorType, strType);
  862. FINFO("Detector type: {$} {$}", m_nCurrentDetectorType, strType.c_str());
  863. //加载校正文件
  864. //LoadCareCalibration(true);
  865. //输出探测器信息(图像相关、软件版本、SN)
  866. ShowDetectorInfo();
  867. //获取探测器温度、电量、wifi信号
  868. ShowStatusInfo();
  869. //设置采集模式,输出该模式信息
  870. FINFO("Call set mode");
  871. nRet = API_CR_set_check_mode(m_nCurrentMode);
  872. if (TestError(nRet, "API_CR_set_check_mode"))
  873. {
  874. FERROR("Set mode failed");
  875. return false;
  876. }
  877. if (CR_NO_ERR != ShowModeInfo())
  878. {
  879. return false;
  880. }
  881. return true;
  882. }
  883. int CareRayCtrl::ShowDetectorInfo()
  884. {
  885. FINFO("Getting Detector Info");
  886. DetectorInfo detectorInfo;
  887. int nRet = API_CR_get_detector_info(&detectorInfo);
  888. if (TestError(nRet, "API_CR_get_detector_info"))
  889. {
  890. FERROR("Get Detector Info Failed");
  891. }
  892. else
  893. {
  894. FINFO("RawImageWidth is: {$}", detectorInfo.rawImageWidth);
  895. FINFO("RawImageHeight is: {$}", detectorInfo.rawImageHeight);
  896. FINFO("MaxPixelValue is: {$}", detectorInfo.maxPixelValue);
  897. FINFO("BitsPerPixel is: {$}", detectorInfo.bitsPerPixel);
  898. FINFO("SoftWareVerion is: {$}", detectorInfo.softWareVersion);
  899. FINFO("SerialNumber is: {$}", detectorInfo.serialNumber);
  900. ConfFeedback(EVT_CONF_PANEL_SERIAL, m_nCurrentPanelID, detectorInfo.serialNumber);
  901. }
  902. return nRet;
  903. }
  904. /***
  905. ** 显示温度、电量、wifi等信息
  906. ***/
  907. int CareRayCtrl::ShowStatusInfo()
  908. {
  909. int nRet;
  910. StatusInfo stInfo;
  911. nRet = API_CR_get_status_info(&stInfo);
  912. if (TestError(nRet, "API_CR_get_status_info"))
  913. {
  914. FERROR("Get Detector Status Info Failed");
  915. }
  916. else
  917. {
  918. FINFO("Current detector temperature:{$}", stInfo.temperature.maxTemperature);
  919. StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nCurrentPanelID, stInfo.temperature.maxTemperature);
  920. bool bCharging = true;
  921. if (stInfo.batInfo.ave_current > 0.00001)
  922. {
  923. bCharging = false;
  924. }
  925. FINFO("Current detector battery: {$}% {$}", stInfo.batInfo.relative_state_of_charge * 100, bCharging ? "Charging" : "Not charging");
  926. int nBatteryValue = 0;
  927. if (bCharging) //有线连接
  928. {
  929. nBatteryValue = 100;
  930. }
  931. else
  932. {
  933. nBatteryValue = (int)(stInfo.batInfo.relative_state_of_charge * 100);
  934. }
  935. StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryValue, "", m_nCurrentPanelID);
  936. //string strLinkQuality = stInfo.wireless_info.link_quality;
  937. FINFO("Current detector wifi link quality: {$}", stInfo.wireless_info.link_quality);
  938. int nLinkQuality = 0;
  939. if (bCharging) //有线连接
  940. {
  941. nLinkQuality = 100;
  942. }
  943. else
  944. {
  945. nLinkQuality = atoi(stInfo.wireless_info.link_quality);
  946. }
  947. StatusFeedback(EVT_STATUS_WIFI, nLinkQuality, "", m_nCurrentPanelID);
  948. }
  949. return nRet;
  950. }
  951. /***
  952. ** 显示当前采集模式的图像信息
  953. ***/
  954. int CareRayCtrl::ShowModeInfo()
  955. {
  956. FINFO("Call get mode info");
  957. ModeInfo stModeInfo;
  958. int nRet = API_CR_get_mode_info(m_nCurrentMode, &stModeInfo);
  959. if (TestError(nRet, "API_CR_get_mode_info"))
  960. {
  961. FERROR("Get Mode Info Failed");
  962. }
  963. else
  964. {
  965. m_nRawImgWidth = stModeInfo.imageWidth;
  966. m_nRawImgHeight = stModeInfo.imageHeight;
  967. //imageSize = 图像数据+65535头的大小
  968. FINFO("ImageWidth = {$}, ImageHeight = {$}, ImageSize = {$}", stModeInfo.imageWidth, stModeInfo.imageHeight, stModeInfo.imageSize);
  969. FINFO("LinesPerPixel = {$}, ColsPerPixel = {$}", stModeInfo.linesPerPixel, stModeInfo.colsPerPixel);//大于1时表示开启BINNING模式
  970. }
  971. return nRet;
  972. }
  973. /***
  974. ** 设置同步模式、采集窗口
  975. ***/
  976. bool CareRayCtrl::SetSyncMode(int nSyncMode, int nXWindowTime)
  977. {
  978. FINFO("SetSyncMode nSyncMode:{$},nXWindowTime:{$}", nSyncMode, nXWindowTime);
  979. int nResult = CR_NO_ERR;
  980. FINFO("Call API_CR_set_sync_mode");
  981. nResult = API_CR_set_sync_mode(nSyncMode);
  982. if (TestError(nResult, "API_CR_set_sync_mode"))
  983. {
  984. FERROR("Set sync mode Failed");
  985. return false;
  986. }
  987. if (nXWindowTime <= 0)
  988. {
  989. FERROR("XWindowTime <= 0, it's invalid!");
  990. return false;
  991. }
  992. //设置探测器的曝光窗口时间
  993. int nDelayTime = 0;
  994. int nWaitTime = 0;
  995. switch (nSyncMode)
  996. {
  997. case EXT_SYNC:
  998. if (m_nExposureMode == RAD)
  999. {
  1000. //m_nXWindowTime = 2500;
  1001. m_nXWindowTime = nXWindowTime;
  1002. }
  1003. else
  1004. {
  1005. m_nXWindowTime = 500;
  1006. }
  1007. nDelayTime = 100; nWaitTime = 5;
  1008. break;
  1009. case SOFT_SYNC:
  1010. nDelayTime = 100; nWaitTime = 5;
  1011. break;
  1012. case AUTO_SYNC:
  1013. nDelayTime = 5; nWaitTime = 5;
  1014. break;
  1015. case MANUAL_SYNC:
  1016. nDelayTime = 500; nWaitTime = 5;
  1017. break;
  1018. case AED_SYNC:
  1019. nDelayTime = 100; nWaitTime = 5;
  1020. break;
  1021. default:
  1022. m_nXWindowTime = 500; nDelayTime = 100; nWaitTime = 5;
  1023. break;
  1024. }
  1025. FINFO("m_nXWindowTime: {$}, Delay Time: {$}, WaitTime: {$}", m_nXWindowTime, nDelayTime, nWaitTime);
  1026. FINFO("Call API_CR_set_cycle_time");
  1027. nResult = API_CR_set_cycle_time(m_nXWindowTime, nDelayTime, nWaitTime);
  1028. if (TestError(nResult, "API_CR_set_cycle_time"))
  1029. {
  1030. FERROR("Set cycle Time Failed");
  1031. return false;
  1032. }
  1033. FINFO("Set cycle time success");
  1034. return true;
  1035. }
  1036. unsigned __stdcall CareRayCtrl::onFPDScanThread(PVOID pvoid)
  1037. {
  1038. CareRayCtrl* pOpr = (CareRayCtrl*)pvoid;
  1039. FINFO("Enter scan thread");
  1040. bool bExit = false;
  1041. DWORD dwTimeOut = INFINITE;
  1042. while (!bExit)
  1043. {
  1044. DWORD dwRet = WaitForMultipleObjects(SCAN_EVENT_COUNT, pOpr->m_hArrayEvent, FALSE, dwTimeOut);
  1045. if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent
  1046. {
  1047. bExit = true;
  1048. }
  1049. else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hAcqEvent
  1050. {
  1051. pOpr->OnAcquireImage();
  1052. }
  1053. else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hProcessImgEvent
  1054. {
  1055. pOpr->OnProcessImg();
  1056. }
  1057. else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hXWinOnEvent
  1058. {
  1059. //SDK
  1060. FINFO("Get XWinOnEvent");
  1061. ULONGLONG dwXrayOnT, dwXrayOffT;
  1062. dwXrayOnT = dwXrayOffT = GetTickCount64();
  1063. FINFO("window on: {$}", dwXrayOnT);
  1064. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1065. while (dwXrayOffT - dwXrayOnT < 500) //窗口暂时写死
  1066. {
  1067. dwXrayOffT = GetTickCount64();
  1068. }
  1069. FINFO("window off: {$}", dwXrayOffT);
  1070. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1071. }
  1072. else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hDarkEvent
  1073. {
  1074. pOpr->OnStartDarkCalibration();
  1075. }
  1076. else if (WAIT_OBJECT_0 + 5 == dwRet) //m_hGainEvent
  1077. {
  1078. pOpr->OnAcquireGainImage();
  1079. }
  1080. }
  1081. FINFO("Level scan thread");
  1082. return 0;
  1083. }
  1084. //每5s向上通知一次状态
  1085. unsigned __stdcall CareRayCtrl::onNotifyDetectorInfoThread(PVOID pvoid)
  1086. {
  1087. CareRayCtrl* pOpr = (CareRayCtrl*)pvoid;
  1088. FINFO("Enter notify info thread");
  1089. while (!pOpr->m_bExitNotify)
  1090. {
  1091. pOpr->ShowStatusInfo();
  1092. Sleep(5000);
  1093. }
  1094. FINFO("Level notify info thread");
  1095. return 0;
  1096. }
  1097. void CareRayCtrl::OnAcquireImage()
  1098. {
  1099. if (SYNC_SOFTWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1100. && !m_bOneKeyCalibration)
  1101. {
  1102. PerformSoftSyncAcq();
  1103. }
  1104. else
  1105. {
  1106. PerformRadAcquisition();
  1107. }
  1108. }
  1109. void CareRayCtrl::OnProcessImg()
  1110. {
  1111. if (SYNC_MANUAL == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode || SYNC_AED == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1112. || SYNC_HARDWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode)
  1113. {
  1114. FINFO("OnProcessImg send window off");
  1115. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1116. }
  1117. int nRet = 0;
  1118. FrameAttr stImgInfo = {0};
  1119. if (m_bGetImage)
  1120. {
  1121. FINFO("Call get image attr");
  1122. nRet = API_CR_get_image_attr(&stImgInfo);
  1123. if (TestError(nRet, "API_CR_get_image_attr"))
  1124. {
  1125. FERROR("get image attr Failed");
  1126. }
  1127. else
  1128. {
  1129. FINFO("Image attr, H: {$}, W: {$}, bits: {$}",
  1130. stImgInfo.image_height, stImgInfo.image_width, stImgInfo.pixel_bits);
  1131. }
  1132. m_nImageSize = stImgInfo.image_height * stImgInfo.image_width * stImgInfo.pixel_bits / 8;
  1133. if (m_pRawImgBuffer != nullptr)
  1134. {
  1135. delete[] m_pRawImgBuffer;
  1136. m_pRawImgBuffer = nullptr;
  1137. }
  1138. m_pRawImgBuffer = new WORD[stImgInfo.image_width * stImgInfo.image_height];
  1139. FINFO("Call get image");
  1140. nRet = API_CR_get_image(m_nImageSize, FALSE, m_pRawImgBuffer);
  1141. if (TestError(nRet, "API_CR_get_image"))
  1142. {
  1143. FERROR("Get image failed");
  1144. return;
  1145. }
  1146. }
  1147. if (m_nExposureMode == AEC)
  1148. {
  1149. FINFO("OnProcessImg AEC");
  1150. DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pRawImgBuffer);
  1151. StatusFeedback(EVT_STATUS_PANEL, PANEL_AEC_PRE_END);
  1152. if (m_nSaveRaw > 1)
  1153. {
  1154. SaveRawFunc(m_pRawImgBuffer, stImgInfo.image_width, stImgInfo.image_height);
  1155. }
  1156. return;
  1157. }
  1158. //整个系统的有图校正流程还没做,先按无图处理
  1159. if (APP_STATUS_CAL_BEGIN == m_nExamMode)
  1160. {
  1161. ConfirmCalExposure();
  1162. if (m_nGainNodeIndex != m_nGainNodeCount) //增益曝光次数够了,这两个值会是相等的
  1163. {
  1164. StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_ACCEPT);
  1165. }
  1166. return;
  1167. }
  1168. FINFO("m_stModeInfo.nWidthOffset:{$},m_stModeInfo.nHeightOffset:{$}", m_stModeInfo.nWidthOffset, m_stModeInfo.nHeightOffset);
  1169. FINFO("Begin get effect image");
  1170. if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, stImgInfo.image_width))
  1171. {
  1172. return;
  1173. }
  1174. FINFO("Get effect image over");
  1175. DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer);
  1176. if (m_nSaveRaw > 1)
  1177. {
  1178. SaveRawFunc(m_pImgBuffer, m_stModeInfo.nImageWidth, m_stModeInfo.nImageHeight);
  1179. }
  1180. FINFO("Call API_CR_set_save_power");
  1181. nRet = API_CR_set_save_power();
  1182. if (TestError(nRet, "API_CR_set_save_power"))
  1183. {
  1184. FERROR("Set save power failed");
  1185. }
  1186. StatusFeedback(EVT_STATUS_PANEL, PANEL_END_ACQ);
  1187. }
  1188. void CareRayCtrl::OnStartDarkCalibration()
  1189. {
  1190. FINFO("Start dark calibration process");
  1191. int nRet = -1;
  1192. FINFO("Call stop cal procedure(FALSE)");
  1193. nRet = API_CR_stop_cal_procedure(FALSE); //参照SDK demo流程,在开始前调用这个接口
  1194. if (TestError(nRet, "API_CR_stop_cal_procedure"))
  1195. {
  1196. FERROR("stop cal procedure failed!");
  1197. }
  1198. FINFO("Call cal offset");
  1199. nRet = API_CR_cal_offset(m_nCurrentMode);
  1200. if (TestError(nRet, "API_CR_cal_offset"))
  1201. {
  1202. FERROR("Start offset failed");
  1203. return;
  1204. }
  1205. FINFO("Query status");
  1206. int nFrameNum = 0;
  1207. ExpProgress calProg;
  1208. do
  1209. {
  1210. nRet = API_CR_query_prog_info(CR_CAL_PROG, &calProg);
  1211. if (TestError(nRet, "API_CR_query_prog_info"))
  1212. {
  1213. FERROR("Query Prog Info Failed");
  1214. API_CR_reset_detector(FALSE);
  1215. return;
  1216. }
  1217. Sleep(100);
  1218. if (TestError(calProg.errorCode))
  1219. {
  1220. break;
  1221. }
  1222. if (calProg.frame_number > nFrameNum)
  1223. {
  1224. FINFO("Now received {$} dark images ", calProg.frame_number);
  1225. nFrameNum = calProg.frame_number;
  1226. }
  1227. if (m_bAbortOffset)
  1228. {
  1229. FINFO("Abort Offset Calibration!");
  1230. FINFO("Call stop cal procedure(TRUE)");
  1231. nRet = API_CR_stop_cal_procedure(TRUE);
  1232. if (TestError(nRet, "API_CR_stop_cal_procedure"))
  1233. {
  1234. FERROR("stop cal procedure failed!");
  1235. }
  1236. break;
  1237. }
  1238. } while (FALSE == calProg.calComplete);
  1239. if (TRUE == calProg.calComplete)
  1240. {
  1241. FINFO("Offset calibration finished!");
  1242. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  1243. }
  1244. else
  1245. {
  1246. FERROR("Error occurred in offset calibration!");
  1247. return;
  1248. }
  1249. }
  1250. void CareRayCtrl::OnAcquireGainImage()
  1251. {
  1252. }
  1253. void CareRayCtrl::OnNotifyDetectorInfo()
  1254. {
  1255. }
  1256. /***
  1257. ** 启动软同步采集
  1258. ** 通过回调反馈进度
  1259. ***/
  1260. int CareRayCtrl::PerformSoftSyncAcq()
  1261. {
  1262. FINFO("PerformSoftSyncAcq start");
  1263. int nRet = -1;
  1264. if (EVT_EXP_EN == m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState)
  1265. {
  1266. FERROR("Detector has Image unrecoved, Omit");
  1267. return nRet;
  1268. }
  1269. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = 0; //开始采集前,恢复初值
  1270. FINFO("Call soft acq");
  1271. nRet = API_CR_start_soft_acquisition();
  1272. if (TestError(nRet, "API_CR_start_soft_acquisition"))
  1273. {
  1274. FERROR("Start soft acq failed");
  1275. }
  1276. else
  1277. {
  1278. FINFO("Call request ready");
  1279. nRet = API_CR_ready_state_request();
  1280. if (TestError(nRet, "API_CR_ready_state_request"))
  1281. {
  1282. FERROR("Request ready state failed");
  1283. }
  1284. else
  1285. {
  1286. FINFO("Call start acq fullimg");
  1287. nRet = API_CR_start_acq_full_image();
  1288. if (TestError(nRet, "API_CR_start_acq_full_image"))
  1289. {
  1290. FERROR("Start acq fullimg failed");
  1291. }
  1292. }
  1293. }
  1294. FINFO("PerformSoftSyncAcq end");
  1295. return nRet;
  1296. }
  1297. int CareRayCtrl::PerformRadAcquisition()
  1298. {
  1299. FINFO("PerformRadAcquisition start");
  1300. int nRet = -1;
  1301. FINFO("Call normal power");
  1302. nRet = API_CR_set_normal_power();
  1303. if (TestError(nRet, "API_CR_set_normal_power"))
  1304. {
  1305. FERROR("Set normal power failed");
  1306. return nRet;
  1307. }
  1308. if (m_nExposureMode == AEC)
  1309. {
  1310. FINFO("Call start acq preview image in AEC");
  1311. nRet = API_CR_start_acq_prev_image();
  1312. if (TestError(nRet, "API_CR_start_acq_prev_image"))
  1313. {
  1314. FERROR("Start acq preview image failed");
  1315. return nRet;
  1316. }
  1317. }
  1318. else
  1319. {
  1320. FINFO("Call start acq full img");
  1321. nRet = API_CR_start_acq_full_image();
  1322. if (TestError(nRet, "API_CR_start_acq_full_image"))
  1323. {
  1324. FERROR("Start acq fullimg failed");
  1325. return nRet;
  1326. }
  1327. }
  1328. if (SYNC_MANUAL == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1329. || SYNC_AED == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode)
  1330. {
  1331. nRet = QueryAutoProgInfo();
  1332. }
  1333. else
  1334. {
  1335. nRet = QueryRadProgInfo();
  1336. }
  1337. //轮询采集状态没有返回图像或终止了采集
  1338. if (CR_NO_ERR != nRet)
  1339. {
  1340. FINFO("Call normal power");
  1341. nRet = API_CR_set_normal_power();
  1342. if (TestError(nRet, "API_CR_set_normal_power"))
  1343. {
  1344. FERROR("Set normal power failed");
  1345. }
  1346. return nRet;
  1347. }
  1348. FINFO("Call normal power");
  1349. nRet = API_CR_set_normal_power();
  1350. if (TestError(nRet, "API_CR_set_normal_power"))
  1351. {
  1352. FERROR("Set normal power failed");
  1353. return nRet;
  1354. }
  1355. if (m_bCancelFlag)//点片退出检查不再上图
  1356. {
  1357. FINFO("PerformRadAcquisition Cancel");
  1358. return -1;
  1359. }
  1360. m_bGetImage = true; //轮询拿到图像,置为true
  1361. SetEvent(m_hProcessImgEvent);
  1362. FINFO("PerformRadAcquisition over");
  1363. return nRet;
  1364. }
  1365. /***
  1366. ** 一键校正时获取一帧暗场图
  1367. ***/
  1368. int CareRayCtrl::PerformDarkAcquisition()
  1369. {
  1370. int nRet = -1;
  1371. int printOver = 0, awaitOver = 0;
  1372. ExpProgress expProg;
  1373. FINFO("Call normal power");
  1374. nRet = API_CR_set_normal_power();
  1375. if (TestError(nRet, "API_CR_set_normal_power"))
  1376. {
  1377. FERROR("Set normal power failed");
  1378. return false;
  1379. }
  1380. FINFO("Call start acq dark fullimg");
  1381. nRet = API_CR_start_acq_dark_full_image();
  1382. if (TestError(nRet, "API_CR_start_acq_dark_full_image"))
  1383. {
  1384. FERROR("Acquire dark image failed");
  1385. return nRet;
  1386. }
  1387. memset(&expProg, 0x0, sizeof(ExpProgress));
  1388. FINFO("Query Detector Status");
  1389. do
  1390. {
  1391. Sleep(50);
  1392. if (CR_NO_ERR != (nRet = API_CR_query_prog_info(CR_RAD_PROG, &expProg)))
  1393. {
  1394. FERROR("Error occurred when query detector status info!");
  1395. return nRet;
  1396. }
  1397. if (expProg.fetchable)
  1398. {
  1399. FINFO("Dark Image will Arrive");
  1400. break;
  1401. }
  1402. } while (TRUE);
  1403. FINFO("Call normal power");
  1404. nRet = API_CR_set_normal_power();
  1405. if (TestError(nRet, "API_CR_set_normal_power"))
  1406. {
  1407. FERROR("Set normal power failed");
  1408. return false;
  1409. }
  1410. FrameAttr stImgInfo;
  1411. FINFO("Call get image attr");
  1412. nRet = API_CR_get_image_attr(&stImgInfo);
  1413. if (TestError(nRet, "API_CR_get_image_attr"))
  1414. {
  1415. FERROR("get image attr failed");
  1416. return nRet;
  1417. }
  1418. else
  1419. {
  1420. FINFO("Image attr, H: {$}, W: {$}, bits: {$}",
  1421. stImgInfo.image_height, stImgInfo.image_width, stImgInfo.pixel_bits);
  1422. }
  1423. if (nullptr == m_pDarkImage)
  1424. {
  1425. m_pDarkImage = new WORD[stImgInfo.image_height * stImgInfo.image_width];
  1426. }
  1427. FINFO("Call get image");
  1428. nRet = API_CR_get_image(stImgInfo.image_height * stImgInfo.image_width * 2, FALSE, m_pDarkImage);
  1429. if (TestError(nRet, "API_CR_get_image"))
  1430. {
  1431. FERROR("Get image failed");
  1432. return nRet;
  1433. }
  1434. return nRet;
  1435. }
  1436. /***
  1437. ** 轮询Manual(SDK的半aed模式)、aed模式采集状态
  1438. ***/
  1439. int CareRayCtrl::QueryAutoProgInfo(bool bIsAED)
  1440. {
  1441. FINFO("Begin query auto exposure progress info");
  1442. ExpProgress expProg;
  1443. memset(&expProg, 0x0, sizeof(ExpProgress));
  1444. bool bPrintOver = false;
  1445. bool bAwaitOver = false;
  1446. int nResult = -1;
  1447. int nTime = 0;
  1448. bool bReady = false; //aed时曝光0-1-0变化,通过这个变量忽略第一个0
  1449. //manual时曝光0-1-0-1...变化,通过这个变量忽略后面的1
  1450. do
  1451. {
  1452. Sleep(50);
  1453. if ((nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg)) != CR_NO_ERR)
  1454. {
  1455. FERROR("Error occurred when query detector status info! {$}, {$}", nResult, expProg.fetchable);
  1456. return nResult;
  1457. }
  1458. switch (expProg.expose_flag)
  1459. {
  1460. case FALSE:
  1461. {
  1462. if (bAwaitOver == false)
  1463. {
  1464. if (APP_STATUS_CAL_BEGIN == m_nExamMode)
  1465. {
  1466. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "false");
  1467. }
  1468. else
  1469. {
  1470. if (MANUAL_SYNC == m_nSyncMode)
  1471. {
  1472. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "false");
  1473. }
  1474. }
  1475. bAwaitOver = true;
  1476. bPrintOver = false;
  1477. FINFO("Waiting for detector Ready...");
  1478. }
  1479. }
  1480. break;
  1481. case TRUE:
  1482. {
  1483. if (!bPrintOver)
  1484. {
  1485. if (!bReady)
  1486. {
  1487. bReady = true;
  1488. m_bDetectorReady = true;
  1489. m_bIsAcqStatus = true;
  1490. //通知ready状态
  1491. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1492. }
  1493. if (APP_STATUS_CAL_BEGIN == m_nExamMode)
  1494. {
  1495. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "true");
  1496. }
  1497. else
  1498. {
  1499. if (MANUAL_SYNC == m_nSyncMode)
  1500. {
  1501. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "true");
  1502. }
  1503. }
  1504. bPrintOver = true;
  1505. bAwaitOver = false;
  1506. FINFO("Detector is ready for Rad Acquisition, press x-ray hand switch now...");
  1507. }
  1508. }
  1509. break;
  1510. default:
  1511. break;
  1512. }//end for switch
  1513. if (expProg.fetchable)
  1514. {
  1515. FINFO("Image will arrive in auto exposure progress");
  1516. break;
  1517. }
  1518. else
  1519. {
  1520. if (m_bCancelFlag)//Manual AED时取消
  1521. {
  1522. //没有图或退出do while循环的处理
  1523. int nRet = -1;
  1524. FINFO("Cancel, Call stop acq");
  1525. nRet = API_CR_stop_acq_frame(); //用于终止曝光流程
  1526. if (TestError(nRet, "API_CR_stop_acq_frame"))
  1527. {
  1528. FERROR("Stop acq failed");
  1529. }
  1530. else
  1531. {
  1532. m_bDetectorReady = false;
  1533. m_bIsAcqStatus = false;
  1534. }
  1535. FINFO("Leave loop");
  1536. return -1;
  1537. }
  1538. }
  1539. } while (true);
  1540. return CR_NO_ERR;
  1541. }
  1542. /***
  1543. ** 轮询硬同步模式采集状态
  1544. ***/
  1545. int CareRayCtrl::QueryRadProgInfo()
  1546. {
  1547. FINFO("Begin query rad exposure progress info");
  1548. ExpProgress expProg;
  1549. memset(&expProg, 0, sizeof(ExpProgress));
  1550. bool bExpError = false;
  1551. bool bExpInit = false;
  1552. bool bExpReady = false;
  1553. bool bExpPermission = false;
  1554. bool bExpPermitted = false;
  1555. bool bExpExpose = false;
  1556. bool bExpComplete = false;
  1557. int nResult = -1;
  1558. do
  1559. {
  1560. Sleep(20);
  1561. if ((nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg)) != CR_NO_ERR)
  1562. {
  1563. FERROR("Error occurred when query detector status info! {$}, {$}", nResult, expProg.fetchable);
  1564. return nResult;
  1565. }
  1566. switch (expProg.expStatus)
  1567. {
  1568. case CR_EXP_ERROR:
  1569. if (!bExpError)
  1570. {
  1571. bExpError = true;
  1572. FINFO("CR_EXP_ERROR(-1)");
  1573. }
  1574. break;
  1575. case CR_EXP_INIT:
  1576. if (!bExpInit)
  1577. {
  1578. bExpInit = true;
  1579. FINFO("CR_EXP_INIT(0)");
  1580. }
  1581. break;
  1582. case CR_EXP_READY:
  1583. if (!bExpReady)
  1584. {
  1585. //通知ready状态
  1586. bExpReady = true;
  1587. FINFO("CR_EXP_READY(1)");
  1588. m_bDetectorReady = true;
  1589. m_bIsAcqStatus = true;
  1590. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1591. }
  1592. break;
  1593. case CR_EXP_WAIT_PERMISSION:
  1594. if (!bExpPermission)
  1595. {
  1596. bExpPermission = true;
  1597. FINFO("CR_EXP_WAIT_PERMISSION(2) Call permit");
  1598. nResult = API_CR_permit_exposure();
  1599. if (TestError(nResult, "API_CR_permit_exposure"))
  1600. {
  1601. FERROR("Permit Exposure Failed!");
  1602. return nResult;
  1603. }
  1604. }
  1605. break;
  1606. case CR_EXP_PERMITTED:
  1607. if (!bExpPermitted)
  1608. {
  1609. bExpPermitted = true;
  1610. FINFO("CR_EXP_PERMITTED(3)");
  1611. }
  1612. break;
  1613. case CR_EXP_EXPOSE:
  1614. if (!bExpPermitted)
  1615. {
  1616. bExpPermitted = true;
  1617. FINFO("CR_EXP_EXPOSE(4)");
  1618. //这个事件基本上都能查询到
  1619. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1620. }
  1621. break;
  1622. case CR_EXP_COMPLETE:
  1623. if (!bExpComplete)
  1624. {
  1625. bExpComplete = true;
  1626. FINFO("CR_EXP_COMPLETE(5)");
  1627. //这个事件不是每次都能查询到
  1628. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1629. }
  1630. break;
  1631. default:
  1632. break;
  1633. }//end for switch
  1634. if (TRUE == expProg.fetchable)
  1635. {
  1636. FINFO("Image will arrive in rad exposure progress");
  1637. break;
  1638. }
  1639. if (m_bCancelFlag) //硬同步时取消
  1640. {
  1641. /*int nRet = -1;
  1642. FINFO("Cancel Call stop acq");
  1643. nRet = API_CR_stop_acq_frame();
  1644. if (TestError(nRet, "API_CR_stop_acq_frame"))
  1645. {
  1646. FERROR("Stop acq failed");
  1647. }
  1648. else
  1649. {
  1650. m_bDetectorReady = false;
  1651. m_bIsAcqStatus = false;
  1652. }*/
  1653. m_bDetectorReady = false;
  1654. m_bIsAcqStatus = false;
  1655. FINFO("Leave loop");
  1656. return -1;
  1657. }
  1658. } while (true);
  1659. m_bDetectorReady = false;
  1660. m_bIsAcqStatus = false;
  1661. return CR_NO_ERR;
  1662. }
  1663. void CareRayCtrl::SaveRawFunc(WORD* pInImg, int nImgWidth, int nImgHeight)
  1664. {
  1665. FINFO("SaveRawFunc nImgWidth:{$},nImgHeight:{$}", nImgWidth, nImgHeight);
  1666. FILE* fp = nullptr;
  1667. string strFileName = "";
  1668. if (m_nExposureMode == AEC)
  1669. {
  1670. strFileName = m_strWorkPath + "\\rawdata\\Preview.raw";
  1671. }
  1672. else
  1673. {
  1674. strFileName = m_strWorkPath + "\\rawdata\\Image.raw";
  1675. }
  1676. if ((fp = fopen(strFileName.c_str(), "wb")) == NULL)
  1677. {
  1678. FERROR("fopen {$} failed, error code:{$}", strFileName, GetLastError());
  1679. return;
  1680. }
  1681. fwrite(pInImg, sizeof(WORD), (size_t)nImgWidth * (size_t)nImgHeight, fp);
  1682. fclose(fp);
  1683. FINFO("Save image over");
  1684. }
  1685. /***
  1686. ** 裁剪图像
  1687. ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
  1688. ***/
  1689. bool CareRayCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
  1690. {
  1691. if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
  1692. {
  1693. FERROR("Illegal parameter, can not get effective image");
  1694. return false;
  1695. }
  1696. try
  1697. {
  1698. for (int i = 0; i < m_stModeInfo.nImageHeight; i++)
  1699. {
  1700. memcpy(pOutImg + i * m_stModeInfo.nImageWidth,
  1701. pInImg + (i + m_stModeInfo.nHeightOffset) * nInWidth + m_stModeInfo.nWidthOffset,
  1702. m_stModeInfo.nImageWidth * sizeof(WORD));
  1703. }
  1704. }
  1705. catch (...)
  1706. {
  1707. FERROR("Get effective image crashed");
  1708. return false;
  1709. }
  1710. return true;
  1711. }
  1712. int CareRayCtrl::CropImageMargin(LPVOID pDstData, int& nDstWidth, int& nDstHeight,
  1713. LPVOID pScrData, int nSrcWidth, int nSrcHeight, int nBits,
  1714. int nLeftMargin, int nTopMargin, int nRightMargin, int nBottomMargin)
  1715. {
  1716. printf("CropImageMargin \n");
  1717. FINFO("CropImageMargin ");
  1718. if ((pDstData == NULL) || (pScrData == NULL) || (nSrcWidth <= 0) || (nSrcHeight <= 0) || (nBits <= 0))
  1719. return -1;
  1720. if ((nLeftMargin >= nSrcWidth) || (nTopMargin >= nSrcHeight))
  1721. return -1;
  1722. int nBitsToBYTE = (int)((nBits + 7) * 0.125);
  1723. if (nBitsToBYTE < 1)
  1724. return -1;
  1725. int nXL, nXR, nYL, nYR;
  1726. nXL = nLeftMargin;//32
  1727. nYL = nTopMargin;
  1728. if (nSrcWidth - nRightMargin < 0)
  1729. return -1;
  1730. nXR = nSrcWidth - nRightMargin - 1; //2783
  1731. if (nXR < nXL)
  1732. return -1;
  1733. if (nSrcHeight - nBottomMargin < 0)
  1734. return -1;
  1735. nYR = nSrcHeight - nBottomMargin - 1;
  1736. if (nYR < nYL)
  1737. return -1;
  1738. nDstWidth = nXR - nXL + 1;
  1739. nDstHeight = nYR - nYL + 1;
  1740. FINFO("TopCrop:{$};Bottom:{$},nDstWidth:{$},nDstHeight:{$},Bits:{$}", nYL, nYR, nDstWidth, nDstHeight, nBitsToBYTE);
  1741. int i = 0;
  1742. #pragma omp parallel private(i)
  1743. {
  1744. #pragma omp for
  1745. for (i = nYL; i <= nYR; i++)
  1746. {
  1747. ::memcpy((WORD*)pDstData + (i - nYL) * nDstWidth, (WORD*)pScrData + (i * nSrcWidth + nXL), nDstWidth * nBitsToBYTE);
  1748. }
  1749. }
  1750. return 0;
  1751. }
  1752. bool CareRayCtrl::LoadCareCalibration(bool bLoad)
  1753. {
  1754. UserCorrection corr;
  1755. memset(&corr, 0x0, sizeof(UserCorrection));
  1756. if (bLoad)
  1757. {
  1758. switch (m_nCurrentDetectorType)
  1759. {
  1760. case CareView_1500R:
  1761. case CareView_500M:
  1762. case CareView_1800R:
  1763. case CareView_1800I:
  1764. case CareView_1800L:
  1765. case CareView_750M:
  1766. case CareView_1500L:
  1767. case CareView_1800RV2:
  1768. {
  1769. FINFO("Load Fixed Correction Files");
  1770. corr.fixedCorr = TRUE;
  1771. }
  1772. break;
  1773. case CareView_500P:
  1774. case CareView_1500P:
  1775. case CareView_1500Rm:
  1776. case CareView_1500C:
  1777. case CareView_1500Cw:
  1778. case CareView_300P:
  1779. case CareView_1500PV2:
  1780. case CareView_750Cw:
  1781. {
  1782. FINFO("Load Portable Correction Files");
  1783. corr.portableCorr = TRUE;
  1784. }
  1785. break;
  1786. default:
  1787. corr.fixedCorr = TRUE;
  1788. }
  1789. }
  1790. FINFO("Call API_CR_set_user_correction");
  1791. int nResult = API_CR_set_user_correction(&corr);
  1792. if (TestError(nResult, "API_CR_set_user_correction"))
  1793. {
  1794. FERROR("Set user Correction Failed!");
  1795. return false;
  1796. }
  1797. else
  1798. {
  1799. FINFO("Set user Correction Success");
  1800. }
  1801. return true;
  1802. }
  1803. /***
  1804. ** 计算一键校正曝光的图像灰度
  1805. ***/
  1806. double CareRayCtrl::GetMean(WORD* imgNoHeader, int pixelNum)
  1807. {
  1808. double imgMean = 0;
  1809. for (int i = 0; i < pixelNum; i++)
  1810. {
  1811. imgMean += imgNoHeader[i];
  1812. }
  1813. imgMean = imgMean / pixelNum;
  1814. return imgMean;
  1815. }
  1816. /***
  1817. ** 等待探测器操作执行完毕
  1818. ***/
  1819. bool CareRayCtrl::WaitRespond(int nTimeOut, const char* szPosition)
  1820. {
  1821. FINFO("--- {$} WaitRespond, {$}ms ---", szPosition, nTimeOut);
  1822. DWORD dwRet = WaitForSingleObject(m_hRespond, nTimeOut);
  1823. if (dwRet == WAIT_TIMEOUT)
  1824. {
  1825. FERROR("Timeout in wait respond");
  1826. return false;
  1827. }
  1828. ResetEvent(m_hRespond);
  1829. return true;
  1830. }
  1831. void CareRayCtrl::StopWaiting(const char* szPosition)
  1832. {
  1833. FINFO("--- Stop waiting respond, {$} ---", szPosition);
  1834. SetEvent(m_hRespond);
  1835. }
  1836. /***
  1837. ** 检测接口是否有错误,true:有错;false:没错
  1838. ***/
  1839. bool CareRayCtrl::TestError(int nRet, const char* szFuncName)
  1840. {
  1841. if (nRet == CR_NO_ERR)
  1842. {
  1843. FINFO("{$} executed successfully", szFuncName);
  1844. return false;
  1845. }
  1846. else
  1847. {
  1848. FERROR("{$} return error {$}, reason: {$}", szFuncName, nRet, CrErrStrList(nRet));
  1849. return true;
  1850. }
  1851. }
  1852. void CareRayCtrl::GetDetectorType(DetectorType eType, string& szType)
  1853. {
  1854. string strType = "Unkown_Type";
  1855. switch (eType)
  1856. {
  1857. case CareView_1500R:
  1858. strType = "CareView_1500R";
  1859. break;
  1860. case CareView_1500Rm:
  1861. strType = "CareView_1500Rm";
  1862. break;
  1863. case CareView_1500P:
  1864. strType = "CareView_1500P";
  1865. break;
  1866. case CareView_1500C:
  1867. strType = "CareView_1500C";
  1868. break;
  1869. case CareView_1800R:
  1870. strType = "CareView_1800R";
  1871. break;
  1872. case CareView_500M:
  1873. strType = "CareView_500M";
  1874. break;
  1875. case CareView_500I:
  1876. strType = "CareView_500I";
  1877. break;
  1878. case CareView_500P:
  1879. strType = "CareView_500P";
  1880. break;
  1881. case CareView_900F:
  1882. strType = "CareView_900F";
  1883. break;
  1884. case CareView_1800I:
  1885. strType = "CareView_1800I";
  1886. break;
  1887. case CareView_1500L:
  1888. strType = "CareView_1500L";
  1889. break;
  1890. case CareView_1500Cw:
  1891. strType = "CareView_1500Cw";
  1892. break;
  1893. case CareView_300P:
  1894. strType = "CareView_300P";
  1895. break;
  1896. case CareView_750M:
  1897. strType = "CareView_750M";
  1898. break;
  1899. case CareView_1800L:
  1900. strType = "CareView_1800L";
  1901. break;
  1902. case CareView_1800RV2:
  1903. strType = "CareView_1800RV2";
  1904. break;
  1905. case CareView_1500PV2:
  1906. strType = "CareView_1500PV2";
  1907. break;
  1908. case CareView_750Cw:
  1909. strType = "CareView_750Cw";
  1910. break;
  1911. case Unkown_Type:
  1912. break;
  1913. default:
  1914. break;
  1915. }
  1916. szType = strType.c_str();
  1917. }
  1918. void CareRayCtrl::ProcessCREvent(int eventID, Event* eventData)
  1919. {
  1920. FINFO("Start process event: {$}", eventID);
  1921. switch (eventID)
  1922. {
  1923. case EVT_DISCONNECT:
  1924. FINFO("EVT_DISCONNECT");
  1925. StatusFeedback(EVT_STATUS_PANEL, PANEL_DISCONNECT);
  1926. break;
  1927. case EVT_READY:
  1928. FINFO("EVT_READY");
  1929. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_READY;
  1930. m_bDetectorReady = true;
  1931. m_bIsAcqStatus = true;
  1932. //通知ready状态
  1933. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1934. break;
  1935. case EVT_EXP_EN:
  1936. FINFO("EVT_EXP_EN");
  1937. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_EXP_EN;
  1938. SetEvent(m_hXWinOnEvent);
  1939. break;
  1940. case EVT_IMAGE_ARRIVE:
  1941. FINFO("EVT_IMAGE_ARRIVE, width: {$}, height: {$}", eventData->width, eventData->height);
  1942. m_nImageSize = eventData->width * eventData->height * 2;
  1943. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_IMAGE_ARRIVE;
  1944. memcpy(m_pRawImgBuffer, eventData->data, (size_t)eventData->width * (size_t)eventData->height * sizeof(WORD));
  1945. m_bGetImage = false; //回调拿到图像,置为false
  1946. SetEvent(m_hProcessImgEvent);
  1947. break;
  1948. case EVT_AEC_PREV_MODE_READY:
  1949. FINFO("EVT_AEC_PREV_MODE_READY");
  1950. break;
  1951. case EVT_AEC_RAD_MODE_READY:
  1952. FINFO("EVT_AEC_RAD_MODE_READY");
  1953. break;
  1954. case EVT_AEC_PREV_IMG_ARRIVE:
  1955. FINFO("EVT_AEC_PREV_IMG_ARRIVE");
  1956. break;
  1957. case EVT_AEC_RAD_IMG_ARRIVE:
  1958. FINFO("EVT_AEC_RAD_IMG_ARRIVE");
  1959. break;
  1960. case EVT_DETECTOR_ERROR:
  1961. FINFO("EVT_DETECTOR_ERROR");
  1962. break;
  1963. case EVT_EXPOSE_FLAG_FALSE:
  1964. FINFO("EVT_EXPOSE_FLAG_FALSE");
  1965. break;
  1966. case EVT_EXPOSE_FLAG_TRUE:
  1967. FINFO("EVT_EXPOSE_FLAG_TRUE");
  1968. break;
  1969. case EVT_INITIAL:
  1970. FINFO("EVT_INITIAL");
  1971. break;
  1972. case EVT_UNUPLOADED_IMG_EXIST:
  1973. FINFO("EVT_UNUPLOADED_IMG_EXIST");
  1974. break;
  1975. case EVT_CONNECTED:
  1976. FINFO("EVT_CONNECTED");
  1977. StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
  1978. break;
  1979. case EVT_SECOND_PANEL_CONNECTED:
  1980. FINFO("EVT_SECOND_PANEL_CONNECTED");
  1981. break;
  1982. case EVT_SECOND_PANEL_DISCONNECTED:
  1983. FINFO("EVT_SECOND_PANEL_DISCONNECTED");
  1984. break;
  1985. case EVT_SHS_STATUS_CHANGED:
  1986. FINFO("EVT_SHS_STATUS_CHANGED");
  1987. break;
  1988. default:
  1989. break;
  1990. }
  1991. FINFO("Process event {$} over", eventID);
  1992. }
  1993. void CareRayCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  1994. {
  1995. if (-1 == nDetectorID)
  1996. {
  1997. nDetectorID = m_nCurrentPanelID;
  1998. }
  1999. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2000. nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2001. }
  2002. void CareRayCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  2003. {
  2004. if (-1 == nDetectorID)
  2005. {
  2006. nDetectorID = m_nCurrentPanelID;
  2007. }
  2008. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2009. nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2010. }
  2011. void CareRayCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  2012. {
  2013. if (-1 == nDetectorID)
  2014. {
  2015. nDetectorID = m_nCurrentPanelID;
  2016. }
  2017. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2018. nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2019. }
  2020. void CareRayCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  2021. {
  2022. if (-1 == nDetectorID)
  2023. {
  2024. nDetectorID = m_nCurrentPanelID;
  2025. }
  2026. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2027. nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2028. }
  2029. void CareRayCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  2030. {
  2031. if (-1 == nDetectorID)
  2032. {
  2033. nDetectorID = m_nCurrentPanelID;
  2034. }
  2035. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2036. nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2037. }
  2038. void CareRayCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  2039. {
  2040. if (-1 == nDetectorID)
  2041. {
  2042. nDetectorID = m_nCurrentPanelID;
  2043. }
  2044. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2045. nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2046. }