SensviewCtrl.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468
  1. #include "stdafx.h"
  2. #include <tlhelp32.h>
  3. #include <sys/stat.h>
  4. #include <fstream> //文件流库函数
  5. #include <atlcomtime.h>
  6. #include "SensviewCtrl.h"
  7. #include "common_api.h"
  8. #include "MyPingip.h"
  9. extern Log4CPP::Logger* gLogger;
  10. #include <shlwapi.h>
  11. #pragma comment(lib,"Shlwapi.lib")
  12. #pragma comment(lib, "Version.lib")
  13. const int nINIT_TIME = 50000;
  14. const int nCMD_TIME = 5000;
  15. SensviewCtrl* g_pSensviewCtrl = nullptr;
  16. SensviewCtrl::SensviewCtrl()
  17. : g_strAppPath("")
  18. , m_nPanelCount(0)
  19. , m_nDetectorID(1)
  20. , m_nDetectorIndex(0)
  21. , m_nCorrectionType(0)
  22. , m_hSDKModule(nullptr)
  23. , m_hInitThread(nullptr)
  24. , m_hExitEvent(nullptr)
  25. , m_hRecoverImage(nullptr)
  26. , m_hCofirmCalib(nullptr)
  27. , m_hEndCalibEvent(nullptr)
  28. , m_hScanEnd(nullptr)
  29. , m_hSharedEvent(nullptr)
  30. , m_hWindowOffEvent(nullptr)
  31. , m_pXWindowoffThread(nullptr)
  32. , m_hScanEventThread(nullptr)
  33. , m_nCurrentMode(-1)
  34. , m_strCurrentExamType("")
  35. , m_bSaveRaw(false)
  36. , m_pwPreviewImg(nullptr)
  37. , m_pwRawImageData(nullptr)
  38. , m_nFrameID(0)
  39. , m_nExiThreshold(0)
  40. , m_bOffsetAll(false)
  41. , m_bGrabStatus(false)
  42. , m_fFrameRate(0.0f)
  43. {
  44. m_pDPC2PanelID = new map<nsDPC::FPDDeviceSensview*, int>();
  45. m_pPanelID2DPC = new map<int, nsDPC::FPDDeviceSensview*>();
  46. //m_pImageBuffer = NULL;
  47. m_strWorkPath = "";
  48. m_eAppStatus = APP_STATUS_IDLE;
  49. m_nImageWidth = 0;
  50. m_nImageHeight = 0;
  51. m_nRawImgWidth = 0;
  52. m_nRawImgHeight = 0;
  53. m_nWidthOffset = 0;
  54. m_nHeightOffset = 0;
  55. m_nImgBits = 16;
  56. m_nPixelPitch = 150;
  57. m_bPreviewEnable = false;
  58. m_nPreviewWidth = 0;
  59. m_nPreviewHeight = 0;
  60. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
  61. m_nDoseParam = 0;
  62. m_fCurrentDose = 0;
  63. m_nCaliFailedCount = 0;
  64. m_bGainPreparing = false;
  65. m_bGainProcess = false;
  66. m_bConfirmCaliRst = false;
  67. m_bPreviewImg = false;
  68. //m_nGainNodeCount = 0;
  69. //m_nGainNodeIndex = 0;
  70. //m_nGainExpCount = 0;
  71. //m_nGainExpIndex = 0;
  72. m_bIsImageRecovering = false;
  73. m_bInCalibrating = false;
  74. m_pHardwareStatusThread = NULL;
  75. m_bInExposure = false;
  76. m_nRecoverImageTimes = 0;
  77. for (int i = 0; i < SENSVIEW_SCAN_NUM; i++)
  78. {
  79. m_hArrayEvent[i] = nullptr;
  80. }
  81. m_bSetCorrectFile = false;
  82. m_mapLogicModeOperationMode.clear();
  83. }
  84. SensviewCtrl::~SensviewCtrl()
  85. {
  86. OnEXIT();
  87. delete m_pDPC2PanelID;
  88. m_pDPC2PanelID = NULL;
  89. delete m_pPanelID2DPC;
  90. m_pPanelID2DPC = NULL;
  91. m_mapLogicModeOperationMode.clear();
  92. }
  93. bool SensviewCtrl::OnEXIT()
  94. {
  95. /*SetEvent(m_hEndHWStatusThreadEvent);
  96. Info("Waiting HWStatus Thread End");
  97. int nResult = WaitForSingleObject(m_hHWStatusThreadEndEvent, 10000);
  98. if (WAIT_TIMEOUT == nResult)
  99. {
  100. Error("HWStatus Thread Quit Failed");
  101. }
  102. else
  103. {
  104. Info("HWStatus Thread Quit Success");
  105. }*/
  106. for (int nDetectorID = 0; nDetectorID < m_nPanelCount; nDetectorID++)
  107. {
  108. DisconnectFD(nDetectorID);
  109. }
  110. SetEvent(m_hExitEvent);
  111. Info("Waiting detector ScanEvent Thread End");
  112. if (WAIT_TIMEOUT == WaitForSingleObject(m_hScanEnd, 2000))
  113. {
  114. Error("Detector ScanEvent Thread Quit Failed");
  115. }
  116. else
  117. {
  118. Info("Detector ScanEvent Thread Quit Success");
  119. }
  120. DeleteHandle();
  121. Info("Free SDK DLL");
  122. FreeSDKDLL();
  123. return true;
  124. }
  125. void SensviewCtrl::DeleteHandle()
  126. {
  127. if (m_hSharedEvent)
  128. {
  129. CloseHandle(m_hSharedEvent);
  130. m_hSharedEvent = nullptr;
  131. }
  132. if (m_hExitEvent)
  133. {
  134. CloseHandle(m_hExitEvent);
  135. m_hExitEvent = nullptr;
  136. }
  137. if (m_hRecoverImage)
  138. {
  139. CloseHandle(m_hRecoverImage);
  140. m_hRecoverImage = nullptr;
  141. }
  142. if (m_hCofirmCalib)
  143. {
  144. CloseHandle(m_hCofirmCalib);
  145. m_hCofirmCalib = nullptr;
  146. }
  147. if (m_hEndCalibEvent)
  148. {
  149. CloseHandle(m_hEndCalibEvent);
  150. m_hEndCalibEvent = nullptr;
  151. }
  152. if (m_hScanEnd)
  153. {
  154. CloseHandle(m_hScanEnd);
  155. m_hScanEnd = nullptr;
  156. }
  157. if (m_hHWStatusThreadEndEvent)
  158. {
  159. CloseHandle(m_hHWStatusThreadEndEvent);
  160. m_hHWStatusThreadEndEvent = NULL;
  161. }
  162. if (m_pwPreviewImg)
  163. {
  164. delete[] m_pwPreviewImg;
  165. m_pwPreviewImg = NULL;
  166. }
  167. if (m_pwRawImageData)
  168. {
  169. delete[] m_pwRawImageData;
  170. m_pwRawImageData = NULL;
  171. }
  172. }
  173. //SDK回调函数
  174. void SensviewCtrl::ProcessEventCallback(void* lpCallbackData, NV_EVENTTYPE eventID, void* lpEventData)
  175. {
  176. if (nullptr == lpCallbackData)
  177. {
  178. return;
  179. }
  180. SensviewCtrl * pCurrentCtrl = (SensviewCtrl *)lpCallbackData;
  181. Info("EventID: {$}", (int)eventID);
  182. switch (eventID)
  183. {
  184. case NV_EVENTTYPE_ACQ:
  185. {
  186. if (!pCurrentCtrl->m_bGrabStatus)
  187. {
  188. Warn("Invalid image, omit");
  189. return;
  190. }
  191. if (nullptr == lpEventData)
  192. {
  193. Warn("Invalid buffer, omit");
  194. return;
  195. }
  196. NV_ImageInfo* pImageInfo = (NV_ImageInfo*)lpEventData;
  197. int nRawImgHeight = pImageInfo->iSizeX;
  198. int nRawImgWidth = pImageInfo->iSizeY;
  199. Info("Image Height: {$}, Width: {$}", nRawImgHeight, nRawImgWidth);
  200. memcpy(pCurrentCtrl->m_pwRawImageData, pImageInfo->pImageBuffer, nRawImgHeight * nRawImgWidth * sizeof(WORD));
  201. pCurrentCtrl->OnProcessImg();
  202. }
  203. break;
  204. case NV_EVENTTYPE_MAXFRAME:
  205. break;
  206. case NV_EVENTTYPE_OFFSETCALFINISH:
  207. {
  208. Info("NV_EVENTTYPE_OFFSETCALFINISH");
  209. pCurrentCtrl->SendNotify();
  210. }
  211. break;
  212. case NV_EVENTTYPE_GAINCALFINISH:
  213. break;
  214. case NV_EVENTTYPE_DEFECTCALFINISH:
  215. break;
  216. case NV_EVENTTYPE_OPENXRAY:
  217. break;
  218. case NV_EVENTTYPE_CLOSEXRAY:
  219. break;
  220. case NV_EVENTTYPE_TEMPERATURE:
  221. {
  222. NV_EVENTDATA_TEMPERATURE* pTemperatureInfo = (NV_EVENTDATA_TEMPERATURE*)lpEventData;
  223. pCurrentCtrl->StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", 1, pTemperatureInfo->temperature1);
  224. }
  225. break;
  226. case NV_EVENTTYPE_SYSTEMSTATUS:
  227. break;
  228. case NV_EVENTTYPE_CONNBREAK:
  229. break;
  230. case NV_EVENTTYPE_AUTOOFFSETCAL:
  231. {
  232. Info("NV_EVENTTYPE_AUTOOFFSETCAL");
  233. pCurrentCtrl->SendNotify();
  234. }
  235. break;
  236. case NV_EVENTTYPE_CALACQ:
  237. break;
  238. default:
  239. break;
  240. }
  241. }
  242. //等到SDK回调返回true, 超时返回false
  243. bool SensviewCtrl::WaitRespond(int nTimeOut)
  244. {
  245. Info("---WaitRespond---:{$}", nTimeOut);
  246. DWORD nResult = WaitForSingleObject(m_hSharedEvent, nTimeOut);
  247. if (WAIT_TIMEOUT == nResult) //偶尔会出现EVT_HARDWARE太慢的情况
  248. {
  249. Warn("Lock TimeOut");//出现超时,肯定是有问题了
  250. ResetEvent(m_hSharedEvent);
  251. return false;
  252. }
  253. ResetEvent(m_hSharedEvent);
  254. return true;
  255. }
  256. void SensviewCtrl::SendNotify()
  257. {
  258. Info("---SendNotify---");
  259. SetEvent(m_hSharedEvent);
  260. }
  261. void SensviewCtrl::ResetLock()
  262. {
  263. ResetEvent(m_hSharedEvent);
  264. }
  265. void SensviewCtrl::Pausetime(DWORD dwSpan)
  266. {
  267. DWORD dtstart = ::GetTickCount();
  268. while ((::GetTickCount() - dtstart) < dwSpan)
  269. {
  270. MSG msg;
  271. while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  272. {
  273. ::TranslateMessage(&msg);
  274. ::DispatchMessage(&msg);
  275. }
  276. }
  277. }
  278. bool SensviewCtrl::Init(string strAppPath)
  279. {
  280. g_strAppPath = strAppPath;
  281. /*m_strWorkPath = strAppPath + (string)m_ModeConfig["SDKPath"];
  282. Info("SensviewCtrl::Init {$}\n", m_strWorkPath.c_str());
  283. if (!LoadSDKDLL(m_strWorkPath))
  284. {
  285. Error("SensviewCtrl::Init LoadSDKDLL failed\n");
  286. return false;
  287. }*/
  288. m_hSharedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  289. m_hWindowOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  290. m_hHWStatusThreadEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  291. Info("SensviewCtrl::Init over\n");
  292. return true;
  293. }
  294. //启动初始化线程
  295. void SensviewCtrl::StartInitFPDThread()
  296. {
  297. if (m_hInitThread)
  298. {
  299. Warn("Init thread already exsit, omit");
  300. return;
  301. }
  302. Info("Start Init Thread");
  303. DWORD unThreadID = 0;
  304. m_hInitThread = CreateThread(0, 0, onInitPanel, this, 0, &unThreadID);
  305. if (m_hInitThread == nullptr)
  306. {
  307. Fatal("Start Init Thread Error");
  308. }
  309. return;
  310. }
  311. //初始化
  312. DWORD SensviewCtrl::onInitPanel(void* pParam)
  313. {
  314. SensviewCtrl* pInstance = (SensviewCtrl*)pParam;
  315. pInstance->Action_Init();
  316. pInstance->m_hInitThread = nullptr;
  317. return true;
  318. }
  319. void SensviewCtrl::Action_Init()
  320. {
  321. Info("SensviewCtrl::Action_Init");
  322. m_bInitialing = true;
  323. int nDetectorID = 1;
  324. Info("Start Register Detector: {$}", nDetectorID);
  325. NV_StatusType nRet = NV_SetEventCallback(SensviewCtrl::ProcessEventCallback, this);
  326. if (TestError(nDetectorID, nRet))
  327. {
  328. Error("Register Detector {$} Callback Failed", nDetectorID);
  329. }
  330. Info("Register Detector {$} Callback Success", nDetectorID);
  331. if (!DetectorInitProcess(nDetectorID))
  332. {
  333. Error("Init process failed");
  334. }
  335. ScanEventThread();
  336. //StartHardwareStatusThread(); //走探测器回调不用主动查询啦
  337. m_bInitialing = false;
  338. Info("Action init over\n");
  339. }
  340. //初始化连接探测器
  341. bool SensviewCtrl::DetectorInitProcess(int nDetectorID, bool bFetchCalibration)
  342. {
  343. OnInitStatus(nDetectorID, PANEL_EVENT_START);
  344. int nDetectorIndex = nDetectorID - 1;
  345. //枚举网络链路上的设备
  346. NV_DET arrDet[8];
  347. int nDetectorCount = 0;
  348. NV_StatusType nRet = NV_EnumDets(arrDet, 8, &nDetectorCount);
  349. if (TestError(nDetectorID, nRet))
  350. {
  351. Error("Discover detector failed");
  352. return false;
  353. }
  354. if (nDetectorCount <= 0)
  355. {
  356. Warn("No any detector in descovery");
  357. return false;
  358. }
  359. m_stDeviceIndex[nDetectorIndex].bExisted = true;
  360. Info("Discover detector number: {$}", nDetectorCount);
  361. for (int i = 0; i < nDetectorCount; i++)
  362. {
  363. Info("DetectorID: {$}, ManufactureName: {$}, ModelName: {$}, DeviceVersion: {$}, SerialNumber: {$}",
  364. arrDet[i]._uDetID, arrDet[i].ManufactureName, arrDet[i].ModelName, arrDet[i].DeviceVersion, arrDet[i].SerialNumber);
  365. }
  366. Info("Call Connect detector1");
  367. nRet = NV_OpenDet(arrDet[0]._uDetID);
  368. if (TestError(nDetectorID, nRet))
  369. {
  370. Error("Connect Detector {$} Failed", nDetectorID);
  371. m_stDeviceIndex[nDetectorIndex].bConnectStatus = false;
  372. return false;
  373. }
  374. m_stDeviceIndex[nDetectorIndex].bConnectStatus = true;
  375. Info("Connect Detector {$} Success", nDetectorID);
  376. ListDetectorInfo(nDetectorID);
  377. //设置帧类型
  378. nRet = NV_SetFrameType(MTU_4KB);
  379. if (TestError(nDetectorID, nRet))
  380. {
  381. Error("Set detector frametype MTU_4KB failed");
  382. return false;
  383. }
  384. Info("Set detector frametype MTU_4KB");
  385. //获取探测器像素尺寸
  386. int nWidth = 0;
  387. int nHeight = 0;
  388. int nBit = 0;
  389. nRet = NV_GetSensorSize(&nWidth, &nHeight, &nBit);
  390. if (TestError(nDetectorID, nRet))
  391. {
  392. Error("Get detector size failed");
  393. return false;
  394. }
  395. Info("Get detector size: width({$}), height({$}), bit({$})", nWidth, nHeight, nBit);
  396. if (bFetchCalibration) //特殊需求,同步校正文件//正常初始化,不同步校正文件
  397. {
  398. DownloadfromDetector(nDetectorID);
  399. }
  400. //暗场的模式组成map<nLogicMode, nOperationMode>
  401. SetOffsetModeScope();
  402. //加载校正
  403. //SetDetectorCorrection(nDetectorID, m_nCorrectionType);
  404. //获取探测器支持的触发模式
  405. ListDetectorTriggerMode(nDetectorID);
  406. //列出探测器支持的Binning模式
  407. ListDetectorBinningMode(nDetectorID);
  408. //列出探测器支持的增益档位
  409. ListDetectorGainMode(nDetectorID);
  410. m_stDeviceIndex[nDetectorIndex].bInitOK = true;
  411. OnInitStatus(nDetectorID, PANEL_EVENT_END_OK);
  412. return true;
  413. }
  414. //重连接
  415. bool SensviewCtrl::RetryConnect(int nDetectorID)
  416. {
  417. Info("RetryConnect start");
  418. return false;
  419. }
  420. bool SensviewCtrl::OnInitStatus(int nPanelIndex, ENUM_PANEL_EVENT_STATE ePanelState)
  421. {
  422. int nDetectorID = 0;
  423. if (PANEL_EVENT_START == ePanelState)
  424. {
  425. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, "");
  426. }
  427. else if (PANEL_EVENT_END_OK == ePanelState)
  428. {
  429. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "");
  430. }
  431. else if (PANEL_EVENT_END_ERROR == ePanelState)
  432. {
  433. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, "");
  434. }
  435. else if (PANEL_EVENT_END == ePanelState) //未连接探测器
  436. {
  437. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "");
  438. }//end if
  439. return true;
  440. }
  441. //辅助线程句柄
  442. void SensviewCtrl::ScanAddHandle()
  443. {
  444. m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  445. m_hRecoverImage = CreateEvent(NULL, FALSE, FALSE, NULL);
  446. m_hCofirmCalib = CreateEvent(NULL, FALSE, FALSE, NULL);
  447. m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  448. m_hOffsetEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  449. m_hArrayEvent[0] = m_hExitEvent;
  450. m_hArrayEvent[1] = m_hRecoverImage;
  451. m_hArrayEvent[2] = m_hCofirmCalib;
  452. m_hArrayEvent[3] = m_hEndCalibEvent;
  453. m_hArrayEvent[4] = m_hOffsetEvent;
  454. m_hScanEnd = CreateEvent(NULL, FALSE, FALSE, NULL);
  455. return;
  456. }
  457. /************************************************************************************
  458. 功能:启动线程,处理一些异步消息
  459. ************************************************************************************/
  460. void SensviewCtrl::ScanEventThread()
  461. {
  462. if (m_hScanEventThread)
  463. {
  464. Info("ScanEvent Thread already run\n");
  465. return;
  466. }
  467. Info("Start ScanEvent Thread");
  468. ScanAddHandle();
  469. DWORD unThreadID;
  470. m_hScanEventThread = (HANDLE)CreateThread(NULL, 0, onScanEvent, (LPVOID)this, 0, &unThreadID);
  471. if (m_hScanEventThread == NULL)
  472. {
  473. Fatal("Start Scan Event Error");
  474. }
  475. else
  476. {
  477. Info("Start ScanEvent Thread ok");
  478. }
  479. //endif
  480. }
  481. /************************************************************************************
  482. 功能:启动线程,处理一些异步消息
  483. m_hRecoverImage 异步,恢复图像
  484. m_hCofirmCalib 异步,确认每一次校正的结果,如剂量大了/小了/
  485. m_hReconnectFD 异步,初始化探测器
  486. ************************************************************************************/
  487. DWORD SensviewCtrl::onScanEvent(void* pParam)
  488. {
  489. SensviewCtrl* pInstance = (SensviewCtrl*)pParam;
  490. if (pInstance == NULL)
  491. {
  492. return false;
  493. }
  494. bool bExitFlag = true;
  495. while (bExitFlag)
  496. {
  497. Info("( Waiting for Signal...)");
  498. DWORD dwResult = WaitForMultipleObjects(SENSVIEW_SCAN_NUM, pInstance->m_hArrayEvent, FALSE, INFINITE);
  499. if (WAIT_OBJECT_0 == dwResult) //m_hExitEvent
  500. {
  501. Info("Get Exit Event");
  502. bExitFlag = false;
  503. }
  504. else if (WAIT_OBJECT_0 + 1 == dwResult) //m_hRecoverImage
  505. {
  506. if (pInstance->m_nRecoverImageTimes < 2)
  507. {
  508. Info("Get RecoverImage Event");
  509. pInstance->RecoverLastImageAuto();
  510. }
  511. else
  512. {
  513. Info("Get RecoverImage Event already, omit it");
  514. pInstance->ErrorFeedback(EVT_ERR_GET_IMAGE, "true");
  515. }
  516. }
  517. else if (WAIT_OBJECT_0 + 2 == dwResult) //m_hCofirmCalib
  518. {
  519. Info("Get Cofirm Calibration Event");
  520. pInstance->ConfirmCalibration();
  521. }
  522. else if (WAIT_OBJECT_0 + 3 == dwResult) //m_hEndCalibEvent
  523. {
  524. Info("Get EndCalibraion Event");
  525. pInstance->OnEndCalibraion();
  526. }
  527. else if (WAIT_OBJECT_0 + 4 == dwResult) //m_hOffsetEvent
  528. {
  529. Info("Get Offset Event");
  530. pInstance->OffsetCalibration();
  531. }
  532. }
  533. SetEvent(pInstance->m_hScanEnd);
  534. Info("Sensview ScanEvent Thread End");
  535. return true;
  536. }
  537. bool SensviewCtrl::SetAppMode(int nDetectorID, int nMode)
  538. {
  539. Info("Set detector({$}) work mode: {$}", nDetectorID, nMode);
  540. return true;
  541. }
  542. //接口成功返回false,接口失败或有错返回true
  543. bool SensviewCtrl::TestError(int nDetectorID, int nErrorStatus)
  544. {
  545. string strLog = "";
  546. switch (nErrorStatus)
  547. {
  548. case NV_SC_SUCCESS:
  549. return false;
  550. case NV_SC_ERROR:
  551. Fatal("Generic error");
  552. break;
  553. case NV_SC_ERR_NOT_INITIALIZED:
  554. Fatal("Detector not Initialized");
  555. break;
  556. case NV_SC_ERR_NOT_IMPLEMENTED:
  557. Error("Function not implemented");
  558. break;
  559. case NV_SC_ERR_RESOURCE_IN_USE:
  560. Error("Resource in use");
  561. break;
  562. case NV_SC_ACCESS_DENIED:
  563. Error("Access denied");
  564. break;
  565. case NV_SC_INVALID_HANDLE:
  566. Error("invalid handle");
  567. break;
  568. case NV_SC_INVALID_ID:
  569. Error("invalid ID");
  570. break;
  571. case NV_SC_NO_DATA:
  572. Error("no data");
  573. break;
  574. case NV_SC_INVALID_PARAMETER:
  575. Error("invalid parameter");
  576. break;
  577. case NV_SC_FILE_IO:
  578. Error("file IO error");
  579. break;
  580. case NV_SC_TIMEOUT:
  581. Error("timeout error");
  582. break;
  583. case NV_SC_ERR_ABORT:
  584. Error("abort error");
  585. break;
  586. case NV_SC_INVALID_BUFFER_SIZE:
  587. Error("invalid buffer size error");
  588. break;
  589. default:
  590. Error("Undefined error");
  591. break;
  592. }
  593. return true;
  594. }
  595. bool SensviewCtrl::LoadSDKDLL(string strWorkPath)
  596. {
  597. string strDllDir = strWorkPath;
  598. if (SetDllDirectory(strDllDir.c_str()) == 0)
  599. {
  600. DWORD dw = GetLastError();
  601. Info("SetDllDirectory error,error code [{$}]", dw);
  602. return false;
  603. }
  604. string strDllPath = strWorkPath + "\\nvDentalDet.dll";
  605. Info("Load nvDentalDet.dll");
  606. m_hSDKModule = LoadLibrary(strDllPath.c_str());
  607. if (NULL == m_hSDKModule)
  608. {
  609. Fatal("Load nvDentalDet.dll failed!");
  610. return false;
  611. }
  612. /*m_fpCreate = (FnCreate)GetProcAddress(m_hSDKModule, IRAY_FPD_PROC_NAME_CREATE);
  613. if (NULL == m_fpCreate)
  614. {
  615. Fatal("GetProcAddress:Create failed!");
  616. return false;
  617. }*/
  618. return true;
  619. }
  620. void SensviewCtrl::FreeSDKDLL()
  621. {
  622. if (m_hSDKModule)
  623. {
  624. FreeLibrary(m_hSDKModule);
  625. m_hSDKModule = NULL;
  626. Info("Free SDK DLL");
  627. }
  628. }
  629. bool SensviewCtrl::AddDPCs(nsDPC::FPDDeviceSensview* pDrvDPC, ResDataObject& Configuration, DeviceIndexStruct& DeviceStruct)
  630. {
  631. map<nsDPC::FPDDeviceSensview*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  632. if (DPCsIter != m_pDPC2PanelID->end())
  633. {
  634. Warn("SensviewCtrl::AddDPCs This DPC already exist\n");
  635. return false;
  636. }
  637. Info("--Func-- AddDPCs {$}", pDrvDPC);
  638. m_pCurrentDPC = pDrvDPC;
  639. //拿到当前探测器的配置
  640. m_stDeviceIndex[m_nPanelCount] = DeviceStruct;
  641. m_ObjFPDsInfo[m_nPanelCount] = Configuration;
  642. Info("AddDPCs, {$} {$} ", m_stDeviceIndex[m_nPanelCount].strDetectorModel, m_stDeviceIndex[m_nPanelCount].strDeviceName);
  643. m_pDPC2PanelID->insert(pair<nsDPC::FPDDeviceSensview*, int>(pDrvDPC, m_nPanelCount));
  644. m_pPanelID2DPC->insert(pair<int, nsDPC::FPDDeviceSensview*>(m_nPanelCount, pDrvDPC));
  645. m_ModeConfig = Configuration;
  646. m_bPreviewImg = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable;
  647. m_nCorrectionType = m_stDeviceIndex[m_nDetectorIndex].AcqModeInfo.nCorrectionType;
  648. m_nPanelCount++;
  649. Info("SensviewCtrl::AddDPCs ok {$}\n", m_nPanelCount);
  650. return true;
  651. }
  652. bool SensviewCtrl::DelDPCs(nsDPC::FPDDeviceSensview* pDrvDPC)
  653. {
  654. map<nsDPC::FPDDeviceSensview*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  655. if (DPCsIter != m_pDPC2PanelID->end())
  656. {
  657. map<int, nsDPC::FPDDeviceSensview*>::iterator PanelIdIter = m_pPanelID2DPC->find(DPCsIter->second);
  658. if (PanelIdIter != m_pPanelID2DPC->end())
  659. {
  660. m_pPanelID2DPC->erase(PanelIdIter);
  661. }
  662. m_stDeviceIndex[DPCsIter->second] = {};
  663. m_ObjFPDsInfo[DPCsIter->second].clear();
  664. m_pDPC2PanelID->erase(DPCsIter);
  665. m_nPanelCount--;
  666. Info("SensviewCtrl::DelDPCs ok {$}\n", m_nPanelCount);
  667. }
  668. return true;
  669. }
  670. void SensviewCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  671. {
  672. if (-1 == nDetectorID)
  673. {
  674. nDetectorID = m_nDetectorIndex;
  675. }
  676. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  677. nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  678. }
  679. void SensviewCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  680. {
  681. if (-1 == nDetectorID)
  682. {
  683. nDetectorID = m_nDetectorIndex;
  684. }
  685. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  686. nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  687. }
  688. void SensviewCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  689. {
  690. if (-1 == nDetectorID)
  691. {
  692. nDetectorID = m_nDetectorIndex;
  693. }
  694. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  695. nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  696. }
  697. void SensviewCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  698. {
  699. if (-1 == nDetectorID)
  700. {
  701. nDetectorID = m_nDetectorIndex;
  702. }
  703. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  704. nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  705. }
  706. void SensviewCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  707. {
  708. if (-1 == nDetectorID)
  709. {
  710. nDetectorID = m_nDetectorIndex;
  711. }
  712. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  713. nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  714. }
  715. void SensviewCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  716. {
  717. if (-1 == nDetectorID)
  718. {
  719. nDetectorID = m_nDetectorIndex;
  720. }
  721. ((*m_pPanelID2DPC)[m_nDetectorIndex])->OnFPDCallback(nDetectorID,
  722. nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  723. }
  724. /********************************************************************/
  725. /*
  726. 将文件删除
  727. /********************************************************************/
  728. bool SensviewCtrl::DeleteOneFolder(string strSourceFolder)
  729. {
  730. Info("Delete {$}", strSourceFolder.c_str());
  731. if (!PathFileExists(strSourceFolder.c_str()))
  732. {
  733. Info("SourceFolder don't exist");
  734. return false;
  735. }
  736. char pFolderSource[MAX_PATH] = { 0 };
  737. memset(pFolderSource, 0x00, MAX_PATH);
  738. strcpy(pFolderSource, strSourceFolder.c_str()); //第一个文件
  739. SHFILEOPSTRUCT sfo;
  740. memset(&sfo, 0, sizeof(SHFILEOPSTRUCT));
  741. sfo.hwnd = NULL;
  742. sfo.wFunc = FO_DELETE;//FO_MOVE;
  743. sfo.pFrom = pFolderSource;
  744. sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;// | FOF_ALLOWUNDO; //| FOF_NOCONFIRMMKDIR;
  745. // FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件;
  746. //FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。
  747. SHFileOperation(&sfo);
  748. Info("Delete File over");
  749. return true;
  750. }
  751. //将strSrcPath文件拷贝到strDstPath目录
  752. bool SensviewCtrl::CopyFile2Folder(string strSrcPath, string strDstPath)
  753. {
  754. //MSDN: This string must be double-null terminated
  755. strSrcPath += '\0';
  756. strDstPath += '\0';
  757. //上面两行代码非常重要,直接影响下面SHFileOperation的稳定性
  758. Info("Copy {$} to {$}", strSrcPath.c_str(), strDstPath.c_str());
  759. if (!PathFileExists(strSrcPath.c_str()))
  760. {
  761. Info("SourceFolder don't exist");
  762. return false;
  763. }
  764. if (!PathFileExists(strDstPath.c_str()))
  765. {
  766. Info("DestFolder don't exist");
  767. return false;
  768. }
  769. SHFILEOPSTRUCT sfo;
  770. sfo.hwnd = NULL;
  771. sfo.wFunc = FO_COPY;//FO_MOVE;
  772. sfo.pFrom = strSrcPath.c_str();
  773. sfo.pTo = strDstPath.c_str();
  774. sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO; //| FOF_NOCONFIRMMKDIR;
  775. // FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件;
  776. //FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。
  777. int nRet = SHFileOperation(&sfo);
  778. Info("Copy File to Folder over, {$}", nRet);
  779. return true;
  780. }
  781. bool SensviewCtrl::SwithPanel(int nPanelId)
  782. {
  783. return true;
  784. }
  785. bool SensviewCtrl::ActivePanel(nsDPC::FPDDeviceSensview* pDrvDPC, bool bActive)
  786. {
  787. Info("ActivePanel start: {$}, DetectorIndex {$}", pDrvDPC, m_nDetectorIndex);
  788. map<nsDPC::FPDDeviceSensview*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  789. if (DPCsIter != m_pDPC2PanelID->end())
  790. {
  791. if (m_nDetectorIndex != DPCsIter->second)
  792. {
  793. Info("DetectorIndex {$} != DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second);
  794. if (!SwithPanel(DPCsIter->second))
  795. {
  796. return false;
  797. }
  798. m_nDetectorIndex = DPCsIter->second;
  799. m_pCurrentDPC = pDrvDPC;
  800. m_nCurrentMode = -1;
  801. m_ModeConfig.clear();
  802. m_ModeConfig = m_ObjFPDsInfo[m_nDetectorIndex];
  803. m_bPreviewImg = m_stDeviceIndex[m_nDetectorIndex].bPreviewEnable;
  804. Info("ActivePanel over: {$}, m_nDetectorIndex {$}", pDrvDPC, m_nDetectorIndex);
  805. for (int i = 0; i < m_nPanelCount; i++)
  806. {
  807. ((nsDPC::FPDDeviceSensview*)(*m_pPanelID2DPC)[i])->UnactiveBySDK(pDrvDPC);
  808. }
  809. }
  810. else
  811. {
  812. Info("DetectorIndex {$} == DPCsIter->second {$}", m_nDetectorIndex, DPCsIter->second);
  813. }
  814. }
  815. else
  816. {
  817. Warn("Not find DPC in group");
  818. return false;
  819. }
  820. return true;
  821. }
  822. bool SensviewCtrl::EnterExam(APP_STATUS eStatus)
  823. {
  824. string strLog = "";
  825. switch (eStatus)
  826. {
  827. case APP_STATUS_IDLE:
  828. strLog = "APP_STATUS_IDLE";
  829. break;
  830. case APP_STATUS_WORK_BEGIN:
  831. strLog = "APP_STATUS_WORK_BEGIN";
  832. break;
  833. case APP_STATUS_WORK_END:
  834. strLog = "APP_STATUS_WORK_END";
  835. break;
  836. case APP_STATUS_DETSHARE_BEGIN:
  837. strLog = "APP_STATUS_DETSHARE_BEGIN";
  838. break;
  839. case APP_STATUS_DETSHAR_END:
  840. strLog = "APP_STATUS_DETSHAR_END";
  841. break;
  842. case APP_STATUS_CAL_BEGIN:
  843. m_bInCalibrating = true;
  844. strLog = "APP_STATUS_CAL_BEGIN";
  845. break;
  846. case APP_STATUS_CAL_END:
  847. m_bInCalibrating = false;
  848. strLog = "APP_STATUS_CAL_END";
  849. break;
  850. default:
  851. break;
  852. }
  853. Info("Enter exam: {$}", strLog.c_str());
  854. m_eAppStatus = eStatus;
  855. return true;
  856. }
  857. /***
  858. ** 说明:连接
  859. ** 加载SDK,初始化SDK,连接探测器等初始化操作
  860. ** 参数:strWorkPath,初始化SDK必须的conf路径
  861. ***/
  862. bool SensviewCtrl::Connect(string strAppPath, nsDPC::FPDDeviceSensview* pDrvDPC)
  863. {
  864. Info("--Func-- Connect");
  865. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  866. {
  867. Warn("Not current DPC, return true");
  868. return true;
  869. }
  870. StartInitFPDThread();
  871. Info("=== Connect detector OK ===");
  872. return true;
  873. }
  874. void SensviewCtrl::DisconnectFD(int nDetectorID)
  875. {
  876. Info("DisconnectFD({$})", nDetectorID);
  877. if (m_bGrabStatus)
  878. {
  879. StopAcquisition(nullptr);
  880. }
  881. NV_StatusType nRet = NV_CloseDet();
  882. if (TestError(nDetectorID, nRet))
  883. {
  884. Fatal("NV_CloseDet Failed");
  885. }
  886. Info("disconnect over");
  887. }
  888. /***
  889. ** 说明:退出
  890. ** 释放SDK
  891. ***/
  892. bool SensviewCtrl::DisConnect(nsDPC::FPDDeviceSensview* pDrvDPC)
  893. {
  894. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  895. {
  896. Warn("Not current DPC, return");
  897. return true;
  898. }
  899. Info("--Func-- DisConnect");
  900. DisconnectFD(m_nDetectorID);
  901. Info("DisConnect Over");
  902. return true;
  903. }
  904. /********************************************************************/
  905. /*
  906. 功能:没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层
  907. /********************************************************************/
  908. bool SensviewCtrl::StartXWindowOffThread()
  909. {
  910. if (m_pXWindowoffThread == NULL)
  911. {
  912. DWORD m_NotifyThreadID = 0;
  913. m_pXWindowoffThread = CreateThread(0, 0, XWindowOffThread, this, 0, &m_NotifyThreadID);
  914. if (m_pXWindowoffThread == NULL)
  915. {
  916. Fatal("Start Exp Thread Failed");
  917. return false;
  918. }
  919. }
  920. return true;
  921. }
  922. /********************************************************************/
  923. /*
  924. 功能:若探测器没有曝光窗口关闭的消息,启动线程,等待500ms曝光窗口过后,模拟发送曝光窗口关闭的消息给HW层
  925. /********************************************************************/
  926. DWORD SensviewCtrl::XWindowOffThread(LPVOID pParam)
  927. {
  928. SensviewCtrl* pCurPanel = (SensviewCtrl*)pParam;
  929. if (pCurPanel == NULL)
  930. {
  931. return false;
  932. }
  933. //DWORD dwTimer = pCurPanel->m_stDeviceIndex[pCurPanel->m_nDetectorIndex].AcqModeInfo.nXwindow;
  934. DWORD dwTimer = 10;
  935. DWORD dwResult = WaitForSingleObject(pCurPanel->m_hWindowOffEvent, dwTimer);
  936. Info("Simulate XWINDOW_OFF");
  937. pCurPanel->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  938. pCurPanel->m_pXWindowoffThread = nullptr;
  939. return true;
  940. }
  941. RET_STATUS SensviewCtrl::SetSyncMode(SYNC_MODE nSyncMode, HARDWARE_TRIGGER_MODE TriggerMode)
  942. {
  943. return RET_STATUS::RET_SUCCEED;
  944. }
  945. bool SensviewCtrl::SetAcqMode(nsDPC::FPDDeviceSensview* pDrvDPC, int nLogicMode, DetModeInfo& AcqModeInfo)
  946. {
  947. Info("## SetAcqMode ##({$})", nLogicMode);
  948. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  949. {
  950. Warn("Not current DPC {$}, {$} != {$} ,return", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nDetectorIndex);
  951. return false;
  952. }
  953. if (m_bGrabStatus)
  954. {
  955. StopAcquisition(nullptr);
  956. }
  957. m_nCurrentMode = nLogicMode;
  958. m_strCurrentExamType = AcqModeInfo.strExamType;
  959. m_nRawImgWidth = AcqModeInfo.nRawImgWidth;
  960. m_nRawImgHeight = AcqModeInfo.nRawImgHeight;
  961. m_nImageWidth = AcqModeInfo.nImageWidth;
  962. m_nImageHeight = AcqModeInfo.nImageHeight;
  963. m_nImgBits = AcqModeInfo.nPhySizeInfoBit;
  964. m_nPixelPitch = AcqModeInfo.nPixelPitch;
  965. m_bSaveRaw = AcqModeInfo.bSaveRawEnable;
  966. m_nCorrectionType = AcqModeInfo.nCorrectionType;
  967. m_nExiThreshold = AcqModeInfo.nExiThreshold;
  968. Info("RawImage({$}*{$}), Bits({$}), CorrectionType: {$}; SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImgBits, m_nCorrectionType, m_bSaveRaw);
  969. if (m_pwRawImageData)
  970. {
  971. delete[] m_pwRawImageData;
  972. m_pwRawImageData = nullptr;
  973. }
  974. m_pwRawImageData = new WORD[m_nRawImgWidth * m_nRawImgHeight];
  975. if (m_pwRawImageData == nullptr)
  976. {
  977. Fatal("Allocate Raw Image Failed");
  978. return false;
  979. }
  980. //设置触发方式
  981. if (!SetDetectorFluSync(m_nDetectorID, AcqModeInfo.nTriggerType))
  982. {
  983. return false;
  984. }
  985. //设置Binning模式
  986. if (!SetDetectorBinningMode(m_nDetectorID, AcqModeInfo.nBinningMode))
  987. {
  988. return false;
  989. }
  990. //设置Gain档位
  991. if (!SetDetectorGainMode(m_nDetectorID, AcqModeInfo.nGainValue))
  992. {
  993. return false;
  994. }
  995. //设置帧率(点片单独设置帧率,透视上层下发帧率)
  996. if (AcqModeInfo.strExamType.find("RAD") != std::string::npos)
  997. {
  998. if (!SetFluPPS(AcqModeInfo.nFrequency * 1.0f))
  999. {
  1000. return false;
  1001. }
  1002. }
  1003. //加载校正
  1004. SetDetectorCorrection(m_nDetectorID, AcqModeInfo.nCorrectionType);
  1005. Info("Set mode over");
  1006. return true;
  1007. }
  1008. /***
  1009. ** 说明:曝光前的准备流程
  1010. ***/
  1011. RET_STATUS SensviewCtrl::PrepareAcquisition(nsDPC::FPDDeviceSensview* pDrvDPC)
  1012. {
  1013. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1014. {
  1015. Warn("Not current DPC, return");
  1016. return RET_STATUS::RET_FAILED;
  1017. }
  1018. if (m_stDeviceIndex[m_nDetectorIndex].bConnectStatus == false)
  1019. {
  1020. Info("Current detector is not connect, return");
  1021. return RET_STATUS::RET_FAILED;
  1022. }
  1023. return RET_STATUS::RET_FAILED;
  1024. }
  1025. RET_STATUS SensviewCtrl::StartAcquisition(nsDPC::FPDDeviceSensview* pDrvDPC)
  1026. {
  1027. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1028. {
  1029. Warn("Not current DPC, return");
  1030. return RET_STATUS::RET_FAILED;
  1031. }
  1032. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1033. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START);
  1034. NV_StatusType nRet = NV_StartAcq();
  1035. if (TestError(m_nDetectorID, nRet))
  1036. {
  1037. Fatal("NV_StartAcq Failed");
  1038. return Ret;
  1039. }
  1040. m_bInExposure = true;
  1041. m_bGrabStatus = true;
  1042. m_nFrameID = 0;
  1043. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1044. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK);
  1045. return RET_STATUS::RET_SUCCEED;
  1046. }
  1047. RET_STATUS SensviewCtrl::StopAcquisition(nsDPC::FPDDeviceSensview* pDrvDPC)
  1048. {
  1049. Info("**StopAcquisition**");
  1050. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1051. NV_StatusType nRet = NV_StopAcq();
  1052. if (TestError(m_nDetectorID, nRet))
  1053. {
  1054. Fatal("NV_StopAcq Failed");
  1055. return Ret;
  1056. }
  1057. Info("Stop Acq Success");
  1058. m_bInExposure = false;
  1059. m_bGrabStatus = false;
  1060. Ret = RET_STATUS::RET_SUCCEED;
  1061. return Ret;
  1062. }
  1063. bool SensviewCtrl::InitCalibration()
  1064. {
  1065. DataFeedback(EVT_DATA_DOSEPARAM, NULL, m_nDoseParam);
  1066. return true;
  1067. }
  1068. /***
  1069. ** 说明:激活校正
  1070. ** 增益校正(探测器采用post-offset,暗场校正基本没用了)时拿到dose回调,算作执行完毕
  1071. ***/
  1072. RET_STATUS SensviewCtrl::ActiveCalibration(CCOS_CALIBRATION_TYPE Type, nsDPC::FPDDeviceSensview* pDrvDPC)
  1073. {
  1074. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1075. {
  1076. Warn("Not current DPC, return");
  1077. return RET_STATUS::RET_FAILED;
  1078. }
  1079. RET_STATUS Ret = RET_STATUS::RET_SUCCEED;
  1080. if (CCOS_CALIBRATION_TYPE_DARK == Type)
  1081. {
  1082. Info("ActiveDarkCalibration");
  1083. }
  1084. else if (CCOS_CALIBRATION_TYPE_XRAY == Type)
  1085. {
  1086. Info("ActiveXrayCalibration");
  1087. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START);
  1088. if (!InitCalibration())
  1089. {
  1090. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR);
  1091. return RET_STATUS::RET_FAILED;
  1092. }
  1093. }
  1094. else
  1095. {
  1096. Error("Active not supported calibration({$}), return! \n", (int)Type);
  1097. Ret = RET_STATUS::RET_NOSUPPORT;
  1098. return Ret;
  1099. }
  1100. m_eCaliType = Type;
  1101. return Ret;
  1102. }
  1103. /***
  1104. ** 说明:开始校正(状态机FrameStart)
  1105. ** Salmon项目只有普通rad模式,所以本接口基本没用
  1106. ***/
  1107. RET_STATUS SensviewCtrl::StartCalibration(nsDPC::FPDDeviceSensview* pDrvDPC)
  1108. {
  1109. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1110. {
  1111. Warn("Not current DPC, return");
  1112. return RET_STATUS::RET_FAILED;
  1113. }
  1114. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1115. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  1116. {
  1117. Info("StartDarkCalibration \n");
  1118. //SetEvent(m_hOffsetEvent);
  1119. Ret = RET_STATUS::RET_SUCCEED;
  1120. }
  1121. else
  1122. {
  1123. Info("StartXrayCalibration \n");
  1124. Ret = RET_STATUS::RET_SUCCEED;
  1125. }
  1126. return Ret;
  1127. }
  1128. bool SensviewCtrl::ConfirmCalibration()
  1129. {
  1130. return true;
  1131. }
  1132. bool SensviewCtrl::AcceptCalibration()
  1133. {
  1134. Info("Accept Calibration");
  1135. return true;
  1136. }
  1137. bool SensviewCtrl::RejectCalibration()
  1138. {
  1139. Info("Reject Calibration");
  1140. return true;
  1141. }
  1142. /***
  1143. ** 说明:终止校正
  1144. ***/
  1145. RET_STATUS SensviewCtrl::AbortCalibration(nsDPC::FPDDeviceSensview* pDrvDPC)
  1146. {
  1147. return RET_STATUS::RET_SUCCEED;
  1148. }
  1149. /***
  1150. ** 说明:准备校正(状态机FramePrep)
  1151. ** 曝光使能过程,使探测器开窗
  1152. ***/
  1153. RET_STATUS SensviewCtrl::PrepareCalibration(nsDPC::FPDDeviceSensview* pDrvDPC)
  1154. {
  1155. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1156. {
  1157. Warn("Not current DPC, return");
  1158. return RET_STATUS::RET_FAILED;
  1159. }
  1160. Debug("PrepareCalibration Over");
  1161. return RET_STATUS::RET_SUCCEED;
  1162. }
  1163. /***
  1164. ** 说明:结束校正
  1165. ** DPC处理完校正报告后调用,此处上传map、报告等文件
  1166. ***/
  1167. RET_STATUS SensviewCtrl::CompleteCalibration(nsDPC::FPDDeviceSensview* pDrvDPC)
  1168. {
  1169. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1170. {
  1171. Warn("Not current DPC, return");
  1172. return RET_STATUS::RET_FAILED;
  1173. }
  1174. SetEvent(m_hEndCalibEvent);
  1175. Info("CompleteCalibration");
  1176. return RET_STATUS::RET_SUCCEED;
  1177. }
  1178. void SensviewCtrl::OnEndCalibraion()
  1179. {
  1180. Info("OnEndCalibraion start");
  1181. Info("Calibration completed!");
  1182. return;
  1183. }
  1184. bool SensviewCtrl::RecoverLastImage()
  1185. {
  1186. Info("Recover Last Image");
  1187. return RecoverImage();
  1188. }
  1189. bool SensviewCtrl::RecoverLastImageAuto()
  1190. {
  1191. Info("Recover Last Image Auto");
  1192. return true;
  1193. }
  1194. bool SensviewCtrl::FlipX(WORD* pData, int nWidth, int nHeight)
  1195. {
  1196. int j = 0;
  1197. int i = 0;
  1198. Info("Flip Image Width:{$},Height:{$}", nWidth, nHeight);
  1199. WORD temp;
  1200. //修改翻转的判断,之前的代码会导致中央区域多翻转一个像素
  1201. for (i = 0; i < nHeight; i++)
  1202. {
  1203. for (j = 0; j < nWidth / 2; j++)
  1204. {
  1205. temp = pData[i * nWidth + j];
  1206. pData[i * nWidth + j] = pData[(i + 1) * nWidth - j - 1];
  1207. pData[(i + 1) * nWidth - j - 1] = temp;
  1208. }
  1209. }
  1210. Info("Flip Image Over");
  1211. return true;
  1212. }
  1213. bool SensviewCtrl::FlipXRotate90(WORD* pData, int nWidth, int nHeight)
  1214. {
  1215. Info("Rotate 270 angle");
  1216. WORD* ptempData = new WORD[nWidth * nHeight];
  1217. memcpy(ptempData, pData, nWidth * nHeight * sizeof(WORD));
  1218. for (int i = 0; i < nWidth; i++)
  1219. for (int j = 0; j < nHeight; j++)
  1220. pData[i * nWidth + j] = ptempData[j * nWidth + (nWidth - 1 - i)];
  1221. delete[]ptempData;
  1222. ptempData = NULL;
  1223. FlipX(pData, nWidth, nHeight);
  1224. return true;
  1225. }
  1226. //读取电池
  1227. bool SensviewCtrl::ReadBatteryStatus(int nDetectorID)
  1228. {
  1229. if (!m_stDeviceIndex[m_nDetectorIndex].bBatteryEnable)
  1230. {
  1231. return false;
  1232. }
  1233. Debug("Read Battery Success");
  1234. return true;
  1235. }
  1236. bool SensviewCtrl::CheckBattery(int nDetectorID)
  1237. {
  1238. return true;
  1239. }
  1240. bool SensviewCtrl::ReadWifiStatus(int nDetectorID)
  1241. {
  1242. if (!m_stDeviceIndex[m_nDetectorIndex].bWifiEnable)
  1243. {
  1244. return false;
  1245. }
  1246. Debug("Read Wifi");
  1247. Warn("Read Wifi Timeout");
  1248. return false;
  1249. }
  1250. bool SensviewCtrl::CheckWiFi(int nDetectorID)
  1251. {
  1252. return true;
  1253. }
  1254. //读取探测器温度
  1255. bool SensviewCtrl::ReadTempStatus(int nDetectorID)
  1256. {
  1257. Debug("Read Temperture");
  1258. Debug("Read Temperture Success");
  1259. return true;
  1260. }
  1261. bool SensviewCtrl::CheckTemperature(int nDetectorID)
  1262. {
  1263. return true;
  1264. }
  1265. //清空板内校正的校正选项,否则写入参数可能会失败
  1266. bool SensviewCtrl::ClearCorrection(int nDetectorID)
  1267. {
  1268. Info("Clear Correction Option");
  1269. return true;
  1270. }
  1271. //设置探测器校正
  1272. bool SensviewCtrl::SetDetectorCorrection(int nDetectorID, int nCorrectionType)
  1273. {
  1274. Info("Set Detector({$}) correction: {$}", nDetectorID, nCorrectionType);
  1275. NV_StatusType nRet = NV_SC_SUCCESS;
  1276. std::string strOffsetType = "";
  1277. if (nCorrectionType & CORRECT_OFFSET)
  1278. {
  1279. /*string strOffsetFile = m_stDeviceIndex[m_nDetectorIndex].strFPDConfFilePath + "\\1.offset";
  1280. Debug("Offset file path: {$}", strOffsetFile);
  1281. std::ifstream inputFile(strOffsetFile.c_str(), std::ios::binary);
  1282. if (!inputFile)
  1283. {
  1284. Error("Load file failed!");
  1285. return false;
  1286. }
  1287. inputFile.seekg(0, std::ios::end);
  1288. int fileSize = inputFile.tellg();
  1289. inputFile.seekg(0, std::ios::beg);
  1290. char* pTemplateData = new char[fileSize];
  1291. inputFile.read(pTemplateData, fileSize);
  1292. Info("Load over, file size: {$}", fileSize);
  1293. nRet = NV_LoadOffsetTemplateData(pTemplateData, fileSize);
  1294. if (TestError(nDetectorID, nRet))
  1295. {
  1296. Warn("NV_LoadOffsetTemplateData Failed");
  1297. return false;
  1298. }
  1299. inputFile.close();*/
  1300. /*nRet = NV_LoadLocalOffsetTemplate();
  1301. if (TestError(nDetectorID, nRet))
  1302. {
  1303. Warn("NV_LoadLocalOffsetTemplate Failed");
  1304. return false;
  1305. }*/
  1306. //校正使能
  1307. strOffsetType = "Offset";
  1308. nRet = NV_SetOffsetCal(NV_CORR_ON);
  1309. if (TestError(nDetectorID, nRet))
  1310. {
  1311. Warn("NV_SetOffsetCal Failed");
  1312. return false;
  1313. }
  1314. }
  1315. else
  1316. {
  1317. strOffsetType = "No-Offset";
  1318. nRet = NV_SetOffsetCal(NV_CORR_OFF);
  1319. if (TestError(nDetectorID, nRet))
  1320. {
  1321. Warn("NV_SetOffsetCal Failed");
  1322. return false;
  1323. }
  1324. }
  1325. std::string strGainType = "";
  1326. if (nCorrectionType & CORRECT_GAIN)
  1327. {
  1328. /*string strGainFile = m_stDeviceIndex[m_nDetectorIndex].strFPDConfFilePath + "\\2.gain";
  1329. Debug("Offset file path: {$}", strGainFile);
  1330. std::ifstream inputFile(strGainFile.c_str(), std::ios::binary);
  1331. if (!inputFile)
  1332. {
  1333. Error("Load file failed!");
  1334. return false;
  1335. }
  1336. inputFile.seekg(0, std::ios::end);
  1337. int fileSize = inputFile.tellg();
  1338. inputFile.seekg(0, std::ios::beg);
  1339. char* pTemplateData = new char[fileSize];
  1340. inputFile.read(pTemplateData, fileSize);
  1341. Info("Load over, file size: {$}", fileSize);
  1342. nRet = NV_LoadGainTemplateData(pTemplateData, fileSize);
  1343. if (TestError(nDetectorID, nRet))
  1344. {
  1345. Warn("NV_LoadGainTemplateData Failed");
  1346. return false;
  1347. }
  1348. inputFile.close();*/
  1349. /*nRet = NV_LoadLocalGainTemplate();
  1350. if (TestError(nDetectorID, nRet))
  1351. {
  1352. Warn("NV_LoadLocalGainTemplate Failed");
  1353. return false;
  1354. }*/
  1355. strGainType = " + Gain";
  1356. nRet = NV_SetGainCal(NV_CORR_ON);
  1357. if (TestError(nDetectorID, nRet))
  1358. {
  1359. Warn("NV_SetGainCal Failed");
  1360. return false;
  1361. }
  1362. }
  1363. else
  1364. {
  1365. strGainType = " No-Gain";
  1366. nRet = NV_SetGainCal(NV_CORR_OFF);
  1367. if (TestError(nDetectorID, nRet))
  1368. {
  1369. Warn("NV_SetGainCal Failed");
  1370. return false;
  1371. }
  1372. }
  1373. std::string strDefectType = "";
  1374. if (nCorrectionType & CORRECT_DEFECT)
  1375. {
  1376. strDefectType = " + Defect";
  1377. nRet = NV_SetDefectCal(NV_CORR_ON);
  1378. if (TestError(nDetectorID, nRet))
  1379. {
  1380. Warn("NV_SetDefectCal Failed");
  1381. return false;
  1382. }
  1383. }
  1384. else
  1385. {
  1386. strGainType = " No-Defect";
  1387. nRet = NV_SetDefectCal(NV_CORR_OFF);
  1388. if (TestError(nDetectorID, nRet))
  1389. {
  1390. Warn("NV_SetDefectCal Failed");
  1391. return false;
  1392. }
  1393. }
  1394. Info("Detector correction type: {$}", strOffsetType + strGainType + strDefectType);
  1395. Info("SetDetectorCorrection Success");
  1396. return true;
  1397. }
  1398. //设置动态探测器内外触发方式
  1399. bool SensviewCtrl::SetDetectorFluSync(int nDetectorID, int nFluSync)
  1400. {
  1401. Info("Set detector({$}) trigger mode: {$}({$})", nDetectorID, DetTriggerMode[nFluSync], nFluSync);
  1402. NV_StatusType nRet = NV_SetAcquisitionMode(NV_AcquisitionMode(nFluSync));
  1403. if (TestError(nDetectorID, nRet))
  1404. {
  1405. Fatal("NV_SetAcquisitionMode Failed");
  1406. return false;
  1407. }
  1408. /*NV_AcquisitionMode aMode;
  1409. NV_StatusType nRet = NV_GetAcquisitionMode(&aMode);
  1410. if (TestError(nDetectorID, nRet))
  1411. {
  1412. Fatal("NV_GetAcquisitionMode Failed");
  1413. return false;
  1414. }
  1415. if ((int)aMode != nFluSync)
  1416. {
  1417. nRet = NV_SetAcquisitionMode(NV_AcquisitionMode(nFluSync));
  1418. if (TestError(nDetectorID, nRet))
  1419. {
  1420. Fatal("NV_SetAcquisitionMode Failed");
  1421. return false;
  1422. }
  1423. }
  1424. else
  1425. {
  1426. Info("Same fluro sync mode, Omit");
  1427. }*/
  1428. return true;
  1429. }
  1430. //设置Binning模式
  1431. bool SensviewCtrl::SetDetectorBinningMode(int nDetectorID, int nBinningMode)
  1432. {
  1433. Info("Set detector({$}) binning mode: {$}({$})", nDetectorID, DetBinningMode[nBinningMode], nBinningMode);
  1434. NV_StatusType nRet = NV_SetBinningMode(NV_BinningMode(nBinningMode));
  1435. if (TestError(nDetectorID, nRet))
  1436. {
  1437. Fatal("NV_SetBinningMode Failed");
  1438. return false;
  1439. }
  1440. return true;
  1441. /*NV_BinningMode bMode;
  1442. NV_StatusType nRet = NV_GetBinningMode(&bMode);
  1443. if (TestError(nDetectorID, nRet))
  1444. {
  1445. Fatal("NV_GetBinningMode Failed");
  1446. return false;
  1447. }
  1448. if ((int)bMode != nBinningMode)
  1449. {
  1450. nRet = NV_SetBinningMode(NV_BinningMode(nBinningMode));
  1451. if (TestError(nDetectorID, nRet))
  1452. {
  1453. Fatal("NV_SetBinningMode Failed");
  1454. return false;
  1455. }
  1456. }
  1457. else
  1458. {
  1459. Info("Same binning mode, Omit");
  1460. }
  1461. return true;*/
  1462. }
  1463. //设置Gain模式
  1464. bool SensviewCtrl::SetDetectorGainMode(int nDetectorID, int nGainValue)
  1465. {
  1466. Info("Set detector({$}) gain level: {$}", nDetectorID, nGainValue);
  1467. NV_StatusType nRet = NV_SetGainEx(nGainValue);
  1468. if (TestError(nDetectorID, nRet))
  1469. {
  1470. Fatal("NV_SetGainEx Failed");
  1471. return false;
  1472. }
  1473. return true;
  1474. /*int nGainTemp = 0;
  1475. NV_StatusType nRet = NV_GetGainEx(&nGainTemp);
  1476. if (TestError(nDetectorID, nRet))
  1477. {
  1478. Fatal("NV_GetGainEx Failed");
  1479. return false;
  1480. }
  1481. if (nGainValue != nGainTemp)
  1482. {
  1483. nRet = NV_SetGainEx(nGainValue);
  1484. if (TestError(nDetectorID, nRet))
  1485. {
  1486. Fatal("NV_SetGainEx Failed");
  1487. return false;
  1488. }
  1489. }
  1490. else
  1491. {
  1492. Info("Same gain mode, Omit");
  1493. }
  1494. return true;*/
  1495. }
  1496. //从校正文件中读取校正日期
  1497. bool SensviewCtrl::GetCalibrationTime(int nDetectorID, bool bExpMode)
  1498. {
  1499. return true;
  1500. }
  1501. //从探测器上下载文件:Gain文件,defect文件
  1502. bool SensviewCtrl::DownloadfromDetector(int nDetectorID)
  1503. {
  1504. string strLog;
  1505. string strWorkDir = m_stDeviceIndex[m_nDetectorIndex].strWorkDir;
  1506. string strLocalPath = strWorkDir;
  1507. string strCreatePath = strWorkDir + "\\Correct\\STE";
  1508. if (!PathFileExists(strCreatePath.c_str()))
  1509. {
  1510. bool bRtn = CreateDirectory(strCreatePath.c_str(), NULL);
  1511. if (bRtn)
  1512. {
  1513. strLog = "create " + strCreatePath + " ok";
  1514. Info("{$}", strLog.c_str());
  1515. }
  1516. else
  1517. {
  1518. strLog = "create " + strCreatePath + " failed";
  1519. Error("{$}", strLog.c_str());
  1520. return false;
  1521. }
  1522. }
  1523. else
  1524. {
  1525. strLog = strCreatePath + " already exist";
  1526. Info("{$}", strLog.c_str());
  1527. }
  1528. return true;
  1529. }
  1530. // 从SDK指定目录拷贝失败的校正文件到CalibrationFailedData中
  1531. bool SensviewCtrl::SaveFailedCalibFiles(int nDetectorID, bool bExpMode)
  1532. {
  1533. Info("SaveCalibrationFailedData");
  1534. Info("SaveCalibrationFailedData over");
  1535. return true;
  1536. }
  1537. bool SensviewCtrl::CleanCalibFiles(int nDetectorID, bool bExpMode)
  1538. {
  1539. return true;
  1540. }
  1541. bool SensviewCtrl::CancelImageRecover()
  1542. {
  1543. Info("Cancel Image Recover");
  1544. return true;
  1545. }
  1546. //-----------------------------------------------------------------------------
  1547. // 函数描述 : 恢复图像:将曝光未获取成功的图像,重新获取出来
  1548. //-----------------------------------------------------------------------------
  1549. bool SensviewCtrl::RecoverImage()
  1550. {
  1551. return true;
  1552. }
  1553. bool SensviewCtrl::IsConnected(string strIP)
  1554. {
  1555. Info("Check ping {$}", strIP);
  1556. CMyPingip obPingIp;
  1557. StatusFeedback(EVT_STATUS_PING, 0, "true");
  1558. if (!obPingIp.PingFunction(strIP.c_str()))
  1559. {
  1560. Info("ping {$} Failed", strIP);
  1561. StatusFeedback(EVT_STATUS_PING, 0, "false");
  1562. return false;
  1563. }
  1564. return true;
  1565. }
  1566. //-----------------------------------------------------------------------------
  1567. // Reconnect探测器(上层button)
  1568. //
  1569. //-----------------------------------------------------------------------------
  1570. bool SensviewCtrl::ResetFPD(nsDPC::FPDDeviceSensview* pDrvDPC)
  1571. {
  1572. Info("Reset FPD");
  1573. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nDetectorIndex)
  1574. {
  1575. Warn("Not current DPC, return");
  1576. return false;
  1577. }
  1578. return true;
  1579. }
  1580. void SensviewCtrl::OnProcessPreImg()
  1581. {
  1582. if (m_bPreviewEnable)
  1583. {
  1584. DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pwPreviewImg);
  1585. }
  1586. }
  1587. void SensviewCtrl::OnProcessImg()
  1588. {
  1589. if (m_bSaveRaw)
  1590. {
  1591. string strImageName = "Flu_" + to_string(m_nFrameID) + ".raw";
  1592. SaveRawImage(strImageName.c_str(), m_pwRawImageData, m_nRawImgWidth, m_nRawImgHeight);
  1593. }
  1594. //暗场图挡图处理
  1595. if (!CheckImageEXI(m_pwRawImageData, m_nRawImgWidth, m_nRawImgHeight, m_nImgBits, m_nExiThreshold, 0.05f))
  1596. {
  1597. Warning("Current frame EXI too low, omit");
  1598. return;
  1599. }
  1600. m_nFrameID++;
  1601. if (m_nFrameID <= 1) //挡住第一张
  1602. {
  1603. Info("Skip first frame");
  1604. return;
  1605. }
  1606. DataFeedback(EVT_DATA_RAW_IMAGE, m_pwRawImageData);
  1607. if (m_strCurrentExamType.find("RAD") != std::string::npos) //只有点片才发关窗终止Workflow
  1608. {
  1609. StartXWindowOffThread();
  1610. }
  1611. }
  1612. bool SensviewCtrl::StartHardwareStatusThread()
  1613. {
  1614. if (m_pHardwareStatusThread == NULL)
  1615. {
  1616. m_hEndHWStatusThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  1617. DWORD m_HardwareStatusID;
  1618. m_pHardwareStatusThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID);
  1619. if (m_pHardwareStatusThread == NULL)
  1620. {
  1621. Fatal("Start HardwareStatus Thread Failed");
  1622. return false;
  1623. }
  1624. }
  1625. return true;
  1626. }
  1627. DWORD SensviewCtrl::HardwareStatusThread(LPVOID pParam)
  1628. {
  1629. SensviewCtrl* pCurPanel = (SensviewCtrl*)pParam;
  1630. if (pCurPanel == NULL)
  1631. {
  1632. return false;
  1633. }
  1634. Info("HardwareStatusThread start");
  1635. DWORD dwTimer = 5000;
  1636. DWORD dwCounter = 0;
  1637. while (true)
  1638. {
  1639. DWORD dwResult = WaitForSingleObject(pCurPanel->m_hEndHWStatusThreadEvent, dwTimer);
  1640. if (dwResult == WAIT_OBJECT_0)
  1641. {
  1642. break;
  1643. }
  1644. else
  1645. {
  1646. if (dwCounter % 60 == 0) //五分钟查一次
  1647. {
  1648. pCurPanel->GetHardwareStatus();
  1649. dwCounter = 0;
  1650. }
  1651. dwCounter++;
  1652. }
  1653. }
  1654. CloseHandle(pCurPanel->m_hEndHWStatusThreadEvent);
  1655. SetEvent(pCurPanel->m_hHWStatusThreadEndEvent);
  1656. Info("HardwareStatusThread stop");
  1657. return true;
  1658. }
  1659. bool SensviewCtrl::GetHardwareStatus()
  1660. {
  1661. if (m_bInExposure)
  1662. {
  1663. Info("In Exposuring,omit check hw status");
  1664. return true;
  1665. }
  1666. for (int i = 0; i < m_nPanelCount; i++)
  1667. {
  1668. int nDetectorID = i + 1;
  1669. if (!GetConnectionStatus(nDetectorID)) // 如果检测到平板探测器失去连接,那么要通知DROC
  1670. {
  1671. Info("FD {$} is communication error", nDetectorID);
  1672. m_stDeviceIndex[i].bConnectStatus = false;
  1673. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nDetectorID);
  1674. }
  1675. else if (m_stDeviceIndex[i].bConnectStatus)
  1676. {
  1677. Info("Check FPD {$} Status", nDetectorID);
  1678. if (m_stDeviceIndex[i].bConnectChanged)
  1679. {
  1680. m_stDeviceIndex[i].bConnectChanged = false;
  1681. }
  1682. /*if (ReadTempStatus(nDetectorID))
  1683. {
  1684. CheckTemperature(nDetectorID);
  1685. }
  1686. if (ReadBatteryStatus(nDetectorID))
  1687. {
  1688. CheckBattery(nDetectorID);
  1689. }
  1690. if (ReadWifiStatus(nDetectorID))
  1691. {
  1692. CheckWiFi(nDetectorID);
  1693. }
  1694. if (ReadLivingTime(nDetectorID))
  1695. {
  1696. CheckLivingTime(nDetectorID);
  1697. }*/
  1698. }
  1699. }
  1700. return true;
  1701. }
  1702. bool SensviewCtrl::GetConnectionStatus(int nDetectorID)
  1703. {
  1704. return false;
  1705. }
  1706. /***
  1707. * 保存RAW图像
  1708. ***/
  1709. bool SensviewCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight)
  1710. {
  1711. Info("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight);
  1712. if (pRawImg == NULL || pImgName == NULL)
  1713. {
  1714. return false;
  1715. }
  1716. string strImagePath = g_strAppPath + "\\Image\\" + pImgName;
  1717. FILE* fp;
  1718. if ((fp = fopen(strImagePath.c_str(), "wb")) == NULL)
  1719. {
  1720. DWORD dw = GetLastError();
  1721. Error("fopen {$} failed, {$}", strImagePath.c_str(), dw);
  1722. return false;
  1723. }
  1724. fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp);
  1725. fclose(fp);
  1726. Info("End to Save Raw Image");
  1727. return true;
  1728. }
  1729. //刷新Offset
  1730. bool SensviewCtrl::StartOffset(bool isAll)
  1731. {
  1732. if (!m_stDeviceIndex[m_nDetectorIndex].bConnectStatus)
  1733. {
  1734. Warn("Detector communication loss");
  1735. return false;
  1736. }
  1737. m_bOffsetAll = isAll;
  1738. Info("Offset mode: {$}", isAll ? "All" : "NoAll");
  1739. SetEvent(m_hOffsetEvent); //OffsetCalibration()
  1740. return true;
  1741. }
  1742. //如果是isAll=true, 则刷新全部模式,如果isAll=false, 则刷新当前模式和点片模式
  1743. bool SensviewCtrl::OffsetCalibration()
  1744. {
  1745. Info("OffsetCalibration start");
  1746. bool bOffsetFailed = false;
  1747. StatusFeedback(PANEL_OFFSET_CAL, OFFSET_RUNNING);
  1748. StatusFeedback(PANEL_OFFSET_COUNT, 1);
  1749. StatusFeedback(PANEL_OFFSET_PROGRESS, 0);
  1750. if (!OffsetProcess(m_nDetectorID, 1))
  1751. {
  1752. Error("Offset process failed");
  1753. bOffsetFailed = true;
  1754. }
  1755. StatusFeedback(PANEL_OFFSET_PROGRESS, 1);
  1756. /*if (m_bOffsetAll)
  1757. {
  1758. int nTotalMode = m_mapLogicModeOperationMode.size();
  1759. StatusFeedback(PANEL_OFFSET_COUNT, nTotalMode);
  1760. int nOffsetProgress = 0;
  1761. for (map<int, int>::iterator it = m_mapLogicModeOperationMode.begin(); it != m_mapLogicModeOperationMode.end(); it++)
  1762. {
  1763. StatusFeedback(PANEL_OFFSET_PROGRESS, nOffsetProgress);
  1764. if (!OffsetProcess(m_nDetectorID, it->second))
  1765. {
  1766. Error("Offset mode {$} failed");
  1767. bOffsetFailed = true;
  1768. break;
  1769. }
  1770. nOffsetProgress++;
  1771. }
  1772. }
  1773. else
  1774. {
  1775. StatusFeedback(PANEL_OFFSET_COUNT, 2);
  1776. Info("Refresh RAD");
  1777. if (!OffsetProcess(m_nDetectorID, 1))
  1778. {
  1779. Error("Offset mode rad failed");
  1780. bOffsetFailed = true;
  1781. }
  1782. StatusFeedback(PANEL_OFFSET_PROGRESS, 1);
  1783. Info("Refresh Mode({$})", 2);
  1784. if (!OffsetProcess(m_nDetectorID, 2))
  1785. {
  1786. Error("Offset mode flu failed");
  1787. bOffsetFailed = true;
  1788. }
  1789. StatusFeedback(PANEL_OFFSET_PROGRESS, 2);
  1790. }*/
  1791. if (bOffsetFailed)
  1792. {
  1793. StatusFeedback(PANEL_OFFSET_CAL, OFFSET_ERROR);
  1794. }
  1795. else
  1796. {
  1797. StatusFeedback(PANEL_OFFSET_CAL, OFFSET_IDLE);
  1798. }
  1799. Info("Offset FINISH");
  1800. return true;
  1801. }
  1802. //刷新暗场
  1803. bool SensviewCtrl::OffsetProcess(int nDetectorID, int nMode)
  1804. {
  1805. Info("OffsetProcess start");
  1806. NV_StatusType nRet = NV_RunOffsetCalThread();
  1807. if (TestError(nDetectorID, nRet))
  1808. {
  1809. Warn("NV_PerformOffsetCal Failed");
  1810. return false;
  1811. }
  1812. ResetLock();
  1813. if (WaitRespond(50000))
  1814. {
  1815. Info("Offset success");
  1816. return true;
  1817. }
  1818. else
  1819. {
  1820. Info("Offset timeout");
  1821. return true;
  1822. }
  1823. //Info("OffsetProcess over");
  1824. return true;
  1825. }
  1826. bool SensviewCtrl::AbortOffset()
  1827. {
  1828. Info("Abort refresh offset");
  1829. NV_StatusType nRet = NV_CancelOffsetCal();
  1830. if (TestError(1, nRet))
  1831. {
  1832. Warn("NV_CancelOffsetCal Failed");
  1833. return false;
  1834. }
  1835. SendNotify();
  1836. StatusFeedback(PANEL_OFFSET_CAL, OFFSET_IDLE);
  1837. return true;
  1838. }
  1839. //检查图像EXI, 返回true: 有射线,返回false: 无射线
  1840. bool SensviewCtrl::CheckImageEXI(WORD* pImage, int nWidth, int nHeight, int nImageBit, int nThreshold, float fArea)
  1841. {
  1842. if (nThreshold == 0)
  1843. {
  1844. Info("Omit check EXI");
  1845. return true;
  1846. }
  1847. Info("Check EXI");
  1848. if (!pImage)
  1849. {
  1850. Error("Buffer is null");
  1851. return false; //图像读入失败。
  1852. }
  1853. int N = 65536;
  1854. int* Histogram = NULL;
  1855. Histogram = new int[N];
  1856. if (Histogram == NULL)
  1857. {
  1858. Error("Alloc buffer failed");
  1859. return false; //内存分配失败。
  1860. }
  1861. memset(Histogram, 0, sizeof(int) * N);
  1862. unsigned long int nCount = 0;
  1863. unsigned long int temp = 0;
  1864. int nIdxI = 0;
  1865. int nIdxJ = 0;
  1866. for (nIdxJ = 30; nIdxJ < nHeight - 30; nIdxJ = nIdxJ + 4)
  1867. {
  1868. for (nIdxI = 30; nIdxI < nWidth - 30; nIdxI = nIdxI + 4)
  1869. {
  1870. temp = int(pImage[nIdxJ * nWidth + nIdxI]);
  1871. Histogram[temp]++;
  1872. nCount++;
  1873. }
  1874. }
  1875. float fCoe = 0.01f;
  1876. int nCoeCount = int(fCoe * nCount);
  1877. int nAreaCount = int((1 - fCoe) * nCount * fArea);
  1878. long int nIdx = 0;
  1879. long int nSum = 0;
  1880. for (nIdx = N - 1; nIdx >= 0; nIdx--)
  1881. {
  1882. nSum += Histogram[nIdx];
  1883. if (nSum >= nCoeCount)
  1884. break;
  1885. }
  1886. unsigned long int fMean = 0;
  1887. unsigned long int nflag = 0;
  1888. for (int i = nIdx; i >= 0; i--)
  1889. {
  1890. if (Histogram[nIdx] == 0)
  1891. {
  1892. continue;
  1893. }
  1894. fMean += nIdx * Histogram[nIdx];
  1895. nflag += Histogram[nIdx];
  1896. if (nflag >= nAreaCount)
  1897. {
  1898. break;
  1899. }
  1900. }
  1901. if (Histogram)
  1902. {
  1903. delete[] Histogram;
  1904. Histogram = NULL;
  1905. }
  1906. if (nflag == 0)
  1907. {
  1908. Warning("Not have Xray image");
  1909. return false; //无x射线
  1910. }
  1911. fMean = unsigned long int(fMean / nflag);
  1912. Info("Mean count({$})", fMean);
  1913. if (fMean >= nThreshold)
  1914. {
  1915. //LogInfo("Xray image");
  1916. return true;
  1917. }
  1918. else
  1919. {
  1920. //LogInfo("Not have Xray image");
  1921. return false;
  1922. }
  1923. }
  1924. bool SensviewCtrl::SetOffsetModeScope()
  1925. {
  1926. Info("SetModeScope");
  1927. int nModeNum = m_pCurrentDPC->GetTotalAcqModeNum();
  1928. Info("Mode number: {$}", nModeNum);
  1929. int nLogicMode = 0;
  1930. int nOperationMode = 0;
  1931. for (int i = 0; i < nModeNum; i++)
  1932. {
  1933. if ((int)m_ModeConfig["ModeTable"][i]["OffsetEnable"] == 1)
  1934. {
  1935. nLogicMode = (int)m_ModeConfig["ModeTable"][i]["LogicMode"];
  1936. nOperationMode = (int)m_ModeConfig["ModeTable"][i]["OperationMode"];
  1937. m_mapLogicModeOperationMode.insert(pair<int, int>(nLogicMode, nOperationMode));
  1938. }
  1939. }
  1940. return true;
  1941. }
  1942. //列出探测器的触发模式
  1943. bool SensviewCtrl::ListDetectorTriggerMode(int nDetectorID)
  1944. {
  1945. Info("ListDetectorTriggerMode");
  1946. int nTempBuffer = 0x0F;
  1947. int nTempCount = 0;
  1948. NV_AcquisitionMode* pMode = new NV_AcquisitionMode[nTempBuffer];
  1949. NV_StatusType nRet = NV_EnumAcquisitionMode(pMode, nTempBuffer, &nTempCount);
  1950. if (TestError(nDetectorID, nRet))
  1951. {
  1952. Warn("NV_EnumAcquisitionMode Failed");
  1953. return false;
  1954. }
  1955. if (nTempCount <= 0)
  1956. {
  1957. Warn("No support any trigger mode");
  1958. return false;
  1959. }
  1960. for (int i = 0; i < nTempCount; i++)
  1961. {
  1962. Info("Index: {$}, TriggerMode: {$}({$})", i, DetTriggerMode[int(pMode[i])], int(pMode[i]));
  1963. }
  1964. delete[] pMode;
  1965. return true;
  1966. }
  1967. //列出探测器的Binning模式
  1968. bool SensviewCtrl::ListDetectorBinningMode(int nDetectorID)
  1969. {
  1970. Info("ListDetectorBinningMode");
  1971. int nTempBuffer = 0x0F;
  1972. int nTempCount = 0;
  1973. NV_BinningMode* pMode = new NV_BinningMode[nTempBuffer];
  1974. NV_StatusType nRet = NV_EnumBinningMode(pMode, nTempBuffer, &nTempCount);
  1975. if (TestError(nDetectorID, nRet))
  1976. {
  1977. Warn("NV_EnumBinningMode Failed");
  1978. return false;
  1979. }
  1980. if (nTempCount <= 0)
  1981. {
  1982. Warn("No support any binning mode");
  1983. return false;
  1984. }
  1985. for (int i = 0; i < nTempCount; i++)
  1986. {
  1987. Info("Index: {$}, BinningMode: {$}({$})", i, DetBinningMode[int(pMode[i])], int(pMode[i]));
  1988. }
  1989. delete[] pMode;
  1990. return true;
  1991. }
  1992. //列出探测器的Gain档位
  1993. bool SensviewCtrl::ListDetectorGainMode(int nDetectorID)
  1994. {
  1995. Info("ListDetectorGainMode");
  1996. int nTempCount = 0;
  1997. NV_StatusType nRet = NV_EnumGains(&nTempCount);
  1998. if (TestError(nDetectorID, nRet))
  1999. {
  2000. Warn("NV_EnumGains Failed");
  2001. return false;
  2002. }
  2003. Info("GainMode: 0~{$}", nTempCount - 1);
  2004. return true;
  2005. }
  2006. //探测器基本信息
  2007. bool SensviewCtrl::ListDetectorInfo(int nDetectorID)
  2008. {
  2009. Info("ListDetectorInfo");
  2010. NV_Version detVer;
  2011. NV_StatusType nRet = NV_GetVersion(&detVer);
  2012. if (TestError(nDetectorID, nRet))
  2013. {
  2014. Warn("NV_GetVersion Failed");
  2015. return false;
  2016. }
  2017. string strFWVersion = std::to_string(detVer.FirmwareVersion >> 24 & 0xFF) + "." + std::to_string(detVer.FirmwareVersion >> 16 & 0xFF) + "."
  2018. + std::to_string(detVer.FirmwareVersion >> 8 & 0xFF) + "." + std::to_string(detVer.FirmwareVersion >> 0 & 0xFF);
  2019. Info("Firmware version: {$}", strFWVersion);
  2020. string strHWVersion = std::to_string(detVer.HardwareVersion >> 24 & 0xFF) + "." + std::to_string(detVer.HardwareVersion >> 16 & 0xFF) + "."
  2021. + std::to_string(detVer.HardwareVersion >> 8 & 0xFF) + "." + std::to_string(detVer.HardwareVersion >> 0 & 0xFF);
  2022. Info("Hardware version: {$}", strHWVersion);
  2023. string strKerVersion = std::to_string(detVer.KernelVersion >> 24 & 0xFF) + "." + std::to_string(detVer.KernelVersion >> 16 & 0xFF) + "."
  2024. + std::to_string(detVer.KernelVersion >> 8 & 0xFF) + "." + std::to_string(detVer.KernelVersion >> 0 & 0xFF);
  2025. Info("Kernel version: {$}", strKerVersion);
  2026. char szSN[32] = "";
  2027. unsigned long iSize = 32;
  2028. nRet = NV_GetSerialNum(szSN, &iSize);
  2029. if (TestError(nDetectorID, nRet))
  2030. {
  2031. Warn("NV_GetSerialNum Failed");
  2032. return false;
  2033. }
  2034. Info("Detector serial number: {$}", szSN);
  2035. return true;
  2036. }
  2037. bool SensviewCtrl::SetFluPPS(float fFluPPS)
  2038. {
  2039. if (fFluPPS <= 0.0f)
  2040. {
  2041. Warn("Current frame rate is Illegal");
  2042. return false;
  2043. }
  2044. Info("Set Detector flu frame rate: {$}", fFluPPS);
  2045. ////方式一:设置扩展曝光时间
  2046. ////计算扩展曝光时间,单位0.1ms
  2047. //int nExpTime = 10000 / int(fFluPPS);
  2048. //int nRet = NV_SetExpTime(nExpTime);
  2049. //if (TestError(m_nDetectorID, nRet))
  2050. //{
  2051. // Fatal("NV_SetExpTime Failed");
  2052. // return false;
  2053. //}
  2054. //方式二:设帧率
  2055. int nRet = NV_SetFramePerSecond(int(fFluPPS));
  2056. if (TestError(m_nDetectorID, nRet))
  2057. {
  2058. Fatal("NV_SetFramePerSecond Failed");
  2059. return false;
  2060. }
  2061. m_fFrameRate = fFluPPS;
  2062. return true;
  2063. }
  2064. bool SensviewCtrl::GetFluPPS(float& fFluPPS)
  2065. {
  2066. fFluPPS = m_fFrameRate;
  2067. return true;
  2068. }