| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958 |
- #include "Detector_TiRayDR.h"
- #include "CCOS.Dev.FPD.TiRayDR.h"
- #include "MyPingip.h"
- #include <dlfcn.h>
- #include <pthread.h>
- #include "LogLocalHelper.h"
- #include "Log4CPP.h"
- using EventListenerType = void(*)(TiRayEvent, void*);
- Detector_TiRayDR* g_pDetector = nullptr;
- // 函数声明
- static std::string generateReadableTimestamp();
- //extern Log4CPP::Logger* mLog::gLogger;
- /****************************************/
- int (*GetSdkVersion_Ptr)(void);
- TiRayError(*Scan_Ptr)(ResultCallback fn, const char* interfaceIp, int scanDuration);
- TiRayError(*SetIp_Ptr)(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp);
- TiRayError(*Startup_Ptr)(TiRayModel model, EventCallback fn, const StartupOption * option);
- void (*Stop_Ptr)();
- TiRayError(*Execute_Ptr)(int detectorId, int commandId, TiRayVariant argv[], int argc);
- TiRayError(*ApplyPreset_Ptr)(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn);
- TiRayError(*GenerateTemplate_Ptr)(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize);
- static int g_load_error = 0;
- static void LoadOneFunc(void* hInstLib, void** pFunction, const char* funcName)
- {
- *pFunction = dlsym(hInstLib, funcName);
- const char* dlsym_error = dlerror();
- if (dlsym_error != NULL) {
- printf("Failed to load %s. Error = %s", funcName, dlsym_error);
- g_load_error = 1;
- }
- }
- void OnEvent(TiRayEvent eventType, TiRayVariant argv[], int argc) {
- if (argc > 0) {
- auto arg = new std::vector<TiRayVariant>(argc);
- for (int i = 0; i < argc; i++) {
- if (argv[i].Type == TiRayVariant::TiRayBuffer) {
- arg->at(i).Type = TiRayVariant::TiRayBuffer;
- arg->at(i).DataLen = argv[i].DataLen;
- arg->at(i).DataValue = new char[argv[i].DataLen];
- memcpy(arg->at(i).DataValue, argv[i].DataValue, argv[i].DataLen);
- }
- else {
- memcpy(&arg->at(i), &argv[i], sizeof(TiRayVariant));
- }
- }
- }
- }
- #define LOAD_ONE_FUNC(handle, funcName) LoadOneFunc(handle, (void**)&(funcName##_Ptr), #funcName)
- /****************************************/
- Detector_TiRayDR::Detector_TiRayDR()
- :m_nPanelCount{},
- m_nCurrentPanelID{0},
- m_nImageWidth{},
- m_nImageHeight{},
- m_nWidthOffset{},
- m_nHeightOffset{},
- m_nRawImgWidth{},
- m_nRawImgHeight{},
- m_nCalibrationRounds{},
- m_nCalibCurrentCalibrationRound{},
- m_nCalibCurrentExposureIndex{},
- m_nExposureNumCurrentRound{},
- m_hTiRayDRModule{},
- m_hReconnectThread{},
- m_hFPDScanThread{},
- m_hRadAcquisitionThread{},
- m_hStatusMonitorThread{},
- m_pRawImgBuffer{},
- m_pImgBuffer{},
- m_pZSKKCalib{},
- m_strDetectorType{},
- m_strSerialNum{},
- m_strCurrentSessionTimestamp{},
- m_nSessionFrameCounter{0},
- m_nImageNum{},
- m_nDetectorID{},
- m_nNotifyStatusTimePeriod{},
- m_pStPanelStatus{},
- m_nReconnectTimePeriod(5000),
- m_nAppStatus(APP_STATUS::APP_STATUS_IDLE),
- m_eCaliType(CCOS_CALIBRATION_TYPE_NONE),
- m_nSyncMode(SYNC_SOFTWARE),
- m_nCalibrationMode(CCOS_CALIBRATION_MODE_ZSKK),
- m_bSaveRaw(true),
- m_bConnected(false),
- m_bAEDReady(false),
- m_bAEDWorkFlag(false),
- m_bExitRadAcqStatus(false),
- m_bMonitorFlag(false)
- {
- m_pDPC2PanelID = new map<FPDDeviceTiRay*, int>();
- m_pPanelID2DPC = new map<int, FPDDeviceTiRay*>();
- m_hExitRadAcqStatus = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- m_hInitEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- m_hExitEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- m_hReConnectEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- m_hRadEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- m_hArrayEvent.push_back(m_hInitEvent);
- m_hArrayEvent.push_back(m_hExitEvent);
- m_hArrayEvent.push_back(m_hReConnectEvent);
- m_hArrayEvent.push_back(m_hRadEvent);
- m_hToggleEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, FALSE);
- }
- Detector_TiRayDR::~Detector_TiRayDR()
- {
- CloseStatusMonitor();
- CloseDetectorScan();
- if (m_hReconnectThread != 0) {
- if (m_bReconnectThreadRunning) {
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += 2; // 设置2秒超时
- // 等待线程结束
- pthread_timedjoin_np(m_hReconnectThread, nullptr, &ts);
- }
- // 如果线程仍在运行,强制取消
- if (m_bReconnectThreadRunning) {
- pthread_cancel(m_hReconnectThread);
- }
- m_hReconnectThread = 0;
- }
- if (m_pRawImgBuffer)
- {
- delete[] m_pRawImgBuffer;
- m_pRawImgBuffer = nullptr;
- }
- if (m_pImgBuffer)
- {
- delete[] m_pImgBuffer;
- m_pImgBuffer = nullptr;
- }
- if (m_pZSKKCalib)
- {
- delete m_pZSKKCalib;
- m_pZSKKCalib = nullptr;
- }
-
- }
- bool Detector_TiRayDR::ScanDetector(string& strDetectorInfo)
- {
- ResDataObject result;
- std::vector<scan_result> scan_results;
- // 扫描探测器并收集所有结果
- scan([&scan_results](scan_result&& res) {
- scan_results.emplace_back(std::move(res));
- });
- if (scan_results.empty()) {
- std::cerr << "[Detector_TiRayDR::ScanDetector] No detectors were found!" << std::endl;
- return false;
- }
- std::cout << "[Detector_TiRayDR::ScanDetector] Scanned " << scan_results.size() << " detector(s):" << std::endl;
- for (size_t i = 0; i < scan_results.size(); ++i) {
- const auto& res = scan_results[i];
- ResDataObject detectorData;
- detectorData.add("SerialNumber", res.sn.c_str());
- detectorData.add("Model", res.model.c_str());
- detectorData.add("TupperIP", res.upper_ip.c_str());
- detectorData.add("DetectorIP", res.detector_ip.c_str());
- std::string key = "DetectorData_" + std::to_string(i);
- result.add(key.c_str(), detectorData);
- // 输出当前探测器信息
- std::cout << "[Detector_TiRayDR::ScanDetector] Detector " << (i + 1) << ":"
- << " Serial number:" << res.sn
- << ", Model:" << res.model
- << ", tupper IP:" << res.upper_ip
- << ", detector IP:" << res.detector_ip << std::endl;
- }
- try {
- strDetectorInfo = result.encode();
- }
- catch (const std::exception& e) {
- std::cerr << "[Detector_TiRayDR::ScanDetector] Encode failed: " << e.what() << std::endl;
- return false;
- }
- return true;
- }
- bool Detector_TiRayDR::DriverEntry(FPDDeviceTiRay* pDrvDPC, ResDataObject& Configuration)
- {
- //FINFO("--TiRayDR Func-- DriverEntry Start");
- map<FPDDeviceTiRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
- if (DPCsIter != m_pDPC2PanelID->end())
- {
- //FERROR("This DPC already exist");
- return false;
- }
- CPanelStatus* p = new CPanelStatus();
- m_pStPanelStatus[m_nPanelCount] = p;
- m_pDPC2PanelID->insert(pair<FPDDeviceTiRay*, int>(pDrvDPC, m_nPanelCount));
- m_pPanelID2DPC->insert(pair<int, FPDDeviceTiRay*>(m_nPanelCount, pDrvDPC));
- m_nPanelCount++;
- m_ModeConfig = Configuration; //记录配置 --目前只有一个平板,多板时应该分别存储
- //FINFO("Config: {$}", m_ModeConfig.encode());
- try
- {
- m_nCalibrationMode = (CCOS_CALIBRATION_MODE)(int)m_ModeConfig["CalibMode"];
- }
- catch (ResDataObjectExption& e)
- {
- //FERROR("Read configuration failed, Error code: {$}", e.what());
- }
- //FINFO("TiRayDR DriverEntry Over");
- return true;
- }
- bool Detector_TiRayDR::Connect(FPDDeviceTiRay* pDrvDPC, const char* szWorkPath)
- {
- FINFO("--TiRayDR Func-- Connect Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FINFO("Not current DPC, return true");
- return true;
- }
- if (!m_pZSKKCalib)
- {
- m_pZSKKCalib = new CZSKKCalibrationCtrl();
- }
- m_strWorkPath = szWorkPath;
- if (m_hFPDScanThread == 0)
- {
- pthread_t threadId;
- int result = pthread_create(&threadId, NULL, onFPDScanThread, this);
- if (result == 0) {
- m_hFPDScanThread = threadId; // 存储线程ID
- }
- else {
- FERROR("Thread creation failed: %d", result);
- return false;
- }
- }
- if (m_hInitEvent) {
- m_hInitEvent->SetEvent();
- }
- FINFO("TiRayDR Connect Over");
- return true;
- }
- bool Detector_TiRayDR::Disconnect()
- {
- FINFO("--TiRayDR Func-- Disconnect Begin");
- m_hExitEvent->SetEvent(); //关闭Scan线程
- bool result = m_hToggleEvent->Wait(65000);
- if (result)
- {
- FINFO("Leave scan thread over");
- }
- else
- {
- FERROR("Till time detectorData");
- }
- FINFO("Call API Stop");
- Stop();
- FINFO("TiRayDR Disconnect Over");
- return true;
- }
- void Detector_TiRayDR::EnterExamMode(int nExamMode)
- {
- switch (nExamMode)
- {
- case APP_STATUS_WORK_BEGIN:
- FINFO("Enter into Exam Windows");
- m_nAppStatus = APP_STATUS_WORK_BEGIN;
- break;
- case APP_STATUS_WORK_END:
- FINFO("Quit Exam Windows");
- m_nAppStatus = APP_STATUS_WORK_END;
- break;
- case APP_STATUS_DETSHARE_BEGIN:
- FINFO("Enter into Detector Share Windows");
- m_nAppStatus = APP_STATUS_DETSHARE_BEGIN;
- break;
- case APP_STATUS_DETSHAR_END:
- FINFO("Quit Detector Share Windows");
- m_nAppStatus = APP_STATUS_DETSHAR_END;
- break;
- case APP_STATUS_CAL_BEGIN:
- FINFO("Enter into Calibration Windows");
- m_nAppStatus = APP_STATUS_CAL_BEGIN;
- break;
- case APP_STATUS_CAL_END:
- FINFO("Quit Calibration Windows");
- m_nAppStatus = APP_STATUS_CAL_END;
- break;
- case APP_STATUS_WORK_IN_SENSITIVITY:
- FINFO("Enter into sensitivity test interface");
- m_nAppStatus = APP_STATUS_WORK_IN_SENSITIVITY;
- break;
- default:
- break;
- }
- }
- /***
- ** 根据采集模式申请图像buffer
- ***/
- bool Detector_TiRayDR::SetAcqMode(int nMode)
- {
- FINFO("--TiRayDR Func-- SetAcqMode Start");
- FINFO("SetAcqMode mode: {$}", nMode);
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("Detector not connected, return");
- return false;
- }
- m_bExitRadAcqStatus = false;
- // 从配置中读取图像参数
- try
- {
- m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"];
- m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"];
- m_nWidthOffset = (int)m_ModeConfig["ModeTable"][0]["WidthOffset"];
- m_nHeightOffset = (int)m_ModeConfig["ModeTable"][0]["HeightOffset"];
- FINFO("Image config - Width: {$}, Height: {$}, WidthOffset: {$}, HeightOffset: {$}",
- m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
- m_bSaveRaw = (int)m_ModeConfig["ModeTable"][0]["IsSaveRaw"];
- FINFO("SaveRaw: {$}", m_bSaveRaw);
- // 重新分配图像缓冲区
- if (m_pImgBuffer != nullptr)
- {
- delete[] m_pImgBuffer;
- m_pImgBuffer = nullptr;
- }
- m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageHeight];
- }
- catch (ResDataObjectExption& e)
- {
- FERROR("Failed to get config: {$}", e.what());
- return false;
- }
- // 根据采集模式设置工作模式
- int workMode;
- const char* modeName;
- // 设置拍摄参数
- int nXWindow = (int)m_ModeConfig["ModeTable"][0]["XWindow"];
- if (nMode == AcqMode::RAD)
- {
- workMode = WorkMode_FreeSync;
- modeName = "RAD";
- }
- else if (nMode == AcqMode::DDR)
- {
- workMode = WorkMode_DDR;
- modeName = "DDR";
- nXWindow = 800;
- }
- else if (nMode == AcqMode::PF)
- {
- workMode = WorkMode_SyncIn;
- modeName = "PF";
- nXWindow = 800;
- }
- else
- {
- FERROR("Invalid acquisition mode: {$}", nMode);
- return false;
- }
- FINFO("Setting work mode to {$} (WorkMode: {$})", modeName, workMode);
- // 设置工作模式
- auto err = write_attribute(Attr_WorkMode, workMode);
- if (err != Err_Success)
- {
- FERROR("Failed to set work mode, error code: {$}", err);
- return false;
- }
- FINFO("Work mode set successfully");
- err = write_attribute(Attr_PhotoInterval, nXWindow);
- if (err != Err_Success)
- {
- FERROR("Failed to write Attr_PhotoInterval, error code: {$}", err);
- return false;
- }
- StatusFeedback(EVT_STATUS_PANEL, PANEL_SLEEP);
- FINFO("TiRayDR SetAcqMode Over");
- return true;
- }
- bool Detector_TiRayDR::SetSyncMode(int nSyncMode)
- {
- FINFO("--TiRayDR Func-- SetSyncMode Start");
- FINFO("SetSyncMode: {$}", nSyncMode);
- std::cout << "--TiRayDR Func-- SetSyncMode Start" << std::endl;
- std::cout << "SetSyncMode: " << nSyncMode << std::endl;
- int nRes;
- TiRayVariant Param[2]{};
- Param[0].Type = TiRayVariant::TiRayInt;
- Param[0].IntValue = TiRayAttribute::Attr_WorkMode;
- Param[1].Type = TiRayVariant::TiRayInt;
- if (nSyncMode == 1)
- {
- Param[1].IntValue = WorkMode::WorkMode_Idle;
- m_nSyncMode = SYNC_MODE::SYNC_SOFTWARE;
- std::cout << "Setting SyncMode to Software Sync" << std::endl;
- nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
- if ((TiRayError)nRes != TiRayError::Err_Success)
- {
- std::cout << "Error: Failed to set SyncMode to Software Sync. Reason: " << nRes << std::endl;
- FERROR("Set SyncMode SoftSync, Reason:{$}", nRes);
- return false;
- }
- else
- {
- std::cout << "Success: Software Sync mode set successfully" << std::endl;
- FINFO("Set SoftSync Success");
- }
- }
- else if (nSyncMode == 2)
- {
- m_nSyncMode = SYNC_MODE::SYNC_HARDWARE;
- Param[1].IntValue = WorkMode::WorkMode_SyncIn;
- std::cout << "Setting SyncMode to Hardware Sync" << std::endl;
- nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
- if ((TiRayError)nRes != TiRayError::Err_Success)
- {
- std::cout << "Error: Failed to set SyncMode to Hardware Sync. Reason: " << nRes << std::endl;
- FERROR("Set SyncMode HardSync, Reason:{$}", nRes);
- return false;
- }
- else
- {
- std::cout << "Success: Hardware Sync mode set successfully" << std::endl;
- FINFO("Set HardSync Success");
- }
- }
- else if (nSyncMode == 3)
- {
- Param[1].IntValue = WorkMode_FreeSync;
- m_nSyncMode = SYNC_MODE::SYNC_AED;
- std::cout << "Setting SyncMode to AED Sync" << std::endl;
- nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
- if ((TiRayError)nRes != TiRayError::Err_Success)
- {
- std::cout << "Error: Failed to set SyncMode to AED Sync. Reason: " << nRes << std::endl;
- FERROR("Set SyncMode AED, Reason:{$}", nRes);
- return false;
- }
- else
- {
- std::cout << "Success: AED Sync mode set successfully" << std::endl;
- FINFO("Set AED Success");
- }
- }
- m_pStPanelStatus[m_nCurrentPanelID]->eSyncMode = (SYNC_MODE)m_nSyncMode;
- FINFO("TiRayDR SetSyncMode Over");
- std::cout << "TiRayDR SetSyncMode Over" << std::endl;
- return true;
- }
- bool Detector_TiRayDR::PrepareAcquisition(FPDDeviceTiRay* pDrvDPC)
- {
- FINFO("--TiRayDR Func-- PrepareAcquisition Start");
- FINFO("PrepareAcquisition start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FERROR("Not current DPC, return");
- return false;
- }
- //未初始化、未连接 不执行
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("Detector not connected, return");
- return false;
- }
- g_pDetector->StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
- // 生成新的会话时间戳,这次拍摄的所有图片都将使用这个时间戳
- m_strCurrentSessionTimestamp = generateReadableTimestamp();
- m_nSessionFrameCounter = 0; // 重置帧计数器
- FINFO("New session started with timestamp: {$}", m_strCurrentSessionTimestamp);
- //m_hRadEvent->SetEvent();
- FINFO("TiRayDR PrepareAcquisition Over");
- return true;
- }
- bool Detector_TiRayDR::StartAcquisition(FPDDeviceTiRay* pDrvDPC)
- {
- std::cout << "--TiRayDR Func-- StartAcquisition Start" << std::endl;
- FINFO("--TiRayDR Func-- StartAcquisition Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- std::cout << "Not current DPC, return" << std::endl;
- FERROR("Not current DPC, return");
- return false;
- }
- //未初始化、未连接 不执行
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- std::cout << "Detector not connected, return" << std::endl;
- FERROR("Detector not connected, return");
- return false;
- }
- if (m_nSyncMode == SYNC_MODE::SYNC_SOFTWARE)
- {
- //SetSyncMode(1);
- auto err = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
- if (err != Err_Success) {
- cout << "[Detector_TiRayDR::StartAcquisition] Failed to Execute_Ptr Cmd_Photo. Error code: " << err << endl;
- return false;
- }
- }
- StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
- m_bAEDWorkFlag = true;
- StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
- std::cout << "TiRayDR StartAcquisition Over" << std::endl;
- FINFO("TiRayDR StartAcquisition Over");
- return true;
- }
- bool Detector_TiRayDR::StopAcquisition(FPDDeviceTiRay* pDrvDPC)
- {
- FINFO("--TiRayDR Func-- StopAcquisition Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FERROR("Not current DPC, return");
- return false;
- }
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("Detector not connected, return");
- return false;
- }
- FINFO("## Stop Acquisition ##");
- StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
- SetTiRayDPCStatus(eDetStatus::DetStatus_Standby); //停止采集
- FINFO("TiRayDR StopAcquisition Over");
- return true;
- }
- bool Detector_TiRayDR::ActiveCalibration(FPDDeviceTiRay* pDrvDPC, CCOS_CALIBRATION_TYPE eType)
- {
- FINFO("--TiRayDR Func-- ActiveCalibration Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FERROR("Not current DPC, return");
- return false;
- }
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("bConnectState is false, Detector not connected, return");
- return false;
- }
- StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START);
- m_nAppStatus = APP_STATUS_CAL_BEGIN; //激活校正,置为校正界面
- m_eCaliType = eType;
- if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
- {
- FINFO("Active Dark Calibration");
- }
- if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
- {
- FINFO("Active Xray Calibration");
- if (m_nCalibrationMode) //厂商校正ActiveCalibration
- {
- }
- //else //ZSKK校正
- //{
- // if (!m_pZSKKCalib)
- // {
- // FERROR("ZSKK Calibration object is undefined");
- // }
- // else
- // {
- // //加载ZSKK的校正文件
- // m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "/rawdata/";
- // m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "/references/";
- // m_pZSKKCalib->m_nFullImgWidth = m_nImageWidth;
- // m_pZSKKCalib->m_nFullImgHeight = m_nImageHeight;
- // m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds;
- // m_pZSKKCalib->m_nSaturationValue = 50000;
- // //LoadZSKKGainMap 参数为false,意思是开始增益校正
- // m_pZSKKCalib->LoadZSKKGainMap(false, m_strDetectorType);
- // m_pZSKKCalib->LoadZSKKPixelMap(false, m_strDetectorType);
- // FINFO("Load ecom gain and pixel map, references file path: {$}", m_pZSKKCalib->m_strRefFilePath);
- // }
- //}
- }
- FINFO("TiRayDR ActiveCalibration Over");
- return true;
- }
- /***
- * 接受曝光图像
- ***/
- bool Detector_TiRayDR::AcceptCalibration()
- {
- FINFO("--TiRayDR Func-- AcceptCalibration Start");
- if (m_nCalibrationMode)//厂商校正AcceptCalibration
- {
- //不做处理
- }
- else //ZSKK校正
- {
- //WORD* pImageBuffer = nullptr;
- ////这里要注意使用的image buffer是哪个,裁剪和不裁剪是不一样的
- //if (m_nWidthOffset != 0 || m_nHeightOffset != 0)
- //{
- // pImageBuffer = m_pImgBuffer;
- //}
- //else
- //{
- // pImageBuffer = m_pImgBuffer;//之后再做区分,先测试用
- //}
- //if (m_nCalibCurrentExposureIndex == 1)
- //{
- // m_pZSKKCalib->AddImageToPixMap(pImageBuffer);
- // m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, true);
- //}
- //else
- //{
- // m_pZSKKCalib->AverageZSKKGainMap(pImageBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮
- //}
- }
- FINFO("TiRayDR AcceptCalibration Over");
- return true;
- }
- /***
- * 拒绝曝光图像
- ***/
- bool Detector_TiRayDR::RejectCalibration()
- {
- const std::string funcTag = "[Detector_TiRayDR::RejectCalibration] ";
- // 检查当前是否在进行增益校正
- if (m_eCaliType != CCOS_CALIBRATION_TYPE_XRAY)
- {
- cout << funcTag << "No active gain calibration in progress" << endl;
- return false;
- }
- bool rejected = false;
- if (m_bUseGainV2)
- {
- if (!m_currentDoseImages.empty())
- {
- m_currentDoseImages.pop_back();
- cout << funcTag << "Rejected last image in dose group " << m_currentDoseIndex
- << ". Remaining in group: " << m_currentDoseImages.size() << endl;
- rejected = true;
- }
- else
- {
- cout << funcTag << "No images in current dose group to reject" << endl;
- }
- }
- else
- {
- if (!m_gainCalibImages.empty())
- {
- m_gainCalibImages.pop_back(); // 移除最后添加的图像
- cout << funcTag << "Rejected last gain image. Remaining: " << m_gainCalibImages.size() << endl;
- rejected = true;
- }
- else
- {
- cout << funcTag << "No gain images to reject" << endl;
- }
- }
- return rejected;
- }
- /***
- * 设置校正轮数
- ***/
- bool Detector_TiRayDR::SetCalibRounds(int nCalibRounds)
- {
- FINFO("--TiRayDR Func-- SetCalibRounds Start");
- m_nCalibrationRounds = nCalibRounds;
- FINFO("Set reference number: {$}", m_nCalibrationRounds);
- FINFO("TiRayDR SetCalibRounds Over");
- return true;
- }
- bool Detector_TiRayDR::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound)
- {
- FINFO("--TiRayDR Func-- GetCalibrationStep Start");
- m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound;
- m_nCalibrationRounds = nCalibrationRounds;
- m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex;
- m_nExposureNumCurrentRound = nExposureNumCurrentRound;
- FINFO("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds,
- nCalibCurrentExposureIndex, nExposureNumCurrentRound);
- FINFO("TiRayDR GetCalibrationStep Over");
- return true;
- }
- bool Detector_TiRayDR::PrepareCalibration(FPDDeviceTiRay* pDrvDPC)
- {
- const std::string funcTag = "[Detector_TiRayDR::PrepareCalibration] ";
- std::cout << funcTag << "--TiRayDR Function-- PrepareCalibration started" << std::endl;
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- std::cout << funcTag << "Error: Not current DPC device, returning false" << std::endl;
- return false;
- }
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- std::cout << funcTag << "Error: Detector not connected (bConnectState is false), returning false" << std::endl;
- return false;
- }
- auto writeAttrWithLog = [this](const std::string& attrName, int value, int err) {
- if (err == Err_Success)
- {
- std::cout << "[Detector_TiRayDR::PrepareCalibration] Success: Wrote attribute " << attrName << " with value " << value << std::endl;
- }
- else
- {
- std::cout << "[Detector_TiRayDR::PrepareCalibration] Error: Failed to write attribute " << attrName << ", error code: " << err << std::endl;
- }
- return err;
- };
- if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
- {
- int ret = DarkAcquisition();
- std::cout << funcTag << "Info: DarkAcquisition returned " << ret << std::endl;
- if (!ret)
- {
- std::cout << funcTag << "Info: Sending calibration start status (EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_BEGIN)" << std::endl;
- StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_BEGIN);
- }
- }
- else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
- {
- std::cout << funcTag << "Info: Preparing X-ray calibration (CCOS_CALIBRATION_TYPE_XRAY)" << std::endl;
- int err = write_attribute(Attr_WorkMode, WorkMode_FreeSync);
- writeAttrWithLog("Attr_WorkMode", WorkMode_FreeSync, err);
- err = write_attribute(Attr_PhotoInterval, 3000);
- writeAttrWithLog("Attr_PhotoInterval", 3000, err);
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
- writeAttrWithLog("Attr_CalibrationMode", CalibrationMode_None, err);
- }
- std::cout << funcTag << "Info: TiRayDR PrepareCalibration completed" << std::endl;
- return true;
- }
- //软同步调用接口,其它同步模式没有动作
- bool Detector_TiRayDR::StartCalibration(FPDDeviceTiRay* pDrvDPC)
- {
- FINFO("--TiRayDR Func-- StartCalibration Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FERROR("Not current DPC, return");
- return false;
- }
- //未初始化、未连接 不执行
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("bConnectState is false, Detector not connected, return");
- return false;
- }
- if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
- {
- FINFO("StartCalibration DARK");
- StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
- m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_Offset;
- }
- else if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
- {
- FINFO("StartCalibration XRAY");
- bool ret = StartAcquisition(pDrvDPC);
- if (!ret)
- {
- FERROR("StartCalibration Over");
- return false;
- }
- m_pStPanelStatus[m_nCurrentPanelID]->eFPDStatus = eDetStatus::DetStatus_XrayCalibration;
- }
- FINFO("TiRayDR StartCalibration Over");
- return true;
- }
- /***
- ** 说明:终止校正
- ***/
- RET_STATUS Detector_TiRayDR::AbortCalibration(FPDDeviceTiRay* pDrvDPC)
- {
- const std::string funcTag = "[Detector_TiRayDR::AbortCalibration] ";
- FINFO("--TiRayDR Func-- AbortCalibration Start");
- if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY)
- {
- // 清除增益校正相关数据
- m_gainCalibImages.clear();
- m_currentDoseImages.clear();
- m_gainV2MeanImages.clear();
- m_currentDoseIndex = 0;
- cout << funcTag << "Aborted " << (!m_bUseGainV2 ? "Gain" : "GainV2")
- << " calibration. All related data cleared" << endl;
- }
- auto err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
- if (err == Err_Success)
- {
- std::cout << funcTag << "Success: Wrote attribute Attr_CalibrationMode with value CalibrationMode_Defect" << std::endl;
- }
- else
- {
- std::cout << funcTag << "Error: Failed to write attribute Attr_CalibrationMode, error code: " << err << std::endl;
- }
- // 恢复初始状态
- m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
- m_nAppStatus = APP_STATUS_CAL_END;
- FINFO("TiRayDR AbortCalibration Over");
- return RET_STATUS::RET_SUCCEED;
- }
- bool Detector_TiRayDR::StopCalibration(FPDDeviceTiRay* pDrvDPC)
- {
- FINFO("--TiRayDR Func-- StopCalibration Start");
- if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
- {
- FERROR("Not current DPC, return");
- return false;
- }
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("bConnectState is false, Detector not connected, return");
- return false;
- }
- m_nAppStatus = APP_STATUS_CAL_END;
- FINFO("TiRayDR StopCalibration Over");
- return true;
- }
- /***
- ** 说明:结束校正
- ** DPC处理完校正报告后调用,此处上传map、报告等文件
- ***/
- bool Detector_TiRayDR::CompleteCalibration(FPDDeviceTiRay* pDrvDPC)
- {
- FINFO("--TiRayDR Func-- CompleteCalibration Start");
- FINFO("Calib Type {$}", (int)m_eCaliType);
- const std::string funcTag = "[Detector_TiRayDR::CompleteCalibration] ";
- if (m_eCaliType == CCOS_CALIBRATION_TYPE_DARK)
- {
- FINFO("DARK Calib over");
- }
- else if (m_eCaliType == CCOS_CALIBRATION_TYPE_XRAY)
- {
- FINFO("XRAY Calib over");
- m_nAppStatus = APP_STATUS_CAL_END;
- }
- m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
- auto err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
- if (err == Err_Success)
- {
- std::cout << funcTag << "Success: Wrote attribute Attr_CalibrationMode with value CalibrationMode_Defect" << std::endl;
- }
- else
- {
- std::cout << funcTag << "Error: Failed to write attribute Attr_CalibrationMode, error code: " << err << std::endl;
- }
- FINFO("TiRayDR CompleteCalibration Over");
- return true;
- }
- bool Detector_TiRayDR::SaveCalibrationFile()
- {
- FINFO("--TiRayDR Func-- SaveCalibrationFile Start");
- if (m_nCalibrationMode)//厂商校正
- {
- //不做处理
- }
- else
- {
- FINFO("Save ZSKK Calibration File");
- m_pZSKKCalib->StoreZSKKGainMap(m_strDetectorType);
- m_pZSKKCalib->StoreZSKKPixMap(m_strDetectorType);
- }
- //更新配置文件中校正日期和时间
- GlobalTime stCurrentTime = { 0 };
- GetLocalTime(&stCurrentTime);
- FINFO("Current time: {$04d}/{$02d}/{$02d} {$02d}:{$02d}:{$02d}:{$03d}",
- stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay,
- stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds);
- FINFO("TiRayDR SaveCalibrationFile Over");
- return true;
- }
- CCOS_CALIBRATION_TYPE Detector_TiRayDR::GetCalibType()
- {
- FINFO("--TiRayDR Func-- GetCalibType Start");
- FINFO("Get Calib Type {$}", (int)m_eCaliType);
- FINFO("TiRayDR GetCalibType Over");
- return m_eCaliType;
- }
- ModelResolveResult Detector_TiRayDR::ResolveModelType(const std::string& detectorType)
- {
- ModelResolveResult result;
- result.isValid = true;
- if (detectorType == "GQ1613") {
- result.model = Model_GQ1613;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_GQ1613)..." << endl;
- }
- else if (detectorType == "DY1613") {
- result.model = Model_DY1613;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY1613)..." << endl;
- }
- else if (detectorType == "LT1719") {
- result.model = Model_LT1719;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_LT1719)..." << endl;
- }
- else if (detectorType == "DY4343") {
- result.model = Model_DY4343;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343)..." << endl;
- }
- else if (detectorType == "DY2530W") {
- result.model = Model_DY2530W;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY2530W)..." << endl;
- }
- else if (detectorType == "DY2121") {
- result.model = Model_DY2121;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY2121)..." << endl;
- }
- else if (detectorType == "DY4343D") {
- result.model = Model_DY4343D;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343D)..." << endl;
- }
- else if (detectorType == "GZ0404") {
- result.model = Model_GZ0404;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_GZ0404)..." << endl;
- }
- else if (detectorType == "DY3543W") {
- result.model = Model_DY3543W;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY3543W)..." << endl;
- }
- else if (detectorType == "DY4343W") {
- result.model = Model_DY4343W;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY4343W)..." << endl;
- }
- else if (detectorType == "DY3543") {
- result.model = Model_DY3543;
- cout << "[Detector_TiRayDR::OpenDetector] Try to start the detector(Model_DY3543)..." << endl;
- }
- else {
- cout << "[Detector_TiRayDR::OpenDetector] Unsupported detector type: " << detectorType << endl;
- // 使用第一个枚举值作为默认,通过isValid标志判断有效性
- result.model = Model_GQ1613;
- result.isValid = false;
- }
- return result;
- }
- bool Detector_TiRayDR::LoadDll(string strWorkPath)
- {
- FINFO("--TiRayDR Func-- LoadDll Start");
- string strSDKPath = "";
- try
- {
- strSDKPath = (string)m_ModeConfig["SDKPath"];
- }
- catch (ResDataObjectExption& e)
- {
- FERROR("Read configuration failed! reason: {$}", e.what());
- return false;
- }
- string workpath = strWorkPath + strSDKPath;
- string drvpath = workpath + "/TiRayLib.so";
- FINFO("SDK path:{$}", drvpath);
- m_hTiRayDRModule = dlopen(drvpath.c_str(), RTLD_LAZY);
- if (m_hTiRayDRModule == nullptr)
- {
- FERROR("Load {$} failed! FERROR: {$}", drvpath.c_str(), dlerror());
- return false;
- }
- LOAD_ONE_FUNC(m_hTiRayDRModule, GetSdkVersion);
- LOAD_ONE_FUNC(m_hTiRayDRModule, Scan);
- LOAD_ONE_FUNC(m_hTiRayDRModule, SetIp);
- LOAD_ONE_FUNC(m_hTiRayDRModule, Startup);
- LOAD_ONE_FUNC(m_hTiRayDRModule, Stop);
- LOAD_ONE_FUNC(m_hTiRayDRModule, Execute);
- LOAD_ONE_FUNC(m_hTiRayDRModule, ApplyPreset);
- LOAD_ONE_FUNC(m_hTiRayDRModule, GenerateTemplate);
-
- FINFO("TiRayDR LoadDll Over");
- return true;
- }
- bool Detector_TiRayDR::ReleaseDll()
- {
- FINFO("--TiRayDR Func-- ReleaseDll Start");
- if (m_hTiRayDRModule != nullptr)
- {
- int result = dlclose(m_hTiRayDRModule);
- if (result != 0) {
- const char* error = dlerror();
- if (error) {
- FERROR("Failed to unload library: %s", error);
- }
- else {
- FERROR("Failed to unload library (unknown error)");
- }
- return false;
- }
- m_hTiRayDRModule = nullptr;
- }
- FINFO("TiRayDR ReleaseDll Over");
- return true;
- }
- /***
- ** 连接探测器
- ***/
- bool Detector_TiRayDR::OpenDetector()
- {
- FINFO("--TiRayDR Func-- OpenDetector Start");
- m_strWiredIP = (std::string)m_ModeConfig["DetectorWiredIP"];
- m_strWirelessIP = (std::string)m_ModeConfig["DetectorWirelessIP"];
- m_strLocalIP = (std::string)m_ModeConfig["LocalIP"];
- m_strSerialNum = (std::string)m_ModeConfig["SerialNumber"];
- FINFO("Configuration parameters loaded - Wired IP:{$}, Wireless IP:{$}, Local IP:{$}",
- m_strWiredIP, m_strWirelessIP, m_strLocalIP);
- FINFO("WiredIP: {$}, LocalIP: {$}, WirelessIP: {$}, SerialNumber:{$}", m_strWiredIP, m_strLocalIP, m_strWirelessIP, m_strSerialNum);
- // 检查连接状态
- bool wired = CheckConnect(m_strWiredIP);
- bool wireless = CheckConnect(m_strWirelessIP);
- FINFO("[Detector_TiRayDR::OpenDetector] Connection status - Wired:{$}, wireless:{$}",
- wired ? "Connected" : "Not connected",
- wireless ? "Connected" : "Not Connected");
- FINFO("[Detector_TiRayDR::OpenDetector] Start scanning the detector...");
- std::vector<scan_result> scan_results;
- scan([&scan_results](scan_result&& result) {
- scan_results.emplace_back(std::move(result));
- });
- if (scan_results.empty()) {
- FINFO("[Detector_TiRayDR::OpenDetector] No detectors were found!");
- return false;
- }
- FINFO("[Detector_TiRayDR::OpenDetector] Scanned to {$} detector:", scan_results.size());
- for (auto& res : scan_results) {
- FINFO("[Detector_TiRayDR::OpenDetector] Serial number:{$}, Model:{$}, tupper IP:{$}, detector IP:{$}",
- res.sn, res.model, res.upper_ip, res.detector_ip);
- }
- m_strDetectorType = (string)m_ModeConfig["DetectorType"];
- FINFO("[Detector_TiRayDR::OpenDetector] Target detector type from config: {$}", m_strDetectorType);
- // 选择目标探测器:优先匹配型号,否则使用第一个
- scan_result target_res = scan_results[0];
- bool found_matching = false;
- for (auto& res : scan_results) {
- if (res.model == m_strDetectorType) {
- target_res = res;
- found_matching = true;
- break; // 找到第一个匹配的即可
- }
- }
- if (found_matching) {
- FINFO("[Detector_TiRayDR::OpenDetector] Found matching detector. Model: {$}, Serial: {$}",
- target_res.model, target_res.sn);
- }
- else {
- FINFO("[Detector_TiRayDR::OpenDetector] No matching detector model, using first detected. Model: {$}, Serial: {$}",
- target_res.model, target_res.sn);
- }
- // 初始化启动参数
- string ip = "0.0.0.0";
- StartupOption option{};
- memcpy(option.Ip, ip.c_str(), std::min(ip.size(), sizeof(option.Ip) - 1));
- option.EnableLog = false;
- // 调用解析函数处理设备类型
- ModelResolveResult resolveResult = ResolveModelType(target_res.model);
- if (!resolveResult.isValid) {
- return false;
- }
- // 启动探测器
- auto err = Startup_Ptr(resolveResult.model, on_event_callback, &option);
- if (err != Err_Success) {
- FINFO("[Detector_TiRayDR::OpenDetector] Failed to start the detector");
- return false;
- }
- auto LoadCalibrationFile = [this](int calibrationParam)
- {
- TiRayError err;
- switch (calibrationParam) {
- case 1:
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
- break;
- case 2:
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_Gain);
- break;
- case 3:
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_Offset);
- break;
- case 4:
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_Defect);
- break;
- default:
- FINFO("[Detector_TiRayDR::OpenDetector] Invalid calibration parameter: {$}", calibrationParam);
- return false;
- }
- if (err != Err_Success) {
- FINFO("[Detector_TiRayDR::OpenDetector] Failed to write Attr_CalibrationMode, error code: {$}", err);
- }
- else {
- FINFO("[Detector_TiRayDR::OpenDetector] Succeeded in writing Attr_CalibrationMode");
- }
- return true;
- };
- FINFO("Start setting the IP address...");
- err = SetIp_Ptr(target_res.sn.c_str(), m_strLocalIP.c_str(), m_strWiredIP.c_str(), nullptr);
- if (err != TiRayError::Err_Success)
- {
- FINFO("The IP setting failed, error code:{$} (will continue to execute)", err);
- return false;
- }
- else {
- FINFO("IP setting was successful");
- }
- while (!m_bConnected)
- {
- usleep(10000);
- }
- m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true;
- //FINFO("m_pStPanelStatus[m_nCurrentPanelID]->bConnectState = true");
- //StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
- //FINFO("Connect detector({$}) success", m_nDetectorID);
- if (m_strDetectorType == "DY4343" || m_strDetectorType == "DY4343D")
- {
- m_bUseGainV2 = true;
- }
- m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"];
- m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"];
- m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][0]["RawImgWidth"];
- m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][0]["RawImgHeight"];
- FINFO("After crop image width: {$}, height: {$}, WidthOffset: {$}, HeightOffset: {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
- m_bSaveRaw = (int)m_ModeConfig["ModeTable"][0]["IsSaveRaw"];
- if (m_pRawImgBuffer == nullptr)
- {
- m_pRawImgBuffer = new WORD[(size_t)m_nRawImgHeight * (size_t)m_nRawImgWidth];
- }
- if (true)
- {
- m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageWidth];
- }
- // 加载校准文件
- cout << "[Detector_TiRayDR::OpenDetector] Start loading the calibration file..." << endl;
- //if (m_nCalibrationMode) //TiRayCalibration
- SetSyncMode(3);
- int nSensitivity = (int)m_ModeConfig["ModeTable"][0]["Sensitivity"];
- int nXWindow = (int)m_ModeConfig["ModeTable"][0]["XWindow"];
- err = write_attribute(Attr_PhotoInterval, nXWindow);
- if (err != Err_Success)
- FINFO("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoInterval. Error code: {$}", err);
- err = write_attribute(Attr_PhotoNumber, 1);
- if (err != Err_Success)
- FINFO("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: {$}", err);
- LoadCalibrationFile(4);
- err = write_attribute(Attr_AEDSensitivity, nSensitivity);
- if (err != Err_Success)
- FINFO("[Detector_TiRayDR::OpenDetector] Failed to write Attr_AEDSensitivity. Error code: {$}", err);
-
- SetTiRayDPCStatus(eDetStatus::DetStatus_Standby);
- FINFO("OpenDetector Over");
- return true;
- }
- bool Detector_TiRayDR::CheckConnect(string strIP)
- {
- CMyPingip obPingIp;
- if (!obPingIp.PingFunction(strIP.c_str()))
- {
- FINFO("ping {$} Failed", strIP);
- return false;
- }
- return true;
- }
- bool Detector_TiRayDR::OpenStatusMonitor()
- {
- FINFO("---Open Status Monitor Thread---");
-
- if (m_hStatusMonitorThread == 0) // 检查线程是否已创建
- {
- int result = pthread_create(&m_hStatusMonitorThread, NULL, TiRayStatusMonitorThread, this);
- if (result != 0) {
- FERROR("Failed to create status monitor thread: %d", result);
- return false;
- }
- }
- return true;
- }
- void* Detector_TiRayDR::TiRayStatusMonitorThread(PVOID pvoid)
- {
- Detector_TiRayDR* pCurrentPanelOpr = static_cast<Detector_TiRayDR*>(pvoid);
- if (pCurrentPanelOpr == nullptr)
- {
- FERROR("TiRay Status Monitor parameter FERROR");
- return nullptr;
- }
- FINFO("Begin StatusMonitor");
- DWORD dwStatusCheckTime = 5000;
- while (!pCurrentPanelOpr->m_bMonitorFlag)
- {
- pCurrentPanelOpr->StatusMonitor();
- usleep(pCurrentPanelOpr->m_nNotifyStatusTimePeriod*1000);
- }
- return 0;
- }
- bool Detector_TiRayDR::StatusMonitor()
- {
- if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
- {
- FERROR("Detector not connected, return");
- ErrorFeedback(EVT_ERR_COMMUNICATE, "true");
- return false;
- }
- //StatusType: 1:Temperature 2:Wifi 3:Battery
- //auto ReadStatus = [this](int StatusType)
- //{
- // TiRayVariant TempParam[1]{};
- // TempParam[0].Type = TiRayVariant::TiRayInt;
- //};
- int nTemperature = 0;
- int nWifiQuality = 0;
- int nBatteryLevel = 0;
- TiRayVariant TemperatureParam[1]{};
- TemperatureParam[0].Type = TiRayVariant::TiRayInt;
- TemperatureParam[0].IntValue = 0;
- Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, TemperatureParam, 1);
- nTemperature = TemperatureParam[0].IntValue;
- TiRayVariant WifiParam[1]{};
- WifiParam[0].Type = TiRayVariant::TiRayInt;
- WifiParam[0].IntValue = nWifiQuality;
- Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, WifiParam, 1);
- TiRayVariant BatteryParam[1]{};
- BatteryParam[0].Type = TiRayVariant::TiRayInt;
- BatteryParam[0].IntValue = nBatteryLevel;
- Execute_Ptr(m_nDetectorID, Cmd_ReadAttribute, BatteryParam, 1);
- StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", m_nCurrentPanelID, nTemperature);
- StatusFeedback(EVT_STATUS_BATTERY_VALUE, nBatteryLevel, "", m_nCurrentPanelID);
- StatusFeedback(EVT_STATUS_WIFI, nWifiQuality, "", m_nCurrentPanelID);
- return true;
- }
- bool Detector_TiRayDR::CloseStatusMonitor()
- {
- m_bMonitorFlag = true;
- m_hStatusMonitorThread = 0;
- FINFO("---Close Status Monitor Thread---");
- return true;
- }
- bool Detector_TiRayDR::CloseDetectorScan()
- {
- m_hExitEvent->SetEvent();
- return false;
- }
- bool Detector_TiRayDR::LoadCalibrationFiles(int nCalibrationMode)
- {
- FINFO("--TiRayDR Func-- LoadCalibrationFiles");
- int nRes;
- TiRayVariant Param[2]{};
- Param[0].Type = TiRayVariant::TiRayInt;
- Param[0].IntValue = TiRayAttribute::Attr_CalibrationMode;
- Param[1].Type = TiRayVariant::TiRayInt;
- if (nCalibrationMode == 1)
- {
- Param[1].IntValue = CalibrationMode::CalibrationMode_None;
- }
- else if (nCalibrationMode == 2)
- {
- Param[1].IntValue = CalibrationMode::CalibrationMode_Gain;
- }
- else if (nCalibrationMode == 3)
- {
- Param[1].IntValue = CalibrationMode::CalibrationMode_Offset;
- }
- else if (nCalibrationMode == 4)
- {
- Param[1].IntValue = CalibrationMode::CalibrationMode_Defect;
- FINFO("All Calibration Mode");
- }
- nRes = Execute_Ptr(m_nDetectorID, Cmd_WriteAttribute, Param, 2);
- if ((TiRayError)nRes != TiRayError::Err_Success)
- {
- FERROR("Use CalibrationMode Failed, Reason:{$}", nRes);
- return false;
- }
- else
- {
- FINFO("Use CalibrationMode Success");
- }
- FINFO("LoadCalibrationFiles Over");
- return true;
- }
- void* Detector_TiRayDR::onFPDScanThread(PVOID pvoid)
- {
- Detector_TiRayDR* pOpr = (Detector_TiRayDR*)pvoid;
- FINFO("Enter scan thread");
- bool bExit = false;
- DWORD dwTimeOut = INFINITE;
- while (!bExit)
- {
- DWORD dwRet = LinuxEvent::WaitForMultipleEvents(pOpr->m_hArrayEvent,dwTimeOut);
- if (WAIT_OBJECT_0 == dwRet) //m_hInitEvent
- {
- pOpr->OnProcessInitFPD();
- }
- else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hExitEvent
- {
- bExit = true;
- }
- else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hReConnectEvent
- {
- pOpr->OnReconnectFPD();
- }
- else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hRadEvent
- {
- FINFO("[Get Rad Event]");
- pOpr->OpenRadAcquisition();
- }
- else if (WAIT_TIMEOUT == dwRet)
- {
- }
- }
- pOpr->m_hToggleEvent->SetEvent();
- FINFO("Leave scan thread");
- return 0;
- }
- void Detector_TiRayDR::OnProcessInitFPD()
- {
- FINFO("--TiRayDR Func-- OnProcessInitFPD");
- StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START);
- if (!LoadDll(m_strWorkPath))
- {
- ErrorFeedback(EVT_ERR_INIT_FAILED, "true");
- StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR); //初始化失败
- return;
- }
- register_event_listener(OnEvent);
- FINFO("Register Event Listener");
- if (!OpenDetector())
- {
- FINFO("Open detector failed, Connect failed");
- ErrorFeedback(EVT_ERR_COMMUNICATE, "true");
- StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END); //初始化时连接失败
- m_hReConnectEvent->SetEvent(); //触发重连逻辑
- }
- else
- {
- m_pStPanelStatus[m_nCurrentPanelID]->bInitOver = true;
- StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK);
- }
- FINFO("OnProcessInitFPD Over");
- }
- void Detector_TiRayDR::OnReconnectFPD()
- {
- FINFO("OnReconnectFPD start");
- if (m_hReconnectThread == 0)
- {
- m_bReconnectThreadRunning = true;
- int result = pthread_create(&m_hReconnectThread, NULL, onReconnectThread, this);
- if (result != 0) {
- FERROR("Failed to create reconnect thread: %d", result);
- m_hReconnectThread = 0;
- m_bReconnectThreadRunning = false;
- }
- }
- FINFO("OnReconnectFPD end");
- }
- /***
- ** 获取一帧暗场图
- ***/
- int Detector_TiRayDR::DarkAcquisition()
- {
- const std::string funcTag = "[Detector_TiRayDR::DarkAcquisition] ";
- TiRayError err;
- // 设置校准模式为None
- err = write_attribute(Attr_CalibrationMode, CalibrationMode_None);
- if (err != Err_Success) {
- cout << funcTag << "Failed to write Attr_CalibrationMode. Error code: " << err << endl;
- return -1;
- }
- // 设置拍摄间隔
- err = write_attribute(Attr_PhotoInterval, 1000);
- if (err != Err_Success) {
- cout << funcTag << "Failed to write Attr_PhotoInterval. Error code: " << err << endl;
- return -1;
- }
- // 设置工作模式为空闲
- err = write_attribute(Attr_WorkMode, WorkMode_Idle);
- if (err != Err_Success) {
- cout << funcTag << "Failed to write Attr_WorkMode. Error code: " << err << endl;
- return -1;
- }
- // 执行拍摄命令
- err = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
- if (err != Err_Success) {
- cout << funcTag << "Failed to Execute_Ptr Cmd_Photo. Error code: " << err << endl;
- return -1;
- }
- return 0; // 成功执行返回0
- }
- /***
- ** 裁剪图像
- ** pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
- ***/
- bool Detector_TiRayDR::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
- {
- if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
- {
- FERROR("Illegal parameter, can not get effective image");
- return false;
- }
- try
- {
- for (int i = 0; i < m_nImageHeight; i++)
- {
- memcpy(pOutImg + i * m_nImageWidth, pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset, m_nImageWidth * sizeof(WORD));
- }
- }
- catch (...)
- {
- FERROR("Get effective image crashed");
- return false;
- }
- return true;
- }
- Detector_TiRayDR::eDetStatus Detector_TiRayDR::GetTiRayDPCStatus(int nDetectorIndex)
- {
- if (-1 == nDetectorIndex)
- {
- nDetectorIndex = m_nCurrentPanelID;
- }
- string strStatus = "Unknown";
- switch (m_pStPanelStatus[nDetectorIndex]->eFPDStatus)
- {
- case eDetStatus::DetStatus_NotIni:
- strStatus = "NotIni";
- break;
- case eDetStatus::DetStatus_NotConn:
- strStatus = "NotConn";
- break;
- case eDetStatus::DetStatus_Sleep:
- strStatus = "Sleep";
- break;
- case eDetStatus::DetStatus_Standby:
- strStatus = "Standby";
- break;
- case eDetStatus::DetStatus_Work:
- strStatus = "Work";
- break;
- case eDetStatus::DetStatus_Acquire:
- strStatus = "Acquire";
- break;
- case eDetStatus::DetStatus_Offset:
- strStatus = "Offset";
- break;
- case eDetStatus::DetStatus_XrayCalibration:
- strStatus = "XrayCalibration";
- break;
- default:
- break;
- }
- FINFO("Driver status: {$}", strStatus.c_str());
- return m_pStPanelStatus[nDetectorIndex]->eFPDStatus;
- }
- bool Detector_TiRayDR::SetTiRayDPCStatus(eDetStatus status, int nDetectorIndex)
- {
- if (-1 == nDetectorIndex)
- {
- nDetectorIndex = m_nCurrentPanelID;
- }
- string strStatus = "Unknown";
- bool bSetStatus = true;
- switch (status)
- {
- case eDetStatus::DetStatus_NotIni:
- strStatus = "NotIni";
- break;
- case eDetStatus::DetStatus_NotConn:
- strStatus = "NotConn";
- break;
- case eDetStatus::DetStatus_Sleep:
- strStatus = "Sleep";
- break;
- case eDetStatus::DetStatus_Standby:
- strStatus = "Standby";
- break;
- case eDetStatus::DetStatus_Work:
- strStatus = "Work";
- break;
- case eDetStatus::DetStatus_Acquire:
- strStatus = "Acquire";
- break;
- case eDetStatus::DetStatus_Offset:
- strStatus = "Offset";
- break;
- case eDetStatus::DetStatus_XrayCalibration:
- strStatus = "XrayCalibration";
- break;
- default:
- bSetStatus = false;
- break;
- }
- if (bSetStatus)
- {
- m_pStPanelStatus[nDetectorIndex]->eFPDStatus = status;
- FINFO("Set driver status: {$}", strStatus.c_str());
- }
- else
- {
- FERROR("{$} {$} is a illegal status", strStatus, (int)status);
- }
- return bSetStatus;
- }
- bool Detector_TiRayDR::IsConnected(string strIP)
- {
- FINFO("Check ping {$}", strIP);
- CMyPingip obPingIp;
- if (!obPingIp.PingFunction(strIP.c_str()))
- {
- FINFO("ping {$} Failed", strIP);
- return false;
- }
- return true;
- }
- bool Detector_TiRayDR::CheckConnection()
- {
- return false;
- }
- bool Detector_TiRayDR::ReConnectFPD()
- {
- CloseStatusMonitor();
- return true;
- }
- bool Detector_TiRayDR::OpenRadAcquisition()
- {
- FINFO("---Begin Rad Acquisition Thread---");
- m_bExitRadAcqStatus = true;
- if (m_hRadAcquisitionThread == 0)
- {
- int result = pthread_create(&m_hRadAcquisitionThread, NULL, RadAcquisitionThread, this);
- if (result != 0) {
- FERROR("Failed to create status monitor thread: %d", result);
- return false;
- }
- }
- return true;
- }
- void* Detector_TiRayDR::RadAcquisitionThread(void* pParam)
- {
- Detector_TiRayDR* pCurrentPanelOpr = reinterpret_cast<Detector_TiRayDR*>(pParam);
- if (pCurrentPanelOpr == nullptr)
- {
- FERROR("Query Acq Status Thread parameter FERROR");
- }
- pCurrentPanelOpr->PerformRadAcquisition();
- pCurrentPanelOpr->CloseRadAcquisition();
- return nullptr;
- }
- bool Detector_TiRayDR::PerformRadAcquisition()
- {
- FINFO("## PerformRadAcquisition ##");
- FINFO("Start Acquisition");
- FINFO("DetectorID: {$}", m_nDetectorID);
- //int nRes = Execute_Ptr(m_nDetectorID, Cmd_Photo, nullptr, 0);
- //if ((TiRayError)nRes != TiRayError::Err_Success)
- //{
- // FERROR("Start Acquisition Failed");
- //}
- while (true)
- {
- usleep(100000);
- if (!m_bExitRadAcqStatus)
- {
- break;
- }
- }
- m_hExitRadAcqStatus->SetEvent();
- FINFO("PerformRadAcquisition Over");
-
- return true;
- }
- bool Detector_TiRayDR::CloseRadAcquisition()
- {
- m_bExitRadAcqStatus = false;
- bool dwResult = false;
- if (m_hExitRadAcqStatus) {
- dwResult = m_hExitRadAcqStatus->Wait(1000);
- }
- if (dwResult)
- {
- FINFO("[Get ExitRadAcqStatus Event]");
- }
- else
- {
- if (m_hRadAcquisitionThread != 0) {
- pthread_cancel(m_hRadAcquisitionThread);
- // 等待线程实际退出
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += 1; // 等待1秒
- pthread_timedjoin_np(m_hRadAcquisitionThread, nullptr, &ts);
- FWARN("Kill QueryAcqStatus Thread");
- }
- FWARN("Kill QueryAcqStatus Thread");
- }
- m_hRadAcquisitionThread = 0;
- FINFO("---Exit Rad Acq Status Thread---");
- return true;
- }
- /***
- ** 检测接口是否有错误,true:有错;false:没错
- ***/
- bool Detector_TiRayDR::TestError(TiRayError nErrorCode)
- {
- if (nErrorCode == TiRayError::Err_Success)
- {
- return true;
- }
- else
- {
- switch (nErrorCode)
- {
- case TiRayError::Err_SystemFailure:
- {
- FERROR("System Internal Error");
- break;
- }
- case TiRayError::Err_WrongModel:
- {
- FERROR("The specified model is incorrect");
- break;
- }
- case TiRayError::Err_DetectorNonExists:
- {
- FERROR("The specified detector with the given ID dose not exist");
- break;
- }
- case TiRayError::Err_NetworkFailure:
- {
- FERROR("The network communication has failed");
- break;
- }
- case TiRayError::Err_InvalidParam:
- {
- FERROR("The provided parameters are incorrect");
- break;
- }
- case TiRayError::Err_UploadInProgress:
- {
- FERROR("The upload is in progress");
- break;
- }
- default:
- FERROR("Unkonwn Error");
- break;
- }
- return false;
- }
- }
- void Detector_TiRayDR::register_event_listener(const EventListener& fn)
- {
- const auto iter = std::find_if(m_listeners.begin(), m_listeners.end(), [&fn](auto& listener) {
- return listener.template target<EventListenerType>() == fn.template target<EventListenerType>();
- });
- if (iter == m_listeners.end())
- m_listeners.push_back(fn);
- }
- void Detector_TiRayDR::unregister_event_listener(const EventListener& fn)
- {
- const auto iter = std::find_if(m_listeners.begin(), m_listeners.end(), [&fn](auto& listener) {
- return listener.template target<EventListenerType>() == fn.template target<EventListenerType>();
- });
- if (iter == m_listeners.end())
- m_listeners.erase(iter);
- }
- bool Detector_TiRayDR::cropImage(unsigned short* srcData, int srcWidth, int srcHeight,
- unsigned short* destData, int destWidth, int destHeight)
- {
- // 验证指针有效性
- if (srcData == nullptr || destData == nullptr) {
- cout << "[Detector_TiRayDR::cropImage] Error: Source or destination pointer is null" << endl;
- return false;
- }
- // 验证尺寸合法性
- if (destWidth <= 0 || destHeight <= 0 ||
- srcWidth <= 0 || srcHeight <= 0 ||
- destWidth > srcWidth || destHeight > srcHeight)
- {
- cout << "[Detector_TiRayDR::cropImage] Invalid crop size: src("
- << srcWidth << "x" << srcHeight << ") dest("
- << destWidth << "x" << destHeight << ")" << endl;
- return false;
- }
- // 从配置中读取裁剪偏移参数,默认为0(居中裁剪)
- int cropOffsetX = 0, cropOffsetY = 0;
- try {
- cropOffsetX = (int)m_ModeConfig["ModeTable"][0]["WidthOffset"];
- cropOffsetY = (int)m_ModeConfig["ModeTable"][0]["HeightOffset"];
- }
- catch (...) {
- cropOffsetX = cropOffsetY = 0;
- }
- // 计算裁剪起始位置
- int startX = (srcWidth - destWidth) / 2 + cropOffsetX;
- int startY = (srcHeight - destHeight) / 2 + cropOffsetY;
- // 边界检查
- if (startX < 0) startX = 0;
- if (startY < 0) startY = 0;
- // 确保裁剪区域不会超出源图像边界
- if (startX + destWidth > srcWidth) {
- destWidth = srcWidth - startX;
- cout << "[Detector_TiRayDR::cropImage] Adjusted destWidth to " << destWidth
- << " to avoid out-of-bounds access" << endl;
- }
- if (startY + destHeight > srcHeight) {
- destHeight = srcHeight - startY;
- cout << "[Detector_TiRayDR::cropImage] Adjusted destHeight to " << destHeight
- << " to avoid out-of-bounds access" << endl;
- }
- // 逐行复制裁剪区域
- for (int y = 0; y < destHeight; ++y)
- {
- // 计算源图像行起始地址
- const unsigned short* srcRow = srcData + (startY + y) * srcWidth + startX;
- // 计算目标图像行起始地址
- unsigned short* destRow = destData + y * destWidth;
- // 复制一行像素
- memcpy(destRow, srcRow, destWidth * sizeof(unsigned short));
- }
- cout << "[Detector_TiRayDR::cropImage] Successfully cropped image from "
- << srcWidth << "x" << srcHeight << " to " << destWidth << "x" << destHeight
- << " with offset (" << cropOffsetX << "," << cropOffsetY << ") -> start ("
- << startX << "," << startY << ")" << endl;
- return true;
- }
- // 生成可读的时间戳字符串: YYYYMMDD_HHMMSS_mmm
- static std::string generateReadableTimestamp()
- {
- GlobalTime currentTime = { 0 };
- GetLocalTime(¤tTime);
- char timestamp[32];
- snprintf(timestamp, sizeof(timestamp), "%04d%02d%02d_%02d%02d%02d_%03d",
- currentTime.wYear, currentTime.wMonth, currentTime.wDay,
- currentTime.wHour, currentTime.wMinute, currentTime.wSecond,
- currentTime.wMilliseconds);
- return std::string(timestamp);
- }
- std::string Detector_TiRayDR::saveProcessedImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp)
- {
- const size_t MAX_PROC_FILE_COUNT = 10;
- const std::string TMPFS_DIR = "/mnt/tmpfs/";
- const std::string BACKUP_DIR = "/userdata/RawData/";
- const std::string ORIGINAL_DIR = detector.m_strWorkPath + "/RawData/";
- const std::string FILE_PREFIX = "Proc_";
- const uintmax_t MIN_REQUIRED_SPACE = size * 2; // 至少需要两倍图像大小的空间
- std::string procDir;
- bool useTmpfs = false;
- std::string filePath;
- // 辅助函数:检查目录空间是否足够
- auto hasEnoughSpace = [&](const std::string& dirPath) -> bool {
- try {
- if (!std::filesystem::exists(dirPath))
- return false;
- auto fsInfo = std::filesystem::space(dirPath);
- bool hasSpace = fsInfo.available >= MIN_REQUIRED_SPACE;
- return hasSpace;
- }
- catch (const std::filesystem::filesystem_error& e) {
- FINFO("Failed to check space for {$}: {$}", dirPath, e.what());
- return false;
- }
- };
- // 辅助函数:尝试在指定目录保存图像
- auto tryToSaveInDir = [&](const std::string& dirPath, bool isTmpfs) -> bool {
- try {
- std::filesystem::create_directories(dirPath);
- filePath = dirPath + FILE_PREFIX + baseTimestamp + ".raw";
- std::ofstream file(filePath, std::ios::binary);
- if (!file.is_open())
- {
- FINFO("Failed to open file: {$}", filePath);
- return false;
- }
- file.write(reinterpret_cast<const char*>(detector.m_pImgBuffer), size);
- file.close();
- if (file.fail())
- {
- FINFO("Failed to write processed image: {$}", filePath);
- // 尝试删除不完整的文件
- std::filesystem::remove(filePath);
- return false;
- }
- FINFO("Saved processed image: {$}", filePath);
- // 使用完整的 baseTimestamp 作为会话标识(格式:YYYYMMDD_HHMMSS_mmm)
- // 清理旧文件,但保护当前会话的文件
- cleanOldFiles(dirPath, FILE_PREFIX, MAX_PROC_FILE_COUNT, isTmpfs, baseTimestamp);
- return true;
- }
- catch (const std::filesystem::filesystem_error& e)
- {
- FINFO("File system error in {$}: {$}", dirPath, e.what());
- return false;
- }
- catch (const std::exception& e)
- {
- FINFO("Unexpected error in {$}: {$}", dirPath, e.what());
- return false;
- }
- };
- // 策略1: 优先使用 tmpfs(如果存在且空间足够)
- if (std::filesystem::exists(TMPFS_DIR) && std::filesystem::is_directory(TMPFS_DIR))
- {
- if (hasEnoughSpace(TMPFS_DIR))
- {
- if (tryToSaveInDir(TMPFS_DIR, true))
- return filePath;
- }
- else
- {
- FINFO("tmpfs space insufficient, trying alternatives");
- }
- }
- // 策略2: 尝试原始目录
- if (hasEnoughSpace(ORIGINAL_DIR))
- {
- if (tryToSaveInDir(ORIGINAL_DIR, false))
- return filePath;
- }
- else
- {
- FINFO("Original directory space insufficient, trying backup");
- }
- // 策略3: 使用备用目录 /userdata/
- FINFO("Using backup directory: {$}", BACKUP_DIR);
- if (tryToSaveInDir(BACKUP_DIR, false))
- return filePath;
- // 所有策略都失败
- FINFO("ERROR: Failed to save processed image in all available directories!");
- return "";
- }
- void Detector_TiRayDR::saveRawImage(Detector_TiRayDR& detector, unsigned short* data, size_t size, const std::string& baseTimestamp)
- {
- const std::string RAW_DIR = detector.m_strWorkPath + "/OriginalData/";
- const std::string BACKUP_RAW_DIR = "/userdata/OriginalData/";
- const std::string FILE_PREFIX = "orig_";
- const size_t MAX_RAW_FILE_COUNT = 20;
- const uintmax_t MIN_REQUIRED_SPACE = size * 2;
- std::string filePath;
- // 辅助函数:尝试保存到指定目录
- auto tryToSaveRawInDir = [&](const std::string& dirPath) -> bool {
- try {
- std::filesystem::create_directories(dirPath);
- filePath = dirPath + FILE_PREFIX + baseTimestamp + ".raw";
- std::ofstream file(filePath, std::ios::binary);
- if (!file.is_open())
- {
- FINFO("Failed to open raw image file: {$}", filePath);
- return false;
- }
- file.write(reinterpret_cast<const char*>(data), size);
- file.close();
- if (file.fail())
- {
- FINFO("Failed to write raw image: {$}", filePath);
- std::filesystem::remove(filePath);
- return false;
- }
- FINFO("Saved raw image: {$}", filePath);
- // 使用完整的 baseTimestamp 作为会话标识(格式:YYYYMMDD_HHMMSS_mmm)
- // 清理旧的原始图,但保护当前会话
- cleanOldFiles(dirPath, FILE_PREFIX, MAX_RAW_FILE_COUNT, false, baseTimestamp);
- return true;
- }
- catch (const std::filesystem::filesystem_error& e)
- {
- FINFO("File system error in {$}: {$}", dirPath, e.what());
- return false;
- }
- };
- // 尝试主目录
- try {
- auto fsInfo = std::filesystem::space(RAW_DIR);
- if (fsInfo.available >= MIN_REQUIRED_SPACE)
- {
- if (tryToSaveRawInDir(RAW_DIR))
- return;
- }
- else
- {
- FINFO("Primary directory space insufficient, using backup");
- }
- }
- catch (const std::filesystem::filesystem_error& e) {
- FINFO("Failed to check primary directory space: {$}", e.what());
- }
- // 尝试备用目录
- if (!tryToSaveRawInDir(BACKUP_RAW_DIR))
- {
- FINFO("ERROR: Failed to save raw image in all available directories!");
- }
- }
- std::filesystem::space_info getFileSystemInfo(const std::string& dirPath) {
- try {
- return std::filesystem::space(dirPath);
- }
- catch (const std::filesystem::filesystem_error& e) {
- FINFO("Failed to get filesystem info for {$}: {$}", dirPath, e.what());
- return {};
- }
- }
- void Detector_TiRayDR::cleanOldFiles(const std::string& dirPath, const std::string& filePrefix,
- size_t maxCount, bool checkSize, const std::string& currentSessionTimestamp)
- {
- try
- {
- // 检查目录是否存在
- if (!std::filesystem::exists(dirPath) || !std::filesystem::is_directory(dirPath))
- {
- return;
- }
- std::vector<std::filesystem::directory_entry> targetFiles;
- std::vector<std::filesystem::directory_entry> currentSessionFiles;
- for (const auto& entry : std::filesystem::directory_iterator(dirPath))
- {
- // 只处理常规文件
- if (!entry.is_regular_file())
- continue;
- // 检查文件扩展名是否为.raw
- const std::string extension = entry.path().extension().string();
- if (extension != ".raw")
- continue;
- // 检查文件名是否以指定前缀开头
- const std::string filename = entry.path().filename().string();
- if (filename.length() < filePrefix.length())
- continue;
- if (filename.substr(0, filePrefix.length()) == filePrefix)
- {
- // 如果提供了当前会话时间戳,检查文件是否属于当前会话
- bool isCurrentSession = false;
- if (!currentSessionTimestamp.empty())
- {
- // 文件名格式:Proc_YYYYMMDD_HHMMSS_mmm_frameNNN.raw
- // currentSessionTimestamp 格式:YYYYMMDD_HHMMSS_mmm
- // 同一次拍摄的所有图片共享相同的会话时间戳(在PrepareAcquisition时生成)
- // 检查文件名是否以 prefix + currentSessionTimestamp 开头
- std::string expectedPrefix = filePrefix + currentSessionTimestamp;
- if (filename.length() >= expectedPrefix.length())
- {
- std::string fileTimestampPart = filename.substr(0, expectedPrefix.length());
- isCurrentSession = (fileTimestampPart == expectedPrefix);
- }
- }
- if (isCurrentSession)
- {
- // 当前会话的文件,单独保存,不参与清理
- currentSessionFiles.push_back(entry);
- }
- else
- {
- targetFiles.push_back(entry);
- }
- }
- }
- if (!currentSessionFiles.empty())
- {
- FINFO("Protected {$} files from current session (timestamp: {$})", currentSessionFiles.size(), currentSessionTimestamp);
- }
- // 按文件最后修改时间排序(最旧的在前)
- std::sort(targetFiles.begin(), targetFiles.end(),
- [](const std::filesystem::directory_entry& a, const std::filesystem::directory_entry& b)
- {
- return std::filesystem::last_write_time(a) < std::filesystem::last_write_time(b);
- });
- // 1. 先按数量限制清理
- size_t filesToDelete = 0;
- if (targetFiles.size() > maxCount)
- {
- filesToDelete = targetFiles.size() - maxCount;
- // 删除超出数量限制的最旧文件
- for (size_t i = 0; i < filesToDelete; ++i)
- {
- const auto& fileToDelete = targetFiles[i];
- if (!std::filesystem::remove(fileToDelete.path()))
- {
- FINFO("Failed to delete file: {$}", fileToDelete.path().string());
- }
- }
- // 更新目标文件列表(移除已删除的文件)
- targetFiles.erase(targetFiles.begin(), targetFiles.begin() + filesToDelete);
- filesToDelete = 0; // 重置计数器用于大小检查
- }
- // 2. 如果需要,按大小限制清理(仅对tmpfs目录)
- if (checkSize && !targetFiles.empty())
- {
- // 获取文件系统信息
- auto fsInfo = getFileSystemInfo(dirPath);
- if (fsInfo.capacity == 0) // 获取信息失败
- {
- return;
- }
- // 计算最大允许使用空间(预留10%作为缓冲)
- const uintmax_t reservedSpace = fsInfo.capacity / 10; // 10%预留空间
- const uintmax_t maxAllowedSize = fsInfo.capacity - reservedSpace;
- // 计算当前文件总大小
- auto calculateTotalSize = [](const std::vector<std::filesystem::directory_entry>& files) {
- uintmax_t total = 0;
- for (const auto& file : files) {
- total += file.file_size();
- }
- return total;
- };
- uintmax_t currentTotalSize = calculateTotalSize(targetFiles);
- // 如果当前总大小超过限制,继续删除最旧的文件
- while (currentTotalSize > maxAllowedSize && !targetFiles.empty())
- {
- const auto& fileToDelete = targetFiles[0];
- uintmax_t fileSize = fileToDelete.file_size();
- if (std::filesystem::remove(fileToDelete.path()))
- {
- // 更新总量和文件列表
- currentTotalSize -= fileSize;
- targetFiles.erase(targetFiles.begin());
- filesToDelete++;
- }
- else
- {
- FINFO("Failed to delete file: {$}", fileToDelete.path().string());
- break; // 删除失败时停止处理
- }
- }
- }
- if (filesToDelete > 0)
- {
- FINFO("Cleanup completed. Deleted {$} files. Remaining: {$}", filesToDelete, targetFiles.size());
- }
- }
- catch (const std::filesystem::filesystem_error& e)
- {
- FINFO("File system error during cleanup: {$}", e.what());
- }
- catch (const std::exception& e)
- {
- FINFO("Unexpected error during cleanup: {$}", e.what());
- }
- }
- void Detector_TiRayDR::handleHardwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
- const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
- detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
- const size_t rawSize = rawPixelCount * sizeof(unsigned short);
- bool cropSuccess = detector.cropImage(
- detector.m_pRawImgBuffer,
- detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
- detector.m_pImgBuffer,
- detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
- );
- if (!cropSuccess)
- {
- cout << "[Detector_TiRayDR::handleAedSyncImage] Failed to crop image" << endl;
- return;
- }
- const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
- // 使用会话时间戳 + 帧号生成文件名
- detector.m_nSessionFrameCounter++;
- char frameStr[16];
- snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
- const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
- std::string processedImagePath = saveProcessedImage(
- detector,
- detector.m_pImgBuffer,
- processedSize,
- baseTimestamp
- );
- if (detector.m_bSaveRaw)
- {
- saveRawImage(
- detector,
- detector.m_pRawImgBuffer,
- rawSize,
- baseTimestamp
- );
- }
- // 应用校准
- // applyCalibration(detector);
- detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
- //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
- detector.m_bExitRadAcqStatus = false;
- }
- void Detector_TiRayDR::handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
- const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
- detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
- const size_t rawSize = rawPixelCount * sizeof(unsigned short);
- bool cropSuccess = detector.cropImage(
- detector.m_pRawImgBuffer,
- detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
- detector.m_pImgBuffer,
- detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
- );
- if (!cropSuccess)
- {
- cout << "[Detector_TiRayDR::handleSoftwareSyncImage] Failed to crop image" << endl;
- return;
- }
- const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
- // 使用会话时间戳 + 帧号生成文件名
- detector.m_nSessionFrameCounter++;
- char frameStr[16];
- snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
- const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
- std::string processedImagePath = saveProcessedImage(
- detector,
- detector.m_pImgBuffer,
- processedSize,
- baseTimestamp
- );
- if (detector.m_bSaveRaw)
- {
- saveRawImage(
- detector,
- detector.m_pRawImgBuffer,
- rawSize,
- baseTimestamp
- );
- }
- detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
- // 应用校准
- // applyCalibration(detector);
- //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
- detector.m_bExitRadAcqStatus = false;
- }
- void Detector_TiRayDR::handleAedSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON);
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
- const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
- detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
- const size_t rawSize = rawPixelCount * sizeof(unsigned short);
- bool cropSuccess = detector.cropImage(
- detector.m_pRawImgBuffer,
- detector.m_nRawImgWidth, detector.m_nRawImgHeight, // 原始图像宽高
- detector.m_pImgBuffer,
- detector.m_nImageWidth, detector.m_nImageHeight // 目标宽高
- );
- if (!cropSuccess)
- {
- cout << "[Detector_TiRayDR::handleAedSyncImage] Failed to crop image" << endl;
- return;
- }
- const size_t processedSize = detector.m_nImageWidth * detector.m_nImageHeight * sizeof(unsigned short);
- // 使用会话时间戳 + 帧号生成文件名
- detector.m_nSessionFrameCounter++;
- char frameStr[16];
- snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
- const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
- std::string processedImagePath = saveProcessedImage(
- detector,
- detector.m_pImgBuffer,
- processedSize,
- baseTimestamp
- );
- if (detector.m_bSaveRaw)
- {
- saveRawImage(
- detector,
- detector.m_pRawImgBuffer,
- rawSize,
- baseTimestamp
- );
- }
- // applyCalibration(detector);
- detector.InfoFeedback(EVT_DATA_RAW_IMAGE, -1, 0, 0, processedImagePath.c_str());
- detector.m_bAEDWorkFlag = false;
- //usleep(500000);
- //detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
- detector.m_bExitRadAcqStatus = false;
- }
- void Detector_TiRayDR::handleDarkCalibration(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- const std::string funcTag = "[Detector_TiRayDR::handleDarkCalibration] ";
- static int callCount = 0;
- static std::vector<TiRayVariant> datas;
- // 处理当前传入的图像数据
- auto size = argv[3].DataLen;
- auto data = argv[3].DataValue;
- image_info image;
- image.width = argv[0].IntValue;
- image.height = argv[1].IntValue;
- image.data.resize(size);
- memcpy(image.data.data(), data, size);
- // 将当前图像数据存入集合
- TiRayVariant variant;
- variant.Type = TiRayVariant::TiRayBuffer;
- variant.DataLen = static_cast<int>(image.data.size());
- variant.DataValue = image.data.data();
- datas.push_back(variant);
- // 调用次数递增(当前已处理的图像数量)
- callCount++;
- // 若未收集到6张图,调用拍摄命令准备下一张
- if (callCount < 6) {
- auto err = Execute_Ptr(detector.m_nDetectorID, Cmd_Photo, nullptr, 0);
- if (err != Err_Success) {
- cout << funcTag << "Failed to execute Cmd_Photo for next image. Error code: " << err << endl;
- // 重置状态,避免异常累积
- callCount = 0;
- datas.clear();
- return;
- }
- cout << funcTag << "Prepared for " << callCount + 1 << "th image" << endl;
- }
- // 收集到6张图,执行模板生成和上传
- else {
- image_info template_image;
- template_image.data.resize(datas[0].DataLen);
- template_image.width = image.width;
- template_image.height = image.height;
- // 生成模板并检查结果
- auto err = GenerateTemplate_Ptr(TemplateType_Offset, datas.data(), static_cast<int>(datas.size()),
- template_image.data.data(), static_cast<int>(template_image.data.size()));
- if (err != Err_Success) {
- cout << funcTag << "Failed to generate offset template. Error code: " << err << endl;
- }
- else {
- cout << funcTag << "Offset template generated successfully with 6 images" << endl;
- // 上传模板并检查结果
- err = detector.upload(detector.offset, template_image.data.data(), static_cast<int>(template_image.data.size()));
- if (err != Err_Success) {
- cout << funcTag << "Failed to upload offset template. Error code: " << err << endl;
- }
- else {
- cout << funcTag << "Offset template uploaded successfully" << endl;
- }
- }
- // 重置静态变量,为下一次校准做准备
- callCount = 0;
- datas.clear();
- }
- }
- void Detector_TiRayDR::handleGainCalibration(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- const std::string funcTag = "[Detector_TiRayDR::handleGainCalibration] ";
- int doseCount = 5; // 剂量数量
- int imagesPerDose = 6; // 每个剂量的图像数量
- auto size = argv[3].DataLen;
- auto data = argv[3].DataValue;
- // 创建图像信息并存储
- image_info image;
- image.width = argv[0].IntValue;
- image.height = argv[1].IntValue;
- image.data.resize(size);
- memcpy(image.data.data(), data, size);
- // 根据模式存储图像
- if (!detector.m_bUseGainV2)
- {
- // Gain模式:直接存储所有30张图像
- detector.m_gainCalibImages.push_back(image);
- cout << funcTag << "Gain mode - Collected " << detector.m_gainCalibImages.size()
- << "/" << doseCount * imagesPerDose << " images" << endl;
- // 收集完30张图像后生成并上传模板
- if (detector.m_gainCalibImages.size() == doseCount * imagesPerDose)
- {
- cout << funcTag << "All 30 gain calibration images collected, generating template..." << endl;
- // 准备数据并生成Gain模板
- std::vector<TiRayVariant> datas;
- for (auto& img : detector.m_gainCalibImages)
- {
- TiRayVariant variant;
- variant.Type = TiRayVariant::TiRayBuffer;
- variant.DataLen = static_cast<int>(img.data.size());
- variant.DataValue = img.data.data();
- datas.push_back(variant);
- }
- image_info template_image;
- template_image.width = detector.m_gainCalibImages[0].width;
- template_image.height = detector.m_gainCalibImages[0].height;
- template_image.data.resize(datas[0].DataLen);
- auto err = GenerateTemplate_Ptr(TemplateType_Gain, datas.data(), static_cast<int>(datas.size()),
- template_image.data.data(), static_cast<int>(template_image.data.size()));
- if (err != Err_Success)
- {
- cout << funcTag << "Failed to generate Gain template. Error code: " << err << endl;
- }
- else
- {
- cout << funcTag << "Gain template generated successfully" << endl;
- // 上传模板
- err = detector.upload(detector.gain, template_image.data.data(),
- static_cast<int>(template_image.data.size()));
- if (err != Err_Success)
- {
- cout << funcTag << "Failed to upload Gain template. Error code: " << err << endl;
- }
- else
- {
- cout << funcTag << "Gain template uploaded successfully" << endl;
- }
- }
- // 清空存储的图像,准备下次校正
- detector.m_gainCalibImages.clear();
- }
- }
- else if (detector.m_bUseGainV2)
- {
- // Gainv2模式:按剂量组存储图像
- detector.m_currentDoseImages.push_back(image);
- cout << funcTag << "Gainv2 mode - Collected " << detector.m_currentDoseImages.size()
- << "/" << imagesPerDose << " images for dose " << detector.m_currentDoseIndex + 1 << endl;
- // 收集完当前剂量的6张图像后生成均值图
- if (detector.m_currentDoseImages.size() == imagesPerDose)
- {
- cout << funcTag << "All " << imagesPerDose << " images for dose " << detector.m_currentDoseIndex + 1
- << " collected, generating mean image..." << endl;
- // 生成当前剂量的均值图
- std::vector<TiRayVariant> datas;
- for (auto& img : detector.m_currentDoseImages)
- {
- TiRayVariant variant;
- variant.Type = TiRayVariant::TiRayBuffer;
- variant.DataLen = static_cast<int>(img.data.size());
- variant.DataValue = img.data.data();
- datas.push_back(variant);
- }
- image_info mean_image;
- mean_image.width = detector.m_currentDoseImages[0].width;
- mean_image.height = detector.m_currentDoseImages[0].height;
- mean_image.data.resize(datas[0].DataLen);
- auto err = GenerateTemplate_Ptr(TemplateType_Mean, datas.data(), static_cast<int>(datas.size()),
- mean_image.data.data(), static_cast<int>(mean_image.data.size()));
- if (err != Err_Success)
- {
- cout << funcTag << "Failed to generate mean image for dose " << detector.m_currentDoseIndex + 1
- << ". Error code: " << err << endl;
- // 清空当前剂量数据,重新收集
- detector.m_currentDoseImages.clear();
- return;
- }
- // 保存均值图并重置当前剂量图像集合
- detector.m_gainV2MeanImages.push_back(mean_image);
- detector.m_currentDoseImages.clear();
- detector.m_currentDoseIndex++;
- cout << funcTag << "Mean image for dose " << detector.m_currentDoseIndex
- << " generated successfully. Total mean images: " << detector.m_gainV2MeanImages.size() << endl;
- // 收集完5个剂量的均值图后生成最终模板
- if (detector.m_gainV2MeanImages.size() == doseCount)
- {
- cout << funcTag << "All " << doseCount << " mean images collected, generating final GainV2 template..." << endl;
- // 生成最终的GainV2模板
- std::vector<TiRayVariant> meanDatas;
- for (auto& meanImg : detector.m_gainV2MeanImages)
- {
- TiRayVariant variant;
- variant.Type = TiRayVariant::TiRayBuffer;
- variant.DataLen = static_cast<int>(meanImg.data.size());
- variant.DataValue = meanImg.data.data();
- meanDatas.push_back(variant);
- }
- image_info final_template;
- final_template.width = detector.m_gainV2MeanImages[0].width;
- final_template.height = detector.m_gainV2MeanImages[0].height;
- final_template.data.resize(meanDatas[0].DataLen);
- auto err = GenerateTemplate_Ptr(TemplateType_GainV2, meanDatas.data(), static_cast<int>(meanDatas.size()),
- final_template.data.data(), static_cast<int>(final_template.data.size()));
- if (err != Err_Success)
- {
- cout << funcTag << "Failed to generate GainV2 template. Error code: " << err << endl;
- }
- else
- {
- cout << funcTag << "GainV2 template generated successfully" << endl;
- // 上传模板
- err = detector.upload(detector.gain, final_template.data.data(),
- static_cast<int>(final_template.data.size()));
- if (err != Err_Success)
- {
- cout << funcTag << "Failed to upload GainV2 template. Error code: " << err << endl;
- }
- else
- {
- cout << funcTag << "GainV2 template uploaded successfully" << endl;
- }
- }
- // 重置所有存储和计数器,准备下次校正
- detector.m_gainV2MeanImages.clear();
- detector.m_currentDoseIndex = 0;
- }
- }
- }
- }
- void Detector_TiRayDR::handleImageReceived(Detector_TiRayDR& detector, TiRayVariant argv[])
- {
- // 处理暗校准模式
- if (CCOS_CALIBRATION_TYPE_DARK == detector.m_eCaliType)
- {
- handleDarkCalibration(detector, argv);
- return;
- }
- else if (CCOS_CALIBRATION_TYPE_XRAY == detector.m_eCaliType)
- {
- handleGainCalibration(detector, argv);
- return;
- }
- // 根据同步模式处理图像
- switch (detector.m_nSyncMode)
- {
- case SYNC_MODE::SYNC_AED:
- handleAedSyncImage(detector, argv);
- break;
- case SYNC_MODE::SYNC_SOFTWARE:
- handleSoftwareSyncImage(detector, argv);
- break;
- case SYNC_MODE::SYNC_HARDWARE:
- handleHardwareSyncImage(detector, argv);
- break;
- }
- }
- void Detector_TiRayDR::on_event_callback(int detectorId, TiRayEvent eventType, TiRayVariant argv[], int argc, void* reservedArg, int reservedArgLen)
- {
- auto& detector = *g_pDetector;
- const std::string funcTag = "[Detector_TiRayDR::on_event_callback] ";
- switch (eventType)
- {
- case TiRayEvent::Evt_DetectorConnect:
- {
- detector.m_nDetectorID = detectorId;
- detector.m_bConnected = true;
- detector.m_pStPanelStatus[detector.m_nCurrentPanelID]->bConnectState = true;
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_CONNECT);
- cout << funcTag << "Evt_DetectorConnect!!!" << endl;
- FINFO("Evt_DetectorConnect!!");
- break;
- }
- case TiRayEvent::Evt_DetectorDisconnect:
- {
- detector.m_nDetectorID = INT_MAX;
- detector.m_bConnected = false;
- detector.m_pStPanelStatus[detector.m_nCurrentPanelID]->bConnectState = false;
- detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_CLOSE);
- detector.m_hReConnectEvent->SetEvent();
- cout << funcTag << "Evt_DetectorDisconnect!!!" << endl;
- FINFO("Evt_DetectorDisconnect!!");
- break;
- }
- case TiRayEvent::Evt_WriteAttribute:
- {
- FINFO("WriteAttribute Success");
- break;
- }
- case TiRayEvent::Evt_ReadAttribute:
- {
- FINFO("ReadAttribute Success");
- //const TiRayAttribute attrib = (TiRayAttribute)argv[0].IntValue;
- //if (attrib == Attr_BatteryStatus) {
- // auto battery_level = argv[1].IntValue;
- // auto is_recharging = argv[2].IntValue;
- //}
- break;
- }
- case TiRayEvent::Evt_ImageReceived:
- {
- cout << funcTag << "Evt_ImageReceived!!!" << endl;
- FINFO("Evt_ImageReceived!!");
- handleImageReceived(detector, argv);
- break;
- }
- case TiRayEvent::Evt_ExposureStatus:
- {
- FINFO("Evt_ExposureStatus:argv {$}, argc {$}", argv[0].IntValue, argc);
- if (argv[0].IntValue == 0)
- {
- detector.m_bAEDReady = true;
- }
- if (argv[0].IntValue == 1)
- {
- detector.m_bAEDReady = false;
- }
- break;
- }
- case TiRayEvent::Evt_UploadProgress:
- cout << funcTag << "Upload progress: " << argv[0].IntValue << "%" << endl;
- break;
- case TiRayEvent::Evt_UpdateFinish:
- cout << funcTag << "Update completed successfully" << endl;
- detector.StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
- break;
- case TiRayEvent::Evt_UploadTimeout:
- // 输出上传超时警告
- cout << funcTag << "Warning: Upload timed detectorData" << endl;
- break;
- default:
- FERROR("not support current event ID:{$}", (int)eventType);
- break;
- }
- }
- void Detector_TiRayDR::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- void Detector_TiRayDR::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- void Detector_TiRayDR::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- void Detector_TiRayDR::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- void Detector_TiRayDR::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- void Detector_TiRayDR::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
- {
- if (-1 == nDetectorID)
- {
- nDetectorID = m_nCurrentPanelID;
- }
- ((FPDDeviceTiRay*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID,
- nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
- }
- bool Detector_TiRayDR::UpdateCalibMode(CCOS_CALIBRATION_MODE eCalibMode)
- {
- FINFO("--TiRayDR Func-- UpdateCalibMode");
- FINFO("CalibMode:{$}", (int)eCalibMode);
- m_nCalibrationMode = eCalibMode;
- FINFO("UpdateCalibMode Over");
- return true;
- }
- void Detector_TiRayDR::SetNotifyStatusTimePeriod(int nTime)
- {
- FINFO("--Func TiRay-- SetNotifyStatusTimePeriod Start");
- FINFO("NotifyStatusTimePeriod:{$}", nTime);
- m_nNotifyStatusTimePeriod = nTime;
- FINFO("SetNotifyStatusTimePeriod Over");
- }
- void Detector_TiRayDR::SetReconnectTimePeriod(int nTime)
- {
- FINFO("--Func TiRay-- SetReconnectTimePeriod Start");
- FINFO("ReconnectTimePeriod:{$}", nTime);
- m_nReconnectTimePeriod = nTime;
- FINFO("SetReconnectTimePeriod Over");
- }
- int Detector_TiRayDR::TiRay_GetSdkVersion()
- {
- return GetSdkVersion_Ptr();
- }
- TiRayError Detector_TiRayDR::TiRay_Execute(int detectorId, int commandId, TiRayVariant argv[], int argc)
- {
- return Execute_Ptr(detectorId, commandId, argv, argc);
- }
- TiRayError Detector_TiRayDR::TiRay_ApplyPreset(int detectorId, TiRayVariant argv[], int argc, ResultCallback fn)
- {
- return ApplyPreset_Ptr(detectorId, argv, argc, fn);
- }
- TiRayError Detector_TiRayDR::TiRay_GenerateTemplate(TemplateType type, TiRayVariant images[], int count, void* templateBuffer, int bufferSize)
- {
- return GenerateTemplate_Ptr(type, images, count, templateBuffer, bufferSize);
- }
- TiRayError Detector_TiRayDR::TiRay_Scan(ResultCallback fn, const char* interfaceIp, int scanDuration)
- {
- return Scan_Ptr(fn, interfaceIp, scanDuration);
- }
- TiRayError Detector_TiRayDR::TiRay_SetIp(const char* detectorSN, const char* upperIp, const char* lowerIp, const char* interfaceIp)
- {
- return SetIp_Ptr(detectorSN, upperIp, lowerIp, interfaceIp);
- }
- TiRayError Detector_TiRayDR::TiRay_Startup(TiRayModel model, EventCallback fn, const StartupOption* option)
- {
- return Startup_Ptr(model, fn, option);
- }
- void Detector_TiRayDR::TiRay_Stop()
- {
- Stop_Ptr();
- }
- /***
- ** 说明:重连探测器线程
- ***/
- void* Detector_TiRayDR::onReconnectThread(PVOID pvoid)
- {
- FINFO("Reconnect detector thread start");
- Detector_TiRayDR* pThis = static_cast<Detector_TiRayDR*>(pvoid);
- while (!pThis->m_bConnected)
- {
- pThis->OpenDetector();
- usleep(pThis->m_nReconnectTimePeriod*1000);
- }
- pThis->m_bReconnectThreadRunning = false;
- FINFO("Leave reconnect detector thread");
- return 0;
- }
- TiRayError Detector_TiRayDR::upload(upload_type type, char* data, int size)
- {
- TiRayVariant param[1]{};
- param[0].Type = TiRayVariant::TiRayBuffer;
- param[0].DataValue = data;
- param[0].DataLen = size;
- if (type == offset) {
- return Execute_Ptr(m_nDetectorID, Cmd_UploadOffsetTemplate, param, 1);
- }
- if (type == gain) {
- return Execute_Ptr(m_nDetectorID, Cmd_UploadGainTemplate, param, 1);
- }
- if (type == firmware) {
- return Execute_Ptr(m_nDetectorID, Cmd_UpdateFirmware, param, 1);
- }
- return Err_InvalidParam;
- }
|