CareRayCtrl.cpp 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256
  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. Debug("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. FINFO("Open detector failed, Connect failed");
  206. return false;
  207. }
  208. if (!InitDetector())
  209. {
  210. FINFO("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. Debug("Exp index and count({$} {$}), note index and count({$} {$})",
  703. m_nGainExpIndex, m_nGainExpCount, m_nGainNodeIndex, m_nGainNodeCount);
  704. return true;
  705. }
  706. void CareRayCtrl::RejectCalExposure()
  707. {
  708. //暂时什么都不处理
  709. }
  710. bool CareRayCtrl::LoadDll(string strWorkPath)
  711. {
  712. string strSDKPath = "";
  713. try
  714. {
  715. strSDKPath = (string)m_ModeConfig["SDKPath"];
  716. }
  717. catch (ResDataObjectExption& e)
  718. {
  719. FERROR("Read configuration failed, Error code: {$}", e.what());
  720. return false;
  721. }
  722. string workpath = strWorkPath + "\\" + strSDKPath;
  723. string drvpath = workpath + "\\CrApi.dll";
  724. //SetDllDirectory(workpath.c_str());
  725. //将SDK路径加入环境变量
  726. char* pathvar;
  727. pathvar = getenv("Path");
  728. printf("pathvar = %s \n\n", pathvar);
  729. string strPath = "Path=";
  730. strPath += pathvar;
  731. strPath += ";";
  732. strPath += workpath;
  733. printf("strPath:%s \n\n", strPath.c_str());
  734. if (_putenv(strPath.c_str()) != 0)
  735. {
  736. DWORD dw = GetLastError();
  737. printf("put env failed! last error:%ld \n", dw);
  738. return false;
  739. }
  740. m_hCareRayModule = LoadLibrary(drvpath.c_str());
  741. if (m_hCareRayModule == nullptr)
  742. {
  743. DWORD dw = GetLastError();
  744. FERROR("Load {$} failed: {$}", drvpath.c_str(), dw);
  745. return false;
  746. }
  747. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_register_callback);
  748. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_connect_detector);
  749. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_disconnect_detector);
  750. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_reset_detector);
  751. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_dual_detector_state);
  752. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_detector_type);
  753. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_detector_info);
  754. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_status_info);
  755. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_check_mode);
  756. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_mode_info);
  757. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_sync_mode);
  758. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_cycle_time);
  759. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_normal_power);
  760. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_save_power);
  761. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_soft_acquisition);
  762. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_ready_state_request);
  763. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_send_exp_request);
  764. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_full_image);
  765. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_image_attr);
  766. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_image);
  767. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_query_prog_info);
  768. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_permit_exposure);
  769. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_stop_acq_frame);
  770. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_stop_cal_procedure);
  771. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_cal_offset);
  772. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_download_factory_cal_files);
  773. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_set_user_correction);
  774. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_get_cal_params);
  775. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_check_img_for_factory_cal);
  776. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_execute_one_key_cal);
  777. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_dark_full_image);
  778. LOAD_PROC_ADDRESS(m_hCareRayModule, CR_start_acq_prev_image);
  779. //共32个
  780. return true;
  781. }
  782. /***
  783. ** 连接探测器
  784. ***/
  785. bool CareRayCtrl::OpenDetector()
  786. {
  787. string strSDKPath = "";
  788. try
  789. {
  790. strSDKPath = (string)m_ModeConfig["SDKPath"];
  791. }
  792. catch (ResDataObjectExption& e)
  793. {
  794. FERROR("Read configuration failed, Error code: {$}", e.what());
  795. return false;
  796. }
  797. string strWorkpath = m_strWorkPath + "\\" + strSDKPath + "\\CareRay";
  798. char* szWorkpath = const_cast<char*>(strWorkpath.c_str());
  799. int nRet = -1;
  800. FINFO("Call connect({$})", szWorkpath);
  801. nRet = API_CR_connect_detector(szWorkpath);
  802. if (CR_NO_ERR != nRet && CR_ALREADY_CONN_ERR != nRet)
  803. {
  804. FERROR("Connect return failed! reson:{$}", CrErrStrList(nRet));
  805. return false;
  806. }
  807. FINFO("Connect executed successfully");
  808. //测试发现,注册回调需要放在连接成功之后
  809. FINFO("Register callback");
  810. nRet = API_CR_register_callback(CREventCallback);
  811. if (TestError(nRet, "API_CR_register_callback"))
  812. {
  813. FERROR("register callback failed!");
  814. }
  815. //如果是双板环境,输出两个平板的信息
  816. if (m_nPanelCount > 1)
  817. {
  818. DetectorActiveState das;
  819. API_CR_get_dual_detector_state(&das);
  820. FINFO("Current Active Detector ID = {$}", das.activeDetectorID);
  821. FINFO("Detector Number = {$}, Detector A type = {$}, Detector B type = {$}",
  822. das.detectorNum, das.detectorAType, das.detectorBType);
  823. FINFO("Detector A connect state = {$}, Detector B connect state = {$}",
  824. das.detectorAstate, das.detectorBstate);
  825. if (das.detectorAstate)
  826. {
  827. m_pStPanelStatus[0]->bConnectState = true;
  828. }
  829. if (das.detectorBstate)
  830. {
  831. m_pStPanelStatus[1]->bConnectState = true;
  832. }
  833. if (0 != das.activeDetectorID)
  834. {
  835. //双板时,若第一块板不连接,API会自动切换到第二块探测器
  836. //此处暂不处理
  837. }
  838. }
  839. else
  840. {
  841. m_pStPanelStatus[0]->bConnectState = true;
  842. }
  843. return true;
  844. }
  845. /***
  846. ** 初始化探测器
  847. ***/
  848. bool CareRayCtrl::InitDetector()
  849. {
  850. int nRet = -1;
  851. //初始化时先reset,恢复缺省状态
  852. FINFO("Call reset");
  853. nRet = API_CR_reset_detector(FALSE);
  854. if (TestError(nRet, "API_CR_reset_detector"))
  855. {
  856. FERROR("reset detector failed!");
  857. }
  858. //获取实际的探测器类型
  859. FINFO("Call gettype");
  860. m_nCurrentDetectorType = API_CR_get_detector_type();
  861. string strType = "";
  862. GetDetectorType((DetectorType)m_nCurrentDetectorType, strType);
  863. FINFO("Detector type: {$} {$}", m_nCurrentDetectorType, strType.c_str());
  864. //加载校正文件
  865. //LoadCareCalibration(true);
  866. //输出探测器信息(图像相关、软件版本、SN)
  867. ShowDetectorInfo();
  868. //获取探测器温度、电量、wifi信号
  869. ShowStatusInfo();
  870. //设置采集模式,输出该模式信息
  871. FINFO("Call set mode");
  872. nRet = API_CR_set_check_mode(m_nCurrentMode);
  873. if (TestError(nRet, "API_CR_set_check_mode"))
  874. {
  875. FERROR("Set mode failed");
  876. return false;
  877. }
  878. if (CR_NO_ERR != ShowModeInfo())
  879. {
  880. return false;
  881. }
  882. return true;
  883. }
  884. int CareRayCtrl::ShowDetectorInfo()
  885. {
  886. FINFO("Getting Detector Info");
  887. DetectorInfo detectorInfo;
  888. int nRet = API_CR_get_detector_info(&detectorInfo);
  889. if (TestError(nRet, "API_CR_get_detector_info"))
  890. {
  891. FERROR("Get Detector Info Failed");
  892. }
  893. else
  894. {
  895. FINFO("RawImageWidth is: {$}", detectorInfo.rawImageWidth);
  896. FINFO("RawImageHeight is: {$}", detectorInfo.rawImageHeight);
  897. FINFO("MaxPixelValue is: {$}", detectorInfo.maxPixelValue);
  898. FINFO("BitsPerPixel is: {$}", detectorInfo.bitsPerPixel);
  899. FINFO("SoftWareVerion is: {$}", detectorInfo.softWareVersion);
  900. FINFO("SerialNumber is: {$}", detectorInfo.serialNumber);
  901. ConfFeedback(EVT_CONF_PANEL_SERIAL, m_nCurrentPanelID, detectorInfo.serialNumber);
  902. }
  903. return nRet;
  904. }
  905. /***
  906. ** 显示温度、电量、wifi等信息
  907. ***/
  908. int CareRayCtrl::ShowStatusInfo()
  909. {
  910. int nRet;
  911. StatusInfo stInfo;
  912. nRet = API_CR_get_status_info(&stInfo);
  913. if (TestError(nRet, "API_CR_get_status_info"))
  914. {
  915. FERROR("Get Detector Status Info Failed");
  916. }
  917. else
  918. {
  919. FINFO("Current detector temperature:{$}", stInfo.temperature.maxTemperature);
  920. StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nCurrentPanelID, stInfo.temperature.maxTemperature);
  921. bool bCharging = true;
  922. if (stInfo.batInfo.ave_current > 0.00001)
  923. {
  924. bCharging = false;
  925. }
  926. FINFO("Current detector battery: {$}% {$}", stInfo.batInfo.relative_state_of_charge * 100, bCharging ? "Charging" : "Not charging");
  927. int nBatteryValue = 0;
  928. if (bCharging) //有线连接
  929. {
  930. nBatteryValue = 100;
  931. }
  932. else
  933. {
  934. nBatteryValue = (int)(stInfo.batInfo.relative_state_of_charge * 100);
  935. }
  936. StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryValue, "", m_nCurrentPanelID);
  937. //string strLinkQuality = stInfo.wireless_info.link_quality;
  938. FINFO("Current detector wifi link quality: {$}", stInfo.wireless_info.link_quality);
  939. int nLinkQuality = 0;
  940. if (bCharging) //有线连接
  941. {
  942. nLinkQuality = 100;
  943. }
  944. else
  945. {
  946. nLinkQuality = atoi(stInfo.wireless_info.link_quality);
  947. }
  948. StatusFeedback(EVT_STATUS_WIFI, nLinkQuality, "", m_nCurrentPanelID);
  949. }
  950. return nRet;
  951. }
  952. /***
  953. ** 显示当前采集模式的图像信息
  954. ***/
  955. int CareRayCtrl::ShowModeInfo()
  956. {
  957. FINFO("Call get mode info");
  958. ModeInfo stModeInfo;
  959. int nRet = API_CR_get_mode_info(m_nCurrentMode, &stModeInfo);
  960. if (TestError(nRet, "API_CR_get_mode_info"))
  961. {
  962. FERROR("Get Mode Info Failed");
  963. }
  964. else
  965. {
  966. m_nRawImgWidth = stModeInfo.imageWidth;
  967. m_nRawImgHeight = stModeInfo.imageHeight;
  968. //imageSize = 图像数据+65535头的大小
  969. FINFO("ImageWidth = {$}, ImageHeight = {$}, ImageSize = {$}", stModeInfo.imageWidth, stModeInfo.imageHeight, stModeInfo.imageSize);
  970. FINFO("LinesPerPixel = {$}, ColsPerPixel = {$}", stModeInfo.linesPerPixel, stModeInfo.colsPerPixel);//大于1时表示开启BINNING模式
  971. }
  972. return nRet;
  973. }
  974. /***
  975. ** 设置同步模式、采集窗口
  976. ***/
  977. bool CareRayCtrl::SetSyncMode(int nSyncMode, int nXWindowTime)
  978. {
  979. FINFO("SetSyncMode nSyncMode:{$},nXWindowTime:{$}", nSyncMode, nXWindowTime);
  980. int nResult = CR_NO_ERR;
  981. FINFO("Call API_CR_set_sync_mode");
  982. nResult = API_CR_set_sync_mode(nSyncMode);
  983. if (TestError(nResult, "API_CR_set_sync_mode"))
  984. {
  985. FERROR("Set sync mode Failed");
  986. return false;
  987. }
  988. if (nXWindowTime <= 0)
  989. {
  990. FERROR("XWindowTime <= 0, it's invalid!");
  991. return false;
  992. }
  993. //设置探测器的曝光窗口时间
  994. int nDelayTime = 0;
  995. int nWaitTime = 0;
  996. switch (nSyncMode)
  997. {
  998. case EXT_SYNC:
  999. if (m_nExposureMode == RAD)
  1000. {
  1001. //m_nXWindowTime = 2500;
  1002. m_nXWindowTime = nXWindowTime;
  1003. }
  1004. else
  1005. {
  1006. m_nXWindowTime = 500;
  1007. }
  1008. nDelayTime = 100; nWaitTime = 5;
  1009. break;
  1010. case SOFT_SYNC:
  1011. nDelayTime = 100; nWaitTime = 5;
  1012. break;
  1013. case AUTO_SYNC:
  1014. nDelayTime = 5; nWaitTime = 5;
  1015. break;
  1016. case MANUAL_SYNC:
  1017. nDelayTime = 500; nWaitTime = 5;
  1018. break;
  1019. case AED_SYNC:
  1020. nDelayTime = 100; nWaitTime = 5;
  1021. break;
  1022. default:
  1023. m_nXWindowTime = 500; nDelayTime = 100; nWaitTime = 5;
  1024. break;
  1025. }
  1026. FINFO("m_nXWindowTime: {$}, Delay Time: {$}, WaitTime: {$}", m_nXWindowTime, nDelayTime, nWaitTime);
  1027. FINFO("Call API_CR_set_cycle_time");
  1028. nResult = API_CR_set_cycle_time(m_nXWindowTime, nDelayTime, nWaitTime);
  1029. if (TestError(nResult, "API_CR_set_cycle_time"))
  1030. {
  1031. FERROR("Set cycle Time Failed");
  1032. return false;
  1033. }
  1034. FINFO("Set cycle time success");
  1035. return true;
  1036. }
  1037. unsigned __stdcall CareRayCtrl::onFPDScanThread(PVOID pvoid)
  1038. {
  1039. CareRayCtrl* pOpr = (CareRayCtrl*)pvoid;
  1040. FINFO("Enter scan thread");
  1041. bool bExit = false;
  1042. DWORD dwTimeOut = INFINITE;
  1043. while (!bExit)
  1044. {
  1045. DWORD dwRet = WaitForMultipleObjects(SCAN_EVENT_COUNT, pOpr->m_hArrayEvent, FALSE, dwTimeOut);
  1046. if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent
  1047. {
  1048. bExit = true;
  1049. }
  1050. else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hAcqEvent
  1051. {
  1052. pOpr->OnAcquireImage();
  1053. }
  1054. else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hProcessImgEvent
  1055. {
  1056. pOpr->OnProcessImg();
  1057. }
  1058. else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hXWinOnEvent
  1059. {
  1060. //SDK
  1061. FINFO("Get XWinOnEvent");
  1062. ULONGLONG dwXrayOnT, dwXrayOffT;
  1063. dwXrayOnT = dwXrayOffT = GetTickCount64();
  1064. FINFO("window on: {$}", dwXrayOnT);
  1065. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1066. while (dwXrayOffT - dwXrayOnT < 500) //窗口暂时写死
  1067. {
  1068. dwXrayOffT = GetTickCount64();
  1069. }
  1070. FINFO("window off: {$}", dwXrayOffT);
  1071. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1072. }
  1073. else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hDarkEvent
  1074. {
  1075. pOpr->OnStartDarkCalibration();
  1076. }
  1077. else if (WAIT_OBJECT_0 + 5 == dwRet) //m_hGainEvent
  1078. {
  1079. pOpr->OnAcquireGainImage();
  1080. }
  1081. }
  1082. FINFO("Level scan thread");
  1083. return 0;
  1084. }
  1085. //每5s向上通知一次状态
  1086. unsigned __stdcall CareRayCtrl::onNotifyDetectorInfoThread(PVOID pvoid)
  1087. {
  1088. CareRayCtrl* pOpr = (CareRayCtrl*)pvoid;
  1089. FINFO("Enter notify info thread");
  1090. while (!pOpr->m_bExitNotify)
  1091. {
  1092. pOpr->ShowStatusInfo();
  1093. Sleep(5000);
  1094. }
  1095. FINFO("Level notify info thread");
  1096. return 0;
  1097. }
  1098. void CareRayCtrl::OnAcquireImage()
  1099. {
  1100. if (SYNC_SOFTWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1101. && !m_bOneKeyCalibration)
  1102. {
  1103. PerformSoftSyncAcq();
  1104. }
  1105. else
  1106. {
  1107. PerformRadAcquisition();
  1108. }
  1109. }
  1110. void CareRayCtrl::OnProcessImg()
  1111. {
  1112. if (SYNC_MANUAL == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode || SYNC_AED == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1113. || SYNC_HARDWARE == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode)
  1114. {
  1115. FINFO("OnProcessImg send window off");
  1116. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1117. }
  1118. FrameAttr stImgInfo = {0};
  1119. if (m_bGetImage)
  1120. {
  1121. FINFO("Call get image attr");
  1122. int 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. StatusFeedback(EVT_STATUS_PANEL, PANEL_END_ACQ);
  1181. }
  1182. void CareRayCtrl::OnStartDarkCalibration()
  1183. {
  1184. FINFO("Start dark calibration process");
  1185. int nRet = -1;
  1186. FINFO("Call stop cal procedure(FALSE)");
  1187. nRet = API_CR_stop_cal_procedure(FALSE); //参照SDK demo流程,在开始前调用这个接口
  1188. if (TestError(nRet, "API_CR_stop_cal_procedure"))
  1189. {
  1190. FERROR("stop cal procedure failed!");
  1191. }
  1192. FINFO("Call cal offset");
  1193. nRet = API_CR_cal_offset(m_nCurrentMode);
  1194. if (TestError(nRet, "API_CR_cal_offset"))
  1195. {
  1196. FERROR("Start offset failed");
  1197. return;
  1198. }
  1199. FINFO("Query status");
  1200. int nFrameNum = 0;
  1201. ExpProgress calProg;
  1202. do
  1203. {
  1204. nRet = API_CR_query_prog_info(CR_CAL_PROG, &calProg);
  1205. if (TestError(nRet, "API_CR_query_prog_info"))
  1206. {
  1207. FERROR("Query Prog Info Failed");
  1208. API_CR_reset_detector(FALSE);
  1209. return;
  1210. }
  1211. Sleep(100);
  1212. if (TestError(calProg.errorCode))
  1213. {
  1214. break;
  1215. }
  1216. if (calProg.frame_number > nFrameNum)
  1217. {
  1218. FINFO("Now received {$} dark images ", calProg.frame_number);
  1219. nFrameNum = calProg.frame_number;
  1220. }
  1221. if (m_bAbortOffset)
  1222. {
  1223. FINFO("Abort Offset Calibration!");
  1224. FINFO("Call stop cal procedure(TRUE)");
  1225. nRet = API_CR_stop_cal_procedure(TRUE);
  1226. if (TestError(nRet, "API_CR_stop_cal_procedure"))
  1227. {
  1228. FERROR("stop cal procedure failed!");
  1229. }
  1230. break;
  1231. }
  1232. } while (FALSE == calProg.calComplete);
  1233. if (TRUE == calProg.calComplete)
  1234. {
  1235. FINFO("Offset calibration finished!");
  1236. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  1237. }
  1238. else
  1239. {
  1240. FERROR("Error occurred in offset calibration!");
  1241. return;
  1242. }
  1243. }
  1244. void CareRayCtrl::OnAcquireGainImage()
  1245. {
  1246. }
  1247. void CareRayCtrl::OnNotifyDetectorInfo()
  1248. {
  1249. }
  1250. /***
  1251. ** 启动软同步采集
  1252. ** 通过回调反馈进度
  1253. ***/
  1254. int CareRayCtrl::PerformSoftSyncAcq()
  1255. {
  1256. FINFO("PerformSoftSyncAcq start");
  1257. int nRet = -1;
  1258. if (EVT_EXP_EN == m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState)
  1259. {
  1260. FERROR("Detector has Image unrecoved, Omit");
  1261. return nRet;
  1262. }
  1263. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = 0; //开始采集前,恢复初值
  1264. FINFO("Call soft acq");
  1265. nRet = API_CR_start_soft_acquisition();
  1266. if (TestError(nRet, "API_CR_start_soft_acquisition"))
  1267. {
  1268. FERROR("Start soft acq failed");
  1269. }
  1270. else
  1271. {
  1272. FINFO("Call request ready");
  1273. nRet = API_CR_ready_state_request();
  1274. if (TestError(nRet, "API_CR_ready_state_request"))
  1275. {
  1276. FERROR("Request ready state failed");
  1277. }
  1278. else
  1279. {
  1280. FINFO("Call start acq fullimg");
  1281. nRet = API_CR_start_acq_full_image();
  1282. if (TestError(nRet, "API_CR_start_acq_full_image"))
  1283. {
  1284. FERROR("Start acq fullimg failed");
  1285. }
  1286. }
  1287. }
  1288. FINFO("PerformSoftSyncAcq end");
  1289. return nRet;
  1290. }
  1291. int CareRayCtrl::PerformRadAcquisition()
  1292. {
  1293. FINFO("PerformRadAcquisition start");
  1294. int nRet = -1;
  1295. FINFO("Call normal power");
  1296. nRet = API_CR_set_normal_power();
  1297. if (TestError(nRet, "API_CR_set_normal_power"))
  1298. {
  1299. FERROR("Set normal power failed");
  1300. return nRet;
  1301. }
  1302. if (m_nExposureMode == AEC)
  1303. {
  1304. FINFO("Call start acq preview image in AEC");
  1305. nRet = API_CR_start_acq_prev_image();
  1306. if (TestError(nRet, "API_CR_start_acq_prev_image"))
  1307. {
  1308. FERROR("Start acq preview image failed");
  1309. }
  1310. }
  1311. else
  1312. {
  1313. FINFO("Call start acq fullimg");
  1314. nRet = API_CR_start_acq_full_image();
  1315. if (TestError(nRet, "API_CR_start_acq_full_image"))
  1316. {
  1317. FERROR("Start acq fullimg failed");
  1318. }
  1319. }
  1320. if (SYNC_MANUAL == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode
  1321. || SYNC_AED == m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode)
  1322. {
  1323. nRet = QueryAutoProgInfo();
  1324. }
  1325. else
  1326. {
  1327. nRet = QueryRadProgInfo();
  1328. }
  1329. //轮询采集状态没有返回图像或终止了采集
  1330. if (CR_NO_ERR != nRet)
  1331. {
  1332. FINFO("Call normal power");
  1333. nRet = API_CR_set_normal_power();
  1334. if (TestError(nRet, "API_CR_set_normal_power"))
  1335. {
  1336. FERROR("Set normal power failed");
  1337. }
  1338. return 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. return nRet;
  1346. }
  1347. if (m_bCancelFlag)//点片退出检查不再上图
  1348. {
  1349. FINFO("PerformRadAcquisition Cancel");
  1350. return -1;
  1351. }
  1352. m_bGetImage = true; //轮询拿到图像,置为true
  1353. SetEvent(m_hProcessImgEvent);
  1354. FINFO("PerformRadAcquisition over");
  1355. return nRet;
  1356. }
  1357. /***
  1358. ** 一键校正时获取一帧暗场图
  1359. ***/
  1360. int CareRayCtrl::PerformDarkAcquisition()
  1361. {
  1362. int nRet = -1;
  1363. int printOver = 0, awaitOver = 0;
  1364. ExpProgress expProg;
  1365. FINFO("Call normal power");
  1366. nRet = API_CR_set_normal_power();
  1367. if (TestError(nRet, "API_CR_set_normal_power"))
  1368. {
  1369. FERROR("Set normal power failed");
  1370. return false;
  1371. }
  1372. FINFO("Call start acq dark fullimg");
  1373. nRet = API_CR_start_acq_dark_full_image();
  1374. if (TestError(nRet, "API_CR_start_acq_dark_full_image"))
  1375. {
  1376. FERROR("Acquire dark image failed");
  1377. return nRet;
  1378. }
  1379. memset(&expProg, 0x0, sizeof(ExpProgress));
  1380. FINFO("Query Detector Status");
  1381. do
  1382. {
  1383. Sleep(50);
  1384. if (CR_NO_ERR != (nRet = API_CR_query_prog_info(CR_RAD_PROG, &expProg)))
  1385. {
  1386. FERROR("Error occurred when query detector status info!");
  1387. return nRet;
  1388. }
  1389. if (expProg.fetchable)
  1390. {
  1391. FINFO("Dark Image will Arrive");
  1392. break;
  1393. }
  1394. } while (TRUE);
  1395. FINFO("Call normal power");
  1396. nRet = API_CR_set_normal_power();
  1397. if (TestError(nRet, "API_CR_set_normal_power"))
  1398. {
  1399. FERROR("Set normal power failed");
  1400. return false;
  1401. }
  1402. FrameAttr stImgInfo;
  1403. FINFO("Call get image attr");
  1404. nRet = API_CR_get_image_attr(&stImgInfo);
  1405. if (TestError(nRet, "API_CR_get_image_attr"))
  1406. {
  1407. FERROR("get image attr failed");
  1408. return nRet;
  1409. }
  1410. else
  1411. {
  1412. FINFO("Image attr, H: {$}, W: {$}, bits: {$}",
  1413. stImgInfo.image_height, stImgInfo.image_width, stImgInfo.pixel_bits);
  1414. }
  1415. if (nullptr == m_pDarkImage)
  1416. {
  1417. m_pDarkImage = new WORD[stImgInfo.image_height * stImgInfo.image_width];
  1418. }
  1419. FINFO("Call get image");
  1420. nRet = API_CR_get_image(stImgInfo.image_height * stImgInfo.image_width * 2, FALSE, m_pDarkImage);
  1421. if (TestError(nRet, "API_CR_get_image"))
  1422. {
  1423. FERROR("Get image failed");
  1424. return nRet;
  1425. }
  1426. return nRet;
  1427. }
  1428. /***
  1429. ** 轮询Manual(SDK的半aed模式)、aed模式采集状态
  1430. ***/
  1431. int CareRayCtrl::QueryAutoProgInfo(bool bIsAED)
  1432. {
  1433. FINFO("Begin query auto exposure progress info");
  1434. ExpProgress expProg;
  1435. memset(&expProg, 0x0, sizeof(ExpProgress));
  1436. bool bPrintOver = false;
  1437. bool bAwaitOver = false;
  1438. int nResult = -1;
  1439. int nTime = 0;
  1440. bool bReady = false; //aed时曝光0-1-0变化,通过这个变量忽略第一个0
  1441. //manual时曝光0-1-0-1...变化,通过这个变量忽略后面的1
  1442. do
  1443. {
  1444. Sleep(50);
  1445. if ((nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg)) != CR_NO_ERR)
  1446. {
  1447. FERROR("Error occurred when query detector status info! {$}, {$}", nResult, expProg.fetchable);
  1448. return nResult;
  1449. }
  1450. switch (expProg.expose_flag)
  1451. {
  1452. case FALSE:
  1453. {
  1454. if (bAwaitOver == false)
  1455. {
  1456. if (APP_STATUS_CAL_BEGIN == m_nExamMode)
  1457. {
  1458. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "false");
  1459. }
  1460. else
  1461. {
  1462. if (MANUAL_SYNC == m_nSyncMode)
  1463. {
  1464. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "false");
  1465. }
  1466. }
  1467. bAwaitOver = true;
  1468. bPrintOver = false;
  1469. FINFO("Waiting for detector Ready...");
  1470. }
  1471. }
  1472. break;
  1473. case TRUE:
  1474. {
  1475. if (!bPrintOver)
  1476. {
  1477. if (!bReady)
  1478. {
  1479. bReady = true;
  1480. m_bDetectorReady = true;
  1481. m_bIsAcqStatus = true;
  1482. //通知ready状态
  1483. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1484. }
  1485. if (APP_STATUS_CAL_BEGIN == m_nExamMode)
  1486. {
  1487. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "true");
  1488. }
  1489. else
  1490. {
  1491. if (MANUAL_SYNC == m_nSyncMode)
  1492. {
  1493. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP, "true");
  1494. }
  1495. }
  1496. bPrintOver = true;
  1497. bAwaitOver = false;
  1498. FINFO("Detector is ready for Rad Acquisition, press x-ray hand switch now...");
  1499. }
  1500. }
  1501. break;
  1502. default:
  1503. break;
  1504. }//end for switch
  1505. if (expProg.fetchable)
  1506. {
  1507. FINFO("Image will arrive in auto exposure progress");
  1508. break;
  1509. }
  1510. else
  1511. {
  1512. if (m_bCancelFlag)//Manual AED时取消
  1513. {
  1514. //没有图或退出do while循环的处理
  1515. int nRet = -1;
  1516. FINFO("Cancel, Call stop acq");
  1517. nRet = API_CR_stop_acq_frame(); //用于终止曝光流程
  1518. if (TestError(nRet, "API_CR_stop_acq_frame"))
  1519. {
  1520. FERROR("Stop acq failed");
  1521. }
  1522. else
  1523. {
  1524. m_bDetectorReady = false;
  1525. m_bIsAcqStatus = false;
  1526. }
  1527. FINFO("Leave loop");
  1528. return -1;
  1529. }
  1530. }
  1531. } while (true);
  1532. return CR_NO_ERR;
  1533. }
  1534. /***
  1535. ** 轮询硬同步模式采集状态
  1536. ***/
  1537. int CareRayCtrl::QueryRadProgInfo()
  1538. {
  1539. FINFO("Begin query rad exposure progress info");
  1540. ExpProgress expProg;
  1541. memset(&expProg, 0, sizeof(ExpProgress));
  1542. bool bExpError = false;
  1543. bool bExpInit = false;
  1544. bool bExpReady = false;
  1545. bool bExpPermission = false;
  1546. bool bExpPermitted = false;
  1547. bool bExpExpose = false;
  1548. bool bExpComplete = false;
  1549. int nResult = -1;
  1550. do
  1551. {
  1552. Sleep(20);
  1553. if ((nResult = API_CR_query_prog_info(CR_RAD_PROG, &expProg)) != CR_NO_ERR)
  1554. {
  1555. FERROR("Error occurred when query detector status info! {$}, {$}", nResult, expProg.fetchable);
  1556. return nResult;
  1557. }
  1558. switch (expProg.expStatus)
  1559. {
  1560. case CR_EXP_ERROR:
  1561. if (!bExpError)
  1562. {
  1563. bExpError = true;
  1564. FINFO("CR_EXP_ERROR(-1)");
  1565. }
  1566. break;
  1567. case CR_EXP_INIT:
  1568. if (!bExpInit)
  1569. {
  1570. bExpInit = true;
  1571. FINFO("CR_EXP_INIT(0)");
  1572. }
  1573. break;
  1574. case CR_EXP_READY:
  1575. if (!bExpReady)
  1576. {
  1577. //通知ready状态
  1578. bExpReady = true;
  1579. FINFO("CR_EXP_READY(1)");
  1580. m_bDetectorReady = true;
  1581. m_bIsAcqStatus = true;
  1582. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1583. }
  1584. break;
  1585. case CR_EXP_WAIT_PERMISSION:
  1586. if (!bExpPermission)
  1587. {
  1588. bExpPermission = true;
  1589. FINFO("CR_EXP_WAIT_PERMISSION(2) Call permit");
  1590. nResult = API_CR_permit_exposure();
  1591. if (TestError(nResult, "API_CR_permit_exposure"))
  1592. {
  1593. FERROR("Permit Exposure Failed!");
  1594. return nResult;
  1595. }
  1596. }
  1597. break;
  1598. case CR_EXP_PERMITTED:
  1599. if (!bExpPermitted)
  1600. {
  1601. bExpPermitted = true;
  1602. FINFO("CR_EXP_PERMITTED(3)");
  1603. }
  1604. break;
  1605. case CR_EXP_EXPOSE:
  1606. if (!bExpPermitted)
  1607. {
  1608. bExpPermitted = true;
  1609. FINFO("CR_EXP_EXPOSE(4)");
  1610. //这个事件基本上都能查询到
  1611. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1612. }
  1613. break;
  1614. case CR_EXP_COMPLETE:
  1615. if (!bExpComplete)
  1616. {
  1617. bExpComplete = true;
  1618. FINFO("CR_EXP_COMPLETE(5)");
  1619. //这个事件不是每次都能查询到
  1620. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1621. }
  1622. break;
  1623. default:
  1624. break;
  1625. }//end for switch
  1626. if (TRUE == expProg.fetchable)
  1627. {
  1628. FINFO("Image will arrive in rad exposure progress");
  1629. break;
  1630. }
  1631. if (m_bCancelFlag) //硬同步时取消
  1632. {
  1633. /*int nRet = -1;
  1634. FINFO("Cancel Call stop acq");
  1635. nRet = API_CR_stop_acq_frame();
  1636. if (TestError(nRet, "API_CR_stop_acq_frame"))
  1637. {
  1638. FERROR("Stop acq failed");
  1639. }
  1640. else
  1641. {
  1642. m_bDetectorReady = false;
  1643. m_bIsAcqStatus = false;
  1644. }*/
  1645. m_bDetectorReady = false;
  1646. m_bIsAcqStatus = false;
  1647. FINFO("Leave loop");
  1648. return -1;
  1649. }
  1650. } while (true);
  1651. m_bDetectorReady = false;
  1652. m_bIsAcqStatus = false;
  1653. return CR_NO_ERR;
  1654. }
  1655. void CareRayCtrl::SaveRawFunc(WORD* pInImg, int nImgWidth, int nImgHeight)
  1656. {
  1657. FINFO("SaveRawFunc nImgWidth:{$},nImgHeight:{$}", nImgWidth, nImgHeight);
  1658. FILE* fp = nullptr;
  1659. string strFileName = "";
  1660. if (m_nExposureMode == AEC)
  1661. {
  1662. strFileName = m_strWorkPath + "\\rawdata\\Preview.raw";
  1663. }
  1664. else
  1665. {
  1666. strFileName = m_strWorkPath + "\\rawdata\\Image.raw";
  1667. }
  1668. if ((fp = fopen(strFileName.c_str(), "wb")) == NULL)
  1669. {
  1670. FERROR("fopen {$} failed, error code:{$}", strFileName, GetLastError());
  1671. return;
  1672. }
  1673. fwrite(pInImg, sizeof(WORD), (size_t)nImgWidth * (size_t)nImgHeight, fp);
  1674. fclose(fp);
  1675. FINFO("Save image over");
  1676. }
  1677. /***
  1678. ** 裁剪图像
  1679. ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
  1680. ***/
  1681. bool CareRayCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
  1682. {
  1683. if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
  1684. {
  1685. FERROR("Illegal parameter, can not get effective image");
  1686. return false;
  1687. }
  1688. try
  1689. {
  1690. for (int i = 0; i < m_stModeInfo.nImageHeight; i++)
  1691. {
  1692. memcpy(pOutImg + i * m_stModeInfo.nImageWidth,
  1693. pInImg + (i + m_stModeInfo.nHeightOffset) * nInWidth + m_stModeInfo.nWidthOffset,
  1694. m_stModeInfo.nImageWidth * sizeof(WORD));
  1695. }
  1696. }
  1697. catch (...)
  1698. {
  1699. FERROR("Get effective image crashed");
  1700. return false;
  1701. }
  1702. return true;
  1703. }
  1704. int CareRayCtrl::CropImageMargin(LPVOID pDstData, int& nDstWidth, int& nDstHeight,
  1705. LPVOID pScrData, int nSrcWidth, int nSrcHeight, int nBits,
  1706. int nLeftMargin, int nTopMargin, int nRightMargin, int nBottomMargin)
  1707. {
  1708. printf("CropImageMargin \n");
  1709. FINFO("CropImageMargin ");
  1710. if ((pDstData == NULL) || (pScrData == NULL) || (nSrcWidth <= 0) || (nSrcHeight <= 0) || (nBits <= 0))
  1711. return -1;
  1712. if ((nLeftMargin >= nSrcWidth) || (nTopMargin >= nSrcHeight))
  1713. return -1;
  1714. int nBitsToBYTE = (int)((nBits + 7) * 0.125);
  1715. if (nBitsToBYTE < 1)
  1716. return -1;
  1717. int nXL, nXR, nYL, nYR;
  1718. nXL = nLeftMargin;//32
  1719. nYL = nTopMargin;
  1720. if (nSrcWidth - nRightMargin < 0)
  1721. return -1;
  1722. nXR = nSrcWidth - nRightMargin - 1; //2783
  1723. if (nXR < nXL)
  1724. return -1;
  1725. if (nSrcHeight - nBottomMargin < 0)
  1726. return -1;
  1727. nYR = nSrcHeight - nBottomMargin - 1;
  1728. if (nYR < nYL)
  1729. return -1;
  1730. nDstWidth = nXR - nXL + 1;
  1731. nDstHeight = nYR - nYL + 1;
  1732. FINFO("TopCrop:{$};Bottom:{$},nDstWidth:{$},nDstHeight:{$},Bits:{$}", nYL, nYR, nDstWidth, nDstHeight, nBitsToBYTE);
  1733. int i = 0;
  1734. #pragma omp parallel private(i)
  1735. {
  1736. #pragma omp for
  1737. for (i = nYL; i <= nYR; i++)
  1738. {
  1739. ::memcpy((WORD*)pDstData + (i - nYL) * nDstWidth, (WORD*)pScrData + (i * nSrcWidth + nXL), nDstWidth * nBitsToBYTE);
  1740. }
  1741. }
  1742. return 0;
  1743. }
  1744. bool CareRayCtrl::LoadCareCalibration(bool bLoad)
  1745. {
  1746. UserCorrection corr;
  1747. memset(&corr, 0x0, sizeof(UserCorrection));
  1748. if (bLoad)
  1749. {
  1750. switch (m_nCurrentDetectorType)
  1751. {
  1752. case CareView_1500R:
  1753. case CareView_500M:
  1754. case CareView_1800R:
  1755. case CareView_1800I:
  1756. case CareView_1800L:
  1757. case CareView_750M:
  1758. case CareView_1500L:
  1759. case CareView_1800RV2:
  1760. {
  1761. FINFO("Load Fixed Correction Files");
  1762. corr.fixedCorr = TRUE;
  1763. }
  1764. break;
  1765. case CareView_500P:
  1766. case CareView_1500P:
  1767. case CareView_1500Rm:
  1768. case CareView_1500C:
  1769. case CareView_1500Cw:
  1770. case CareView_300P:
  1771. case CareView_1500PV2:
  1772. case CareView_750Cw:
  1773. {
  1774. FINFO("Load Portable Correction Files");
  1775. corr.portableCorr = TRUE;
  1776. }
  1777. break;
  1778. default:
  1779. corr.fixedCorr = TRUE;
  1780. }
  1781. }
  1782. FINFO("Call API_CR_set_user_correction");
  1783. int nResult = API_CR_set_user_correction(&corr);
  1784. if (TestError(nResult, "API_CR_set_user_correction"))
  1785. {
  1786. FERROR("Set user Correction Failed!");
  1787. return false;
  1788. }
  1789. else
  1790. {
  1791. FINFO("Set user Correction Success");
  1792. }
  1793. return true;
  1794. }
  1795. /***
  1796. ** 计算一键校正曝光的图像灰度
  1797. ***/
  1798. double CareRayCtrl::GetMean(WORD* imgNoHeader, int pixelNum)
  1799. {
  1800. double imgMean = 0;
  1801. for (int i = 0; i < pixelNum; i++)
  1802. {
  1803. imgMean += imgNoHeader[i];
  1804. }
  1805. imgMean = imgMean / pixelNum;
  1806. return imgMean;
  1807. }
  1808. /***
  1809. ** 等待探测器操作执行完毕
  1810. ***/
  1811. bool CareRayCtrl::WaitRespond(int nTimeOut, const char* szPosition)
  1812. {
  1813. FINFO("--- {$} WaitRespond, {$}ms ---", szPosition, nTimeOut);
  1814. DWORD dwRet = WaitForSingleObject(m_hRespond, nTimeOut);
  1815. if (dwRet == WAIT_TIMEOUT)
  1816. {
  1817. FERROR("Timeout in wait respond");
  1818. return false;
  1819. }
  1820. ResetEvent(m_hRespond);
  1821. return true;
  1822. }
  1823. void CareRayCtrl::StopWaiting(const char* szPosition)
  1824. {
  1825. FINFO("--- Stop waiting respond, {$} ---", szPosition);
  1826. SetEvent(m_hRespond);
  1827. }
  1828. /***
  1829. ** 检测接口是否有错误,true:有错;false:没错
  1830. ***/
  1831. bool CareRayCtrl::TestError(int nRet, const char* szFuncName)
  1832. {
  1833. if (nRet == CR_NO_ERR)
  1834. {
  1835. Debug("{$} executed successfully", szFuncName);
  1836. return false;
  1837. }
  1838. else
  1839. {
  1840. FERROR("{$} return error {$}, reason: {$}", szFuncName, nRet, CrErrStrList(nRet));
  1841. return true;
  1842. }
  1843. }
  1844. void CareRayCtrl::GetDetectorType(DetectorType eType, string& szType)
  1845. {
  1846. string strType = "Unkown_Type";
  1847. switch (eType)
  1848. {
  1849. case CareView_1500R:
  1850. strType = "CareView_1500R";
  1851. break;
  1852. case CareView_1500Rm:
  1853. strType = "CareView_1500Rm";
  1854. break;
  1855. case CareView_1500P:
  1856. strType = "CareView_1500P";
  1857. break;
  1858. case CareView_1500C:
  1859. strType = "CareView_1500C";
  1860. break;
  1861. case CareView_1800R:
  1862. strType = "CareView_1800R";
  1863. break;
  1864. case CareView_500M:
  1865. strType = "CareView_500M";
  1866. break;
  1867. case CareView_500I:
  1868. strType = "CareView_500I";
  1869. break;
  1870. case CareView_500P:
  1871. strType = "CareView_500P";
  1872. break;
  1873. case CareView_900F:
  1874. strType = "CareView_900F";
  1875. break;
  1876. case CareView_1800I:
  1877. strType = "CareView_1800I";
  1878. break;
  1879. case CareView_1500L:
  1880. strType = "CareView_1500L";
  1881. break;
  1882. case CareView_1500Cw:
  1883. strType = "CareView_1500Cw";
  1884. break;
  1885. case CareView_300P:
  1886. strType = "CareView_300P";
  1887. break;
  1888. case CareView_750M:
  1889. strType = "CareView_750M";
  1890. break;
  1891. case CareView_1800L:
  1892. strType = "CareView_1800L";
  1893. break;
  1894. case CareView_1800RV2:
  1895. strType = "CareView_1800RV2";
  1896. break;
  1897. case CareView_1500PV2:
  1898. strType = "CareView_1500PV2";
  1899. break;
  1900. case CareView_750Cw:
  1901. strType = "CareView_750Cw";
  1902. break;
  1903. case Unkown_Type:
  1904. break;
  1905. default:
  1906. break;
  1907. }
  1908. szType = strType.c_str();
  1909. }
  1910. void CareRayCtrl::ProcessCREvent(int eventID, Event* eventData)
  1911. {
  1912. FINFO("Start process event: {$}", eventID);
  1913. switch (eventID)
  1914. {
  1915. case EVT_DISCONNECT:
  1916. FINFO("EVT_DISCONNECT");
  1917. StatusFeedback(EVT_STATUS_PANEL, PANEL_DISCONNECT);
  1918. break;
  1919. case EVT_READY:
  1920. FINFO("EVT_READY");
  1921. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_READY;
  1922. m_bDetectorReady = true;
  1923. m_bIsAcqStatus = true;
  1924. //通知ready状态
  1925. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  1926. break;
  1927. case EVT_EXP_EN:
  1928. FINFO("EVT_EXP_EN");
  1929. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_EXP_EN;
  1930. SetEvent(m_hXWinOnEvent);
  1931. break;
  1932. case EVT_IMAGE_ARRIVE:
  1933. FINFO("EVT_IMAGE_ARRIVE, width: {$}, height: {$}", eventData->width, eventData->height);
  1934. m_nImageSize = eventData->width * eventData->height * 2;
  1935. m_pStPanelStatus[m_nCurrentPanelID]->nSoftAcqState = EVT_IMAGE_ARRIVE;
  1936. memcpy(m_pRawImgBuffer, eventData->data, (size_t)eventData->width * (size_t)eventData->height * sizeof(WORD));
  1937. m_bGetImage = false; //回调拿到图像,置为false
  1938. SetEvent(m_hProcessImgEvent);
  1939. break;
  1940. case EVT_AEC_PREV_MODE_READY:
  1941. FINFO("EVT_AEC_PREV_MODE_READY");
  1942. break;
  1943. case EVT_AEC_RAD_MODE_READY:
  1944. FINFO("EVT_AEC_RAD_MODE_READY");
  1945. break;
  1946. case EVT_AEC_PREV_IMG_ARRIVE:
  1947. FINFO("EVT_AEC_PREV_IMG_ARRIVE");
  1948. break;
  1949. case EVT_AEC_RAD_IMG_ARRIVE:
  1950. FINFO("EVT_AEC_RAD_IMG_ARRIVE");
  1951. break;
  1952. case EVT_DETECTOR_ERROR:
  1953. FINFO("EVT_DETECTOR_ERROR");
  1954. break;
  1955. case EVT_EXPOSE_FLAG_FALSE:
  1956. FINFO("EVT_EXPOSE_FLAG_FALSE");
  1957. break;
  1958. case EVT_EXPOSE_FLAG_TRUE:
  1959. FINFO("EVT_EXPOSE_FLAG_TRUE");
  1960. break;
  1961. case EVT_INITIAL:
  1962. FINFO("EVT_INITIAL");
  1963. break;
  1964. case EVT_UNUPLOADED_IMG_EXIST:
  1965. FINFO("EVT_UNUPLOADED_IMG_EXIST");
  1966. break;
  1967. case EVT_CONNECTED:
  1968. FINFO("EVT_CONNECTED");
  1969. StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
  1970. break;
  1971. case EVT_SECOND_PANEL_CONNECTED:
  1972. FINFO("EVT_SECOND_PANEL_CONNECTED");
  1973. break;
  1974. case EVT_SECOND_PANEL_DISCONNECTED:
  1975. FINFO("EVT_SECOND_PANEL_DISCONNECTED");
  1976. break;
  1977. case EVT_SHS_STATUS_CHANGED:
  1978. FINFO("EVT_SHS_STATUS_CHANGED");
  1979. break;
  1980. default:
  1981. break;
  1982. }
  1983. FINFO("Process event {$} over", eventID);
  1984. }
  1985. void CareRayCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  1986. {
  1987. if (-1 == nDetectorID)
  1988. {
  1989. nDetectorID = m_nCurrentPanelID;
  1990. }
  1991. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  1992. nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  1993. }
  1994. void CareRayCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  1995. {
  1996. if (-1 == nDetectorID)
  1997. {
  1998. nDetectorID = m_nCurrentPanelID;
  1999. }
  2000. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2001. nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2002. }
  2003. void CareRayCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  2004. {
  2005. if (-1 == nDetectorID)
  2006. {
  2007. nDetectorID = m_nCurrentPanelID;
  2008. }
  2009. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2010. nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2011. }
  2012. void CareRayCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  2013. {
  2014. if (-1 == nDetectorID)
  2015. {
  2016. nDetectorID = m_nCurrentPanelID;
  2017. }
  2018. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2019. nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2020. }
  2021. void CareRayCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  2022. {
  2023. if (-1 == nDetectorID)
  2024. {
  2025. nDetectorID = m_nCurrentPanelID;
  2026. }
  2027. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2028. nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2029. }
  2030. void CareRayCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  2031. {
  2032. if (-1 == nDetectorID)
  2033. {
  2034. nDetectorID = m_nCurrentPanelID;
  2035. }
  2036. ((FPDDeviceCareRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2037. nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2038. }