Detector_TiRayDR.cpp 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819
  1. #include "Detector_TiRayDR.h"
  2. #include "CCOS.Dev.FPD.TiRayDR.h"
  3. #include "MyPingip.h"
  4. #include <dlfcn.h>
  5. #include <pthread.h>
  6. using EventListenerType = void(*)(TiRayEvent, void*);
  7. Detector_TiRayDR* g_pDetector = nullptr;
  8. //extern Log4CPP::Logger* mLog::gLogger;
  9. /****************************************/
  10. int (*GetSdkVersion_Ptr)(void);
  11. TiRayError(*Scan_Ptr)(ResultCallback fn, const char* interfaceIp, int scanDuration);
  12. TiRayError(*SetIp_Ptr)(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp);
  13. TiRayError(*Startup_Ptr)(TiRayModel model, EventCallback fn, const StartupOption * option);
  14. void (*Stop_Ptr)();
  15. TiRayError(*Execute_Ptr)(int detectorId, int commandId, TiRayVariant argv[], int argc);
  16. TiRayError(*ApplyPreset_Ptr)(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn);
  17. TiRayError(*GenerateTemplate_Ptr)(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize);
  18. static int g_load_error = 0;
  19. static void LoadOneFunc(void* hInstLib, void** pFunction, const char* funcName)
  20. {
  21. *pFunction = dlsym(hInstLib, funcName);
  22. const char* dlsym_error = dlerror();
  23. if (dlsym_error != NULL) {
  24. printf("Failed to load %s. Error = %s", funcName, dlsym_error);
  25. g_load_error = 1;
  26. }
  27. }
  28. void OnEvent(TiRayEvent eventType, TiRayVariant argv[], int argc) {
  29. if (argc > 0) {
  30. auto arg = new std::vector<TiRayVariant>(argc);
  31. for (int i = 0; i < argc; i++) {
  32. if (argv[i].Type == TiRayVariant::TiRayBuffer) {
  33. arg->at(i).Type = TiRayVariant::TiRayBuffer;
  34. arg->at(i).DataLen = argv[i].DataLen;
  35. arg->at(i).DataValue = new char[argv[i].DataLen];
  36. memcpy(arg->at(i).DataValue, argv[i].DataValue, argv[i].DataLen);
  37. }
  38. else {
  39. memcpy(&arg->at(i), &argv[i], sizeof(TiRayVariant));
  40. }
  41. }
  42. }
  43. }
  44. #define LOAD_ONE_FUNC(handle, funcName) LoadOneFunc(handle, (void**)&(funcName##_Ptr), #funcName)
  45. /****************************************/
  46. Detector_TiRayDR::Detector_TiRayDR()
  47. :m_nPanelCount{},
  48. m_nCurrentPanelID{},
  49. m_nImageWidth{},
  50. m_nImageHeight{},
  51. m_nWidthOffset{},
  52. m_nHeightOffset{},
  53. m_nRawImgWidth{},
  54. m_nRawImgHeight{},
  55. m_nCalibrationRounds{},
  56. m_nCalibCurrentCalibrationRound{},
  57. m_nCalibCurrentExposureIndex{},
  58. m_nExposureNumCurrentRound{},
  59. m_hTiRayDRModule{},
  60. m_hReconnectThread{},
  61. m_hFPDScanThread{},
  62. m_hRadAcquisitionThread{},
  63. m_hStatusMonitorThread{},
  64. m_pRawImgBuffer{},
  65. m_pImgBuffer{},
  66. m_pZSKKCalib{},
  67. m_strDetectorType{},
  68. m_strSerialNum{},
  69. m_nImageNum{},
  70. m_nDetectorID{},
  71. m_nNotifyStatusTimePeriod{},
  72. m_pStPanelStatus{},
  73. m_nReconnectTimePeriod(5000),
  74. m_nAppStatus(APP_STATUS::APP_STATUS_IDLE),
  75. m_eCaliType(CCOS_CALIBRATION_TYPE_NONE),
  76. m_nSyncMode(SYNC_SOFTWARE),
  77. m_nCalibrationMode(CCOS_CALIBRATION_MODE_ZSKK),
  78. m_bSaveRaw(true),
  79. m_bConnected(false),
  80. m_bAEDReady(false),
  81. m_bAEDWorkFlag(false),
  82. m_bExitRadAcqStatus(false),
  83. m_bMonitorFlag(false)
  84. {
  85. m_pDPC2PanelID = new map<FPDDeviceTiRay*, int>();
  86. m_pPanelID2DPC = new map<int, FPDDeviceTiRay*>();
  87. m_hExitRadAcqStatus = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  88. m_hInitEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  89. m_hExitEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  90. m_hReConnectEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  91. m_hRadEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  92. m_hArrayEvent.push_back(m_hInitEvent);
  93. m_hArrayEvent.push_back(m_hExitEvent);
  94. m_hArrayEvent.push_back(m_hReConnectEvent);
  95. m_hArrayEvent.push_back(m_hRadEvent);
  96. m_hToggleEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
  97. }
  98. Detector_TiRayDR::~Detector_TiRayDR()
  99. {
  100. CloseStatusMonitor();
  101. CloseDetectorScan();
  102. if (m_hReconnectThread != 0) {
  103. if (m_bReconnectThreadRunning) {
  104. struct timespec ts;
  105. clock_gettime(CLOCK_REALTIME, &ts);
  106. ts.tv_sec += 2; // 设置2秒超时
  107. // 等待线程结束
  108. pthread_timedjoin_np(m_hReconnectThread, nullptr, &ts);
  109. }
  110. // 如果线程仍在运行,强制取消
  111. if (m_bReconnectThreadRunning) {
  112. pthread_cancel(m_hReconnectThread);
  113. }
  114. m_hReconnectThread = 0;
  115. }
  116. if (m_pRawImgBuffer)
  117. {
  118. delete[] m_pRawImgBuffer;
  119. m_pRawImgBuffer = nullptr;
  120. }
  121. if (m_pImgBuffer)
  122. {
  123. delete[] m_pImgBuffer;
  124. m_pImgBuffer = nullptr;
  125. }
  126. if (m_pZSKKCalib)
  127. {
  128. delete m_pZSKKCalib;
  129. m_pZSKKCalib = nullptr;
  130. }
  131. }
  132. bool Detector_TiRayDR::ScanDetector(string& strDetectorInfo)
  133. {
  134. ResDataObject result;
  135. std::vector<scan_result> scan_results;
  136. // 扫描探测器并收集所有结果
  137. scan([&scan_results](scan_result&& res) {
  138. scan_results.emplace_back(std::move(res));
  139. });
  140. if (scan_results.empty()) {
  141. std::cerr << "[Detector_TiRayDR::ScanDetector] No detectors were found!" << std::endl;
  142. return false;
  143. }
  144. std::cout << "[Detector_TiRayDR::ScanDetector] Scanned " << scan_results.size() << " detector(s):" << std::endl;
  145. for (size_t i = 0; i < scan_results.size(); ++i) {
  146. const auto& res = scan_results[i];
  147. ResDataObject detectorData;
  148. detectorData.add("SerialNumber", res.sn.c_str());
  149. detectorData.add("Model", res.model.c_str());
  150. detectorData.add("TupperIP", res.upper_ip.c_str());
  151. detectorData.add("DetectorIP", res.detector_ip.c_str());
  152. std::string key = "DetectorData_" + std::to_string(i);
  153. result.add(key.c_str(), detectorData);
  154. // 输出当前探测器信息
  155. std::cout << "[Detector_TiRayDR::ScanDetector] Detector " << (i + 1) << ":"
  156. << " Serial number:" << res.sn
  157. << ", Model:" << res.model
  158. << ", tupper IP:" << res.upper_ip
  159. << ", detector IP:" << res.detector_ip << std::endl;
  160. }
  161. try {
  162. strDetectorInfo = result.encode();
  163. }
  164. catch (const std::exception& e) {
  165. std::cerr << "[Detector_TiRayDR::ScanDetector] Encode failed: " << e.what() << std::endl;
  166. return false;
  167. }
  168. return true;
  169. }
  170. bool Detector_TiRayDR::DriverEntry(FPDDeviceTiRay* pDrvDPC, ResDataObject& Configuration)
  171. {
  172. //mLog::FINFO("--TiRayDR Func-- DriverEntry Start");
  173. map<FPDDeviceTiRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  174. if (DPCsIter != m_pDPC2PanelID->end())
  175. {
  176. //mLog::FERROR("This DPC already exist");
  177. return false;
  178. }
  179. CPanelStatus* p = new CPanelStatus();
  180. m_pStPanelStatus[m_nPanelCount] = p;
  181. m_pDPC2PanelID->insert(pair<FPDDeviceTiRay*, int>(pDrvDPC, m_nPanelCount));
  182. m_pPanelID2DPC->insert(pair<int, FPDDeviceTiRay*>(m_nPanelCount, pDrvDPC));
  183. m_nPanelCount++;
  184. m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储
  185. //mLog::FINFO("Config: {$}", m_ModeConfig.encode());
  186. try
  187. {
  188. m_nCalibrationMode = (CCOS_CALIBRATION_MODE)(int)m_ModeConfig["CalibMode"];
  189. }
  190. catch (ResDataObjectExption& e)
  191. {
  192. //mLog::FERROR("Read configuration failed, Error code: {$}", e.what());
  193. }
  194. //mLog::FINFO("TiRayDR DriverEntry Over");
  195. return true;
  196. }
  197. bool Detector_TiRayDR::Connect(FPDDeviceTiRay* pDrvDPC, const char* szWorkPath)
  198. {
  199. //mLog::FINFO("--TiRayDR Func-- Connect Start");
  200. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  201. {
  202. //mLog::FINFO("Not current DPC, return true");
  203. return true;
  204. }
  205. if (!m_pZSKKCalib)
  206. {
  207. m_pZSKKCalib = new CZSKKCalibrationCtrl();
  208. }
  209. m_strWorkPath = szWorkPath;
  210. if (m_hFPDScanThread == 0)
  211. {
  212. pthread_t threadId;
  213. int result = pthread_create(&threadId, NULL, onFPDScanThread, this);
  214. if (result == 0) {
  215. m_hFPDScanThread = threadId; // 存储线程ID
  216. }
  217. else {
  218. //mLog::FERROR("Thread creation failed: %d", result);
  219. return false;
  220. }
  221. }
  222. if (m_hInitEvent) {
  223. m_hInitEvent->SetEvent();
  224. }
  225. //mLog::FINFO("TiRayDR Connect Over");
  226. return true;
  227. }
  228. bool Detector_TiRayDR::Disconnect()
  229. {
  230. //mLog::FINFO("--TiRayDR Func-- Disconnect Begin");
  231. m_hExitEvent->SetEvent(); //关闭Scan线程
  232. bool result = m_hToggleEvent->Wait(65000);
  233. if (result)
  234. {
  235. //mLog::FINFO("Leave scan thread over");
  236. }
  237. else
  238. {
  239. //mLog::FERROR("Till time detectorData");
  240. }
  241. //mLog::FINFO("Call API Stop");
  242. Stop();
  243. //mLog::FINFO("TiRayDR Disconnect Over");
  244. return true;
  245. }
  246. void Detector_TiRayDR::EnterExamMode(int nExamMode)
  247. {
  248. switch (nExamMode)
  249. {
  250. case APP_STATUS_WORK_BEGIN:
  251. //mLog::FINFO("Enter into Exam Windows");
  252. m_nAppStatus = APP_STATUS_WORK_BEGIN;
  253. break;
  254. case APP_STATUS_WORK_END:
  255. //mLog::FINFO("Quit Exam Windows");
  256. m_nAppStatus = APP_STATUS_WORK_END;
  257. break;
  258. case APP_STATUS_DETSHARE_BEGIN:
  259. //mLog::FINFO("Enter into Detector Share Windows");
  260. m_nAppStatus = APP_STATUS_DETSHARE_BEGIN;
  261. break;
  262. case APP_STATUS_DETSHAR_END:
  263. //mLog::FINFO("Quit Detector Share Windows");
  264. m_nAppStatus = APP_STATUS_DETSHAR_END;
  265. break;
  266. case APP_STATUS_CAL_BEGIN:
  267. //mLog::FINFO("Enter into Calibration Windows");
  268. m_nAppStatus = APP_STATUS_CAL_BEGIN;
  269. break;
  270. case APP_STATUS_CAL_END:
  271. //mLog::FINFO("Quit Calibration Windows");
  272. m_nAppStatus = APP_STATUS_CAL_END;
  273. break;
  274. case APP_STATUS_WORK_IN_SENSITIVITY:
  275. //mLog::FINFO("Enter into sensitivity test interface");
  276. m_nAppStatus = APP_STATUS_WORK_IN_SENSITIVITY;
  277. break;
  278. default:
  279. break;
  280. }
  281. }
  282. /***
  283. ** 根据采集模式申请图像buffer
  284. ***/
  285. bool Detector_TiRayDR::SetAcqMode(int nMode)
  286. {
  287. //mLog::FINFO("--TiRayDR Func-- SetAcqMode Start");
  288. //mLog::FINFO("Detector_TiRayDR::SetAcqMode mode:{$}", nMode);
  289. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  290. {
  291. //mLog::FERROR("Detector not connected, return");
  292. return false;
  293. }
  294. int nRes;
  295. m_bExitRadAcqStatus = false;
  296. try
  297. {
  298. //设置采集模式,根据不同的场景设置不同的采集模式
  299. m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"];
  300. m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"];
  301. m_nWidthOffset = (int)m_ModeConfig["ModeTable"][0]["WidthOffset"];
  302. m_nHeightOffset = (int)m_ModeConfig["ModeTable"][0]["HeightOffset"];
  303. //mLog::FINFO("After crop image width: {$}, height: {$}, WidthOffset: {$}, HeightOffset: {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
  304. m_bSaveRaw = (int)m_ModeConfig["ModeTable"][0]["IsSaveRaw"];
  305. //mLog::FINFO("m_nSaveRaw:{$}", m_bSaveRaw);
  306. if (nullptr != m_pImgBuffer)
  307. {
  308. delete[] m_pImgBuffer;
  309. m_pImgBuffer = nullptr;
  310. }
  311. m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageHeight];
  312. }
  313. catch (ResDataObjectExption& e)
  314. {
  315. //mLog::FERROR("Get config FERROR: {$}", e.what());
  316. return false;
  317. }
  318. //TiRayVariant Param[2]{};
  319. //Param[0].Type = TiRayVariant::TiRayInt;
  320. //Param[0].IntValue = TiRayAttribute::Attr_BinningMode;
  321. //Param[1].Type = TiRayVariant::TiRayInt;
  322. //Param[1].IntValue = BinningMode::Binning_None;
  323. //nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
  324. //if ((TiRayError)nRes != TiRayError::Err_Success)
  325. //{
  326. // //mLog::Error("Set BinningMode Failed, Reason:{$}", nRes);
  327. // return false;
  328. //}
  329. //else
  330. //{
  331. // //mLog::FINFO("Set BinningMode Success");
  332. //}
  333. //TiRayVariant ParamAED[2]{};
  334. //ParamAED[0].Type = TiRayVariant::TiRayInt;
  335. //ParamAED[0].IntValue = TiRayAttribute::Attr_AEDSensitivity;
  336. //ParamAED[1].Type = TiRayVariant::TiRayInt;
  337. //ParamAED[1].IntValue = 200;
  338. //nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, ParamAED, 2);
  339. //if ((TiRayError)nRes != TiRayError::Err_Success)
  340. //{
  341. // //mLog::Error("Set BinningMode Failed, Reason:{$}", nRes);
  342. // return false;
  343. //}
  344. //else
  345. //{
  346. // //mLog::FINFO("Set BinningMode Success");
  347. //}
  348. StatusFeedback(EVT_STATUS_PANEL, PANEL_SLEEP);
  349. //mLog::FINFO("TiRayDR SetAcqMode Over");
  350. return true;
  351. }
  352. bool Detector_TiRayDR::SetSyncMode(int nSyncMode)
  353. {
  354. //mLog::FINFO("--TiRayDR Func-- SetSyncMode Start");
  355. //mLog::FINFO("SetSyncMode: {$}", nSyncMode);
  356. std::cout << "--TiRayDR Func-- SetSyncMode Start" << std::endl;
  357. std::cout << "SetSyncMode: " << nSyncMode << std::endl;
  358. int nRes;
  359. TiRayVariant Param[2]{};
  360. Param[0].Type = TiRayVariant::TiRayInt;
  361. Param[0].IntValue = TiRayAttribute::Attr_WorkMode;
  362. Param[1].Type = TiRayVariant::TiRayInt;
  363. if (nSyncMode == 1)
  364. {
  365. Param[1].IntValue = WorkMode::WorkMode_Idle;
  366. m_nSyncMode = SYNC_MODE::SYNC_SOFTWARE;
  367. std::cout << "Setting SyncMode to Software Sync" << std::endl;
  368. nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
  369. if ((TiRayError)nRes != TiRayError::Err_Success)
  370. {
  371. std::cout << "Error: Failed to set SyncMode to Software Sync. Reason: " << nRes << std::endl;
  372. //mLog::Error("Set SyncMode SoftSync, Reason:{$}", nRes);
  373. return false;
  374. }
  375. else
  376. {
  377. std::cout << "Success: Software Sync mode set successfully" << std::endl;
  378. //mLog::FINFO("Set SoftSync Success");
  379. }
  380. }
  381. else if (nSyncMode == 2)
  382. {
  383. m_nSyncMode = SYNC_MODE::SYNC_HARDWARE;
  384. Param[1].IntValue = WorkMode::WorkMode_SyncIn;
  385. std::cout << "Setting SyncMode to Hardware Sync" << std::endl;
  386. nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
  387. if ((TiRayError)nRes != TiRayError::Err_Success)
  388. {
  389. std::cout << "Error: Failed to set SyncMode to Hardware Sync. Reason: " << nRes << std::endl;
  390. //mLog::Error("Set SyncMode HardSync, Reason:{$}", nRes);
  391. return false;
  392. }
  393. else
  394. {
  395. std::cout << "Success: Hardware Sync mode set successfully" << std::endl;
  396. //mLog::FINFO("Set HardSync Success");
  397. }
  398. }
  399. else if (nSyncMode == 3)
  400. {
  401. Param[1].IntValue = WorkMode_FreeSync;
  402. m_nSyncMode = SYNC_MODE::SYNC_AED;
  403. std::cout << "Setting SyncMode to AED Sync" << std::endl;
  404. nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
  405. if ((TiRayError)nRes != TiRayError::Err_Success)
  406. {
  407. std::cout << "Error: Failed to set SyncMode to AED Sync. Reason: " << nRes << std::endl;
  408. //mLog::Error("Set SyncMode AED, Reason:{$}", nRes);
  409. return false;
  410. }
  411. else
  412. {
  413. std::cout << "Success: AED Sync mode set successfully" << std::endl;
  414. //mLog::FINFO("Set AED Success");
  415. }
  416. }
  417. m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)m_nSyncMode;
  418. //mLog::FINFO("TiRayDR SetSyncMode Over");
  419. std::cout << "TiRayDR SetSyncMode Over" << std::endl;
  420. return true;
  421. }
  422. bool Detector_TiRayDR::PrepareAcquisition(FPDDeviceTiRay* pDrvDPC)
  423. {
  424. //mLog::FINFO("--TiRayDR Func-- PrepareAcquisition Start");
  425. //mLog::FINFO("PrepareAcquisition start");
  426. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  427. {
  428. //mLog::FERROR("Not current DPC, return");
  429. return false;
  430. }
  431. //未初始化、未连接 不执行
  432. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  433. {
  434. //mLog::FERROR("Detector not connected, return");
  435. return false;
  436. }
  437. if (m_bAEDReady)
  438. {
  439. g_pDetector->StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  440. }
  441. g_pDetector->StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  442. //m_hRadEvent->SetEvent();
  443. //mLog::FINFO("TiRayDR PrepareAcquisition Over");
  444. return true;
  445. }
  446. bool Detector_TiRayDR::StartAcquisition(FPDDeviceTiRay* pDrvDPC)
  447. {
  448. //mLog::FINFO("--TiRayDR Func-- StartAcquisition Start");
  449. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  450. {
  451. //mLog::FERROR("Not current DPC, return");
  452. return false;
  453. }
  454. //未初始化、未连接 不执行
  455. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  456. {
  457. //mLog::FERROR("Detector not connected, return");
  458. return false;
  459. }
  460. if (m_nSyncMode == SYNC_MODE::SYNC_SOFTWARE)
  461. {
  462. //SetSyncMode(1);
  463. auto err = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
  464. if (err != Err_Success) {
  465. cout << "[Detector_TiRayDR::StartAcquisition] Failed to Execute_Ptr Cmd_Photo. Error code: " << err << endl;
  466. return false;
  467. }
  468. }
  469. StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
  470. m_bAEDWorkFlag = true;
  471. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  472. //mLog::FINFO("TiRayDR StartAcquisition Over");
  473. return true;
  474. }
  475. bool Detector_TiRayDR::StopAcquisition(FPDDeviceTiRay* pDrvDPC)
  476. {
  477. //mLog::FINFO("--TiRayDR Func-- StopAcquisition Start");
  478. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  479. {
  480. //mLog::FERROR("Not current DPC, return");
  481. return false;
  482. }
  483. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  484. {
  485. //mLog::FERROR("Detector not connected, return");
  486. return false;
  487. }
  488. //mLog::FINFO("## Stop Acquisition ##");
  489. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  490. SetTiRayDPCStatus(eDetStatus::DetStatus_Standby); //停止采集
  491. //mLog::FINFO("TiRayDR StopAcquisition Over");
  492. return true;
  493. }
  494. bool Detector_TiRayDR::ActiveCalibration(FPDDeviceTiRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType)
  495. {
  496. //mLog::FINFO("--TiRayDR Func-- ActiveCalibration Start");
  497. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  498. {
  499. //mLog::FERROR("Not current DPC, return");
  500. return false;
  501. }
  502. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  503. {
  504. //mLog::FERROR("bConnectState is false, Detector not connected, return");
  505. return false;
  506. }
  507. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START);
  508. m_nAppStatus = APP_STATUS_CAL_BEGIN; //激活校正,置为校正界面
  509. m_eCaliType = eType;
  510. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  511. {
  512. //mLog::FINFO("Active Dark Calibration");
  513. }
  514. if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
  515. {
  516. //mLog::FINFO("Active Xray Calibration");
  517. if (m_nCalibrationMode) //厂商校正ActiveCalibration
  518. {
  519. }
  520. //else //ZSKK校正
  521. //{
  522. // if (!m_pZSKKCalib)
  523. // {
  524. // //mLog::FERROR("ZSKK Calibration object is undefined");
  525. // }
  526. // else
  527. // {
  528. // //加载ZSKK的校正文件
  529. // m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "/rawdata/";
  530. // m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "/references/";
  531. // m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth;
  532. // m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight;
  533. // m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds;
  534. // m_pZSKKCalib->m_nSaturationValue = 50000;
  535. // //LoadZSKKGainMap 参数为false,意思是开始增益校正
  536. // m_pZSKKCalib->LoadZSKKGainMap(false, m_strDetectorType);
  537. // m_pZSKKCalib->LoadZSKKPixelMap(false, m_strDetectorType);
  538. // //mLog::FINFO("Load ecom gain and pixel map, references file path: {$}", m_pZSKKCalib->m_strRefFilePath);
  539. // }
  540. //}
  541. }
  542. //mLog::FINFO("TiRayDR ActiveCalibration Over");
  543. return true;
  544. }
  545. /***
  546. * 接受曝光图像
  547. ***/
  548. bool Detector_TiRayDR::AcceptCalibration()
  549. {
  550. //mLog::FINFO("--TiRayDR Func-- AcceptCalibration Start");
  551. if (m_nCalibrationMode)//厂商校正AcceptCalibration
  552. {
  553. //不做处理
  554. }
  555. else //ZSKK校正
  556. {
  557. //WORD* pImageBuffer = nullptr;
  558. ////这里要注意使用的image buffer是哪个,裁剪和不裁剪是不一样的
  559. //if (m_nWidthOffset != 0 || m_nHeightOffset != 0)
  560. //{
  561. // pImageBuffer = m_pImgBuffer;
  562. //}
  563. //else
  564. //{
  565. // pImageBuffer = m_pImgBuffer;//之后再做区分,先测试用
  566. //}
  567. //if (m_nCalibCurrentExposureIndex == 1)
  568. //{
  569. // m_pZSKKCalib->AddImageToPixMap(pImageBuffer);
  570. // m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, true);
  571. //}
  572. //else
  573. //{
  574. // m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮
  575. //}
  576. }
  577. //mLog::FINFO("TiRayDR AcceptCalibration Over");
  578. return true;
  579. }
  580. /***
  581. * 拒绝曝光图像
  582. ***/
  583. bool Detector_TiRayDR::RejectCalibration()
  584. {
  585. const std::string funcTag = "[Detector_TiRayDR::RejectCalibration] ";
  586. // 检查当前是否在进行增益校正
  587. if (m_eCaliType != CCOS_CALIBRATION_TYPE_XRAY)
  588. {
  589. cout << funcTag << "No active gain calibration in progress" << endl;
  590. return false;
  591. }
  592. bool rejected = false;
  593. if (m_bUseGainV2)
  594. {
  595. if (!m_currentDoseImages.empty())
  596. {
  597. m_currentDoseImages.pop_back();
  598. cout << funcTag << "Rejected last image in dose group " << m_currentDoseIndex
  599. << ". Remaining in group: " << m_currentDoseImages.size() << endl;
  600. rejected = true;
  601. }
  602. else
  603. {
  604. cout << funcTag << "No images in current dose group to reject" << endl;
  605. }
  606. }
  607. else
  608. {
  609. if (!m_gainCalibImages.empty())
  610. {
  611. m_gainCalibImages.pop_back(); // 移除最后添加的图像
  612. cout << funcTag << "Rejected last gain image. Remaining: " << m_gainCalibImages.size() << endl;
  613. rejected = true;
  614. }
  615. else
  616. {
  617. cout << funcTag << "No gain images to reject" << endl;
  618. }
  619. }
  620. return rejected;
  621. }
  622. /***
  623. * 设置校正轮数
  624. ***/
  625. bool Detector_TiRayDR::SetCalibRounds(int nCalibRounds)
  626. {
  627. //mLog::FINFO("--TiRayDR Func-- SetCalibRounds Start");
  628. m_nCalibrationRounds = nCalibRounds;
  629. //mLog::FINFO("Set reference number: {$}", m_nCalibrationRounds);
  630. //mLog::FINFO("TiRayDR SetCalibRounds Over");
  631. return true;
  632. }
  633. bool Detector_TiRayDR::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound)
  634. {
  635. //mLog::FINFO("--TiRayDR Func-- GetCalibrationStep Start");
  636. m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound;
  637. m_nCalibrationRounds = nCalibrationRounds;
  638. m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex;
  639. m_nExposureNumCurrentRound = nExposureNumCurrentRound;
  640. //mLog::FINFO("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds,
  641. //nCalibCurrentExposureIndex, nExposureNumCurrentRound);
  642. //mLog::FINFO("TiRayDR GetCalibrationStep Over");
  643. return true;
  644. }
  645. bool Detector_TiRayDR::PrepareCalibration(FPDDeviceTiRay* pDrvDPC)
  646. {
  647. const std::string funcTag = "[Detector_TiRayDR::PrepareCalibration] ";
  648. std::cout << funcTag << "--TiRayDR Function-- PrepareCalibration started" << std::endl;
  649. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  650. {
  651. std::cout << funcTag << "Error: Not current DPC device, returning false" << std::endl;
  652. return false;
  653. }
  654. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  655. {
  656. std::cout << funcTag << "Error: Detector not connected (bConnectState is false), returning false" << std::endl;
  657. return false;
  658. }
  659. auto writeAttrWithLog = [this](const std::string& attrName, int value, int err) {
  660. if (err == Err_Success)
  661. {
  662. std::cout << "[Detector_TiRayDR::PrepareCalibration] Success: Wrote attribute " << attrName << " with value " << value << std::endl;
  663. }
  664. else
  665. {
  666. std::cout << "[Detector_TiRayDR::PrepareCalibration] Error: Failed to write attribute " << attrName << ", error code: " << err << std::endl;
  667. }
  668. return err;
  669. };
  670. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  671. {
  672. int ret = DarkAcquisition();
  673. std::cout << funcTag << "Info: DarkAcquisition returned " << ret << std::endl;
  674. if (!ret)
  675. {
  676. std::cout << funcTag << "Info: Sending calibration start status (EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_BEGIN)" << std::endl;
  677. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_BEGIN);
  678. }
  679. }
  680. else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
  681. {
  682. std::cout << funcTag << "Info: Preparing X-ray calibration (CCOS_CALIBRATION_TYPE_XRAY)" << std::endl;
  683. int err = write_attribute(Attr_WorkMode, WorkMode_FreeSync);
  684. writeAttrWithLog("Attr_WorkMode", WorkMode_FreeSync, err);
  685. err = write_attribute(Attr_PhotoInterval, 3000);
  686. writeAttrWithLog("Attr_PhotoInterval", 3000, err);
  687. err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
  688. writeAttrWithLog("Attr_CalibrationMode", CalibrationMode_None, err);
  689. }
  690. std::cout << funcTag << "Info: TiRayDR PrepareCalibration completed" << std::endl;
  691. return true;
  692. }
  693. //软同步调用接口,其它同步模式没有动作
  694. bool Detector_TiRayDR::StartCalibration(FPDDeviceTiRay* pDrvDPC)
  695. {
  696. //mLog::FINFO("--TiRayDR Func-- StartCalibration Start");
  697. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  698. {
  699. //mLog::FERROR("Not current DPC, return");
  700. return false;
  701. }
  702. //未初始化、未连接 不执行
  703. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  704. {
  705. //mLog::FERROR("bConnectState is false, Detector not connected, return");
  706. return false;
  707. }
  708. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  709. {
  710. //mLog::FINFO("StartCalibration DARK");
  711. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  712. m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Offset;
  713. }
  714. else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
  715. {
  716. //mLog::FINFO("StartCalibration XRAY");
  717. bool ret = StartAcquisition(pDrvDPC);
  718. if (!ret)
  719. {
  720. //mLog::FERROR("StartCalibration Over");
  721. return false;
  722. }
  723. m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_XrayCalibration;
  724. }
  725. //mLog::FINFO("TiRayDR StartCalibration Over");
  726. return true;
  727. }
  728. /***
  729. ** 说明:终止校正
  730. ***/
  731. RET_STATUS Detector_TiRayDR::AbortCalibration(FPDDeviceTiRay* pDrvDPC)
  732. {
  733. const std::string funcTag = "[Detector_TiRayDR::AbortCalibration] ";
  734. //mLog::FINFO("--TiRayDR Func-- AbortCalibration Start");
  735. if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY)
  736. {
  737. // 清除增益校正相关数据
  738. m_gainCalibImages.clear();
  739. m_currentDoseImages.clear();
  740. m_gainV2MeanImages.clear();
  741. m_currentDoseIndex = 0;
  742. cout << funcTag << "Aborted " << (!m_bUseGainV2 ? "Gain" : "GainV2")
  743. << " calibration. All related data cleared" << endl;
  744. }
  745. auto err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
  746. if (err == Err_Success)
  747. {
  748. std::cout << funcTag << "Success: Wrote attribute Attr_CalibrationMode with value CalibrationMode_Defect" << std::endl;
  749. }
  750. else
  751. {
  752. std::cout << funcTag << "Error: Failed to write attribute Attr_CalibrationMode, error code: " << err << std::endl;
  753. }
  754. // 恢复初始状态
  755. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
  756. m_nAppStatus = APP_STATUS_CAL_END;
  757. //mLog::FINFO("TiRayDR AbortCalibration Over");
  758. return RET_STATUS::RET_SUCCEED;
  759. }
  760. bool Detector_TiRayDR::StopCalibration(FPDDeviceTiRay* pDrvDPC)
  761. {
  762. //mLog::FINFO("--TiRayDR Func-- StopCalibration Start");
  763. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  764. {
  765. //mLog::FERROR("Not current DPC, return");
  766. return false;
  767. }
  768. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  769. {
  770. //mLog::FERROR("bConnectState is false, Detector not connected, return");
  771. return false;
  772. }
  773. m_nAppStatus = APP_STATUS_CAL_END;
  774. //mLog::FINFO("TiRayDR StopCalibration Over");
  775. return true;
  776. }
  777. /***
  778. ** 说明:结束校正
  779. ** DPC处理完校正报告后调用,此处上传map、报告等文件
  780. ***/
  781. bool Detector_TiRayDR::CompleteCalibration(FPDDeviceTiRay* pDrvDPC)
  782. {
  783. //mLog::FINFO("--TiRayDR Func-- CompleteCalibration Start");
  784. //mLog::FINFO("Calib Type {$}", (int)m_eCaliType);
  785. const std::string funcTag = "[Detector_TiRayDR::CompleteCalibration] ";
  786. if (m_eCaliType == CCOS_CALIBRATION_TYPE_DARK)
  787. {
  788. //mLog::FINFO("DARK Calib over");
  789. }
  790. else if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY)
  791. {
  792. //mLog::FINFO("XRAY Calib over");
  793. m_nAppStatus = APP_STATUS_CAL_END;
  794. }
  795. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
  796. auto err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
  797. if (err == Err_Success)
  798. {
  799. std::cout << funcTag << "Success: Wrote attribute Attr_CalibrationMode with value CalibrationMode_Defect" << std::endl;
  800. }
  801. else
  802. {
  803. std::cout << funcTag << "Error: Failed to write attribute Attr_CalibrationMode, error code: " << err << std::endl;
  804. }
  805. //mLog::FINFO("TiRayDR CompleteCalibration Over");
  806. return true;
  807. }
  808. bool Detector_TiRayDR::SaveCalibrationFile()
  809. {
  810. //mLog::FINFO("--TiRayDR Func-- SaveCalibrationFile Start");
  811. if (m_nCalibrationMode)//厂商校正
  812. {
  813. //不做处理
  814. }
  815. else
  816. {
  817. //mLog::FINFO("Save ZSKK Calibration File");
  818. m_pZSKKCalib->StoreZSKKGainMap(m_strDetectorType);
  819. m_pZSKKCalib->StoreZSKKPixMap(m_strDetectorType);
  820. }
  821. //更新配置文件中校正日期和时间
  822. GlobalTime stCurrentTime = { 0 };
  823. GetLocalTime(&stCurrentTime);
  824. //mLog::FINFO("Current time: {$04d}/{$02d}/{$02d} {$02d}:{$02d}:{$02d}:{$03d}",
  825. //stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay,
  826. //stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds);
  827. //mLog::FINFO("TiRayDR SaveCalibrationFile Over");
  828. return true;
  829. }
  830. CCOS_CALIBRATION_TYPE Detector_TiRayDR::GetCalibType()
  831. {
  832. //mLog::FINFO("--TiRayDR Func-- GetCalibType Start");
  833. //mLog::FINFO("Get Calib Type {$}", (int)m_eCaliType);
  834. //mLog::FINFO("TiRayDR GetCalibType Over");
  835. return m_eCaliType;
  836. }
  837. ModelResolveResult Detector_TiRayDR::ResolveModelType(const std::string& detectorType)
  838. {
  839. ModelResolveResult result;
  840. result.isValid = true;
  841. if (detectorType == "TiRay_GQ1613") {
  842. result.model = Model_GQ1613;
  843. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_GQ1613)..." << endl;
  844. }
  845. else if (detectorType == "TiRay_DY1613") {
  846. result.model = Model_DY1613;
  847. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY1613)..." << endl;
  848. }
  849. else if (detectorType == "TiRay_LT1719") {
  850. result.model = Model_LT1719;
  851. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_LT1719)..." << endl;
  852. }
  853. else if (detectorType == "TiRay_DY4343") {
  854. result.model = Model_DY4343;
  855. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343)..." << endl;
  856. }
  857. else if (detectorType == "TiRay_DY2530W") {
  858. result.model = Model_DY2530W;
  859. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY2530W)..." << endl;
  860. }
  861. else if (detectorType == "TiRay_DY2121") {
  862. result.model = Model_DY2121;
  863. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY2121)..." << endl;
  864. }
  865. else if (detectorType == "TiRay_DY4343D") {
  866. result.model = Model_DY4343D;
  867. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343D)..." << endl;
  868. }
  869. else if (detectorType == "TiRay_GZ0404") {
  870. result.model = Model_GZ0404;
  871. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_GZ0404)..." << endl;
  872. }
  873. else if (detectorType == "TiRay_DY3543W") {
  874. result.model = Model_DY3543W;
  875. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY3543W)..." << endl;
  876. }
  877. else if (detectorType == "TiRay_DY4343W") {
  878. result.model = Model_DY4343W;
  879. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343W)..." << endl;
  880. }
  881. else if (detectorType == "TiRay_DY3543") {
  882. result.model = Model_DY3543;
  883. cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY3543)..." << endl;
  884. }
  885. else {
  886. cout << "[Detector_TiRayDR::OpenDetector] Unsupported detector type: " << detectorType << endl;
  887. // 使用第一个枚举值作为默认,通过isValid标志判断有效性
  888. result.model = Model_GQ1613;
  889. result.isValid = false;
  890. }
  891. return result;
  892. }
  893. bool Detector_TiRayDR::LoadDll(string strWorkPath)
  894. {
  895. //mLog::FINFO("--TiRayDR Func-- LoadDll Start");
  896. string strSDKPath = "";
  897. try
  898. {
  899. strSDKPath = (string)m_ModeConfig["SDKPath"];
  900. }
  901. catch (ResDataObjectExption& e)
  902. {
  903. //mLog::FERROR("Read configuration failed! reason: {$}", e.what());
  904. return false;
  905. }
  906. string workpath = strWorkPath + strSDKPath;
  907. string drvpath = workpath + "/TiRayLib.so";
  908. //mLog::FINFO("SDK path:{$}", drvpath);
  909. m_hTiRayDRModule = dlopen(drvpath.c_str(), RTLD_LAZY);
  910. if (m_hTiRayDRModule == nullptr)
  911. {
  912. //mLog::FERROR("Load {$} failed! FERROR: {$}", drvpath.c_str(), dlerror());
  913. return false;
  914. }
  915. LOAD_ONE_FUNC(m_hTiRayDRModule, GetSdkVersion);
  916. LOAD_ONE_FUNC(m_hTiRayDRModule, Scan);
  917. LOAD_ONE_FUNC(m_hTiRayDRModule, SetIp);
  918. LOAD_ONE_FUNC(m_hTiRayDRModule, Startup);
  919. LOAD_ONE_FUNC(m_hTiRayDRModule, Stop);
  920. LOAD_ONE_FUNC(m_hTiRayDRModule, Execute);
  921. LOAD_ONE_FUNC(m_hTiRayDRModule, ApplyPreset);
  922. LOAD_ONE_FUNC(m_hTiRayDRModule, GenerateTemplate);
  923. //mLog::FINFO("TiRayDR LoadDll Over");
  924. return true;
  925. }
  926. bool Detector_TiRayDR::ReleaseDll()
  927. {
  928. //mLog::FINFO("--TiRayDR Func-- ReleaseDll Start");
  929. if (m_hTiRayDRModule != nullptr)
  930. {
  931. int result = dlclose(m_hTiRayDRModule);
  932. if (result != 0) {
  933. const char* error = dlerror();
  934. if (error) {
  935. //mLog::FERROR("Failed to unload library: %s", error);
  936. }
  937. else {
  938. //mLog::FERROR("Failed to unload library (unknown error)");
  939. }
  940. return false;
  941. }
  942. m_hTiRayDRModule = nullptr;
  943. }
  944. //mLog::FINFO("TiRayDR ReleaseDll Over");
  945. return true;
  946. }
  947. /***
  948. ** 连接探测器
  949. ***/
  950. bool Detector_TiRayDR::OpenDetector()
  951. {
  952. cout << "[Detector_TiRayDR::OpenDetector] Start executing the detector connection..." << endl;
  953. //mLog::FINFO("--TiRayDR Func-- OpenDetector Start");
  954. // 检查连接状态
  955. bool wired = CheckConnect(m_strWiredIP);
  956. bool wireless = CheckConnect(m_strWirelessIP);
  957. cout << "[Detector_TiRayDR::OpenDetector] Connection status - Wired:" << (wired ? "Connected" : "Not connected")
  958. << ", wireless:" << (wireless ? "Connected" : "Not Connected") << endl;
  959. cout << "[Detector_TiRayDR::OpenDetector] Start scanning the detector..." << endl;
  960. std::vector<scan_result> scan_results;
  961. scan([&scan_results](scan_result&& result) {
  962. scan_results.emplace_back(std::move(result));
  963. });
  964. if (scan_results.empty()) {
  965. cout << "[Detector_TiRayDR::OpenDetector] No detectors were found!" << endl;
  966. return false;
  967. }
  968. cout << "[Detector_TiRayDR::OpenDetector] Scanned to" << scan_results.size() << " detector:" << endl;
  969. for (auto& res : scan_results) {
  970. cout << "[Detector_TiRayDR::OpenDetector] Serial number:" << res.sn
  971. << ", Model:" << res.model
  972. << ", tupper IP:" << res.upper_ip
  973. << ", detector IP:" << res.detector_ip << endl;
  974. }
  975. m_strDetectorType = (string)m_ModeConfig["DeviceName"];
  976. // 初始化启动参数
  977. string ip = "0.0.0.0";
  978. StartupOption option{};
  979. memcpy(option.Ip, ip.c_str(), std::min(ip.size(), sizeof(option.Ip) - 1));
  980. option.EnableLog = true;
  981. // 调用解析函数处理设备类型
  982. ModelResolveResult resolveResult = ResolveModelType(m_strDetectorType);
  983. if (!resolveResult.isValid) {
  984. return false;
  985. }
  986. // 启动探测器
  987. auto err = Startup_Ptr(resolveResult.model, on_event_callback, &option);
  988. if (err != Err_Success) {
  989. cout << "[Detector_TiRayDR::OpenDetector] Failed to start the detector" << endl;
  990. return false;
  991. }
  992. auto LoadCalibrationFile = [this](int calibrationParam)
  993. {
  994. TiRayError err;
  995. switch (calibrationParam) {
  996. case 1:
  997. err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
  998. break;
  999. case 2:
  1000. err = write_attribute(Attr_CalibrationMode, CalibrationMode_Gain);
  1001. break;
  1002. case 3:
  1003. err = write_attribute(Attr_CalibrationMode, CalibrationMode_Offset);
  1004. break;
  1005. case 4:
  1006. err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
  1007. break;
  1008. default:
  1009. cout << "[Detector_TiRayDR::OpenDetector] Invalid calibration parameter: " << calibrationParam << endl;
  1010. return false;
  1011. }
  1012. if (err != Err_Success) {
  1013. cout << "[Detector_TiRayDR::OpenDetector] Failed to write Attr_CalibrationMode, error code: " << err << endl;
  1014. }
  1015. else {
  1016. cout << "[Detector_TiRayDR::OpenDetector] Succeeded in writing Attr_CalibrationMode" << endl;
  1017. }
  1018. return true;
  1019. };
  1020. m_strWiredIP = (std::string)m_ModeConfig["DetectorWiredIP"];
  1021. m_strWirelessIP = (std::string)m_ModeConfig["DetectorWirelessIP"];
  1022. m_strLocalIP = (std::string)m_ModeConfig["LocalIP"];
  1023. m_strSerialNum = (std::string)m_ModeConfig["SerialNumber"];
  1024. cout << "[Detector_TiRayDR::OpenDetector] Configuration parameters loaded - Wired IP:" << m_strWiredIP
  1025. << ", Wireless IP:" << m_strWirelessIP << ", Local IP:" << m_strLocalIP << endl;
  1026. //mLog::FINFO("WiredIP: {$}, LocalIP: {$}, WirelessIP: {$}, SerialNumber:{$}", m_strWiredIP, m_strLocalIP, m_strWirelessIP, m_strSerialNum);
  1027. cout << "[Detector_TiRayDR::OpenDetector] Start setting the IP address..." << endl;
  1028. err = SetIp_Ptr(m_strSerialNum.c_str(), m_strLocalIP.c_str(), m_strWiredIP.c_str(), nullptr);
  1029. if (err != TiRayError::Err_Success)
  1030. {
  1031. cout << "[Detector_TiRayDR::OpenDetector] The IP setting failed, error code:" << err << " (will continue to execute)" << endl;
  1032. }
  1033. else {
  1034. cout << "[Detector_TiRayDR::OpenDetector] IP setting was successful" << endl;
  1035. }
  1036. while (!m_bConnected)
  1037. {
  1038. usleep(10000);
  1039. }
  1040. m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true;
  1041. ////mLog::FINFO("m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true");
  1042. //StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
  1043. ////mLog::FINFO("Connect detector({$}) success", m_nDetectorID);
  1044. if (m_strDetectorType == "TiRay_DY4343" || m_strDetectorType == "TiRay_DY4343D")
  1045. {
  1046. m_bUseGainV2 = true;
  1047. }
  1048. m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"];
  1049. m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"];
  1050. m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][0]["RawImgWidth"];
  1051. m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][0]["RawImgHeight"];
  1052. //mLog::FINFO("After crop image width: {$}, height: {$}, WidthOffset: {$}, HeightOffset: {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
  1053. m_bSaveRaw = (int)m_ModeConfig["ModeTable"][0]["IsSaveRaw"];
  1054. if (m_pRawImgBuffer == nullptr)
  1055. {
  1056. m_pRawImgBuffer = new WORD[(size_t)m_nRawImgHeight * (size_t)m_nRawImgWidth];
  1057. }
  1058. if (true)
  1059. {
  1060. m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageWidth];
  1061. }
  1062. // 加载校准文件
  1063. cout << "[Detector_TiRayDR::OpenDetector] Start loading the calibration file..." << endl;
  1064. //if (m_nCalibrationMode) //TiRayCalibration
  1065. SetSyncMode(3);
  1066. err = write_attribute(Attr_PhotoInterval, 3000);
  1067. if (err != Err_Success)
  1068. cout << "[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoInterval. Error code: " << err << endl;
  1069. err = write_attribute(Attr_PhotoNumber, 1);
  1070. if (err != Err_Success)
  1071. cout << "[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: " << err << endl;
  1072. LoadCalibrationFile(4);
  1073. printf("read detector attributes......\n");
  1074. /*auto [err1, work_mode] = read_attribute<int>(Attr_WorkMode);
  1075. if (err1 != Err_Success)
  1076. std::cout << "read Attr_WorkMode failed with error = " << err1 << std::endl;
  1077. else
  1078. std::cout << "read Attr_WorkMode " << work_mode << std::endl;
  1079. auto [err2, photo_interval] = read_attribute<int>(Attr_PhotoInterval);
  1080. if (err2 != Err_Success)
  1081. std::cout << "read Attr_PhotoInterval failed with error = " << err2 << std::endl;
  1082. else
  1083. std::cout << "read Attr_PhotoInterval " << photo_interval << std::endl;
  1084. auto [err3, photo_number] = read_attribute<int>(Attr_PhotoNumber);
  1085. if (err3 != Err_Success)
  1086. std::cout << "read Attr_PhotoNumber failed with error = " << err3 << std::endl;
  1087. else
  1088. std::cout << "read Attr_PhotoNumber " << photo_number << std::endl;
  1089. auto [err4, calibration_mode] = read_attribute<int>(Attr_CalibrationMode);
  1090. if (err4 != Err_Success)
  1091. std::cout << "read Attr_CalibrationMode failed with error = " << err4 << std::endl;
  1092. else
  1093. std::cout << "read Attr_CalibrationMode " << calibration_mode << std::endl;*/
  1094. //else
  1095. //{
  1096. // LoadCalibrationFile(3);
  1097. // //mLog::Info("Load ZSKK Reference file");
  1098. // m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "/rawdata/";
  1099. // m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "/references/";
  1100. // //读取配置文件中RAD模式的高和宽
  1101. // m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth;
  1102. // m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight;
  1103. // m_pZSKKCalib->m_nSaturationValue = 50000;
  1104. // if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strDetectorType))
  1105. // {
  1106. // //mLog::Warn("Load ZSKK Gain calibration failed");
  1107. // }
  1108. // if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_strDetectorType))
  1109. // {
  1110. // //mLog::Warn("Load ZSKK Defect calibration failed");
  1111. // }
  1112. //}
  1113. SetTiRayDPCStatus(eDetStatus::DetStatus_Standby);
  1114. //mLog::FINFO("OpenDetector Over");
  1115. return true;
  1116. }
  1117. bool Detector_TiRayDR::CheckConnect(string strIP)
  1118. {
  1119. CMyPingip obPingIp;
  1120. if (!obPingIp.PingFunction(strIP.c_str()))
  1121. {
  1122. //mLog::FINFO("ping {$} Failed", strIP);
  1123. return false;
  1124. }
  1125. return true;
  1126. }
  1127. bool Detector_TiRayDR::OpenStatusMonitor()
  1128. {
  1129. //mLog::FINFO("---Open Status Monitor Thread---");
  1130. if (m_hStatusMonitorThread == 0) // 检查线程是否已创建
  1131. {
  1132. int result = pthread_create(&m_hStatusMonitorThread, NULL, TiRayStatusMonitorThread, this);
  1133. if (result != 0) {
  1134. //mLog::FERROR("Failed to create status monitor thread: %d", result);
  1135. return false;
  1136. }
  1137. }
  1138. return true;
  1139. }
  1140. void* Detector_TiRayDR::TiRayStatusMonitorThread(PVOID pvoid)
  1141. {
  1142. Detector_TiRayDR* pCurrentPanelOpr = static_cast<Detector_TiRayDR*>(pvoid);
  1143. if (pCurrentPanelOpr == nullptr)
  1144. {
  1145. //mLog::FERROR("TiRay Status Monitor parameter FERROR");
  1146. return nullptr;
  1147. }
  1148. //mLog::FINFO("Begin StatusMonitor");
  1149. DWORD dwStatusCheckTime = 5000;
  1150. while (!pCurrentPanelOpr->m_bMonitorFlag)
  1151. {
  1152. pCurrentPanelOpr->StatusMonitor();
  1153. usleep(pCurrentPanelOpr->m_nNotifyStatusTimePeriod*1000);
  1154. }
  1155. return 0;
  1156. }
  1157. bool Detector_TiRayDR::StatusMonitor()
  1158. {
  1159. if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
  1160. {
  1161. //mLog::FERROR("Detector not connected, return");
  1162. ErrorFeedback(EVT_ERR_COMMUNICATE, "true");
  1163. return false;
  1164. }
  1165. //StatusType: 1:Temperature 2:Wifi 3:Battery
  1166. //auto ReadStatus = [this](int StatusType)
  1167. //{
  1168. // TiRayVariant TempParam[1]{};
  1169. // TempParam[0].Type = TiRayVariant::TiRayInt;
  1170. //};
  1171. int nTemperature = 0;
  1172. int nWifiQuality = 0;
  1173. int nBatteryLevel = 0;
  1174. TiRayVariant TemperatureParam[1]{};
  1175. TemperatureParam[0].Type = TiRayVariant::TiRayInt;
  1176. TemperatureParam[0].IntValue = 0;
  1177. Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, TemperatureParam, 1);
  1178. nTemperature = TemperatureParam[0].IntValue;
  1179. TiRayVariant WifiParam[1]{};
  1180. WifiParam[0].Type = TiRayVariant::TiRayInt;
  1181. WifiParam[0].IntValue = nWifiQuality;
  1182. Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, WifiParam, 1);
  1183. TiRayVariant BatteryParam[1]{};
  1184. BatteryParam[0].Type = TiRayVariant::TiRayInt;
  1185. BatteryParam[0].IntValue = nBatteryLevel;
  1186. Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, BatteryParam, 1);
  1187. StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nCurrentPanelID, nTemperature);
  1188. StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryLevel, "", m_nCurrentPanelID);
  1189. StatusFeedback(EVT_STATUS_WIFI, nWifiQuality, "", m_nCurrentPanelID);
  1190. return true;
  1191. }
  1192. bool Detector_TiRayDR::CloseStatusMonitor()
  1193. {
  1194. m_bMonitorFlag = true;
  1195. m_hStatusMonitorThread = 0;
  1196. //mLog::FINFO("---Close Status Monitor Thread---");
  1197. return true;
  1198. }
  1199. bool Detector_TiRayDR::CloseDetectorScan()
  1200. {
  1201. m_hExitEvent->SetEvent();
  1202. return false;
  1203. }
  1204. bool Detector_TiRayDR::LoadCalibrationFiles(int nCalibrationMode)
  1205. {
  1206. //mLog::FINFO("--TiRayDR Func-- LoadCalibrationFiles");
  1207. int nRes;
  1208. TiRayVariant Param[2]{};
  1209. Param[0].Type = TiRayVariant::TiRayInt;
  1210. Param[0].IntValue = TiRayAttribute::Attr_CalibrationMode;
  1211. Param[1].Type = TiRayVariant::TiRayInt;
  1212. if (nCalibrationMode == 1)
  1213. {
  1214. Param[1].IntValue = CalibrationMode::CalibrationMode_None;
  1215. }
  1216. else if (nCalibrationMode == 2)
  1217. {
  1218. Param[1].IntValue = CalibrationMode::CalibrationMode_Gain;
  1219. }
  1220. else if (nCalibrationMode == 3)
  1221. {
  1222. Param[1].IntValue = CalibrationMode::CalibrationMode_Offset;
  1223. }
  1224. else if (nCalibrationMode == 4)
  1225. {
  1226. Param[1].IntValue = CalibrationMode::CalibrationMode_Defect;
  1227. //mLog::FINFO("All Calibration Mode");
  1228. }
  1229. nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
  1230. if ((TiRayError)nRes != TiRayError::Err_Success)
  1231. {
  1232. //mLog::Error("Use CalibrationMode Failed, Reason:{$}", nRes);
  1233. return false;
  1234. }
  1235. else
  1236. {
  1237. //mLog::FINFO("Use CalibrationMode Success");
  1238. }
  1239. //mLog::FINFO("LoadCalibrationFiles Over");
  1240. return true;
  1241. }
  1242. void* Detector_TiRayDR::onFPDScanThread(PVOID pvoid)
  1243. {
  1244. Detector_TiRayDR* pOpr = (Detector_TiRayDR*)pvoid;
  1245. //mLog::FINFO("Enter scan thread");
  1246. bool bExit = false;
  1247. DWORD dwTimeOut = INFINITE;
  1248. while (!bExit)
  1249. {
  1250. DWORD dwRet = LinuxEvent::WaitForMultipleEvents(pOpr->m_hArrayEvent,dwTimeOut);
  1251. if (WAIT_OBJECT_0 == dwRet) //m_hInitEvent
  1252. {
  1253. pOpr->OnProcessInitFPD();
  1254. }
  1255. else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hExitEvent
  1256. {
  1257. bExit = true;
  1258. }
  1259. else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hReConnectEvent
  1260. {
  1261. pOpr->OnReconnectFPD();
  1262. }
  1263. else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hRadEvent
  1264. {
  1265. //mLog::FINFO("[Get Rad Event]");
  1266. pOpr->OpenRadAcquisition();
  1267. }
  1268. else if (WAIT_TIMEOUT == dwRet)
  1269. {
  1270. }
  1271. }
  1272. pOpr->m_hToggleEvent->SetEvent();
  1273. //mLog::FINFO("Leave scan thread");
  1274. return 0;
  1275. }
  1276. void Detector_TiRayDR::OnProcessInitFPD()
  1277. {
  1278. //mLog::FINFO("--TiRayDR Func-- OnProcessInitFPD");
  1279. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START);
  1280. if (!LoadDll(m_strWorkPath))
  1281. {
  1282. ErrorFeedback(EVT_ERR_INIT_FAILED, "true");
  1283. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR); //初始化失败
  1284. return;
  1285. }
  1286. register_event_listener(OnEvent);
  1287. //mLog::FINFO("Register Event Listener");
  1288. if (!OpenDetector())
  1289. {
  1290. //mLog::FINFO("Open detector failed, Connect failed");
  1291. ErrorFeedback(EVT_ERR_COMMUNICATE, "true");
  1292. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END); //初始化时连接失败
  1293. }
  1294. else
  1295. {
  1296. m_pStPanelStatus[m_nCurrentPanelID]->bInitOver = true;
  1297. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK);
  1298. }
  1299. //mLog::FINFO("OnProcessInitFPD Over");
  1300. }
  1301. void Detector_TiRayDR::OnReconnectFPD()
  1302. {
  1303. //mLog::FINFO("OnReconnectFPD start");
  1304. if (m_hReconnectThread == 0)
  1305. {
  1306. m_bReconnectThreadRunning = true;
  1307. int result = pthread_create(&m_hReconnectThread, NULL, onReconnectThread, this);
  1308. if (result != 0) {
  1309. //mLog::FERROR("Failed to create reconnect thread: %d", result);
  1310. m_hReconnectThread = 0;
  1311. m_bReconnectThreadRunning = false;
  1312. }
  1313. }
  1314. //mLog::FINFO("OnReconnectFPD end");
  1315. }
  1316. /***
  1317. ** 获取一帧暗场图
  1318. ***/
  1319. int Detector_TiRayDR::DarkAcquisition()
  1320. {
  1321. const std::string funcTag = "[Detector_TiRayDR::DarkAcquisition] ";
  1322. TiRayError err;
  1323. // 设置校准模式为None
  1324. err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
  1325. if (err != Err_Success) {
  1326. cout << funcTag << "Failed to write Attr_CalibrationMode. Error code: " << err << endl;
  1327. return -1;
  1328. }
  1329. // 设置拍摄间隔
  1330. err = write_attribute(Attr_PhotoInterval, 1000);
  1331. if (err != Err_Success) {
  1332. cout << funcTag << "Failed to write Attr_PhotoInterval. Error code: " << err << endl;
  1333. return -1;
  1334. }
  1335. // 设置工作模式为空闲
  1336. err = write_attribute(Attr_WorkMode, WorkMode_Idle);
  1337. if (err != Err_Success) {
  1338. cout << funcTag << "Failed to write Attr_WorkMode. Error code: " << err << endl;
  1339. return -1;
  1340. }
  1341. // 执行拍摄命令
  1342. err = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
  1343. if (err != Err_Success) {
  1344. cout << funcTag << "Failed to Execute_Ptr Cmd_Photo. Error code: " << err << endl;
  1345. return -1;
  1346. }
  1347. return 0; // 成功执行返回0
  1348. }
  1349. /***
  1350. ** 裁剪图像
  1351. ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
  1352. ***/
  1353. bool Detector_TiRayDR::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
  1354. {
  1355. if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
  1356. {
  1357. //mLog::FERROR("Illegal parameter, can not get effective image");
  1358. return false;
  1359. }
  1360. try
  1361. {
  1362. for (int i = 0; i < m_nImageHeight; i++)
  1363. {
  1364. memcpy(pOutImg + i * m_nImageWidth, pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset, m_nImageWidth * sizeof(WORD));
  1365. }
  1366. }
  1367. catch (...)
  1368. {
  1369. //mLog::FERROR("Get effective image crashed");
  1370. return false;
  1371. }
  1372. return true;
  1373. }
  1374. Detector_TiRayDR::eDetStatus Detector_TiRayDR::GetTiRayDPCStatus(int nDetectorIndex)
  1375. {
  1376. if (-1 == nDetectorIndex)
  1377. {
  1378. nDetectorIndex = m_nCurrentPanelID;
  1379. }
  1380. string strStatus = "Unknown";
  1381. switch (m_pStPanelStatus[nDetectorIndex]->eFPDStatus)
  1382. {
  1383. case eDetStatus::DetStatus_NotIni:
  1384. strStatus = "NotIni";
  1385. break;
  1386. case eDetStatus::DetStatus_NotConn:
  1387. strStatus = "NotConn";
  1388. break;
  1389. case eDetStatus::DetStatus_Sleep:
  1390. strStatus = "Sleep";
  1391. break;
  1392. case eDetStatus::DetStatus_Standby:
  1393. strStatus = "Standby";
  1394. break;
  1395. case eDetStatus::DetStatus_Work:
  1396. strStatus = "Work";
  1397. break;
  1398. case eDetStatus::DetStatus_Acquire:
  1399. strStatus = "Acquire";
  1400. break;
  1401. case eDetStatus::DetStatus_Offset:
  1402. strStatus = "Offset";
  1403. break;
  1404. case eDetStatus::DetStatus_XrayCalibration:
  1405. strStatus = "XrayCalibration";
  1406. break;
  1407. default:
  1408. break;
  1409. }
  1410. //mLog::FINFO("Driver status: {$}", strStatus.c_str());
  1411. return m_pStPanelStatus[nDetectorIndex]->eFPDStatus;
  1412. }
  1413. bool Detector_TiRayDR::SetTiRayDPCStatus(eDetStatus status, int nDetectorIndex)
  1414. {
  1415. if (-1 == nDetectorIndex)
  1416. {
  1417. nDetectorIndex = m_nCurrentPanelID;
  1418. }
  1419. string strStatus = "Unknown";
  1420. bool bSetStatus = true;
  1421. switch (status)
  1422. {
  1423. case eDetStatus::DetStatus_NotIni:
  1424. strStatus = "NotIni";
  1425. break;
  1426. case eDetStatus::DetStatus_NotConn:
  1427. strStatus = "NotConn";
  1428. break;
  1429. case eDetStatus::DetStatus_Sleep:
  1430. strStatus = "Sleep";
  1431. break;
  1432. case eDetStatus::DetStatus_Standby:
  1433. strStatus = "Standby";
  1434. break;
  1435. case eDetStatus::DetStatus_Work:
  1436. strStatus = "Work";
  1437. break;
  1438. case eDetStatus::DetStatus_Acquire:
  1439. strStatus = "Acquire";
  1440. break;
  1441. case eDetStatus::DetStatus_Offset:
  1442. strStatus = "Offset";
  1443. break;
  1444. case eDetStatus::DetStatus_XrayCalibration:
  1445. strStatus = "XrayCalibration";
  1446. break;
  1447. default:
  1448. bSetStatus = false;
  1449. break;
  1450. }
  1451. if (bSetStatus)
  1452. {
  1453. m_pStPanelStatus[nDetectorIndex]->eFPDStatus = status;
  1454. //mLog::FINFO("Set driver status: {$}", strStatus.c_str());
  1455. }
  1456. else
  1457. {
  1458. //mLog::FERROR("{$} {$} is a illegal status", strStatus, (int)status);
  1459. }
  1460. return bSetStatus;
  1461. }
  1462. bool Detector_TiRayDR::IsConnected(string strIP)
  1463. {
  1464. //mLog::FINFO("Check ping {$}", strIP);
  1465. CMyPingip obPingIp;
  1466. if (!obPingIp.PingFunction(strIP.c_str()))
  1467. {
  1468. //mLog::FINFO("ping {$} Failed", strIP);
  1469. return false;
  1470. }
  1471. return true;
  1472. }
  1473. bool Detector_TiRayDR::CheckConnection()
  1474. {
  1475. return false;
  1476. }
  1477. bool Detector_TiRayDR::ReConnectFPD()
  1478. {
  1479. CloseStatusMonitor();
  1480. return true;
  1481. }
  1482. bool Detector_TiRayDR::OpenRadAcquisition()
  1483. {
  1484. //mLog::FINFO("---Begin Rad Acquisition Thread---");
  1485. m_bExitRadAcqStatus = true;
  1486. if (m_hRadAcquisitionThread == 0)
  1487. {
  1488. int result = pthread_create(&m_hRadAcquisitionThread, NULL, RadAcquisitionThread, this);
  1489. if (result != 0) {
  1490. //mLog::FERROR("Failed to create status monitor thread: %d", result);
  1491. return false;
  1492. }
  1493. }
  1494. return true;
  1495. }
  1496. void* Detector_TiRayDR::RadAcquisitionThread(void* pParam)
  1497. {
  1498. Detector_TiRayDR* pCurrentPanelOpr = reinterpret_cast<Detector_TiRayDR*>(pParam);
  1499. if (pCurrentPanelOpr == nullptr)
  1500. {
  1501. //mLog::FERROR("Query Acq Status Thread parameter FERROR");
  1502. }
  1503. pCurrentPanelOpr->PerformRadAcquisition();
  1504. pCurrentPanelOpr->CloseRadAcquisition();
  1505. return nullptr;
  1506. }
  1507. bool Detector_TiRayDR::PerformRadAcquisition()
  1508. {
  1509. //mLog::FINFO("## PerformRadAcquisition ##");
  1510. //mLog::FINFO("Start Acquisition");
  1511. //mLog::FINFO("DetectorID: {$}", m_nDetectorID);
  1512. //int nRes = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
  1513. //if ((TiRayError)nRes != TiRayError::Err_Success)
  1514. //{
  1515. // //mLog::FERROR("Start Acquisition Failed");
  1516. //}
  1517. while (true)
  1518. {
  1519. usleep(100000);
  1520. if (!m_bExitRadAcqStatus)
  1521. {
  1522. break;
  1523. }
  1524. }
  1525. m_hExitRadAcqStatus->SetEvent();
  1526. //mLog::FINFO("PerformRadAcquisition Over");
  1527. return true;
  1528. }
  1529. bool Detector_TiRayDR::CloseRadAcquisition()
  1530. {
  1531. m_bExitRadAcqStatus = false;
  1532. bool dwResult = false;
  1533. if (m_hExitRadAcqStatus) {
  1534. dwResult = m_hExitRadAcqStatus->Wait(1000);
  1535. }
  1536. if (dwResult)
  1537. {
  1538. //mLog::FINFO("[Get ExitRadAcqStatus Event]");
  1539. }
  1540. else
  1541. {
  1542. if (m_hRadAcquisitionThread != 0) {
  1543. pthread_cancel(m_hRadAcquisitionThread);
  1544. // 等待线程实际退出
  1545. struct timespec ts;
  1546. clock_gettime(CLOCK_REALTIME, &ts);
  1547. ts.tv_sec += 1; // 等待1秒
  1548. pthread_timedjoin_np(m_hRadAcquisitionThread, nullptr, &ts);
  1549. //mLog::FWARN("Kill QueryAcqStatus Thread");
  1550. }
  1551. //mLog::FWARN("Kill QueryAcqStatus Thread");
  1552. }
  1553. m_hRadAcquisitionThread = 0;
  1554. //mLog::FINFO("---Exit Rad Acq Status Thread---");
  1555. return true;
  1556. }
  1557. /***
  1558. ** 检测接口是否有错误,true:有错;false:没错
  1559. ***/
  1560. bool Detector_TiRayDR::TestError(TiRayError nErrorCode)
  1561. {
  1562. if (nErrorCode == TiRayError::Err_Success)
  1563. {
  1564. return true;
  1565. }
  1566. else
  1567. {
  1568. switch (nErrorCode)
  1569. {
  1570. case TiRayError::Err_SystemFailure:
  1571. {
  1572. //mLog::FERROR("System Internal Error");
  1573. break;
  1574. }
  1575. case TiRayError::Err_WrongModel:
  1576. {
  1577. //mLog::FERROR("The specified model is incorrect");
  1578. break;
  1579. }
  1580. case TiRayError::Err_DetectorNonExists:
  1581. {
  1582. //mLog::FERROR("The specified detector with the given ID dose not exist");
  1583. break;
  1584. }
  1585. case TiRayError::Err_NetworkFailure:
  1586. {
  1587. //mLog::FERROR("The network communication has failed");
  1588. break;
  1589. }
  1590. case TiRayError::Err_InvalidParam:
  1591. {
  1592. //mLog::FERROR("The provided parameters are incorrect");
  1593. break;
  1594. }
  1595. case TiRayError::Err_UploadInProgress:
  1596. {
  1597. //mLog::FERROR("The upload is in progress");
  1598. break;
  1599. }
  1600. default:
  1601. //mLog::FERROR("Unkonwn Error");
  1602. break;
  1603. }
  1604. return false;
  1605. }
  1606. }
  1607. void Detector_TiRayDR::register_event_listener(const EventListener& fn)
  1608. {
  1609. const auto iter = std::find_if(m_listeners.begin(), m_listeners.end(), [&fn](auto& listener) {
  1610. return listener.template target<EventListenerType>() == fn.template target<EventListenerType>();
  1611. });
  1612. if (iter == m_listeners.end())
  1613. m_listeners.push_back(fn);
  1614. }
  1615. void Detector_TiRayDR::unregister_event_listener(const EventListener& fn)
  1616. {
  1617. const auto iter = std::find_if(m_listeners.begin(), m_listeners.end(), [&fn](auto& listener) {
  1618. return listener.template target<EventListenerType>() == fn.template target<EventListenerType>();
  1619. });
  1620. if (iter == m_listeners.end())
  1621. m_listeners.erase(iter);
  1622. }
  1623. bool Detector_TiRayDR::cropImage(unsigned short* srcData, int srcWidth, int srcHeight,
  1624. unsigned short* destData, int destWidth, int destHeight)
  1625. {
  1626. // 验证指针有效性
  1627. if (srcData == nullptr || destData == nullptr) {
  1628. cout << "[Detector_TiRayDR::cropImage] Error: Source or destination pointer is null" << endl;
  1629. return false;
  1630. }
  1631. // 验证尺寸合法性
  1632. if (destWidth <= 0 || destHeight <= 0 ||
  1633. srcWidth <= 0 || srcHeight <= 0 ||
  1634. destWidth > srcWidth || destHeight > srcHeight)
  1635. {
  1636. cout << "[Detector_TiRayDR::cropImage] Invalid crop size: src("
  1637. << srcWidth << "x" << srcHeight << ") dest("
  1638. << destWidth << "x" << destHeight << ")" << endl;
  1639. return false;
  1640. }
  1641. // 计算裁剪起始位置
  1642. int startX = (srcWidth - destWidth) / 2;
  1643. int startY = (srcHeight - destHeight) / 2;
  1644. // 边界检查
  1645. if (startX < 0) startX = 0;
  1646. if (startY < 0) startY = 0;
  1647. // 确保裁剪区域不会超出源图像边界
  1648. if (startX + destWidth > srcWidth) {
  1649. destWidth = srcWidth - startX;
  1650. cout << "[Detector_TiRayDR::cropImage] Adjusted destWidth to " << destWidth
  1651. << " to avoid out-of-bounds access" << endl;
  1652. }
  1653. if (startY + destHeight > srcHeight) {
  1654. destHeight = srcHeight - startY;
  1655. cout << "[Detector_TiRayDR::cropImage] Adjusted destHeight to " << destHeight
  1656. << " to avoid out-of-bounds access" << endl;
  1657. }
  1658. // 逐行复制裁剪区域
  1659. for (int y = 0; y < destHeight; ++y)
  1660. {
  1661. // 计算源图像行起始地址
  1662. const unsigned short* srcRow = srcData + (startY + y) * srcWidth + startX;
  1663. // 计算目标图像行起始地址
  1664. unsigned short* destRow = destData + y * destWidth;
  1665. // 复制一行像素
  1666. memcpy(destRow, srcRow, destWidth * sizeof(unsigned short));
  1667. }
  1668. cout << "[Detector_TiRayDR::cropImage] Successfully cropped image from "
  1669. << srcWidth << "x" << srcHeight << " to " << destWidth << "x" << destHeight << endl;
  1670. return true;
  1671. }
  1672. std::string Detector_TiRayDR::saveProcessedImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp)
  1673. {
  1674. const size_t MAX_PROC_FILE_COUNT = 10;
  1675. const std::string TMPFS_DIR = "/mnt/tmpfs/";
  1676. const std::string ORIGINAL_DIR = detector.m_strWorkPath + "/RawData/";
  1677. std::string procDir;
  1678. bool useTmpfs = false;
  1679. // 确定存储目录
  1680. if (std::filesystem::exists(TMPFS_DIR) && std::filesystem::is_directory(TMPFS_DIR))
  1681. {
  1682. procDir = TMPFS_DIR;
  1683. useTmpfs = true;
  1684. std::cout << "[Detector_TiRayDR::saveProcessedImage] Using tmpfs directory: " << procDir << std::endl;
  1685. }
  1686. else
  1687. {
  1688. procDir = ORIGINAL_DIR;
  1689. std::cout << "[Detector_TiRayDR::saveProcessedImage] /mnt/tmpfs not found, using original directory: " << procDir << std::endl;
  1690. }
  1691. const std::string FILE_PREFIX = "Proc_";
  1692. std::string filePath;
  1693. try
  1694. {
  1695. std::filesystem::create_directories(procDir);
  1696. filePath = procDir + FILE_PREFIX + baseTimestamp + ".raw";
  1697. std::ofstream file(filePath, std::ios::binary);
  1698. if (file.is_open())
  1699. {
  1700. file.write(reinterpret_cast<const char*>(detector.m_pImgBuffer), size);
  1701. std::cout << "[Detector_TiRayDR::saveProcessedImage] Saved image: " << filePath << std::endl;
  1702. }
  1703. else
  1704. {
  1705. std::cout << "[Detector_TiRayDR::saveProcessedImage] Failed to open file: " << filePath << std::endl;
  1706. return "";
  1707. }
  1708. cleanOldFiles(procDir, FILE_PREFIX, MAX_PROC_FILE_COUNT, useTmpfs);
  1709. }
  1710. catch (const std::filesystem::filesystem_error& e)
  1711. {
  1712. std::cout << "[Detector_TiRayDR::saveProcessedImage] File system error: " << e.what() << std::endl;
  1713. return "";
  1714. }
  1715. catch (const std::exception& e)
  1716. {
  1717. std::cout << "[Detector_TiRayDR::saveProcessedImage] Unexpected error: " << e.what() << std::endl;
  1718. return "";
  1719. }
  1720. return filePath;
  1721. }
  1722. void Detector_TiRayDR::saveRawImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp)
  1723. {
  1724. const std::string RAW_DIR = detector.m_strWorkPath + "/OriginalData/";
  1725. const std::string FILE_PREFIX = "orig_";
  1726. const size_t MAX_RAW_FILE_COUNT = 20;
  1727. std::string filePath;
  1728. try
  1729. {
  1730. std::filesystem::create_directories(RAW_DIR);
  1731. filePath = RAW_DIR + FILE_PREFIX + baseTimestamp + ".raw";
  1732. std::ofstream file(filePath, std::ios::binary);
  1733. if (file.is_open())
  1734. {
  1735. // 直接写入unsigned short缓冲区数据
  1736. file.write(reinterpret_cast<const char*>(data), size);
  1737. cout << "[Detector_TiRayDR::saveRawImage] Saved raw image: " << filePath << endl;
  1738. }
  1739. else
  1740. {
  1741. cout << "[Detector_TiRayDR::saveRawImage] Failed to open file: " << filePath << endl;
  1742. return;
  1743. }
  1744. // 清理旧的原始图
  1745. cleanOldFiles(RAW_DIR, FILE_PREFIX, MAX_RAW_FILE_COUNT, false);
  1746. }
  1747. catch (const std::filesystem::filesystem_error& e)
  1748. {
  1749. cout << "[Detector_TiRayDR::saveRawImage] File system error: " << e.what() << endl;
  1750. }
  1751. }
  1752. std::filesystem::space_info getFileSystemInfo(const std::string& dirPath) {
  1753. try {
  1754. return std::filesystem::space(dirPath);
  1755. }
  1756. catch (const std::filesystem::filesystem_error& e) {
  1757. std::cout << "[getFileSystemInfo] Failed to get filesystem info for "
  1758. << dirPath << ": " << e.what() << std::endl;
  1759. return {};
  1760. }
  1761. }
  1762. void Detector_TiRayDR::cleanOldFiles(const std::string& dirPath, const std::string& filePrefix,
  1763. size_t maxCount, bool checkSize)
  1764. {
  1765. const std::string funcTag = "[Detector_TiRayDR::cleanOldFiles] ";
  1766. try
  1767. {
  1768. // 检查目录是否存在
  1769. if (!std::filesystem::exists(dirPath) || !std::filesystem::is_directory(dirPath))
  1770. {
  1771. std::cout << funcTag << "Directory not found: " << dirPath << std::endl;
  1772. return;
  1773. }
  1774. std::vector<std::filesystem::directory_entry> targetFiles;
  1775. for (const auto& entry : std::filesystem::directory_iterator(dirPath))
  1776. {
  1777. // 只处理常规文件
  1778. if (!entry.is_regular_file())
  1779. continue;
  1780. // 检查文件扩展名是否为.raw
  1781. const std::string extension = entry.path().extension().string();
  1782. if (extension != ".raw")
  1783. continue;
  1784. // 检查文件名是否以指定前缀开头
  1785. const std::string filename = entry.path().filename().string();
  1786. if (filename.length() < filePrefix.length())
  1787. continue;
  1788. if (filename.substr(0, filePrefix.length()) == filePrefix)
  1789. {
  1790. targetFiles.push_back(entry);
  1791. }
  1792. }
  1793. // 按文件最后修改时间排序(最旧的在前)
  1794. std::sort(targetFiles.begin(), targetFiles.end(),
  1795. [](const std::filesystem::directory_entry& a, const std::filesystem::directory_entry& b)
  1796. {
  1797. return std::filesystem::last_write_time(a) < std::filesystem::last_write_time(b);
  1798. });
  1799. // 1. 先按数量限制清理
  1800. size_t filesToDelete = 0;
  1801. if (targetFiles.size() > maxCount)
  1802. {
  1803. filesToDelete = targetFiles.size() - maxCount;
  1804. // 删除超出数量限制的最旧文件
  1805. for (size_t i = 0; i < filesToDelete; ++i)
  1806. {
  1807. const auto& fileToDelete = targetFiles[i];
  1808. if (std::filesystem::remove(fileToDelete.path()))
  1809. {
  1810. std::cout << funcTag << "Deleted old file (count limit): " << fileToDelete.path() << std::endl;
  1811. }
  1812. else
  1813. {
  1814. std::cout << funcTag << "Failed to delete file: " << fileToDelete.path() << std::endl;
  1815. }
  1816. }
  1817. // 更新目标文件列表(移除已删除的文件)
  1818. targetFiles.erase(targetFiles.begin(), targetFiles.begin() + filesToDelete);
  1819. filesToDelete = 0; // 重置计数器用于大小检查
  1820. }
  1821. // 2. 如果需要,按大小限制清理(仅对tmpfs目录)
  1822. if (checkSize && !targetFiles.empty())
  1823. {
  1824. // 获取文件系统信息
  1825. auto fsInfo = getFileSystemInfo(dirPath);
  1826. if (fsInfo.capacity == 0) // 获取信息失败
  1827. {
  1828. std::cout << funcTag << "Cannot check filesystem size, skipping size check" << std::endl;
  1829. return;
  1830. }
  1831. // 计算最大允许使用空间(预留10%作为缓冲)
  1832. const uintmax_t reservedSpace = fsInfo.capacity / 10; // 10%预留空间
  1833. const uintmax_t maxAllowedSize = fsInfo.capacity - reservedSpace;
  1834. // 计算当前文件总大小
  1835. auto calculateTotalSize = [](const std::vector<std::filesystem::directory_entry>& files) {
  1836. uintmax_t total = 0;
  1837. for (const auto& file : files) {
  1838. total += file.file_size();
  1839. }
  1840. return total;
  1841. };
  1842. uintmax_t currentTotalSize = calculateTotalSize(targetFiles);
  1843. std::cout << funcTag << "Current files total size: " << currentTotalSize
  1844. << ", Max allowed size: " << maxAllowedSize << std::endl;
  1845. // 如果当前总大小超过限制,继续删除最旧的文件
  1846. while (currentTotalSize > maxAllowedSize && !targetFiles.empty())
  1847. {
  1848. const auto& fileToDelete = targetFiles[0];
  1849. uintmax_t fileSize = fileToDelete.file_size();
  1850. if (std::filesystem::remove(fileToDelete.path()))
  1851. {
  1852. std::cout << funcTag << "Deleted old file (size limit): " << fileToDelete.path()
  1853. << " (" << fileSize << " bytes)" << std::endl;
  1854. // 更新总量和文件列表
  1855. currentTotalSize -= fileSize;
  1856. targetFiles.erase(targetFiles.begin());
  1857. filesToDelete++;
  1858. }
  1859. else
  1860. {
  1861. std::cout << funcTag << "Failed to delete file: " << fileToDelete.path() << std::endl;
  1862. break; // 删除失败时停止处理
  1863. }
  1864. }
  1865. }
  1866. std::cout << funcTag << "Cleanup completed. Deleted " << filesToDelete
  1867. << " files. Remaining: " << targetFiles.size() << std::endl;
  1868. }
  1869. catch (const std::filesystem::filesystem_error& e)
  1870. {
  1871. std::cout << funcTag << "File system error: " << e.what() << std::endl;
  1872. }
  1873. catch (const std::exception& e)
  1874. {
  1875. std::cout << funcTag << "Unexpected error: " << e.what() << std::endl;
  1876. }
  1877. }
  1878. void Detector_TiRayDR::handleHardwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
  1879. {
  1880. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1881. const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
  1882. detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
  1883. const size_t rawSize = rawPixelCount * sizeof(unsigned short);
  1884. bool cropSuccess = cropImage(
  1885. detector.m_pRawImgBuffer,
  1886. detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
  1887. detector.m_pImgBuffer,
  1888. detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
  1889. );
  1890. if (!cropSuccess)
  1891. {
  1892. cout << "[Detector_TiRayDR::handleAedSyncImage] Failed to crop image" << endl;
  1893. return;
  1894. }
  1895. const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
  1896. // 生成关联的基础文件名
  1897. const std::string baseTimestamp = std::to_string(
  1898. std::chrono::duration_cast<std::chrono::milliseconds>(
  1899. std::chrono::system_clock::now().time_since_epoch()
  1900. ).count()
  1901. );
  1902. std::string processedImagePath = saveProcessedImage(
  1903. detector,
  1904. detector.m_pImgBuffer,
  1905. processedSize,
  1906. baseTimestamp
  1907. );
  1908. if (detector.m_bSaveRaw)
  1909. {
  1910. saveRawImage(
  1911. detector,
  1912. detector.m_pRawImgBuffer,
  1913. rawSize,
  1914. baseTimestamp
  1915. );
  1916. }
  1917. // 应用校准
  1918. // applyCalibration(detector);
  1919. detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
  1920. //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1921. detector.m_bExitRadAcqStatus = false;
  1922. }
  1923. void Detector_TiRayDR::handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
  1924. {
  1925. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1926. const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
  1927. detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
  1928. const size_t rawSize = rawPixelCount * sizeof(unsigned short);
  1929. bool cropSuccess = cropImage(
  1930. detector.m_pRawImgBuffer,
  1931. detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
  1932. detector.m_pImgBuffer,
  1933. detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
  1934. );
  1935. if (!cropSuccess)
  1936. {
  1937. cout << "[Detector_TiRayDR::handleSoftwareSyncImage] Failed to crop image" << endl;
  1938. return;
  1939. }
  1940. const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
  1941. // 生成关联的基础文件名
  1942. const std::string baseTimestamp = std::to_string(
  1943. std::chrono::duration_cast<std::chrono::milliseconds>(
  1944. std::chrono::system_clock::now().time_since_epoch()
  1945. ).count()
  1946. );
  1947. std::string processedImagePath = saveProcessedImage(
  1948. detector,
  1949. detector.m_pImgBuffer,
  1950. processedSize,
  1951. baseTimestamp
  1952. );
  1953. if (detector.m_bSaveRaw)
  1954. {
  1955. saveRawImage(
  1956. detector,
  1957. detector.m_pRawImgBuffer,
  1958. rawSize,
  1959. baseTimestamp
  1960. );
  1961. }
  1962. detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
  1963. // 应用校准
  1964. // applyCalibration(detector);
  1965. //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1966. detector.m_bExitRadAcqStatus = false;
  1967. }
  1968. void Detector_TiRayDR::handleAedSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
  1969. {
  1970. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
  1971. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON);
  1972. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  1973. const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
  1974. detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
  1975. const size_t rawSize = rawPixelCount * sizeof(unsigned short);
  1976. bool cropSuccess = cropImage(
  1977. detector.m_pRawImgBuffer,
  1978. detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
  1979. detector.m_pImgBuffer,
  1980. detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
  1981. );
  1982. if (!cropSuccess)
  1983. {
  1984. cout << "[Detector_TiRayDR::handleAedSyncImage] Failed to crop image" << endl;
  1985. return;
  1986. }
  1987. const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
  1988. // 生成关联的基础文件名
  1989. const std::string baseTimestamp = std::to_string(
  1990. std::chrono::duration_cast<std::chrono::milliseconds>(
  1991. std::chrono::system_clock::now().time_since_epoch()
  1992. ).count()
  1993. );
  1994. std::string processedImagePath = saveProcessedImage(
  1995. detector,
  1996. detector.m_pImgBuffer,
  1997. processedSize,
  1998. baseTimestamp
  1999. );
  2000. if (detector.m_bSaveRaw)
  2001. {
  2002. saveRawImage(
  2003. detector,
  2004. detector.m_pRawImgBuffer,
  2005. rawSize,
  2006. baseTimestamp
  2007. );
  2008. }
  2009. // applyCalibration(detector);
  2010. detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
  2011. detector.m_bAEDWorkFlag = false;
  2012. //usleep(500000);
  2013. //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  2014. detector.m_bExitRadAcqStatus = false;
  2015. }
  2016. void Detector_TiRayDR::handleDarkCalibration(Detector_TiRayDR& detector, TiRayVariant argv[])
  2017. {
  2018. const std::string funcTag = "[Detector_TiRayDR::handleDarkCalibration] ";
  2019. static int callCount = 0;
  2020. static std::vector<TiRayVariant> datas;
  2021. // 处理当前传入的图像数据
  2022. auto size = argv[3].DataLen;
  2023. auto data = argv[3].DataValue;
  2024. image_info image;
  2025. image.width = argv[0].IntValue;
  2026. image.height = argv[1].IntValue;
  2027. image.data.resize(size);
  2028. memcpy(image.data.data(), data, size);
  2029. // 将当前图像数据存入集合
  2030. TiRayVariant variant;
  2031. variant.Type = TiRayVariant::TiRayBuffer;
  2032. variant.DataLen = static_cast<int>(image.data.size());
  2033. variant.DataValue = image.data.data();
  2034. datas.push_back(variant);
  2035. // 调用次数递增(当前已处理的图像数量)
  2036. callCount++;
  2037. // 若未收集到6张图,调用拍摄命令准备下一张
  2038. if (callCount < 6) {
  2039. auto err = Execute_Ptr(detector.m_nDetectorID, Cmd_Photo, nullptr, 0);
  2040. if (err != Err_Success) {
  2041. cout << funcTag << "Failed to execute Cmd_Photo for next image. Error code: " << err << endl;
  2042. // 重置状态,避免异常累积
  2043. callCount = 0;
  2044. datas.clear();
  2045. return;
  2046. }
  2047. cout << funcTag << "Prepared for " << callCount + 1 << "th image" << endl;
  2048. }
  2049. // 收集到6张图,执行模板生成和上传
  2050. else {
  2051. image_info template_image;
  2052. template_image.data.resize(datas[0].DataLen);
  2053. template_image.width = image.width;
  2054. template_image.height = image.height;
  2055. // 生成模板并检查结果
  2056. auto err = GenerateTemplate_Ptr(Offset, datas.data(), static_cast<int>(datas.size()),
  2057. template_image.data.data(), static_cast<int>(template_image.data.size()));
  2058. if (err != Err_Success) {
  2059. cout << funcTag << "Failed to generate offset template. Error code: " << err << endl;
  2060. }
  2061. else {
  2062. cout << funcTag << "Offset template generated successfully with 6 images" << endl;
  2063. // 上传模板并检查结果
  2064. err = detector.upload(detector.offset, template_image.data.data(), static_cast<int>(template_image.data.size()));
  2065. if (err != Err_Success) {
  2066. cout << funcTag << "Failed to upload offset template. Error code: " << err << endl;
  2067. }
  2068. else {
  2069. cout << funcTag << "Offset template uploaded successfully" << endl;
  2070. }
  2071. }
  2072. // 重置静态变量,为下一次校准做准备
  2073. callCount = 0;
  2074. datas.clear();
  2075. }
  2076. }
  2077. void Detector_TiRayDR::handleGainCalibration(Detector_TiRayDR& detector, TiRayVariant argv[])
  2078. {
  2079. const std::string funcTag = "[Detector_TiRayDR::handleGainCalibration] ";
  2080. int doseCount = 5; // 剂量数量
  2081. int imagesPerDose = 6; // 每个剂量的图像数量
  2082. auto size = argv[3].DataLen;
  2083. auto data = argv[3].DataValue;
  2084. // 创建图像信息并存储
  2085. image_info image;
  2086. image.width = argv[0].IntValue;
  2087. image.height = argv[1].IntValue;
  2088. image.data.resize(size);
  2089. memcpy(image.data.data(), data, size);
  2090. // 根据模式存储图像
  2091. if (!detector.m_bUseGainV2)
  2092. {
  2093. // Gain模式:直接存储所有30张图像
  2094. detector.m_gainCalibImages.push_back(image);
  2095. cout << funcTag << "Gain mode - Collected " << detector.m_gainCalibImages.size()
  2096. << "/" << doseCount * imagesPerDose << " images" << endl;
  2097. // 收集完30张图像后生成并上传模板
  2098. if (detector.m_gainCalibImages.size() == doseCount * imagesPerDose)
  2099. {
  2100. cout << funcTag << "All 30 gain calibration images collected, generating template..." << endl;
  2101. // 准备数据并生成Gain模板
  2102. std::vector<TiRayVariant> datas;
  2103. for (auto& img : detector.m_gainCalibImages)
  2104. {
  2105. TiRayVariant variant;
  2106. variant.Type = TiRayVariant::TiRayBuffer;
  2107. variant.DataLen = static_cast<int>(img.data.size());
  2108. variant.DataValue = img.data.data();
  2109. datas.push_back(variant);
  2110. }
  2111. image_info template_image;
  2112. template_image.width = detector.m_gainCalibImages[0].width;
  2113. template_image.height = detector.m_gainCalibImages[0].height;
  2114. template_image.data.resize(datas[0].DataLen);
  2115. auto err = GenerateTemplate_Ptr(Gain, datas.data(), static_cast<int>(datas.size()),
  2116. template_image.data.data(), static_cast<int>(template_image.data.size()));
  2117. if (err != Err_Success)
  2118. {
  2119. cout << funcTag << "Failed to generate Gain template. Error code: " << err << endl;
  2120. }
  2121. else
  2122. {
  2123. cout << funcTag << "Gain template generated successfully" << endl;
  2124. // 上传模板
  2125. err = detector.upload(detector.gain, template_image.data.data(),
  2126. static_cast<int>(template_image.data.size()));
  2127. if (err != Err_Success)
  2128. {
  2129. cout << funcTag << "Failed to upload Gain template. Error code: " << err << endl;
  2130. }
  2131. else
  2132. {
  2133. cout << funcTag << "Gain template uploaded successfully" << endl;
  2134. }
  2135. }
  2136. // 清空存储的图像,准备下次校正
  2137. detector.m_gainCalibImages.clear();
  2138. }
  2139. }
  2140. else if (detector.m_bUseGainV2)
  2141. {
  2142. // Gainv2模式:按剂量组存储图像
  2143. detector.m_currentDoseImages.push_back(image);
  2144. cout << funcTag << "Gainv2 mode - Collected " << detector.m_currentDoseImages.size()
  2145. << "/" << imagesPerDose << " images for dose " << detector.m_currentDoseIndex + 1 << endl;
  2146. // 收集完当前剂量的6张图像后生成均值图
  2147. if (detector.m_currentDoseImages.size() == imagesPerDose)
  2148. {
  2149. cout << funcTag << "All " << imagesPerDose << " images for dose " << detector.m_currentDoseIndex + 1
  2150. << " collected, generating mean image..." << endl;
  2151. // 生成当前剂量的均值图
  2152. std::vector<TiRayVariant> datas;
  2153. for (auto& img : detector.m_currentDoseImages)
  2154. {
  2155. TiRayVariant variant;
  2156. variant.Type = TiRayVariant::TiRayBuffer;
  2157. variant.DataLen = static_cast<int>(img.data.size());
  2158. variant.DataValue = img.data.data();
  2159. datas.push_back(variant);
  2160. }
  2161. image_info mean_image;
  2162. mean_image.width = detector.m_currentDoseImages[0].width;
  2163. mean_image.height = detector.m_currentDoseImages[0].height;
  2164. mean_image.data.resize(datas[0].DataLen);
  2165. auto err = GenerateTemplate_Ptr(Mean, datas.data(), static_cast<int>(datas.size()),
  2166. mean_image.data.data(), static_cast<int>(mean_image.data.size()));
  2167. if (err != Err_Success)
  2168. {
  2169. cout << funcTag << "Failed to generate mean image for dose " << detector.m_currentDoseIndex + 1
  2170. << ". Error code: " << err << endl;
  2171. // 清空当前剂量数据,重新收集
  2172. detector.m_currentDoseImages.clear();
  2173. return;
  2174. }
  2175. // 保存均值图并重置当前剂量图像集合
  2176. detector.m_gainV2MeanImages.push_back(mean_image);
  2177. detector.m_currentDoseImages.clear();
  2178. detector.m_currentDoseIndex++;
  2179. cout << funcTag << "Mean image for dose " << detector.m_currentDoseIndex
  2180. << " generated successfully. Total mean images: " << detector.m_gainV2MeanImages.size() << endl;
  2181. // 收集完5个剂量的均值图后生成最终模板
  2182. if (detector.m_gainV2MeanImages.size() == doseCount)
  2183. {
  2184. cout << funcTag << "All " << doseCount << " mean images collected, generating final GainV2 template..." << endl;
  2185. // 生成最终的GainV2模板
  2186. std::vector<TiRayVariant> meanDatas;
  2187. for (auto& meanImg : detector.m_gainV2MeanImages)
  2188. {
  2189. TiRayVariant variant;
  2190. variant.Type = TiRayVariant::TiRayBuffer;
  2191. variant.DataLen = static_cast<int>(meanImg.data.size());
  2192. variant.DataValue = meanImg.data.data();
  2193. meanDatas.push_back(variant);
  2194. }
  2195. image_info final_template;
  2196. final_template.width = detector.m_gainV2MeanImages[0].width;
  2197. final_template.height = detector.m_gainV2MeanImages[0].height;
  2198. final_template.data.resize(meanDatas[0].DataLen);
  2199. auto err = GenerateTemplate_Ptr(GainV2, meanDatas.data(), static_cast<int>(meanDatas.size()),
  2200. final_template.data.data(), static_cast<int>(final_template.data.size()));
  2201. if (err != Err_Success)
  2202. {
  2203. cout << funcTag << "Failed to generate GainV2 template. Error code: " << err << endl;
  2204. }
  2205. else
  2206. {
  2207. cout << funcTag << "GainV2 template generated successfully" << endl;
  2208. // 上传模板
  2209. err = detector.upload(detector.gain, final_template.data.data(),
  2210. static_cast<int>(final_template.data.size()));
  2211. if (err != Err_Success)
  2212. {
  2213. cout << funcTag << "Failed to upload GainV2 template. Error code: " << err << endl;
  2214. }
  2215. else
  2216. {
  2217. cout << funcTag << "GainV2 template uploaded successfully" << endl;
  2218. }
  2219. }
  2220. // 重置所有存储和计数器,准备下次校正
  2221. detector.m_gainV2MeanImages.clear();
  2222. detector.m_currentDoseIndex = 0;
  2223. }
  2224. }
  2225. }
  2226. }
  2227. void Detector_TiRayDR::handleImageReceived(Detector_TiRayDR& detector, TiRayVariant argv[])
  2228. {
  2229. // 处理暗校准模式
  2230. if (CCOS_CALIBRATION_TYPE_DARK == detector.m_eCaliType)
  2231. {
  2232. handleDarkCalibration(detector, argv);
  2233. return;
  2234. }
  2235. else if (CCOS_CALIBRATION_TYPE_XRAY == detector.m_eCaliType)
  2236. {
  2237. handleGainCalibration(detector, argv);
  2238. return;
  2239. }
  2240. // 根据同步模式处理图像
  2241. switch (detector.m_nSyncMode)
  2242. {
  2243. case SYNC_MODE::SYNC_AED:
  2244. handleAedSyncImage(detector, argv);
  2245. break;
  2246. case SYNC_MODE::SYNC_SOFTWARE:
  2247. handleSoftwareSyncImage(detector, argv);
  2248. break;
  2249. case SYNC_MODE::SYNC_HARDWARE:
  2250. handleHardwareSyncImage(detector, argv);
  2251. break;
  2252. }
  2253. }
  2254. void Detector_TiRayDR::on_event_callback(int detectorId, TiRayEvent eventType, TiRayVariant argv[], int argc, void* reservedArg, int reservedArgLen)
  2255. {
  2256. auto& detector = *g_pDetector;
  2257. const std::string funcTag = "[Detector_TiRayDR::on_event_callback] ";
  2258. switch (eventType)
  2259. {
  2260. case TiRayEvent::Evt_DetectorConnect:
  2261. {
  2262. detector.m_nDetectorID = detectorId;
  2263. detector.m_bConnected = true;
  2264. detector.m_pStPanelStatus[detector.m_nCurrentPanelID]->bConnectState = true;
  2265. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
  2266. cout << funcTag << "Evt_DetectorConnect!!!" << endl;
  2267. //mLog::FINFO("Evt_DetectorConnect!!");
  2268. break;
  2269. }
  2270. case TiRayEvent::Evt_DetectorDisconnect:
  2271. {
  2272. detector.m_nDetectorID = INT_MAX;
  2273. detector.m_bConnected = false;
  2274. detector.m_pStPanelStatus[detector.m_nCurrentPanelID]->bConnectState = false;
  2275. detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE);
  2276. detector.m_hReConnectEvent->SetEvent();
  2277. cout << funcTag << "Evt_DetectorDisconnect!!!" << endl;
  2278. //mLog::FINFO("Evt_DetectorDisconnect!!");
  2279. break;
  2280. }
  2281. case TiRayEvent::Evt_WriteAttribute:
  2282. {
  2283. //mLog::FINFO("WriteAttribute Success");
  2284. break;
  2285. }
  2286. case TiRayEvent::Evt_ReadAttribute:
  2287. {
  2288. //mLog::FINFO("ReadAttribute Success");
  2289. //const TiRayAttribute attrib = (TiRayAttribute)argv[0].IntValue;
  2290. //if (attrib == Attr_BatteryStatus) {
  2291. // auto battery_level = argv[1].IntValue;
  2292. // auto is_recharging = argv[2].IntValue;
  2293. //}
  2294. break;
  2295. }
  2296. case TiRayEvent::Evt_ImageReceived:
  2297. {
  2298. cout << funcTag << "Evt_ImageReceived!!!" << endl;
  2299. //mLog::FINFO("Evt_ImageReceived!!");
  2300. handleImageReceived(detector, argv);
  2301. break;
  2302. }
  2303. case TiRayEvent::Evt_ExposureStatus:
  2304. {
  2305. //mLog::FINFO("argv {$}, argc {$}", argv[0].IntValue, argc);
  2306. if (argv[0].IntValue == 0)
  2307. {
  2308. detector.m_bAEDReady = true;
  2309. }
  2310. if (argv[0].IntValue == 1)
  2311. {
  2312. detector.m_bAEDReady = false;
  2313. }
  2314. break;
  2315. }
  2316. case TiRayEvent::Evt_UploadProgress:
  2317. cout << funcTag << "Upload progress: " << argv[0].IntValue << "%" << endl;
  2318. break;
  2319. case TiRayEvent::Evt_UpdateFinish:
  2320. cout << funcTag << "Update completed successfully" << endl;
  2321. detector.StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  2322. break;
  2323. case TiRayEvent::Evt_UploadTimeout:
  2324. // 输出上传超时警告
  2325. cout << funcTag << "Warning: Upload timed detectorData" << endl;
  2326. break;
  2327. default:
  2328. //mLog::FERROR("not support current event ID:{$}", (int)eventType);
  2329. break;
  2330. }
  2331. }
  2332. void Detector_TiRayDR::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  2333. {
  2334. if (-1 == nDetectorID)
  2335. {
  2336. nDetectorID = m_nCurrentPanelID;
  2337. }
  2338. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2339. nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2340. }
  2341. void Detector_TiRayDR::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  2342. {
  2343. if (-1 == nDetectorID)
  2344. {
  2345. nDetectorID = m_nCurrentPanelID;
  2346. }
  2347. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2348. nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2349. }
  2350. void Detector_TiRayDR::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  2351. {
  2352. if (-1 == nDetectorID)
  2353. {
  2354. nDetectorID = m_nCurrentPanelID;
  2355. }
  2356. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2357. nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2358. }
  2359. void Detector_TiRayDR::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  2360. {
  2361. if (-1 == nDetectorID)
  2362. {
  2363. nDetectorID = m_nCurrentPanelID;
  2364. }
  2365. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2366. nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2367. }
  2368. void Detector_TiRayDR::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  2369. {
  2370. if (-1 == nDetectorID)
  2371. {
  2372. nDetectorID = m_nCurrentPanelID;
  2373. }
  2374. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2375. nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2376. }
  2377. void Detector_TiRayDR::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  2378. {
  2379. if (-1 == nDetectorID)
  2380. {
  2381. nDetectorID = m_nCurrentPanelID;
  2382. }
  2383. ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
  2384. nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  2385. }
  2386. bool Detector_TiRayDR::UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode)
  2387. {
  2388. //mLog::FINFO("--TiRayDR Func-- UpdateCalibMode");
  2389. //mLog::FINFO("CalibMode:{$}", (int)eCalibMode);
  2390. m_nCalibrationMode = eCalibMode;
  2391. //mLog::FINFO("UpdateCalibMode Over");
  2392. return true;
  2393. }
  2394. void Detector_TiRayDR::SetNotifyStatusTimePeriod(int nTime)
  2395. {
  2396. //mLog::FINFO("--Func TiRay-- SetNotifyStatusTimePeriod Start");
  2397. //mLog::FINFO("NotifyStatusTimePeriod:{$}", nTime);
  2398. m_nNotifyStatusTimePeriod = nTime;
  2399. //mLog::FINFO("SetNotifyStatusTimePeriod Over");
  2400. }
  2401. void Detector_TiRayDR::SetReconnectTimePeriod(int nTime)
  2402. {
  2403. //mLog::FINFO("--Func TiRay-- SetReconnectTimePeriod Start");
  2404. //mLog::FINFO("ReconnectTimePeriod:{$}", nTime);
  2405. m_nReconnectTimePeriod = nTime;
  2406. //mLog::FINFO("SetReconnectTimePeriod Over");
  2407. }
  2408. int Detector_TiRayDR::TiRay_GetSdkVersion()
  2409. {
  2410. return GetSdkVersion_Ptr();
  2411. }
  2412. TiRayError Detector_TiRayDR::TiRay_Execute(int detectorId, int commandId, TiRayVariant argv[], int argc)
  2413. {
  2414. return Execute_Ptr(detectorId, commandId, argv, argc);
  2415. }
  2416. TiRayError Detector_TiRayDR::TiRay_ApplyPreset(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn)
  2417. {
  2418. return ApplyPreset_Ptr(detectorId, argv, argc, fn);
  2419. }
  2420. TiRayError Detector_TiRayDR::TiRay_GenerateTemplate(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize)
  2421. {
  2422. return GenerateTemplate_Ptr(type, images, count, templateBuffer, bufferSize);
  2423. }
  2424. TiRayError Detector_TiRayDR::TiRay_Scan(ResultCallback fn, const char* interfaceIp, int scanDuration)
  2425. {
  2426. return Scan_Ptr(fn, interfaceIp, scanDuration);
  2427. }
  2428. TiRayError Detector_TiRayDR::TiRay_SetIp(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp)
  2429. {
  2430. return SetIp_Ptr(detectorSN, upperIp, lowerIp, interfaceIp);
  2431. }
  2432. TiRayError Detector_TiRayDR::TiRay_Startup(TiRayModel model, EventCallback fn, const StartupOption* option)
  2433. {
  2434. return Startup_Ptr(model, fn, option);
  2435. }
  2436. void Detector_TiRayDR::TiRay_Stop()
  2437. {
  2438. Stop_Ptr();
  2439. }
  2440. /***
  2441. ** 说明:重连探测器线程
  2442. ***/
  2443. void* Detector_TiRayDR::onReconnectThread(PVOID pvoid)
  2444. {
  2445. //mLog::FINFO("Reconnect detector thread start");
  2446. Detector_TiRayDR* pThis = static_cast<Detector_TiRayDR*>(pvoid);
  2447. while (!pThis->m_bConnected)
  2448. {
  2449. pThis->OpenDetector();
  2450. usleep(pThis->m_nReconnectTimePeriod*1000);
  2451. }
  2452. pThis->m_bReconnectThreadRunning = false;
  2453. //mLog::FINFO("Leave reconnect detector thread");
  2454. return 0;
  2455. }
  2456. TiRayError Detector_TiRayDR::upload(upload_type type, char* data, int size)
  2457. {
  2458. TiRayVariant param[1]{};
  2459. param[0].Type = TiRayVariant::TiRayBuffer;
  2460. param[0].DataValue = data;
  2461. param[0].DataLen = size;
  2462. if (type == offset) {
  2463. return Execute_Ptr(m_nDetectorID, Cmd_UploadOffsetTemplate, param, 1);
  2464. }
  2465. if (type == gain) {
  2466. return Execute_Ptr(m_nDetectorID, Cmd_UploadGainTemplate, param, 1);
  2467. }
  2468. if (type == firmware) {
  2469. return Execute_Ptr(m_nDetectorID, Cmd_UpdateFirmware, param, 1);
  2470. }
  2471. return Err_InvalidParam;
  2472. }