TrixellCtrl.cpp 232 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999
  1. #include "stdafx.h"
  2. #include <tlhelp32.h>
  3. #include "TrixellCtrl.h"
  4. #include "common_api.h"
  5. #include "MyPingip.h"
  6. #include "CiniFile.h"
  7. #include "DeviceConf_Api.h" //加载、处理固件升级、shock信息的配置
  8. extern Log4CPP::Logger* gLogger;
  9. TrixellCtrl* g_pDetector = nullptr;
  10. const string str3543EZINI = "\\Detector3543EZe.ini";
  11. const string str3543DRCINI = "\\Detector3543DRcs.ini";
  12. const string str2430EZINI = "\\Detector2430EZ.ini";
  13. const string str3543EZINI_BK = "\\Detector3543EZe_bk.ini";
  14. const string str3543DRCINI_BK = "\\Detector3543DRcs_bk.ini";
  15. const string str2430EZINI_BK = "\\Detector2430EZ_bk.ini";
  16. const string STR_FXDFILE = "_DefectMapRef_DetMode1_0.fxd";
  17. const string STR_GainFILE = "_GainLinRef_DetMode1_0.fxd";
  18. const string STR_Manual_DefectFILE = "_DefectMapManual_DetMode1.fxd";
  19. const string STR_FXDFILEL = "_DefectMapRef_DetMode2_0.fxd"; //长曝光模式 defect文件名
  20. const string STR_GainFILEL = "_GainLinRef_DetMode2_0.fxd"; //长曝光模式 gain文件名
  21. const string STR_Manual_DefectFILEL = "_DefectMapManual_DetMode2.fxd"; //长曝光模式 defect文件名
  22. const string STR_FIRMWARE_HISTORY = "C:\\Addon\\IC\\Detectortools\\";
  23. //SDK采集模式的宏定义,和DetectorXXXX.ini中modes.application.X.Y中的X对应
  24. //一般顺序:rad、aed、rad_lte、tomo
  25. const int g_nRADmode = 1;
  26. const int g_nAEDmode = 2;
  27. const int g_nRADLTEmode = 3;
  28. const int g_nTOMOmode = 4;
  29. const int g_nRespondTimeout = 5000;
  30. const int g_nConnectTimeout = 20000;
  31. const int g_nRespondTimeoutLong = 30000;
  32. #define MAX_STRING 1024
  33. TrixellCtrl::TrixellCtrl()
  34. {
  35. m_nPanelCount = 0;
  36. m_nCurrentPanelID = 0;
  37. m_pDPC2PanelID = new map<FPDDeviceTrixell*, int>();
  38. m_pPanelID2DPC = new map<int, FPDDeviceTrixell*>();
  39. m_hTrixellModule = NULL;
  40. m_strPanelType = "";
  41. m_strWorkPath = "";
  42. m_strPanelIP = "";
  43. m_strCfgPath = "";
  44. m_bOpened = false;
  45. m_bConnected = false;
  46. m_bLoaded = false;
  47. m_eAppStatus = APP_STATUS_IDLE;
  48. m_nCurrentMode = -1;
  49. m_nCurrentOmMode = -1;
  50. m_nCurrentAppMode = -1;
  51. m_bWorkMode = false;
  52. m_nImageWidth = 0;
  53. m_nImageHeight = 0;
  54. m_nRawImgWidth = 0;
  55. m_nRawImgHeight = 0;
  56. m_nWidthOffset = 0;
  57. m_nHeightOffset = 0;
  58. m_pImgBuffer = NULL;
  59. m_pPreImgBuffer = NULL;
  60. m_pRawImgBuffer = NULL;
  61. m_nImgBits = 16;
  62. m_nPixelPitch = 148;
  63. m_bPreviewEnable = false;
  64. m_nPreviewWidth = 0;
  65. m_nPreviewHeight = 0;
  66. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE;
  67. m_fDose = 0;
  68. m_fCurrentDose = 0;
  69. m_eStatus = DetStatus_NotIni;
  70. m_nXwinOnIndex = 0;
  71. m_nTomoImgIndex = 0;
  72. m_nTomoImgCount = 30;
  73. m_nCaliFailedCount = 0;
  74. m_bGainPreparing = false;
  75. m_bGainProcess = false;
  76. m_bConfirmCaliRst = false;
  77. m_bAutoContinueCal = false;
  78. m_nSaveRaw = PIX_IMG_NONE;
  79. m_bPreviewImg = false;
  80. m_bExpEnable = false;
  81. m_eImgType = PIX_IMG_FULL;
  82. m_bWaitAcqEnd = false;
  83. m_bPrepShot = false;
  84. //m_nGainNodeCount = 0;
  85. //m_nGainNodeIndex = 0;
  86. //m_nGainExpCount = 0;
  87. //m_nGainExpIndex = 0;
  88. m_eCorrectionType = CT_OFFSET;
  89. m_eCurrentCT = CT_NONE;
  90. m_bAbortRefreshOft = false;
  91. m_nOftRefreshTimer = 0; //缺省2分钟
  92. m_nAngle = 0;
  93. m_nIgnoreImgCount = 0;
  94. m_nIgnoreImgNum = 0;
  95. InitializeCriticalSection(&m_cs);
  96. m_nDetectorID = 0; //目前只支持单板,此处缺省0即可
  97. m_bAttaching = false;
  98. m_bModuleConnecting = false;
  99. m_bModulePresent = false;
  100. m_bModuleEnable = true;
  101. m_bUpdateFirmwareDirect = false;
  102. m_bNeedFeedback = false;
  103. m_bLTEenable = false;
  104. m_eSyncMode = SYNC_SOFTWARE;
  105. m_bTransImageSuccess = true; //缺省true,曝光后置为false
  106. //m_nTotalShockNumber = -1;
  107. m_nAttachFPDID = -1;
  108. m_nUpdateFPDID = -1;
  109. m_strAttachFPD = "";
  110. m_nAttachFPDID = -1;
  111. m_nShockFPDID = -1;
  112. //m_nInitFPDCount = 0;
  113. m_bExitShockCheck = false;
  114. m_nRefreshOftMode = 0;
  115. m_bIsImageRecovering = false;
  116. m_nRequireHWType = 0;
  117. m_nStatusTimeout = 600;
  118. m_nPollingTimes = 0;
  119. m_nStopPollingIndex = -1;
  120. m_bIsExpInAuto = true; //缺省true 如果没有开始aed流程就退出检查,这样不会调用stopacq
  121. m_bRefreshing = false;
  122. m_bReInitialize = false;
  123. m_hModuleThread = NULL;
  124. m_hFPDScanThread = NULL;
  125. m_hFPDStatusThread = NULL;
  126. m_hCheckShockThread = NULL;
  127. m_hRespondEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  128. m_hShareEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  129. m_hCheckShockEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  130. m_hToggleEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  131. m_hQuitAdaptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  132. m_hQuitStatusEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  133. m_hStopScanEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  134. m_hProcessImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  135. m_hXWinOnEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  136. m_hXWinOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  137. m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  138. m_hDarkEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  139. m_hClosePollingEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  140. m_hArrayEvent[0] = m_hStopScanEvent;
  141. m_hArrayEvent[1] = m_hProcessImgEvent;
  142. m_hArrayEvent[2] = m_hXWinOnEvent;
  143. m_hArrayEvent[3] = m_hXWinOffEvent;
  144. m_hArrayEvent[4] = m_hEndCalibEvent;
  145. m_hArrayEvent[5] = m_hDarkEndEvent;
  146. m_hArrayEvent[6] = m_hClosePollingEvent;
  147. m_nCfgCalibPrepare = 0;
  148. m_bAutonumousMode = false;
  149. m_strAutonumousMetaData = "";
  150. m_nAutonumousImageIndex = 0;
  151. m_nCalibrationMode = CCOS_CALIBRATION_MODE_ZSKK;
  152. m_pZSKKCalib = nullptr;
  153. m_nCalibCurrentCalibrationRound = 0;
  154. m_nCalibrationRounds = 0;
  155. m_nCalibCurrentExposureIndex = 0;
  156. m_nExposureNumCurrentRound = 0;
  157. m_bSaveCalibrationRaw = true;
  158. }
  159. TrixellCtrl::~TrixellCtrl()
  160. {
  161. if (m_pImgBuffer)
  162. {
  163. delete[] m_pImgBuffer;
  164. m_pImgBuffer = nullptr;
  165. }
  166. if (m_hRespondEvent)
  167. {
  168. CloseHandle(m_hRespondEvent);
  169. m_hRespondEvent = nullptr;
  170. }
  171. if (m_hShareEvent)
  172. {
  173. CloseHandle(m_hShareEvent);
  174. m_hShareEvent = nullptr;
  175. }
  176. if (m_hProcessImgEvent)
  177. {
  178. CloseHandle(m_hProcessImgEvent);
  179. m_hProcessImgEvent = nullptr;
  180. }
  181. if (m_hXWinOnEvent)
  182. {
  183. CloseHandle(m_hXWinOnEvent);
  184. m_hXWinOnEvent = nullptr;
  185. }
  186. if (m_hXWinOffEvent)
  187. {
  188. CloseHandle(m_hXWinOffEvent);
  189. m_hXWinOffEvent = nullptr;
  190. }
  191. if (m_hStopScanEvent)
  192. {
  193. CloseHandle(m_hStopScanEvent);
  194. m_hStopScanEvent = nullptr;
  195. }
  196. if (m_hDarkEndEvent)
  197. {
  198. CloseHandle(m_hDarkEndEvent);
  199. m_hDarkEndEvent = nullptr;
  200. }
  201. if (m_hEndCalibEvent)
  202. {
  203. CloseHandle(m_hEndCalibEvent);
  204. m_hEndCalibEvent = nullptr;
  205. }
  206. if (m_hCheckShockEvent)
  207. {
  208. CloseHandle(m_hCheckShockEvent);
  209. m_hCheckShockEvent = nullptr;
  210. }
  211. if (m_hToggleEvent)
  212. {
  213. CloseHandle(m_hToggleEvent);
  214. m_hToggleEvent = nullptr;
  215. }
  216. if (m_hQuitAdaptEvent)
  217. {
  218. CloseHandle(m_hQuitAdaptEvent);
  219. m_hQuitAdaptEvent = nullptr;
  220. }
  221. if (m_nPanelCount != 0)
  222. {
  223. for (int i = 0; i < m_nPanelCount; i++)
  224. {
  225. delete[] m_pStPanelStatus[i];
  226. }
  227. }
  228. if (m_pZSKKCalib)
  229. {
  230. delete m_pZSKKCalib;
  231. m_pZSKKCalib = nullptr;
  232. }
  233. delete m_pDPC2PanelID;
  234. m_pDPC2PanelID = NULL;
  235. delete m_pPanelID2DPC;
  236. m_pPanelID2DPC = NULL;
  237. }
  238. #define LOAD_PROC_ADDRESS(handle,func) \
  239. if ((func = (CB_##func)GetProcAddress(handle, #func)) == NULL) { printf("Error occurs while loading entry point!!! \n'%s'\n", #func); }\
  240. bool TrixellCtrl::AddDPCs(FPDDeviceTrixell* pDrvDPC, ResDataObject& Configuration, DeviceIndexStruct& DeviceStruct)
  241. {
  242. map<FPDDeviceTrixell*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  243. if (DPCsIter != m_pDPC2PanelID->end())
  244. {
  245. Warn("TrixellCtrl::AddDPCs This DPC already exist\n");
  246. return false;
  247. }
  248. Info("--Func-- AddDPCs {$}", pDrvDPC);
  249. //拿到当前探测器的配置
  250. m_stDeviceIndex[m_nPanelCount] = DeviceStruct;
  251. m_ModeConfig = Configuration;
  252. ResDataObject objFPDInfo;
  253. //拿到当前探测器的配置
  254. try
  255. {
  256. CPanelStatus* p = new CPanelStatus[1];
  257. m_pStPanelStatus[m_nPanelCount] = p;
  258. if (m_nPanelCount == 0)
  259. {
  260. m_ObjFPDsInfo.add("FPDNum", 1);
  261. }
  262. else
  263. {
  264. m_ObjFPDsInfo["FPDNum"] = m_nPanelCount + 1;
  265. }
  266. objFPDInfo.add("FPD", Configuration[DetectorDescription]);
  267. m_pStPanelStatus[m_nPanelCount]->strPanelType = (string)Configuration[DetectorDescription];
  268. if (m_pStPanelStatus[m_nPanelCount]->strPanelType == "3543DRgx")
  269. {
  270. m_pStPanelStatus[m_nPanelCount]->bHaveAutonumousMode = true;
  271. }
  272. m_pStPanelStatus[m_nPanelCount]->objPanelConfig = Configuration;
  273. if (m_ObjFPDsInfo.GetFirstOf("FPDs") >= 0)
  274. {
  275. m_ObjFPDsInfo["FPDs"].add("FPD", Configuration[DetectorDescription]);
  276. }
  277. else
  278. {
  279. m_ObjFPDsInfo.add("FPDs", objFPDInfo);
  280. }
  281. }
  282. catch (ResDataObjectExption& e)
  283. {
  284. Error("Get detector configuration failed: {$}", e.what());
  285. return false;
  286. }
  287. m_pDPC2PanelID->insert(pair<FPDDeviceTrixell*, int>(pDrvDPC, m_nPanelCount));
  288. m_pPanelID2DPC->insert(pair<int, FPDDeviceTrixell*>(m_nPanelCount, pDrvDPC));
  289. m_nPanelCount++;
  290. Info("TrixellCtrl::AddDPCs ok {$}\n", m_nPanelCount);
  291. return true;
  292. }
  293. bool TrixellCtrl::DelDPCs(FPDDeviceTrixell* pDrvDPC)
  294. {
  295. map<FPDDeviceTrixell*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  296. if (DPCsIter != m_pDPC2PanelID->end())
  297. {
  298. map<int, FPDDeviceTrixell*>::iterator PanelIdIter = m_pPanelID2DPC->find(DPCsIter->second);
  299. if (PanelIdIter != m_pPanelID2DPC->end())
  300. {
  301. m_pPanelID2DPC->erase(PanelIdIter);
  302. //删掉相应的探测器配置,用于修改SDK
  303. ResDataObject objFPDsInfo = m_ObjFPDsInfo;
  304. ResDataObject objFPDInfo;
  305. int nCount = (int)objFPDsInfo["FPDs"].GetKeyCount("FPD");
  306. if (nCount > 0)
  307. {
  308. m_ObjFPDsInfo.clear();
  309. m_ObjFPDsInfo.add("FPDNum", m_nPanelCount - 1);
  310. for (int i = 0; i < nCount; i++)
  311. {
  312. if (i != DPCsIter->second)
  313. {
  314. objFPDInfo.add("FPD", objFPDsInfo["FPDNum"][i]);
  315. }
  316. }
  317. m_ObjFPDsInfo.add("FPDs", objFPDInfo);
  318. }
  319. }
  320. m_pDPC2PanelID->erase(DPCsIter);
  321. m_nPanelCount--;
  322. Info("TrixellCtrl::DelDPCs ok {$}\n", m_nPanelCount);
  323. }
  324. return true;
  325. }
  326. bool TrixellCtrl::SwitchPanel(int nPanelId)
  327. {
  328. //切换前动作
  329. //1.图像恢复过程,不能切换 - 恢复流程不执行完毕,应该不会走到切换流程,暂不处理
  330. //2.使能状态,需要先停止采集 - 切换时应该也到不了FramePrep阶段,暂不处理
  331. //3.停止当前板的状态反馈 - 现在多板状态都交由SDK反馈,这里不用停
  332. //4.重置图像宽高等参数 - selectexammode去处理
  333. if (!SetSystemState(STATE_QUIET))
  334. {
  335. Error("Set Quiet State Failed");
  336. return false;
  337. }
  338. else
  339. {
  340. Info("Set Quiet State OK");
  341. }
  342. if (!SetActiveDetector(nPanelId))
  343. {
  344. Error("Active detector Failed");
  345. return false;
  346. }
  347. return true;
  348. }
  349. bool TrixellCtrl::ActivePanel(FPDDeviceTrixell* pDrvDPC)
  350. {
  351. Info("ActivePanel start: {$}, m_nCurrentPanelID {$}", pDrvDPC, m_nCurrentPanelID);
  352. map<FPDDeviceTrixell*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  353. if (DPCsIter != m_pDPC2PanelID->end())
  354. {
  355. if (m_nCurrentPanelID != DPCsIter->second)
  356. {
  357. Info("m_nCurrentPanelID {$} != DPCsIter->second {$}", m_nCurrentPanelID, DPCsIter->second);
  358. if (!SwitchPanel(DPCsIter->second))
  359. {
  360. return false;
  361. }
  362. m_nCurrentPanelID = DPCsIter->second;
  363. m_pCurrentDPC = pDrvDPC;
  364. m_nCurrentMode = -1;
  365. Info("ActivePanel over: {$}, m_nCurrentPanelID {$}", pDrvDPC, m_nCurrentPanelID);
  366. }
  367. else
  368. {
  369. Info("m_nCurrentPanelID {$} == DPCsIter->second {$}", m_nCurrentPanelID, DPCsIter->second);
  370. }
  371. }
  372. else
  373. {
  374. return false;
  375. }
  376. return true;
  377. }
  378. bool TrixellCtrl::EnterExam(APP_STATUS eStatus)
  379. {
  380. string strLog = "";
  381. switch (eStatus)
  382. {
  383. case APP_STATUS_IDLE:
  384. strLog = "APP_STATUS_IDLE";
  385. break;
  386. case APP_STATUS_WORK_BEGIN:
  387. strLog = "APP_STATUS_WORK_BEGIN";
  388. break;
  389. case APP_STATUS_WORK_END:
  390. strLog = "APP_STATUS_WORK_END";
  391. break;
  392. case APP_STATUS_DETSHARE_BEGIN:
  393. strLog = "APP_STATUS_DETSHARE_BEGIN";
  394. break;
  395. case APP_STATUS_DETSHAR_END:
  396. strLog = "APP_STATUS_DETSHAR_END";
  397. break;
  398. case APP_STATUS_CAL_BEGIN:
  399. strLog = "APP_STATUS_CAL_BEGIN";
  400. break;
  401. case APP_STATUS_CAL_END:
  402. strLog = "APP_STATUS_CAL_END";
  403. break;
  404. case APP_STATUS_WORK_IN_SENSITIVITY:
  405. strLog = "APP_STATUS_WORK_IN_SENSITIVITY";
  406. break;
  407. default:
  408. break;
  409. }
  410. Info("Enter exam: {$}", strLog.c_str());
  411. m_eAppStatus = eStatus;
  412. if (APP_STATUS_WORK_BEGIN == eStatus) //如果红外对接后再进检查,也要进行attach
  413. {
  414. if (m_pStPanelStatus[0]->bConnectStatus == false)
  415. {
  416. Info("Panel status connect status false");
  417. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", 0);
  418. }
  419. }
  420. else if (APP_STATUS_WORK_END == eStatus)
  421. {
  422. if (PIX_OM_AED == m_nCurrentOmMode)
  423. {
  424. if (!m_bIsExpInAuto)
  425. {
  426. m_bWaitAcqEnd = true;
  427. LockPixrad("StopAcquisition");
  428. Info("Calling StopAcquisition");
  429. error_status ErrorStatus = TED_PixRad_StopAcquisition(); //EVT_END_ACQUISITION
  430. if (TestError(ErrorStatus))
  431. {
  432. Info("Stop acquisition command OK");
  433. LockPixrad(); //等待回调(stop操作执行完毕)
  434. UnlockPixrad("StopAcquisition");
  435. }
  436. else
  437. {
  438. Error("Stop acuqisition command failed");
  439. UnlockPixrad("StopAcquisition");
  440. }
  441. }
  442. }
  443. }
  444. return true;
  445. }
  446. int TrixellCtrl::GetDPCsCount()
  447. {
  448. return m_nPanelCount;
  449. }
  450. /***
  451. ** 说明:连接
  452. ** 加载SDK,初始化SDK,连接探测器等初始化操作
  453. ** 参数:strWorkPath,初始化SDK必须的conf路径
  454. ***/
  455. bool TrixellCtrl::Connect(string strWorkPath, FPDDeviceTrixell* pDrvDPC)
  456. {
  457. Info("--Func-- Connect");
  458. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  459. {
  460. Debug("Not current DPC, return true");
  461. return true;
  462. }
  463. m_strWorkPath = strWorkPath;
  464. Info("Current work path: {$}", m_strWorkPath);
  465. if (!m_pZSKKCalib)
  466. {
  467. m_pZSKKCalib = new CZSKKCalibrationCtrl();
  468. }
  469. int nRet = InitDetector();
  470. if (INIT_SUCCESS == nRet)
  471. {
  472. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_OK, "", m_nCurrentPanelID);
  473. }
  474. else if (INIT_FIRMWARE == nRet)
  475. {
  476. }
  477. else if (INIT_CONNECT_ERR == nRet)
  478. {
  479. Error("TrixellCtrl::Connect INIT_CONNECT_ERR");
  480. }
  481. else
  482. {
  483. Error("Connect detector failed");
  484. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", m_nCurrentPanelID);
  485. return false;
  486. }
  487. DWORD dwThreadId;
  488. if (NULL == m_hFPDScanThread)
  489. {
  490. m_hFPDScanThread = CreateThread(NULL, 0, onFPDScanThread, this, 0, &dwThreadId); //启动辅助线程
  491. }
  492. if (NULL == m_hFPDStatusThread)
  493. {
  494. m_hFPDStatusThread = CreateThread(NULL, 0, onFPDStatusThread, this, 0, &dwThreadId);
  495. }
  496. if (m_hCheckShockThread == NULL)
  497. {
  498. m_hCheckShockThread = CreateThread(NULL, 0, onCheckShockThread, this, 0, &dwThreadId);
  499. }
  500. m_eStatus = DetStatus_Standby; //初始化完毕,置为Standby
  501. Info("=== Connect detector OK ===");
  502. return true;
  503. }
  504. /***
  505. ** 说明:退出
  506. ** 释放SDK
  507. ***/
  508. void TrixellCtrl::DisConnect(FPDDeviceTrixell* pDrvDPC)
  509. {
  510. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  511. {
  512. Info("Not current DPC, return");
  513. return;
  514. }
  515. Info("--Func-- DisConnect");
  516. //先退出自动重连线程,避免和接下来的退出流程冲突
  517. if (m_hFPDStatusThread != NULL)
  518. {
  519. ResetEvent(m_hToggleEvent);
  520. SetEvent(m_hQuitStatusEvent);
  521. DWORD result = WaitForSingleObject(m_hToggleEvent, 65000);
  522. if (result == WAIT_OBJECT_0)
  523. {
  524. Info("Leave Thread Over");
  525. }
  526. else if (result == WAIT_TIMEOUT)
  527. {
  528. Warn("Till time out");
  529. }
  530. m_hFPDStatusThread = NULL;
  531. }
  532. //退出SDK
  533. try
  534. {
  535. if (!SetSystemState(STATE_QUIET))
  536. {
  537. Warn("Set Quiet State Failed");
  538. }
  539. else
  540. {
  541. Info("Set Quiet State OK");
  542. }
  543. Info("Calling close");
  544. error_status ErrorStatus = TED_PixRad_Close();
  545. if (TestError(ErrorStatus))
  546. {
  547. Info("Close detector ok");
  548. }
  549. else
  550. {
  551. Warn("Close detector failed");
  552. }
  553. Info("DisConnect Call PixRad_UnregisterEventCallback");
  554. TED_PixRad_UnregisterEventCallback(EventCallback);
  555. m_bOpened = false;
  556. }
  557. catch (...)
  558. {
  559. Fatal("Close detector crash");
  560. }
  561. //退出线程
  562. StopThread();
  563. Info("DisConnect Over");
  564. }
  565. /***
  566. ** 说明:DPC下发要attach的探测器信息
  567. ** 参数:strFPDType,探测器类型
  568. ** nDetectorID,该探测器对应的subDPC ID
  569. ***/
  570. void TrixellCtrl::SetAttachFPDInfo(string strFPDType, int nDetectorID)
  571. {
  572. Info("The {$}({$}) is ready to be attached", strFPDType, nDetectorID);
  573. m_strAttachFPD = strFPDType;
  574. m_nAttachFPDID = nDetectorID;
  575. }
  576. /***
  577. ** 说明:用户确认要连接当前attach的探测器
  578. ***/
  579. bool TrixellCtrl::AttachDetector(FPDDeviceTrixell* pDrvDPC)
  580. {
  581. map<FPDDeviceTrixell*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  582. if (DPCsIter != m_pDPC2PanelID->end())
  583. {
  584. int nDetectorID = m_nAttachFPDID;
  585. Info("--Func-- AttachDetector(ID:{$})", nDetectorID);
  586. m_bModuleConnecting = true;
  587. m_bAttaching = false;
  588. //ping通探测器,修改配置 begin
  589. string strSetIP = "";
  590. string strConfHostIP = "";
  591. try
  592. {
  593. strConfHostIP = (string)m_pStPanelStatus[m_nAttachFPDID]->objPanelConfig["connections"]["LocalIP"] + R"(/24)";
  594. }
  595. catch (ResDataObjectExption& exp)
  596. {
  597. Error("Get configuration failed, {$}", exp.what());
  598. m_bModuleConnecting = false;
  599. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", nDetectorID);
  600. return false;
  601. }
  602. strSetIP = m_pStPanelStatus[m_nAttachFPDID]->strModuleIP;
  603. int nPingTotalTime = 30;//ping不通,一次约6s,共30次,4分钟左右超时
  604. int nPingTimes = 0;
  605. Info("AttachDetector strSetIP:{$}", strSetIP);
  606. for (; nPingTimes < nPingTotalTime; nPingTimes++)
  607. {
  608. bool bConnect = IsConnected(strSetIP); //有ping权限么?
  609. if (bConnect)
  610. {
  611. Info("Ping Detector successfully");
  612. break;
  613. }
  614. Sleep(2000);
  615. if (!InDetectorShare()) //如果退出Share界面了,返回false
  616. {
  617. m_bModuleConnecting = false;
  618. return false;
  619. }
  620. }
  621. if (nPingTotalTime == nPingTimes) //如果没有ping通探测器,不连接
  622. {
  623. //UnlockPixrad();
  624. Error("Cannot Ping Detector IP Failed");
  625. m_bModuleConnecting = false;
  626. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", nDetectorID);
  627. return false;
  628. }
  629. if (ModifyModuleFPDConf(strSetIP, strConfHostIP))
  630. {
  631. ConfFeedback(EVT_CONF_MODULE_IP, m_nAttachFPDID, strSetIP.c_str()); //把配置文件中的反馈上去
  632. m_pStPanelStatus[m_nAttachFPDID]->objPanelConfig["SerialNumber"] = m_strModuleSN.c_str();
  633. }
  634. else
  635. {
  636. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", nDetectorID);
  637. m_bModuleConnecting = false;
  638. return false;
  639. }
  640. //end
  641. //修改连接配置,使接下来调用API,执行连接过程
  642. SetConnectConf(true, nDetectorID);
  643. CloseDetector();
  644. m_bModulePresent = false;//防止:释放SDK后,红外断开,无法拿到红外断开状态,影响后面attach其他探测器进入share界面弹错误窗
  645. int nRet = InitDetector(true, nDetectorID);
  646. if (nRet != INIT_FIRMWARE)
  647. {
  648. if (m_pStPanelStatus[nDetectorID]->bConnectStatus)
  649. {
  650. Info("Attach succeed");
  651. UpdatePanelSerialFile(m_strModuleType, m_strModuleSN,
  652. m_pStPanelStatus[m_nAttachFPDID]->strModuleIP, "", true);
  653. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_OK, "", nDetectorID);
  654. m_bModuleConnecting = false;
  655. return true;
  656. }
  657. else
  658. {
  659. Info("Attach failed");
  660. DisconnectDetector(nDetectorID);
  661. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", nDetectorID);
  662. m_bModuleConnecting = false;
  663. return false;
  664. }
  665. }
  666. else if (m_pStPanelStatus[nDetectorID]->bNeedUpdateFW)
  667. {
  668. Info("Attach pending");
  669. m_nUpdateFPDID = nDetectorID;
  670. //启动线程,升级固件
  671. HANDLE hUpdateThread;
  672. DWORD unThreadID;
  673. hUpdateThread = CreateThread(NULL, 0, onUpdateFWThread, this, 0, &unThreadID);
  674. if (hUpdateThread == NULL)
  675. {
  676. Error("Start Update Firmware Thread Error");
  677. }
  678. }
  679. }
  680. return true;
  681. }
  682. /***
  683. ** 说明:用户确认不连接当前attach的探测器
  684. ***/
  685. void TrixellCtrl::CancelAttach()
  686. {
  687. Info("Cancel the attach process");
  688. m_bAttaching = false;
  689. }
  690. RET_STATUS TrixellCtrl::SetSyncMode(SYNC_MODE nSyncMode, HARDWARE_TRIGGER_MODE TriggerMode)
  691. {
  692. m_eSyncMode = nSyncMode;
  693. return RET_STATUS::RET_SUCCEED;
  694. }
  695. /***
  696. ** 说明:设置当前的曝光模式
  697. ** 参数:nLogicMode,从配置文件读取,与SDK配置application mode对应
  698. ***/
  699. bool TrixellCtrl::SelectExamMode(int nLogicMode, FPDDeviceTrixell* pDrvDPC)
  700. {
  701. Info("TrixellCtrl::SelectExamMode start");
  702. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  703. {
  704. Info("Not current DPC {$}, {$} != {$} ,return", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nCurrentPanelID);
  705. return false;
  706. }
  707. Info("SelectExamMode({$})", nLogicMode);
  708. if (m_nCurrentAppMode == nLogicMode) //同样appmode下没必要再次走下面的流程
  709. {
  710. Info("Same appmode, return true");
  711. return true;
  712. }
  713. m_nRawImgWidth = m_stDeviceIndex[m_nCurrentPanelID].nRawWidth;
  714. m_nRawImgHeight = m_stDeviceIndex[m_nCurrentPanelID].nRawHeight;
  715. m_nImageWidth = m_stDeviceIndex[m_nCurrentPanelID].nFullImageWidth;
  716. m_nImageHeight = m_stDeviceIndex[m_nCurrentPanelID].nFullImageHeight;
  717. m_nWidthOffset = m_stDeviceIndex[m_nCurrentPanelID].nImageLeftOffset;
  718. m_nHeightOffset = m_stDeviceIndex[m_nCurrentPanelID].nImageTopffset;
  719. m_nImgBits = m_stDeviceIndex[m_nCurrentPanelID].nImageBits;
  720. m_nPixelPitch = m_stDeviceIndex[m_nCurrentPanelID].nPixelSpace;
  721. m_nSaveRaw = m_stDeviceIndex[m_nCurrentPanelID].nSaveRaw;
  722. m_nTomoImgCount = m_stDeviceIndex[m_nCurrentPanelID].nFrameCount;
  723. if (m_pImgBuffer)
  724. {
  725. delete m_pImgBuffer;
  726. m_pImgBuffer = NULL;
  727. }
  728. m_pImgBuffer = new WORD[m_nImageHeight * m_nImageWidth];
  729. if (m_pRawImgBuffer)
  730. {
  731. delete m_pRawImgBuffer;
  732. m_pRawImgBuffer = NULL;
  733. }
  734. m_pRawImgBuffer = new WORD[m_nRawImgHeight * m_nRawImgWidth];
  735. Info("Image size(W*H), Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$}), Bits({$}), PixelPitch({$}), SaveRaw({$}), FrameCount({$})",
  736. m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset, m_nImgBits, m_nPixelPitch, m_nSaveRaw, m_nTomoImgCount);
  737. m_bPreviewEnable = m_stDeviceIndex[m_nCurrentPanelID].bPreviewEnable;
  738. m_nPreviewWidth = m_stDeviceIndex[m_nCurrentPanelID].nPreviewWidth;
  739. m_nPreviewHeight = m_stDeviceIndex[m_nCurrentPanelID].nPreviewHeight;
  740. Info("Preview size(W*H {$}*{$}), PreviewEnable({$})", m_nPreviewWidth, m_nPreviewHeight, m_bPreviewEnable);
  741. if (m_bPreviewEnable)
  742. {
  743. if (m_pPreImgBuffer)
  744. {
  745. delete m_pPreImgBuffer;
  746. m_pPreImgBuffer = NULL;
  747. }
  748. m_pPreImgBuffer = new WORD[m_nPreviewHeight * m_nPreviewWidth];
  749. }
  750. ConfFeedback(EVT_CONF_RAW_WIDTH, m_nCurrentPanelID, "", m_nImageWidth);
  751. ConfFeedback(EVT_CONF_RAW_HIGHT, m_nCurrentPanelID, "", m_nImageHeight);
  752. ConfFeedback(EVT_CONF_RAW_BITS, m_nCurrentPanelID, "", m_nImgBits);
  753. ConfFeedback(EVT_CONF_PIXELSPACE, m_nCurrentPanelID, "", 0, (float)m_nPixelPitch);
  754. ConfFeedback(EVT_CONF_PREVIEW_WIDTH, m_nCurrentPanelID, "", m_nPreviewWidth);
  755. ConfFeedback(EVT_CONF_PREVIEW_HIGHT, m_nCurrentPanelID, "", m_nPreviewHeight);
  756. eDetOperationMode nOmMode = (eDetOperationMode)m_nCurrentOmMode;
  757. /*if (SYNC_AED == m_stDeviceIndex[m_nCurrentPanelID].nSyncMode)
  758. {
  759. nOmMode = PIX_OM_AED;
  760. }*/
  761. if (!SetFpdExamMode("", nOmMode, nLogicMode, true))
  762. {
  763. return false;
  764. }
  765. m_nCurrentAppMode = nLogicMode;
  766. //加载校正文件,暂时先放到初始化流程中,同探测器多模式还需要考虑
  767. return true;
  768. }
  769. RET_STATUS TrixellCtrl::SetFrameRate(FLOAT frameRate, FPDDeviceTrixell* pDrvDPC)
  770. {
  771. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  772. {
  773. Info("Not current DPC, return");
  774. return RET_STATUS::RET_FAILED;
  775. }
  776. return RET_STATUS::RET_SUCCEED;
  777. }
  778. bool TrixellCtrl::GetCalibrationStep(int nCalibCurrentCalibrationRound, int nCalibrationRounds, int nCalibCurrentExposureIndex, int nExposureNumCurrentRound)
  779. {
  780. m_nCalibCurrentCalibrationRound = nCalibCurrentCalibrationRound;
  781. m_nCalibrationRounds = nCalibrationRounds;
  782. m_nCalibCurrentExposureIndex = nCalibCurrentExposureIndex;
  783. m_nExposureNumCurrentRound = nExposureNumCurrentRound;
  784. Info("Calibration Step===Round: {$}/{$}, ExposureNum: {$}/{$}", nCalibCurrentCalibrationRound, nCalibrationRounds, nCalibCurrentExposureIndex, nExposureNumCurrentRound);
  785. return true;
  786. }
  787. /***
  788. ** 说明:曝光前的准备流程
  789. ***/
  790. RET_STATUS TrixellCtrl::PrepareAcquisition(FPDDeviceTrixell* pDrvDPC)
  791. {
  792. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  793. {
  794. Info("Not current DPC, return");
  795. return RET_STATUS::RET_FAILED;
  796. }
  797. if (m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus == false)
  798. {
  799. Info("Current detector is not connect, return");
  800. return RET_STATUS::RET_FAILED;
  801. }
  802. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  803. //设置到工作模式
  804. if (!SetSystemState(STATE_PATIENT))
  805. {
  806. Error("Set patient state failed");
  807. return Ret;
  808. }
  809. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START);
  810. /***
  811. ** tomo采集,根据和子系统沟通,机架反馈曝光次数后,子系统才给探测器设置曝光次数,
  812. ** 对应到状态机中的FrameReady之后 FrameStart之前,
  813. ** 因此,将非aed模式的SetParam放到FrameStart调用,
  814. ** aed模式到ready状态耗时比较久,所以在此处单独处理,
  815. ** 将SetParam放到aed判断里面调用
  816. ***/
  817. //SetApplicationParam(m_nCurrentMode);
  818. if (PIX_OM_AED == m_nCurrentOmMode) //AED模式需要提前到ready状态(耗时约1.8s)
  819. {
  820. if (DetStatus_Acquire == m_eStatus && !m_bIsExpInAuto) //重复使能直接返回
  821. {
  822. return RET_STATUS::RET_SUCCEED;
  823. }
  824. SetApplicationParam(m_nCurrentMode);
  825. try
  826. {
  827. application_mode applicationMode = application_mode(m_nCurrentMode - 1);
  828. LockPixrad("ApplicationAcquisition");
  829. Info("Calling ApplicationAcquisition(appmode:{$} acqmode:AED)", (int)applicationMode);
  830. error_status ErrorStatus = TED_PixRad_ApplicationAcquisition(applicationMode); //EVT_START_ACQUISITION->EVT_READY
  831. if (TestError(ErrorStatus))
  832. {
  833. Info("Application acquisition command OK");
  834. Ret = RET_STATUS::RET_SUCCEED;
  835. m_nXwinOnIndex = 0; //开始采集,置为初值
  836. m_nTomoImgIndex = 0; //开始采集,置为初值
  837. m_nIgnoreImgNum = 0; //开始采集,置为初值
  838. m_eStatus = DetStatus_Acquire;
  839. LockPixrad(); //等待回调
  840. UnlockPixrad("ApplicationAcquisition");
  841. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP);
  842. }
  843. else
  844. {
  845. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR);
  846. UnlockPixrad("ApplicationAcquisition"); //执行失败,解锁
  847. }
  848. }
  849. catch (...)
  850. {
  851. Error("Start acq crash!");
  852. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR);
  853. UnlockPixrad("ApplicationAcquisition"); //执行崩溃,解锁
  854. }
  855. }
  856. else
  857. {
  858. StatusFeedback(EVT_STATUS_PANEL, PANEL_READY_EXP);
  859. Ret = RET_STATUS::RET_SUCCEED;
  860. }
  861. return Ret;
  862. }
  863. RET_STATUS TrixellCtrl::StartAcquisition(FPDDeviceTrixell* pDrvDPC)
  864. {
  865. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  866. {
  867. Info("Not current DPC, return");
  868. return RET_STATUS::RET_FAILED;
  869. }
  870. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  871. if (-1 == m_nCurrentMode)
  872. {
  873. Warn("Current mode({$}) is illegal, may not select exam mode successfully, return failed", m_nCurrentMode);
  874. return Ret;
  875. }
  876. if (m_nCurrentOmMode == PIX_OM_AED)
  877. {
  878. Info("AED return");
  879. return RET_STATUS::RET_SUCCEED;
  880. }
  881. if (m_eStatus == DetStatus_Acquire)
  882. {
  883. Error("Already in acquire state, forbid start acquisition");
  884. return Ret;
  885. }
  886. if (m_nCurrentOmMode != PIX_OM_AED) //aed模式采集命令在FramePrep下发
  887. {
  888. /***
  889. ** tomo采集,根据和子系统沟通,机架反馈曝光次数后,子系统才给探测器设置曝光次数,
  890. ** 对应到状态机中的FrameReady之后 FrameStart之前,
  891. ** 因此,将非aed模式的SetParam放到此处调用
  892. ***/
  893. SetApplicationParam(m_nCurrentMode);
  894. try
  895. {
  896. application_mode applicationMode = application_mode(m_nCurrentMode - 1);
  897. if (m_bLTEenable && m_nCurrentOmMode == PIX_OM_RAD) //软同步 长曝光
  898. {
  899. applicationMode = application_mode(g_nRADLTEmode - 1);
  900. }
  901. string strTemp = "unknown";
  902. if (PIX_OM_AED == m_nCurrentOmMode)
  903. {
  904. strTemp = "aed";
  905. }
  906. else if (PIX_OM_RAD == m_nCurrentOmMode)
  907. {
  908. strTemp = "rad";
  909. }
  910. else if (PIX_OM_TOMO == m_nCurrentOmMode)
  911. {
  912. strTemp = "tomo";
  913. }
  914. LockPixrad("ApplicationAcquisition"); //等待上一步操作执行完毕
  915. Info("Calling ApplicationAcquisition(appmode:{$} acqmode:{$})", (int)applicationMode, strTemp.c_str());
  916. error_status ErrorStatus = TED_PixRad_ApplicationAcquisition(applicationMode); //EVT_START_ACQUISITION
  917. if (TestError(ErrorStatus))
  918. {
  919. Info("Application acquisition command OK");
  920. Ret = RET_STATUS::RET_SUCCEED;
  921. m_eStatus = DetStatus_Acquire;
  922. m_nXwinOnIndex = 0; //开始采集,置为初值
  923. m_nTomoImgIndex = 0; //开始采集,置为初值
  924. m_nIgnoreImgNum = 0; //开始采集,置为初值
  925. Info("m_nIgnoreImgCount:{$}", m_nIgnoreImgCount);
  926. if (m_nIgnoreImgCount != 0)
  927. {
  928. Info("m_nIgnoreImgCount != 0");
  929. LockPixrad("ApplicationAcquisition");
  930. }
  931. }
  932. else
  933. {
  934. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR);
  935. }
  936. }
  937. catch (...)
  938. {
  939. Error("Start acq crash!");
  940. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR);
  941. }
  942. UnlockPixrad("ApplicationAcquisition");
  943. }
  944. else
  945. {
  946. m_eStatus = DetStatus_Acquire;
  947. Ret = RET_STATUS::RET_SUCCEED;
  948. }
  949. if (Ret == RET_STATUS::RET_SUCCEED)
  950. {
  951. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK);
  952. }
  953. return Ret;
  954. }
  955. RET_STATUS TrixellCtrl::StopAcquisition(FPDDeviceTrixell* pDrvDPC)
  956. {
  957. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  958. {
  959. Info("Not current DPC, return");
  960. return RET_STATUS::RET_FAILED;
  961. }
  962. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  963. if (m_eStatus != DetStatus_Acquire)
  964. {
  965. Warn("Not in acq state, does not need stop acquisition");
  966. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  967. return RET_STATUS::RET_SUCCEED;
  968. }
  969. //可以调用TED_PixRad_StopAcquisition的情况
  970. //1.AED没曝光
  971. //2.序列采集过程
  972. //3.收到preview还没收到full image
  973. //不可以调用TED_PixRad_StopAcquisition的情况
  974. //1.Tomo传图过程
  975. if (m_eStatus == DetStatus_Acquire && PIX_OM_TOMO == m_nCurrentOmMode && m_nXwinOnIndex == m_nTomoImgCount)
  976. {
  977. //tomo模式,已经曝光完毕,正在传图,这时如果调用TED_PixRad_StopAcquisition会终止传图,所以需要等待传图完毕
  978. m_bWaitAcqEnd = true;
  979. //已经收到回调,没必要再调用TED_PixRad_StopAcquisition
  980. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  981. return RET_STATUS::RET_SUCCEED;
  982. }
  983. //2.非Tomo传图过程
  984. if (m_eStatus == DetStatus_Acquire && m_nCurrentOmMode != PIX_OM_TOMO && m_nXwinOnIndex != 0)
  985. {
  986. //rad/aed模式,已经曝光完毕,正在传图,这时如果调用TED_PixRad_StopAcquisition会终止传图,所以需要等待传图完毕
  987. m_bWaitAcqEnd = true;
  988. //已经收到回调,没必要再调用TED_PixRad_StopAcquisition
  989. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  990. return RET_STATUS::RET_SUCCEED;
  991. }
  992. if (m_eStatus == DetStatus_Acquire)
  993. {
  994. //m_bWaitAcqEnd = true;
  995. Info("Calling StopAcquisition");
  996. error_status ErrorStatus = TED_PixRad_StopAcquisition(); //EVT_END_ACQUISITION
  997. if (TestError(ErrorStatus))
  998. {
  999. Info("Stop acquisition command OK");
  1000. Ret = RET_STATUS::RET_SUCCEED;
  1001. }
  1002. else
  1003. {
  1004. Error("Stop acuqisition command failed");
  1005. return Ret;
  1006. }
  1007. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  1008. }
  1009. else
  1010. {
  1011. Info("Not in acquire state, return");
  1012. Ret = RET_STATUS::RET_SUCCEED;
  1013. }
  1014. return Ret;
  1015. }
  1016. /***
  1017. * 设置校正点数
  1018. ***/
  1019. bool TrixellCtrl::SetReferenceNum(int nReferenceNum)
  1020. {
  1021. m_nCalibrationRounds = nReferenceNum;
  1022. Info("Set reference number: {$}", m_nCalibrationRounds);
  1023. return true;
  1024. }
  1025. /***
  1026. ** 说明:激活校正
  1027. ** 增益校正(探测器采用post-offset,暗场校正基本没用了)时拿到dose回调,算作执行完毕
  1028. ***/
  1029. RET_STATUS TrixellCtrl::ActiveCalibration(CCOS_CALIBRATION_TYPE Type)
  1030. {
  1031. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1032. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_START);
  1033. if (CCOS_CALIBRATION_TYPE_DARK == Type)
  1034. {
  1035. Info("ActiveDarkCalibration");
  1036. Ret = RET_STATUS::RET_SUCCEED;
  1037. }
  1038. else if (CCOS_CALIBRATION_TYPE_XRAY == Type)
  1039. {
  1040. Info("ActiveXrayCalibration");
  1041. m_eStatus = DetStatus_XrayCalibration;
  1042. /*
  1043. * Tomo增益校正流程
  1044. * S1. 调用TED_PixRad_XRayCalibration,收到EVT_START_XRAY_CALIBRATION等(没啥用),EVT_DOSE_PARAM_REQUEST -- Active结束
  1045. * S2. 调用TED_PixRad_ResumeSequence,收到EVT_WAIT_STOP_XRAY
  1046. * S3. 调用TED_PixRad_ResumeSequence,收到一些列回调,EVT_WAIT_START_XRAY -- PrepareCalibration(FramePrep)结束
  1047. * S4. 调用TED_PixRad_ResumeSequence,收到 25组窗口回调 ,EVT_WAIT_STOP_XRAY
  1048. * S5. 调用TED_PixRad_ResumeSequence,收到EVT_DOSE_PARAM_REQUEST
  1049. * 循环 -> S2 总共收到4次EVT_DOSE_PARAM_REQUEST,2.5, 0.25, 0.5, 5ugy
  1050. * 最后一组曝光完毕后 S5 收到EVT_END_XRAY_CALIBRATION -- 校正结束
  1051. */
  1052. if (m_nCalibrationMode) //Trixell 校正
  1053. {
  1054. if (ActiveGainCalibration())
  1055. {
  1056. Ret = RET_STATUS::RET_SUCCEED;
  1057. m_nCaliFailedCount = 0; //开始增益校正,置为初值
  1058. }
  1059. }
  1060. else //ZSKK校正
  1061. {
  1062. //设置到工作状态
  1063. if (!SetSystemState(STATE_PATIENT)) //需要在PATIENT状态执行gain
  1064. {
  1065. Error("Set quiet state failed");
  1066. Ret = RET_STATUS::RET_FAILED;
  1067. }
  1068. if (!m_pZSKKCalib)
  1069. {
  1070. Error("ZSKK Calibration object is undefined");
  1071. Ret = RET_STATUS::RET_FAILED;
  1072. }
  1073. else
  1074. {
  1075. //反馈Dose信息
  1076. DataFeedback(EVT_DATA_DOSEPARAM, NULL, 0, 2.5);
  1077. //加载ZSKK的校正文件
  1078. m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "\\rawdata\\";
  1079. m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "\\references\\";
  1080. m_pZSKKCalib->m_nFullImgWidth = m_stDeviceIndex[m_nCurrentPanelID].nFullImageWidth;
  1081. m_pZSKKCalib->m_nFullImgHeight = m_stDeviceIndex[m_nCurrentPanelID].nFullImageHeight;
  1082. m_pZSKKCalib->m_nReferenceNum = m_nCalibrationRounds;
  1083. m_pZSKKCalib->m_nSaturationValue = 50000;
  1084. m_pZSKKCalib->LoadZSKKGainMap(false, m_strPanelType);
  1085. m_pZSKKCalib->LoadZSKKPixelMap(false, m_strPanelType);
  1086. Info("Load ZSKK map successful");
  1087. Info("References: {$}", m_pZSKKCalib->m_strRefFilePath);
  1088. Ret = RET_STATUS::RET_SUCCEED;
  1089. }
  1090. }
  1091. }
  1092. else
  1093. {
  1094. Error("Active not supported calibration({$}), return! \n", (int)Type);
  1095. Ret = RET_STATUS::RET_NOSUPPORT;
  1096. return Ret;
  1097. }
  1098. m_eCaliType = Type;
  1099. return Ret;
  1100. }
  1101. /***
  1102. ** 说明:准备校正(状态机FramePrep)
  1103. ** 曝光使能过程,使探测器开窗
  1104. ***/
  1105. RET_STATUS TrixellCtrl::PrepareCalibration(FPDDeviceTrixell* pDrvDPC)
  1106. {
  1107. if (m_eStatus != DetStatus_XrayCalibration) //offset校正直接返回
  1108. {
  1109. Warn("Not in xraycalibration state, return");
  1110. return RET_STATUS::RET_SUCCEED;
  1111. }
  1112. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1113. if (m_nCalibrationMode) //Trixell校正
  1114. {
  1115. Info("Manual trigger next calibration exposure");
  1116. if (ResumeSequence(true))
  1117. {
  1118. Ret = RET_STATUS::RET_SUCCEED;
  1119. }
  1120. }
  1121. else //ZSKK校正
  1122. {
  1123. //1.切换到工作模式
  1124. if (!SetSystemState(STATE_PATIENT))
  1125. {
  1126. Error("Set quiet state failed");
  1127. Ret = RET_STATUS::RET_FAILED;
  1128. }
  1129. //2.设置参数
  1130. if (!SetApplicationParam(m_nCurrentMode))
  1131. {
  1132. Error("Set application parameter failed");
  1133. Ret = RET_STATUS::RET_FAILED;
  1134. }
  1135. if (PIX_OM_AED == m_nCurrentOmMode)
  1136. {
  1137. ApplicationAcquireSequence();
  1138. }
  1139. Ret = RET_STATUS::RET_SUCCEED;
  1140. }
  1141. Info("PrepareCalibration Over");
  1142. return Ret;
  1143. }
  1144. /***
  1145. ** 说明:开始校正(状态机FrameStart)
  1146. ***/
  1147. RET_STATUS TrixellCtrl::StartCalibration(FPDDeviceTrixell* pDrvDPC)
  1148. {
  1149. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1150. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  1151. {
  1152. Info("StartDarkCalibration \n");
  1153. m_eStatus = DetStatus_Offset; //开始offset
  1154. if (RefreshOffset(m_bPreviewEnable, m_nCurrentOmMode, m_nCurrentMode, false))
  1155. {
  1156. Ret = RET_STATUS::RET_SUCCEED;
  1157. }
  1158. else
  1159. {
  1160. m_eStatus = DetStatus_Standby; //开始offset执行失败,置回Standby
  1161. }
  1162. }
  1163. else
  1164. {
  1165. Info("StartXrayCalibration \n");
  1166. if (m_nCurrentOmMode == PIX_OM_TOMO) //非Tomo模式,由于ResumeSequence()耗时较长,在FramePrep中完成触发
  1167. {
  1168. if (!ResumeSequence(false)) //Tomo增益,使SDK返回开窗回调
  1169. {
  1170. return Ret;
  1171. }
  1172. }
  1173. if (m_nCalibrationMode)//Trixell校正
  1174. {
  1175. }
  1176. else //ZSKK校正
  1177. {
  1178. if (PIX_OM_RAD == m_nCurrentOmMode)
  1179. {
  1180. ApplicationAcquireSequence();
  1181. }
  1182. }
  1183. Ret = RET_STATUS::RET_SUCCEED;
  1184. m_nXwinOnIndex = 0; //开始校正,置为初值
  1185. }
  1186. return Ret;
  1187. }
  1188. /***
  1189. * 接受曝光图像
  1190. ***/
  1191. bool TrixellCtrl::AcceptCalibration()
  1192. {
  1193. Info("Accept calibration exposure result");
  1194. if (m_nCalibrationMode)//Trixell校正
  1195. {
  1196. //不做处理
  1197. }
  1198. else //ZSKK校正
  1199. {
  1200. if (m_nCalibCurrentExposureIndex == 1)
  1201. {
  1202. m_pZSKKCalib->AddImageToPixMap(m_pImgBuffer);
  1203. m_pZSKKCalib->AverageZSKKGainMap(m_pImgBuffer, m_nCalibCurrentCalibrationRound - 1, true);
  1204. }
  1205. else
  1206. {
  1207. m_pZSKKCalib->AverageZSKKGainMap(m_pImgBuffer, m_nCalibCurrentCalibrationRound - 1, false); //曝光第几轮
  1208. }
  1209. }
  1210. Info("Accept calibration exposure over");
  1211. return true;
  1212. }
  1213. /***
  1214. * 拒绝曝光图像
  1215. ***/
  1216. bool TrixellCtrl::RejectCalibration()
  1217. {
  1218. Info("Reject calibration exposure result");
  1219. //不做处理
  1220. return true;
  1221. }
  1222. //Salmon项目中DPC等待dose反馈,不会再拿dose,所以用不到了
  1223. RET_STATUS TrixellCtrl::GetDoseRequest(float& DoseReq, FPDDeviceTrixell* pDrvDPC)
  1224. {
  1225. Info("GetDoseRequest \n");
  1226. if (CCOS_CALIBRATION_TYPE_XRAY == m_eCaliType)
  1227. {
  1228. DoseReq = (float)m_fDose;
  1229. }
  1230. else
  1231. {
  1232. DoseReq = 0;
  1233. }
  1234. m_fCurrentDose = DoseReq;
  1235. Info("Dose request : {$}", DoseReq);
  1236. return RET_STATUS::RET_SUCCEED;
  1237. }
  1238. /***
  1239. ** 说明:终止校正
  1240. ***/
  1241. RET_STATUS TrixellCtrl::AbortCalibration(FPDDeviceTrixell* pDrvDPC)
  1242. {
  1243. Info("AbortCalibration \n");
  1244. m_eCaliType = CCOS_CALIBRATION_TYPE_NONE; //恢复初值
  1245. m_bConfirmCaliRst = false; //终止校正,恢复初值
  1246. m_bAutoContinueCal = false; //终止校正,恢复初值
  1247. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1248. if (m_nCalibrationMode) //Trixell校正
  1249. {
  1250. Info("Calling CancelingSequence");
  1251. error_status ErrorStatus = TED_PixRad_CancelSequence();
  1252. if (!TestError(ErrorStatus))
  1253. {
  1254. Error("CancelSequence Command Failed");
  1255. }
  1256. else
  1257. {
  1258. Info("CancelSequence Command OK");
  1259. Ret = RET_STATUS::RET_SUCCEED;
  1260. }
  1261. }
  1262. else
  1263. {
  1264. Info("Abort ZSKK calibration");
  1265. m_pZSKKCalib->LoadZSKKGainMap(true, m_strPanelType); //重新加载增益校正文件
  1266. m_pZSKKCalib->AbortZSKKPixMap(m_strPanelType); //放弃坏点校正并重新加载原来的坏点校正文件
  1267. }
  1268. m_eStatus = DetStatus_Standby;
  1269. return Ret;
  1270. }
  1271. /***
  1272. ** 说明:增益校正时响应上层调用的FramePost
  1273. ** 曝光结束后在此等到当前的曝光结果:OK,剂量高/低,有物体。避免状态机被其它设备拉入下一次流程
  1274. ** Salmon系统中没有其它驱动触发跳转,所以用不到了
  1275. ***/
  1276. RET_STATUS TrixellCtrl::PostCalibration(FPDDeviceTrixell* pDrvDPC)
  1277. {
  1278. //if (m_eStatus != DetStatus_XrayCalibration)
  1279. //{
  1280. // Warn( "Not in xraycalibration state, return");
  1281. // return RET_STATUS::RET_SUCCEED;
  1282. //}
  1283. //if (m_bGainProcess)
  1284. //{
  1285. // LockPixrad("WaitGainRst");
  1286. // LockPixrad(); //等待当前增益曝光结束
  1287. // UnlockPixrad("WaitGainRst");
  1288. //}
  1289. ////当前节点曝光结束,需要等到dose回调再让FramePost结束
  1290. //if (m_nGainExpIndex == m_nGainExpCount)
  1291. //{
  1292. // if (m_fCurrentDose == m_fDose) //当前节点曝光结束,如果这两个值还相等,说明SDK还没回调Dose,需要等待
  1293. // {
  1294. // LockPixrad("WaitDose");
  1295. // LockPixrad(); //等待下一次dose回调
  1296. // UnlockPixrad("WaitDose");
  1297. // }
  1298. // m_bAutoContinueCal = false; //剂量改变后,不能自动进行下一次增益
  1299. // m_nGainNodeIndex++;
  1300. // m_nGainExpCount = (int)m_ModeConfig["ModeTable"][m_nCurrentMode - 1]["CalibConfig"][m_nGainNodeIndex]["ImgCount"];
  1301. // Info( "Gain node index: %d, current node exp count: %d, exp index: %d", m_nGainNodeIndex, m_nGainExpCount, m_nGainExpIndex);
  1302. //}
  1303. //Info( "Over, Gain calibration already exposure %d times, need %d times", m_nGainExpIndex, m_nGainExpCount);
  1304. //m_nGainExpIndex = 0; //恢复初值
  1305. return RET_STATUS::RET_SUCCEED;
  1306. }
  1307. bool TrixellCtrl::SaveCalibrationFile()
  1308. {
  1309. Info("Save Calibration File");
  1310. if (m_nCalibrationMode)//Trixell校正
  1311. {
  1312. //不做处理
  1313. }
  1314. else
  1315. {
  1316. Info("Save ZSKK Calibration File");
  1317. m_pZSKKCalib->StoreZSKKGainMap(m_strPanelType);
  1318. m_pZSKKCalib->StoreZSKKPixMap(m_strPanelType);
  1319. }
  1320. //修改探测器状态,否则校正完成后进入检查页面不能正常ready
  1321. m_eStatus = DetStatus_Standby;
  1322. //更新配置文件中校正日期和时间
  1323. SYSTEMTIME stCurrentTime = { 0 };
  1324. GetLocalTime(&stCurrentTime);
  1325. //Info("Current time: %04d/%02d/%02d %02d:%02d:%02d:%03d",
  1326. Info("Current time: {$d04}/{$d02}/{$d02} {$d02}:{$d02}:{$d02}:{$d02}",
  1327. stCurrentTime.wYear, stCurrentTime.wMonth, stCurrentTime.wDay,
  1328. stCurrentTime.wHour, stCurrentTime.wMinute, stCurrentTime.wSecond, stCurrentTime.wMilliseconds);
  1329. Info("Save Calibration File over");
  1330. return true;
  1331. }
  1332. /***
  1333. ** 说明:结束校正
  1334. ** DPC处理完校正报告后调用,此处上传map、报告等文件
  1335. ***/
  1336. RET_STATUS TrixellCtrl::CompleteCalibration(FPDDeviceTrixell* pDrvDPC)
  1337. {
  1338. Info("CompleteCalibration");
  1339. SetEvent(m_hEndCalibEvent);
  1340. return RET_STATUS::RET_SUCCEED;
  1341. }
  1342. /***
  1343. ** 说明:设置长短曝光模式
  1344. ***/
  1345. bool TrixellCtrl::SetLTEMode(bool bEnable)
  1346. {
  1347. Info("{$} LTE mode", bEnable ? "Enable" : "Disable");
  1348. m_bLTEenable = bEnable;
  1349. return true;
  1350. }
  1351. bool TrixellCtrl::RecoverLastImage()
  1352. {
  1353. Info("Recover Last Image");
  1354. if (m_bIsImageRecovering)
  1355. {
  1356. Warn("Recover Image is processing, return");
  1357. return false;
  1358. }
  1359. LockPixrad("RecoverLastImage");
  1360. m_bIsImageRecovering = true;
  1361. error_status eErr = TED_PixRad_RecoverLastImage(true);
  1362. if (!TestError(eErr))
  1363. {
  1364. Error("Recover Last Image Failed");
  1365. UnlockPixrad("RecoverLastImage");
  1366. return false;
  1367. }
  1368. LockPixrad("RecoverLastImage");
  1369. UnlockPixrad("RecoverLastImage");
  1370. return true;
  1371. }
  1372. bool TrixellCtrl::WakeupDetector(int nDetectorID)
  1373. {
  1374. Info("WakeupDetector SetDetectorStatusPolling == true");
  1375. SetDetectorStatusPolling(nDetectorID, true);
  1376. Sleep(50); //确保开启polling
  1377. StatusFeedback(EVT_STATUS_SLEEP, 0, "false", nDetectorID);
  1378. return true;
  1379. }
  1380. bool TrixellCtrl::LoadDLL(string strWorkPath)
  1381. {
  1382. string workpath = strWorkPath + "\\";
  1383. try
  1384. {
  1385. workpath += (string)m_ModeConfig["SDKPath"];
  1386. m_strCfgPath = (string)m_ModeConfig["CFGPath"];
  1387. }
  1388. catch (ResDataObjectExption &e)
  1389. {
  1390. Error("Read configuration failed, Error code: {$}", e.what());
  1391. return false;
  1392. }
  1393. string drvpath = workpath + "\\pixrad.dll";
  1394. Debug("{$}", drvpath.c_str());
  1395. DWORD PathLen = 32768;
  1396. char* pszPath = new char[PathLen];
  1397. DWORD Len = GetEnvironmentVariable("Path", pszPath, PathLen);
  1398. if (Len > PathLen)
  1399. {
  1400. delete[] pszPath;
  1401. return false;
  1402. }
  1403. std::string::size_type pos = 0;
  1404. string EnvPath = pszPath;
  1405. delete[] pszPath;
  1406. EnvPath.find(workpath, 0);
  1407. if ((pos = EnvPath.find(workpath, pos)) == std::string::npos)
  1408. {
  1409. string NewPath = EnvPath;
  1410. NewPath += ";";
  1411. NewPath += workpath;
  1412. if (SetEnvironmentVariable("Path", NewPath.c_str()) == FALSE)
  1413. {
  1414. return false;
  1415. }
  1416. else
  1417. {
  1418. //Info("pathvar = {$} \n\n", NewPath.c_str());
  1419. }
  1420. }
  1421. Info("Load Trixell API module");
  1422. //int nTemp = putenv(strPath.c_str());
  1423. //if (nTemp != 0)
  1424. //{
  1425. // DWORD dw = GetLastError();
  1426. // //printf("Add dll failed: %d \n", dw);
  1427. // return false;
  1428. //}
  1429. //pathvar = getenv("Path");
  1430. ////printf("pathvar = %s \n\n", pathvar);
  1431. //m_hTrixellModule = LoadLibrary(drvpath.c_str());
  1432. m_hTrixellModule = LoadLibraryEx(drvpath.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH/*LOAD_LIBRARY_SEARCH_USER_DIRS*/);
  1433. if (m_hTrixellModule == NULL)
  1434. {
  1435. DWORD dw = GetLastError();
  1436. Error("Load {$} failed: {$} \n", drvpath.c_str(), dw);
  1437. return false;
  1438. }
  1439. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RegisterEventCallback);
  1440. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_UnregisterEventCallback);
  1441. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RegisterOutputMsgCallback);
  1442. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_UnregisterOutputMsgCallback);
  1443. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SwitchSSID);
  1444. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_Open);
  1445. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_Close);
  1446. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ResetDetector);
  1447. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_StartAcquisition);
  1448. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_StopAcquisition);
  1449. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetConfigParameters);
  1450. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetHardwareStatus);
  1451. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetDetectorHardwareStatus);
  1452. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetSystemStatus);
  1453. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetSystemState);
  1454. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_DarkCalibration);
  1455. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_XRayCalibration);
  1456. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_CancelSequence);
  1457. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SetActiveDetector);
  1458. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetActiveDetector);
  1459. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_PerformDetectorSelfTest);
  1460. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SwitchSSID);
  1461. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SetSystemState);
  1462. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ResumeSequence);
  1463. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetWifiStatus);
  1464. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetDetectorWifiStatus);
  1465. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ModulePolling);
  1466. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ModuleSetIpConfig);
  1467. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ModuleSwitchSSID);
  1468. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ModuleSetNetworkConfig);
  1469. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_Connect);
  1470. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_Disconnect);
  1471. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RecoverLastImage);
  1472. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_DetectorControl);
  1473. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_LoadReferences);
  1474. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetLastAcquisitionData);
  1475. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SetImageMetadata);
  1476. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetStoredImageList);
  1477. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetStoredImage);
  1478. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RemoveStoredImage);
  1479. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ApplicationControl);
  1480. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RemoveAllStoredImages);
  1481. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetSystemCalibrationTimeStatus);
  1482. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_DetectorStatusPolling);
  1483. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetVoltage);
  1484. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ModuleGetInfo);
  1485. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SetApplicationParameters);
  1486. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_ApplicationAcquisition);
  1487. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_GetDetectorInformation);
  1488. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_OpenRemoteStorageSession);
  1489. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_CloseRemoteStorageSession);
  1490. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RemoteStorageUploadFile);
  1491. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RemoteStorageDownloadFile);
  1492. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_RemoteStorageCreateDirectory);
  1493. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_SaveImage);
  1494. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_LoadImage);
  1495. LOAD_PROC_ADDRESS(m_hTrixellModule, TED_PixRad_TransferStoredImages);
  1496. Info("Load Trixell API module over");
  1497. return true;
  1498. }
  1499. /***
  1500. ** 说明:验证返回是否有错误
  1501. ** 返回值:true,没有错误;false,有错误
  1502. ***/
  1503. bool TrixellCtrl::TestError(error_status err, int nFpdID, string strFuncName)
  1504. {
  1505. if (-1 == nFpdID)
  1506. {
  1507. nFpdID = m_nCurrentPanelID;
  1508. }
  1509. if (nFpdID != 0 && nFpdID != 1 && nFpdID != 2) //按最大三板处理
  1510. {
  1511. //如果是SDK不反馈ID的错误,则置为-1,避免下面数组越界
  1512. nFpdID = -1;
  1513. }
  1514. switch (err)
  1515. {
  1516. //general error
  1517. case ERR_SUCCESS:
  1518. Debug("{$} There is no error", strFuncName.c_str());
  1519. return true;
  1520. case ERR_UNKNOWN:
  1521. Error("TestError {$} ERR_UNKNOWN", strFuncName.c_str());
  1522. break;
  1523. //system error 1000+
  1524. case ERR_BAD_STATE:
  1525. Error("TestError {$} ERR_BAD_STATE", strFuncName.c_str());
  1526. break;
  1527. case ERR_BAD_PARAMETER:
  1528. Error("TestError {$} ERR_BAD_PARAMETER", strFuncName.c_str());
  1529. break;
  1530. case ERR_CONFIG_PARAMETER:
  1531. Error("TestError {$} ERR_CONFIG_PARAMETER", strFuncName.c_str());
  1532. break;
  1533. case ERR_REFERENCE_MISSING:
  1534. Error("TestError {$} ERR_REFERENCE_MISSING", strFuncName.c_str());
  1535. break;
  1536. case ERR_CONFIG_FILE_NOT_FOUND:
  1537. Error("TestError {$} ERR_CONFIG_FILE_NOT_FOUND", strFuncName.c_str());
  1538. break;
  1539. case ERR_CALLBACK_ALREADY_REGISTERED:
  1540. Error("TestError {$} ERR_CALLBACK_ALREADY_REGISTERED", strFuncName.c_str());
  1541. break;
  1542. case ERR_DETECTOR_OPERATION_NOT_ALLOWED:
  1543. Error("TestError {$} ERR_DETECTOR_OPERATION_NOT_ALLOWED", strFuncName.c_str());
  1544. break;
  1545. //hw error 2000+
  1546. case ERR_ACQ_NOT_END:
  1547. Error("TestError {$} ERR_ACQ_NOT_END", strFuncName.c_str());
  1548. break;
  1549. case ERR_DETECTOR_INIT_FAILED:
  1550. Error("TestError {$} ERR_DETECTOR_INIT_FAILED", strFuncName.c_str());
  1551. if (nFpdID != -1)
  1552. {
  1553. m_pStPanelStatus[nFpdID]->bConnectStatus = false;
  1554. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nFpdID);
  1555. }
  1556. break;
  1557. case ERR_DETECTOR_REQUEST:
  1558. Error("TestError {$} ERR_DETECTOR_REQUEST", strFuncName.c_str());
  1559. break;
  1560. case ERR_DETECTOR_COMMUNICATION:
  1561. Error("TestError {$} ERR_DETECTOR_COMMUNICATION({$})", strFuncName.c_str(), nFpdID);
  1562. if (nFpdID != -1)
  1563. {
  1564. m_pStPanelStatus[nFpdID]->bConnectStatus = false;
  1565. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nFpdID);
  1566. }
  1567. break;
  1568. case ERR_DETECTOR_BATTERY_LOW_LEVEL:
  1569. Error("TestError {$} ERR_DETECTOR_BATTERY_LOW_LEVEL", strFuncName.c_str());
  1570. break;
  1571. case ERR_DETECTOR_CONFIGURATION:
  1572. Error("TestError {$} ERR_DETECTOR_CONFIGURATION", strFuncName.c_str());
  1573. break;
  1574. case ERR_DETECTOR_UNREACHABLE:
  1575. Error("TestError {$} ERR_DETECTOR_UNREACHABLE Fpd({$})", strFuncName.c_str(), nFpdID);
  1576. if (nFpdID != -1)
  1577. {
  1578. m_pStPanelStatus[nFpdID]->bConnectStatus = false;
  1579. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", nFpdID);
  1580. }
  1581. break;
  1582. case ERR_DETECTOR_IMAGE_PENDING:
  1583. Error("TestError {$} ERR_DETECTOR_IMAGE_PENDING Fpd({$})", strFuncName.c_str(), nFpdID);
  1584. //需要考虑图像恢复机制 ys
  1585. break;
  1586. case ERR_MODULE_INIT_FAILED:
  1587. Error("TestError {$} ERR_MODULE_INIT_FAILED", strFuncName.c_str());
  1588. break;
  1589. case ERR_MODULE_COMMUNICATION:
  1590. Error("TestError {$} ERR_MODULE_COMMUNICATION Fpd({$})", strFuncName.c_str(), nFpdID);
  1591. break;
  1592. //acq error 3000+
  1593. case ERR_ACQUISITION_CANCELED:
  1594. Error("TestError {$} ERR_ACQUISITION_CANCELED", strFuncName.c_str());
  1595. break;
  1596. case ERR_BAD_DETECTOR_HOST_SYNCHRO:
  1597. Error("TestError {$} ERR_BAD_DETECTOR_HOST_SYNCHRO", strFuncName.c_str());
  1598. break;
  1599. //cali error 4000+
  1600. case ERR_CALIBRATION_ACQUISITION:
  1601. Error("TestError {$} ERR_CALIBRATION_ACQUISITION", strFuncName.c_str());
  1602. break;
  1603. //load error 5000+
  1604. case LOAD_ERROR:
  1605. Error("TestError {$} LOAD_ERROR", strFuncName.c_str());
  1606. break;
  1607. case ERR_LOAD_GAIN:
  1608. Error("{$} ERR_LOAD_GAIN", strFuncName.c_str());
  1609. break;
  1610. case ERR_LOAD_DEFECTMAP:
  1611. Error("TestError {$} ERR_LOAD_DEFECTMAP", strFuncName.c_str());
  1612. break;
  1613. //sequence error 6000+
  1614. case ERR_SEQUENCE_CANCELED:
  1615. Error("TestError {$} ERR_SEQUENCE_CANCELED", strFuncName.c_str());
  1616. break;
  1617. case ERR_RESUME_TIMEOUT:
  1618. Error("TestError {$} ERR_RESUME_TIMEOUT", strFuncName.c_str());
  1619. break;
  1620. default:
  1621. Error("TestError {$} Unknown Error: {$}", strFuncName.c_str(), (int)err);
  1622. break;
  1623. }
  1624. return false;
  1625. }
  1626. /***
  1627. ** 说明:验证返回是否有错误
  1628. ** 返回值:true,没有错误;false,有错误
  1629. ***/
  1630. bool TrixellCtrl::TestRSError(rs_error_status err, int nFpdID, string strFuncName)
  1631. {
  1632. switch (err)
  1633. {
  1634. case RS_ERR_SUCCESS:
  1635. Debug("{$} There is no error", strFuncName.c_str());
  1636. return true;
  1637. case RS_ERR_UNKNOWN:
  1638. Error("{$} ERR_UNKNOWN", strFuncName.c_str());
  1639. break;
  1640. case RS_ERR_SESSION_DISABLED:
  1641. Error("{$} ERR_SESSION_DISABLED", strFuncName.c_str());
  1642. break;
  1643. case RS_ERR_OPERATION_FAILED:
  1644. Error("{$} ERR_OPERATION_FAILED", strFuncName.c_str());
  1645. break;
  1646. default:
  1647. Error("{$} Unknown Error: {$}", strFuncName.c_str(), (int)err);
  1648. break;
  1649. }
  1650. return false;
  1651. }
  1652. /***
  1653. ** 说明:修改SDK配置Pixrad.ini
  1654. ** 参数:ResConfig 探测器类型配置
  1655. ** 例
  1656. {
  1657. "FPDNum": 2, //探测器数量
  1658. "FPDs":
  1659. {
  1660. "FPD": "2430EZ",
  1661. "FPD": "3543EZh"
  1662. }
  1663. }
  1664. ** 此函数的逻辑是按最多三块泰雷兹平板设计的,超过限制代码和配置文件都需要调整!!
  1665. ***/
  1666. bool TrixellCtrl::ConfigPixradSDK(ResDataObject ResConfig)
  1667. {
  1668. Info("Reset Pixrad ini, {$}", ResConfig.encode());
  1669. int nFPDNum = 0;
  1670. bool bRet = true;
  1671. if (ResConfig.GetFirstOf("FPDNum") >= 0)
  1672. {
  1673. nFPDNum = (int)ResConfig["FPDNum"];
  1674. if (nFPDNum > 0)
  1675. {
  1676. string strIniPath = m_strWorkPath + "\\" + m_strCfgPath + "\\PixRad.ini";
  1677. string strPanelType = ""; //存储探测器类型,e.g. 3543EZh
  1678. string strConfigPath = ""; //存储探测器配置文件名称,e.g. Detector3543EZe
  1679. string strConfigItem = ""; //要修改的ini文件配置项
  1680. Info("{$}", strIniPath.c_str()); //输出ini文件全路径
  1681. bRet = CIniFileCreat(strIniPath.c_str());
  1682. if (bRet)
  1683. {
  1684. int i = 0;
  1685. for (i = 0; i < nFPDNum; i++)
  1686. {
  1687. strPanelType = (string)ResConfig["FPDs"][i];
  1688. int nPanelID = 0;
  1689. //轮询已轮询过的探测器类型,看和当前的是否重复,重复则nPanelID自增
  1690. for (int j = 0; j < i; j++)
  1691. {
  1692. if ((string)ResConfig["FPDs"][j] == strPanelType)
  1693. {
  1694. nPanelID++;
  1695. }
  1696. }
  1697. if (strPanelType.find("3543EZh") != string::npos
  1698. && strPanelType.find("3543EZhd") == string::npos)
  1699. {
  1700. //3543EZh探测器在SDK中的类型是3543EZe
  1701. strPanelType = "3543EZe";
  1702. }
  1703. strConfigPath = "Detector" + strPanelType;
  1704. if (nPanelID == 1)
  1705. {
  1706. strConfigPath += "_A";
  1707. }
  1708. else if (nPanelID == 2)
  1709. {
  1710. strConfigPath += "_B";
  1711. }
  1712. strConfigPath += ".ini";
  1713. if (i == 0)
  1714. {
  1715. strConfigItem = "configfile.detector.0";
  1716. }
  1717. else if (i == 1)
  1718. {
  1719. strConfigItem = "configfile.detector.1";
  1720. }
  1721. else
  1722. {
  1723. strConfigItem = "configfile.detector.2";
  1724. }
  1725. //修改配置项
  1726. bool bFind = CIniFileGetValueByKey2(strConfigItem.c_str(), strConfigPath.c_str());
  1727. if (bFind)
  1728. {
  1729. Info("Same configfile.detector setting");
  1730. }
  1731. else
  1732. {
  1733. strConfigPath = strConfigItem + " = " + strConfigPath;
  1734. Info("Set configuration ({$}) \n", strConfigPath.c_str());
  1735. bRet = CIniFileSetItemByKey("configuration", strConfigItem.c_str(), strConfigPath.c_str());
  1736. if (bRet)
  1737. {
  1738. Info("Set {$} Success \n", strConfigItem.c_str());
  1739. }
  1740. else
  1741. {
  1742. Error("Set {$} failed", strConfigItem.c_str());
  1743. }
  1744. }
  1745. }
  1746. //将用不到的配置项删掉
  1747. for (int j = i; j < 3; j++) //临时写成3,按最大3板处理
  1748. {
  1749. std::ostringstream ostrKey;
  1750. string strKey = "";
  1751. ostrKey << "configfile.detector." << j;
  1752. strKey = ostrKey.str();
  1753. std::ostringstream ostrValue;
  1754. string strValue = "";
  1755. bool bFind = false;
  1756. char tem[200];
  1757. bFind = CIniFileGetValueByKey(strKey.c_str(), tem);
  1758. if (bFind)
  1759. {
  1760. ostrValue << ";" << strKey << " = " << "Detector3543EZe.ini";
  1761. strValue = ostrValue.str();
  1762. Info("Set configuration ({$}) \n", strValue.c_str());
  1763. if (CIniFileSetItemByKey("configuration", strKey.c_str(), strValue.c_str()))
  1764. {
  1765. Info("Set {$} success", strValue.c_str());
  1766. }
  1767. else
  1768. {
  1769. Warn("Set {$} failed", strValue.c_str());
  1770. }
  1771. }
  1772. }
  1773. CIniFileClose();
  1774. }
  1775. else
  1776. {
  1777. Error("Read Pixrad.ini file failed");
  1778. CIniFileCloseWithoutWrite();
  1779. return bRet;
  1780. }
  1781. }
  1782. else
  1783. {
  1784. Error("There is no fpd(FPDNum: {$})", nFPDNum);
  1785. //printf("There is no fpd(FPDNum: %d) \n", nFPDNum);
  1786. bRet = false;
  1787. }
  1788. }
  1789. else
  1790. {
  1791. Error("The configuration is illegal");
  1792. bRet = false;
  1793. }
  1794. Info("Reset Pixrad ini Over");
  1795. return bRet;
  1796. }
  1797. void TrixellCtrl::EventCallback(const event_id eventID, const Event* eventData, void* customData)
  1798. {
  1799. TrixellCtrl* pOpr = static_cast<TrixellCtrl*>(customData);
  1800. if (NULL == pOpr)
  1801. {
  1802. Fatal("EventCallback is NULL");
  1803. }
  1804. else
  1805. {
  1806. pOpr->ProcessEvent(eventID, eventData);
  1807. }
  1808. }
  1809. /***
  1810. ** 说明:探测器上传下载文件的进度回调
  1811. ***/
  1812. void TrixellCtrl::RsprogressCallback(const unsigned int unTransferred_bytes, const unsigned int unTotal_bytes, void* pCustomData)
  1813. {
  1814. TrixellCtrl* pLib = static_cast<TrixellCtrl*>(pCustomData);
  1815. Info("Transferred Bytes:{$},Total Bytes:{$}", unTransferred_bytes, unTotal_bytes);
  1816. }
  1817. /***
  1818. ** 说明:调用API,初始化SDK
  1819. ** 参数:bAttachProcess 是否在attach流程
  1820. ** 返回值:0,失败;1,成功;2,成功 但需要升级固件
  1821. ***/
  1822. int TrixellCtrl::InitDetector(bool bAttachProcess, int nDetectorID)
  1823. {
  1824. Info("Begin OpenDetector");
  1825. if (-1 == nDetectorID)
  1826. {
  1827. nDetectorID = m_nCurrentPanelID;
  1828. }
  1829. if (m_bOpened)
  1830. {
  1831. Info("Already opened, skip this step");
  1832. //return true;
  1833. }
  1834. else
  1835. {
  1836. if (!m_bLoaded) //确保加载dll操作只进行一次
  1837. {
  1838. if (!LoadDLL(m_strWorkPath))
  1839. {
  1840. return INIT_FAILED; //失败
  1841. }
  1842. m_bLoaded = true;
  1843. }
  1844. //modify20210908配置失败后,将备份恢复,然后尝试再次配置一次
  1845. string strIniPath = m_strWorkPath + "\\OEMDrivers\\Detector\\Trixell\\TrixellDRDetector\\config_Pixrad\\PixRad.ini";
  1846. string strSrcPath = m_strWorkPath + "\\OEMDrivers\\Detector\\Trixell\\TrixellDRDetector\\config_Pixrad\\PixRad_bk.ini";
  1847. if (!ConfigPixradSDK(m_ObjFPDsInfo))
  1848. {
  1849. Warn("ConfigPixradSDK Failed, try again");
  1850. CopyFile2Folder(strSrcPath, strIniPath);
  1851. if (!ConfigPixradSDK(m_ObjFPDsInfo))
  1852. {
  1853. Error("ConfigPixradSDK Failed");
  1854. return INIT_FAILED;
  1855. }
  1856. }
  1857. CopyFile2Folder(strIniPath, strSrcPath);
  1858. Info("Calling RegisterEventCallback");
  1859. error_status ErrorStatus = TED_PixRad_RegisterEventCallback(EventCallback, this);
  1860. if (!TestError(ErrorStatus))
  1861. {
  1862. Error("Register event callback failed");
  1863. return INIT_FAILED;
  1864. }
  1865. string strConfigPath = m_strWorkPath + "\\" + m_strCfgPath;
  1866. Info("Call Open: {$}", strConfigPath.c_str());
  1867. error_status Err = TED_PixRad_Open(strConfigPath.c_str()); //没有EVT_DETECTOR_INIT
  1868. if (!TestError(Err))
  1869. {
  1870. Info("InitDetector Call PixRad_UnregisterEventCallback");
  1871. TED_PixRad_UnregisterEventCallback(EventCallback);
  1872. return INIT_FAILED;
  1873. }
  1874. Sleep(50); //Open执行结束会有EVT_ACTIVE_STATE回调
  1875. m_bOpened = true;
  1876. }
  1877. ConnectDetector(bAttachProcess, nDetectorID);
  1878. if (m_pStPanelStatus[m_nCurrentPanelID]->bConnectStatus)
  1879. {
  1880. Info("Connect detector over");
  1881. }
  1882. else
  1883. {
  1884. ErrorFeedback(EVT_ERR_COMMUNICATE, "true", m_nCurrentPanelID);
  1885. return INIT_FAILED;
  1886. }
  1887. Info("OpenDetector Over");
  1888. return INIT_SUCCESS;
  1889. }
  1890. /***
  1891. ** 说明:调用API,释放SDK
  1892. ***/
  1893. bool TrixellCtrl::CloseDetector()
  1894. {
  1895. Info("Closing Detector and API");
  1896. if (!SetSystemState(STATE_QUIET))
  1897. {
  1898. Error("Set Quiet State Failed");
  1899. }
  1900. else
  1901. {
  1902. Info("Set Quiet State OK");
  1903. }
  1904. for (int nID = 0; nID < m_nPanelCount; nID++)
  1905. {
  1906. SetStatusPolling(nID, false);
  1907. }
  1908. try
  1909. {
  1910. Info("Calling close");
  1911. error_status ErrorStatus = TED_PixRad_Close();
  1912. if (TestError(ErrorStatus))
  1913. {
  1914. Info("Close detector ok");
  1915. }
  1916. else
  1917. {
  1918. Warn("Close detector failed");
  1919. }
  1920. Info("CloseDetector Call PixRad_UnregisterEventCallback");
  1921. TED_PixRad_UnregisterEventCallback(EventCallback);
  1922. }
  1923. catch (...)
  1924. {
  1925. Fatal("Close detector crash");
  1926. }
  1927. m_bOpened = false;
  1928. for (int nID = 0; nID < m_nPanelCount; nID++)
  1929. {
  1930. m_pStPanelStatus[nID]->bInitOK = false; //close执行结束,恢复初值
  1931. }
  1932. return true;
  1933. }
  1934. /***
  1935. ** 说明:调用API,连接探测器
  1936. ** nDetectorID: 探测器ID
  1937. ** bAttachProcess: true表示是attach过程
  1938. ***/
  1939. bool TrixellCtrl::ConnectDetector(bool bAttachProcess, int nDetectorID)
  1940. {
  1941. Info("ConnectDetector nDetectorID:{$}", nDetectorID);
  1942. if (!SetSystemState(STATE_QUIET))
  1943. {
  1944. Error("Set Quite State Failed");
  1945. return false;
  1946. }
  1947. else
  1948. {
  1949. Info("Set Quite State OK");
  1950. }
  1951. for (int nID = 0; nID < m_nPanelCount; ++nID)
  1952. {
  1953. Info("Call Connect({$})", nID);
  1954. error_status ErrorStatus = TED_PixRad_Connect(nID, ""); //EVT_DETECTOR_INIT
  1955. if (!TestError(ErrorStatus, nID, "Connect"))
  1956. {
  1957. Error("Connect detector API failed");
  1958. continue;
  1959. }
  1960. if (!WaitRespond(g_nConnectTimeout, "Connect")) //设置一个10秒的连接超时
  1961. {
  1962. Error("Connect detector timeout");
  1963. continue;
  1964. }
  1965. if (m_pStPanelStatus[nID]->bConnectStatus)
  1966. {
  1967. Info("Connect {$} Detector success", nID);
  1968. }
  1969. else
  1970. {
  1971. Warn("Connect {$} Detector failed", nID);
  1972. continue;
  1973. }
  1974. if (!SetActiveDetector(nID))
  1975. {
  1976. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, "", nID);
  1977. continue;
  1978. }
  1979. if (m_pStPanelStatus[nID]->bConnectStatus)
  1980. {
  1981. if (!m_pStPanelStatus[nID]->bDarkCalibDone)
  1982. {
  1983. Info("ConnectDetector synctype == SYNC_SOFTWARE");
  1984. m_nRefreshOftMode = g_nRADmode;
  1985. m_bRefreshing = true;
  1986. RefreshOffset(true, PIX_OM_RAD, g_nRADmode);
  1987. m_bRefreshing = false;
  1988. }
  1989. /*if (!m_pStPanelStatus[nID]->bAEDDarkCalibDone)
  1990. {
  1991. Info("ConnectDetector synctype == SYNC_AED");
  1992. m_nRefreshOftMode = g_nAEDmode;
  1993. m_bRefreshing = true;
  1994. RefreshOffset(true, PIX_OM_AED, g_nAEDmode);
  1995. m_bRefreshing = false;
  1996. }*/
  1997. }
  1998. FactoryCorrectionActive(bAttachProcess, nID);
  1999. m_strPanelType = m_stDeviceIndex[m_nCurrentPanelID].strDeviceName;
  2000. if (m_nCalibrationMode)//Trixell校正
  2001. {
  2002. }
  2003. else
  2004. {
  2005. Info("Load ZSKK Reference file");
  2006. m_pZSKKCalib->m_strRawImgPath = m_strWorkPath + "\\rawdata\\";
  2007. m_pZSKKCalib->m_strRefFilePath = m_strWorkPath + "\\references\\";
  2008. m_pZSKKCalib->m_nFullImgWidth = m_stDeviceIndex[m_nCurrentPanelID].nFullImageWidth;
  2009. m_pZSKKCalib->m_nFullImgHeight = m_stDeviceIndex[m_nCurrentPanelID].nFullImageHeight;
  2010. m_pZSKKCalib->m_nSaturationValue = 50000;
  2011. if (!m_pZSKKCalib->LoadZSKKGainMap(true, m_strPanelType))
  2012. {
  2013. Warn("Load ZSKK Gain calibration failed");
  2014. }
  2015. if (!m_pZSKKCalib->LoadZSKKPixelMap(true, m_strPanelType))
  2016. {
  2017. Warn("Load ZSKK Defect calibration failed");
  2018. }
  2019. }
  2020. GetConfigParameters(nID);
  2021. GetDetectorInformation(nID, true);
  2022. SetDetectorStatusPolling(nID, true);
  2023. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "", nID);
  2024. Info("Connect detector({$}) over", nID);
  2025. }
  2026. return true;
  2027. }
  2028. bool TrixellCtrl::ConnectDetectorInFWUpdating(int nDetectorID)
  2029. {
  2030. Info("Connect Detector({$}) in firmware updating", nDetectorID);
  2031. return true;
  2032. }
  2033. /***
  2034. ** 说明:调用API,断开探测器连接
  2035. ** nDetectorID: 探测器ID
  2036. ***/
  2037. bool TrixellCtrl::DisconnectDetector(int nDetectorID)
  2038. {
  2039. Info("Disconnect Detector:{$}", nDetectorID);
  2040. if (m_nCalibrationMode)//Trixell校正
  2041. {
  2042. //什么也不用做
  2043. }
  2044. else
  2045. {
  2046. Info("Unload ZSKK Reference file");
  2047. m_pZSKKCalib->UnLoadZSKKGainMap();
  2048. m_pZSKKCalib->UnLoadZSKKPixMap();
  2049. }
  2050. if (!SetSystemState(STATE_QUIET))
  2051. {
  2052. Error("Set Quite State Failed");
  2053. }
  2054. else
  2055. {
  2056. Info("Set Quite State OK");
  2057. }
  2058. error_status eErrorStatus = TED_PixRad_Disconnect(nDetectorID); //EVT_DETECTOR_CLOSE
  2059. if (TestError(eErrorStatus))
  2060. {
  2061. Info("Disconnect Detector Success");
  2062. }
  2063. else
  2064. {
  2065. Error("Disconnect Detector Failed");
  2066. }
  2067. SetConnectConf(false, nDetectorID);
  2068. ErrorFeedback(EVT_ERR_MAX_NUMBER, "false", nDetectorID);
  2069. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_DISCONNECT_SUCCESS, "", nDetectorID);
  2070. return true;
  2071. }
  2072. /***
  2073. ** 说明:锁住流程,等待操作执行完毕
  2074. ** 参数:strPosition 执行lock的操作
  2075. ** 推荐用法:等待上一步操作完成(strposition有值);等待回调(strposition为空)。
  2076. ** 特殊流程下等待回调可写清strposition,便于分析日志
  2077. ** 完善用法(借鉴自v2):调用SDK接口前先lock,确保当前没有未执行完毕的接口,
  2078. ** 接口调用完成后再次lock,等待回调(异步接口的执行结果),
  2079. ** 最后unlock,确保本接口解锁,不影响其它流程
  2080. ***/
  2081. bool TrixellCtrl::LockPixrad(string strPosition, int nTimeout)
  2082. {
  2083. Info("--- LockPixrad {$} ---", strPosition.c_str());
  2084. DWORD nResult = WaitForSingleObject(m_hShareEvent, nTimeout);
  2085. if (WAIT_TIMEOUT == nResult)
  2086. {
  2087. ResetEvent(m_hShareEvent);
  2088. Warn("Wait response timeout");
  2089. return false;
  2090. }
  2091. ResetEvent(m_hShareEvent);
  2092. return true;
  2093. }
  2094. /***
  2095. ** 说明:操作执行完毕,解锁流程
  2096. ** 参数:strPosition 执行unlock的操作
  2097. ** 推荐用法:操作完成(strposition有值);收到回调(strposition为空)
  2098. ***/
  2099. void TrixellCtrl::UnlockPixrad(string strPosition)
  2100. {
  2101. Info("--- UnlockPixrad {$} ---", strPosition.c_str());
  2102. SetEvent(m_hShareEvent);
  2103. }
  2104. /***
  2105. ** 说明:调用API获取探测器配置
  2106. ** 调用时机:调用API连接探测器时;断线重连后第一次收到HW回调时
  2107. ***/
  2108. bool TrixellCtrl::GetConfigParameters(int nDetectorID)
  2109. {
  2110. memset(&m_configParams, 0, sizeof(m_configParams));
  2111. Info("Calling GetConfigParameters");
  2112. error_status ErrorStatus = TED_PixRad_GetConfigParameters(m_configParams);
  2113. if (!TestError(ErrorStatus))
  2114. {
  2115. Error("Get Config Para Failed");
  2116. return false;
  2117. }
  2118. string strPanelType = "";
  2119. Info("nbDetectorTypes = {$}", m_configParams.nbDetectorTypes);
  2120. for (int i = 0; i < m_configParams.nbDetectorTypes; ++i)
  2121. {
  2122. Info("<<<<<Show Detector Type {$} Information:", i);
  2123. Info("Name = {$}", m_configParams.detectorType[i].name);
  2124. Info("nbDetectorModes = {$}", m_configParams.detectorType[i].nbDetectorModes);
  2125. }
  2126. for (int i = 0; i < m_configParams.nbDetectors; ++i)
  2127. {
  2128. if (i != nDetectorID)
  2129. {
  2130. Debug("{$} is not current detector, skip", i);
  2131. continue; //多板情况下,未连接平板拿不到以下信息
  2132. }
  2133. Info("<<<<<Show detector {$} informations", i);
  2134. Info("Detector type name = {$}", m_configParams.detectorConfig[i].typeName);
  2135. Info("Detector communication path = {$}", m_configParams.detectorConfig[i].path);
  2136. Info("Product serial number = {$}", m_configParams.detectorConfig[i].serialNumber);
  2137. strPanelType = m_configParams.detectorConfig[i].typeName;
  2138. ConfFeedback(EVT_CONF_PANEL_SERIAL, i, m_configParams.detectorConfig[i].serialNumber);
  2139. m_pStPanelStatus[i]->strPanelSN = m_configParams.detectorConfig[i].serialNumber;
  2140. Info("Product configuration version = {$}", m_configParams.detectorConfig[i].version);
  2141. Info("Product part number = {$}", m_configParams.detectorConfig[i].partNumber);
  2142. m_pStPanelStatus[i]->strPartNumber = m_configParams.detectorConfig[i].partNumber;
  2143. Info("Product interface board number = {$}", m_configParams.detectorConfig[i].interfaceBoard);
  2144. Info("Product manufacturing date = {$}", m_configParams.detectorConfig[i].date);
  2145. InfoFeedback(EVT_INFO_FIRMWARE, i, 0, 0, m_configParams.detectorConfig[i].version);
  2146. ConfFeedback(EVT_CONF_PART_NUMBER, i, m_configParams.detectorConfig[i].partNumber);
  2147. ConfFeedback(EVT_CONF_IFBOARD, i, m_configParams.detectorConfig[i].interfaceBoard);
  2148. ConfFeedback(EVT_CONF_DATECODE, i, m_configParams.detectorConfig[i].date);
  2149. if (m_configParams.detectorConfig[i].remoteDeviceConfig != 0)
  2150. {
  2151. Debug("<<<<<Show Remote Device Config");
  2152. Debug("Product serial number = {$}", m_configParams.detectorConfig[i].remoteDeviceConfig->serialNumber);
  2153. Debug("Product manufacturing date = {$}", m_configParams.detectorConfig[i].remoteDeviceConfig->date);
  2154. Debug("Product configuration version = {$}", m_configParams.detectorConfig[i].remoteDeviceConfig->version);
  2155. }
  2156. if (m_configParams.detectorConfig[i].batteryConfig != 0)
  2157. {
  2158. Debug("<<<<<Show battery Config");
  2159. string strBatterySN = m_configParams.detectorConfig[i].batteryConfig->identification;
  2160. Info("identification of the battery = {$}", m_configParams.detectorConfig[i].batteryConfig->identification);
  2161. strBatterySN = strBatterySN.erase(0, strBatterySN.length() - 4);
  2162. ConfFeedback(EVT_CONF_BATTERY_SN, i, strBatterySN.c_str());
  2163. Debug("year of exchange of the battery = {$}", m_configParams.detectorConfig[i].batteryConfig->exchangeYear);
  2164. Debug("week of exchange of the battery = {$}", m_configParams.detectorConfig[i].batteryConfig->exchangeWeek);
  2165. Debug("percentage from what battery is authorized to recharge = {$}", m_configParams.detectorConfig[i].batteryConfig->rechargeTrigger);
  2166. Debug("minimum charge level (in percentage) to accept a wake up command = {$}", m_configParams.detectorConfig[i].batteryConfig->lowLevelWakeUpTrigger);
  2167. Debug("minimum charge level (in percentage) to accept acquiring image = {$}", m_configParams.detectorConfig[i].batteryConfig->lowLevelStartImageTrigger);
  2168. Debug("the temperature in used to divide the charging current to limit temperature of detector = {$}", m_configParams.detectorConfig[i].batteryConfig->securityTemperature);
  2169. }
  2170. if (m_configParams.detectorConfig[i].wifiConfig != 0)
  2171. {
  2172. Info("<<<<<Show Wifi Config");
  2173. Info("Front-End Wifi Mode = {$}", (int)m_configParams.detectorConfig[i].wifiConfig->frontEndInfo.mode);
  2174. Info("Front-End Country Code = {$}", m_configParams.detectorConfig[i].wifiConfig->frontEndInfo.countryCode);
  2175. m_strDetectorSSID_Old = m_configParams.detectorConfig[i].wifiConfig->frontEndInfo.ssid;
  2176. Info("Front-End SSID = {$}", m_strDetectorSSID_Old.c_str());
  2177. ConfFeedback(EVT_CONF_WIFI_SSID, i, m_configParams.detectorConfig[i].wifiConfig->frontEndInfo.ssid);
  2178. }
  2179. }
  2180. Info("Host Nick Name= {$}", m_configParams.hostConfig.nickName);
  2181. Info("library version number = {$}", m_configParams.libraryConfig.versionNumber);
  2182. return true;
  2183. }
  2184. /*
  2185. 激活、关闭探测器模式
  2186. strPanelType: 预留参数
  2187. nOmMode: 自定义的OpreationMode,根据上层传下来的检查模式赋值,包括rad,aed,tomo。用来设置SDK所需的OpreationMode
  2188. nAppMode: CCOS配置文件中的LogicMode,与SDK配置文件中的application mode对应(目前只输出日志使用)
  2189. bEnable: 激活或关闭,目前不受接口外部传值影响
  2190. */
  2191. bool TrixellCtrl::SetFpdExamMode(string strPanelType, int nOmMode, int nAppMode, bool bEnable)
  2192. {
  2193. Info("SetFpdExamMode nOmMode:{$}, nAppMode:{$}", nOmMode, nAppMode);
  2194. Info("Current OmMode: {$}", m_nCurrentOmMode);
  2195. /*
  2196. tips 1:
  2197. Autotrigger and digital tomo cannot be both enable at same time. Enabling one automatically disables the other.
  2198. tips 2:
  2199. DC_SYNCHRONIZATION: when the detector is shared between several host, its internal settings can be changer according to the need of each host.
  2200. This command allows to synchronize the internal settings of the panel with the host.
  2201. */
  2202. control_type type = DC_AUTOTRIGGER_NORMAL;
  2203. string strOmMode = "unknown";
  2204. string strEnable = bEnable ? "enable" : "disable";
  2205. if (nOmMode == PIX_OM_RAD)
  2206. {
  2207. Info("Set FPD to RAD mode");
  2208. m_nCurrentMode = g_nRADmode;
  2209. m_nCurrentOmMode = nOmMode; //记录当前的操作模式
  2210. //目前只可能用到rad、aed和tomo,所以如果不是aed、tomo则不需要disable.一旦之后用到了别的模式,此处需要扩充或修改.
  2211. Info("Current operation mode {$} does not need to be disabled, return", m_nCurrentOmMode);
  2212. return true;
  2213. }
  2214. else if(nOmMode == PIX_OM_AED)
  2215. {
  2216. Info("Set FPD to AED mode");
  2217. strOmMode = "AED";
  2218. type = DC_AUTOTRIGGER_NORMAL;
  2219. m_nCurrentMode = g_nAEDmode;
  2220. }
  2221. else if (nOmMode == PIX_OM_TOMO)
  2222. {
  2223. Info("Set FPD to TOMO mode");
  2224. strOmMode = "TOMO";
  2225. type = DC_DIGITAL_TOMO;
  2226. m_nCurrentMode = g_nTOMOmode;
  2227. }
  2228. else
  2229. {
  2230. Warn("Undefined OmMode {$}", nOmMode);
  2231. return false;
  2232. }
  2233. if (!SetSystemState(STATE_QUIET)) //需要在QUIET状态下设置
  2234. {
  2235. Info("Set quiet state failed");
  2236. return false;
  2237. }
  2238. Info("Calling DetectorControl, strEnable:{$} strOmMode:{$} nOmMode({$})", strEnable.c_str(), strOmMode, nOmMode);
  2239. error_status ErrorCode = TED_PixRad_DetectorControl(type, bEnable); //EVT_DETECTOR_CONTROL_CHANGED
  2240. if (!TestError(ErrorCode))
  2241. {
  2242. return false;
  2243. }
  2244. if (!WaitRespond(g_nRespondTimeoutLong, "Control"))
  2245. {
  2246. Error("Detector control timeout");
  2247. return false;
  2248. }
  2249. m_nCurrentOmMode = nOmMode;
  2250. if (!SetSystemState(STATE_QUIET)) //恢复到QUIET状态
  2251. {
  2252. Error("Set quiet state failed");
  2253. }
  2254. return true;
  2255. }
  2256. /*
  2257. bEnablePreview: 是否开启了预览图,目前暂时用不到
  2258. nOmMode: 自定义的OpreationMode,根据上层传下来的检查模式赋值,包括rad,aed,tomo。用来设置SDK所需的OpreationMode
  2259. nAppMode: CCOS配置文件中的LogicMode,与SDK配置文件中的application mode对应
  2260. */
  2261. bool TrixellCtrl::RefreshOffset(bool bEnablePreview, int nOmMode, int nAppMode, bool bWaitOver)
  2262. {
  2263. Info("Refresh offset begin bWaitOver:{$}", bWaitOver);
  2264. if (!SetSystemState(STATE_QUIET)) //需要在quiet状态刷新offset
  2265. {
  2266. Error("Set quiet state failed");
  2267. return false;
  2268. }
  2269. application_mode applicationMode = (application_mode)(nAppMode - 1);
  2270. operating_mode operatingMode;
  2271. if (PIX_OM_AED == nOmMode)
  2272. {
  2273. operatingMode = OM_RAD_AUTOTRIGGER;
  2274. }
  2275. else if (PIX_OM_RAD == nOmMode)
  2276. {
  2277. operatingMode = OM_RAD;
  2278. }
  2279. else if (PIX_OM_TOMO == nOmMode)
  2280. {
  2281. operatingMode = OM_DIGITAL_TOMO;
  2282. }
  2283. else
  2284. {
  2285. Error("No support current operation mode: {$}, return false", nOmMode);
  2286. return false;
  2287. }
  2288. unsigned short detectorMode = defaultDetectorMode;
  2289. LockPixrad("Darkcalibration");
  2290. Info("Calling DarkCalibration(applicationMode: {$}, operatingMode: {$})", (int)applicationMode, (int)operatingMode);
  2291. error_status Err = TED_PixRad_DarkCalibration(applicationMode, operatingMode, detectorMode);
  2292. //EVT_ACTIVE_STATE(REFERENCE) -> EVT_START_DARK_CALIBRATION -> EVT_END_DARK_CALIBRATION -> EVT_ACTIVE_STATE(STAND_BY)
  2293. if (!TestError(Err))
  2294. {
  2295. Error("Refresh offset failed");
  2296. UnlockPixrad("Darkcalibration");
  2297. return false;
  2298. }
  2299. //以下内容先加回来,完善校正内容时再增加
  2300. //目的是校正时不卡住状态机,等执行完毕后直接通过Notify使状态机跳转
  2301. if (bWaitOver)
  2302. {
  2303. LockPixrad("Darkcalibration"); //等待回调(dark操作执行完毕)
  2304. UnlockPixrad("Darkcalibration");
  2305. Info("Refresh offset over");
  2306. if (!SetSystemState(STATE_QUIET)) //恢复到quiet
  2307. {
  2308. Error("Set quiet state failed");
  2309. }
  2310. }
  2311. return true;
  2312. }
  2313. /*
  2314. nAppMode: CCOS配置文件中的LogicMode,与SDK配置文件中的application mode对应
  2315. */
  2316. bool TrixellCtrl::LoadReference(int nAppMode, int nDetectorID, bool bLTEenable)
  2317. {
  2318. application_mode applicationMode = application_mode(nAppMode - 1);
  2319. operating_mode operatingMode = OM_DEFAULT;
  2320. unsigned short detectorMode = defaultDetectorMode;
  2321. unsigned short gainReferenceId = defaultReferenceId;
  2322. unsigned short dmReferenceId = defaultReferenceId;
  2323. LockPixrad("LoadReferences");
  2324. Info("Calling LoadReference(appmode: {$})", (int)applicationMode);
  2325. error_status Err = TED_PixRad_LoadReferences(applicationMode, operatingMode, detectorMode, gainReferenceId, dmReferenceId);
  2326. //EVT_STATUS_POLLING_CHANGED -> EVT_START_LOAD_REFERENCES -> EVT_END_LOAD_REFERENCES -> EVT_ACTIVE_STATE(STANDBY)
  2327. if (!TestError(Err))
  2328. {
  2329. Error("Load reference command failed");
  2330. UnlockPixrad("LoadReferences");
  2331. return false;
  2332. }
  2333. Info("Load reference command ok");
  2334. LockPixrad("LoadReferences"); //等待回调(load操作执行完毕)
  2335. UnlockPixrad("LoadReferences");
  2336. if (!SetSystemState(STATE_QUIET)) //恢复到quiet,上面流程会转换到standby状态
  2337. {
  2338. return false;
  2339. }
  2340. if (CT_ALL == m_eCorrectionType)
  2341. {
  2342. Info("Load reference success");
  2343. }
  2344. else
  2345. {
  2346. Warn("Load reference failed");
  2347. return false;
  2348. }
  2349. return true;
  2350. }
  2351. bool TrixellCtrl::LoadReferenceEx(application_mode aMode, operating_mode oMode, unsigned short usDetectorMode, unsigned short usGainID, unsigned short usDMID)
  2352. {
  2353. Info("LoadReferenceEx");
  2354. LockPixrad("LoadReferences");
  2355. Info("Calling LoadReference(application_mode: {$}, operating_mode: {$})", (int)aMode, (int)oMode);
  2356. error_status ErrorStatus = TED_PixRad_LoadReferences(aMode, oMode, usDetectorMode, usGainID, usDMID);
  2357. //EVT_STATUS_POLLING_CHANGED -> EVT_START_LOAD_REFERENCES -> EVT_END_LOAD_REFERENCES -> EVT_ACTIVE_STATE(STANDBY)
  2358. if (!TestError(ErrorStatus))
  2359. {
  2360. Error("Load reference command failed");
  2361. UnlockPixrad("LoadReferences");
  2362. return false;
  2363. }
  2364. Info("Load reference command ok");
  2365. LockPixrad("LoadReferences"); //等待回调(load操作执行完毕)
  2366. UnlockPixrad("LoadReferences");
  2367. if (!SetSystemState(STATE_QUIET)) //恢复到quiet,上面流程会转换到standby状态
  2368. {
  2369. return false;
  2370. }
  2371. return true;
  2372. }
  2373. bool TrixellCtrl::GetSystemState(system_state& stState)
  2374. {
  2375. Info("Calling GetSystemState");
  2376. error_status Err = TED_PixRad_GetSystemState(stState);
  2377. if (!TestError(Err))
  2378. {
  2379. return false;
  2380. }
  2381. else
  2382. {
  2383. switch (stState)
  2384. {
  2385. case STATE_QUIET:
  2386. Info("Current System is in Quiet State");
  2387. break;
  2388. case STATE_REFERENCE:
  2389. Info("Current System is in Reference State");
  2390. break;
  2391. case STATE_STAND_BY:
  2392. Info("Current System is in Standby State");
  2393. break;
  2394. case STATE_PATIENT:
  2395. Info("Current System is in Patient State");
  2396. break;
  2397. default:
  2398. Info("Current System State is {$}", (int)stState);
  2399. break;
  2400. }
  2401. }
  2402. return true;
  2403. }
  2404. bool TrixellCtrl::SetSystemState(system_state stState)
  2405. {
  2406. Info("SetSystemState stState:{$}", (int)stState);
  2407. LockPixrad("SetSystemState"); //等待上一步调用完成
  2408. system_state currentstate;
  2409. if (!GetSystemState(currentstate))
  2410. {
  2411. UnlockPixrad("SetSystemState");
  2412. return false;
  2413. }
  2414. if (currentstate != stState)
  2415. {
  2416. Info("Calling SetSystemState");
  2417. error_status Err = TED_PixRad_SetSystemState(stState); //EVT_ACTIVE_STATE
  2418. if (!TestError(Err))
  2419. {
  2420. UnlockPixrad("SetSystemState");
  2421. return false;
  2422. }
  2423. switch (stState)
  2424. {
  2425. case STATE_QUIET: //default state, no background task is running
  2426. Info("Current System is in Quiet State");
  2427. break;
  2428. case STATE_REFERENCE: //performs specific operation like calibration, references load and hardware information functions
  2429. Info("Current System is in Reference State");
  2430. break;
  2431. case STATE_STAND_BY: //have no use for other detectors than Pixium 4600
  2432. Info("Current System is in Standby State");
  2433. break;
  2434. case STATE_PATIENT: //in this state, Pixrad is ready for clean image acquisition
  2435. Info("Current System is in Patient State");
  2436. break;
  2437. default:
  2438. Info("Current System State is {$}", (int)stState);
  2439. break;
  2440. }
  2441. LockPixrad(); //等待回调(set操作执行完毕)
  2442. }
  2443. UnlockPixrad("SetSystemState");
  2444. return true;
  2445. }
  2446. /***
  2447. ** 设置Pixrad的 acquisition type (x, offset, dm);
  2448. ** output type (short, float);
  2449. ** preview activation (true, false);
  2450. ** correction type ();
  2451. ** nAppMode: CCOS配置文件中的LogicMode,与SDK配置文件中的application mode对应
  2452. ***/
  2453. bool TrixellCtrl::SetApplicationParam(int nAppMode)
  2454. {
  2455. application_mode applicationMode = (application_mode)(nAppMode - 1); //appmode从0开始计数
  2456. Info("applicationMode:{$} nAppMode:{$}, currentID:{$}, type:{$}", (int)applicationMode, nAppMode, m_nCurrentPanelID, (int)m_eCorrectionType);
  2457. ApplicationParameter pAppParam[5] = { 0 };
  2458. char szTemp[5] = { 0 }; //用于转换值
  2459. sprintf_s(szTemp, "%d", m_nTomoImgCount);
  2460. pAppParam[0].name = "acquisition.type"; pAppParam[0].value = "x";
  2461. pAppParam[1].name = "output.type"; pAppParam[1].value = "short";
  2462. pAppParam[2].name = "output.preview"; pAppParam[2].value = "false";
  2463. if (m_bPreviewEnable)
  2464. {
  2465. pAppParam[2].name = "output.preview"; pAppParam[2].value = "true";
  2466. }
  2467. if (m_eStatus == DetStatus_XrayCalibration)
  2468. {
  2469. pAppParam[2].name = "output.preview"; pAppParam[2].value = "false";
  2470. }
  2471. // 如果设置单一校正模式,比如offset,需要调用两遍 TED_PixRad_SetApplicationParameters,第一遍all.enable = false,第二遍offset.enable = true
  2472. if (m_eCorrectionType != m_eCurrentCT && m_eCurrentCT != CT_NONE)
  2473. {
  2474. switch (m_eCurrentCT)
  2475. {
  2476. case CT_OFFSET:
  2477. Info("Offset correction disable");
  2478. pAppParam[3].name = "offset.enabled"; pAppParam[3].value = "false";
  2479. break;
  2480. case CT_GAIN:
  2481. Info("Gain correction disable");
  2482. pAppParam[3].name = "gain.enabled"; pAppParam[3].value = "false";
  2483. break;
  2484. case CT_DEFECT:
  2485. Info("Defect correction disable");
  2486. pAppParam[3].name = "defect.enabled"; pAppParam[3].value = "false";
  2487. break;
  2488. case CT_ALL:
  2489. Info("All correction disable");
  2490. pAppParam[3].name = "all.enabled"; pAppParam[3].value = "false";
  2491. break;
  2492. default:
  2493. break;
  2494. }
  2495. Info("Calling SetApplicationParameters");
  2496. error_status ErrorStatus = TED_PixRad_SetApplicationParameters(applicationMode, pAppParam, 4); //EVT_APPLICATION_PARAMETERS_STATUS
  2497. if (TestError(ErrorStatus))
  2498. {
  2499. Info("Set application parameters command OK");
  2500. }
  2501. else
  2502. {
  2503. Error("Set application parameters command Failed");
  2504. return false;
  2505. }
  2506. }
  2507. if (CT_ALL == m_eCorrectionType)
  2508. {
  2509. Info("All correction enable");
  2510. m_eCurrentCT = CT_ALL;
  2511. pAppParam[3].name = "all.enabled"; pAppParam[3].value = "true";
  2512. }
  2513. else if (CT_OFFSET == m_eCorrectionType)
  2514. {
  2515. Info("Offset correction enable");
  2516. m_eCurrentCT = CT_OFFSET;
  2517. pAppParam[3].name = "offset.enabled"; pAppParam[3].value = "true";
  2518. }
  2519. else if (CT_GAIN == m_eCorrectionType)
  2520. {
  2521. Info("Gain correction enable");
  2522. m_eCurrentCT = CT_GAIN;
  2523. pAppParam[3].name = "gain.enabled"; pAppParam[3].value = "true";
  2524. }
  2525. else if (CT_DEFECT == m_eCorrectionType)
  2526. {
  2527. Info("Defect correction enable");
  2528. m_eCurrentCT = CT_DEFECT;
  2529. pAppParam[3].name = "defect.enabled"; pAppParam[3].value = "true";
  2530. }
  2531. else
  2532. {
  2533. Info("Null correction");
  2534. m_eCurrentCT = CT_NONE;
  2535. pAppParam[3].name = "all.enabled"; pAppParam[3].value = "false";
  2536. }
  2537. pAppParam[4].name = "image.number"; pAppParam[4].value = szTemp;
  2538. // pAppParam.name 还可以设置以下值:
  2539. // offset.enable /gain.enabled /defectmap.enabled /echoline.enabled /echocolumn.ebable /
  2540. // clipping.enabled /butting.enable /pixelcluster.enable /image.number
  2541. Info("Calling SetApplicationParameters");
  2542. error_status ErrorStatus = TED_PixRad_SetApplicationParameters(applicationMode, pAppParam, 5); //EVT_APPLICATION_PARAMETERS_STATUS
  2543. if (TestError(ErrorStatus))
  2544. {
  2545. Info("Set application parameters command OK");
  2546. return true;
  2547. }
  2548. return false;
  2549. }
  2550. bool TrixellCtrl::ActiveGainCalibration()
  2551. {
  2552. if (!SetSystemState(STATE_QUIET)) //需要在quiet状态执行gain
  2553. {
  2554. Error("Set quiet state failed");
  2555. return false;
  2556. }
  2557. application_mode applicationMode = (application_mode)(m_nCurrentMode - 1);
  2558. if (m_bLTEenable && m_nCurrentOmMode == PIX_OM_RAD) //软同步 长曝光
  2559. {
  2560. applicationMode = application_mode(g_nRADLTEmode - 1);
  2561. }
  2562. unsigned short gainReferenceId = defaultReferenceId;
  2563. unsigned short dmReferenceId = defaultReferenceId;
  2564. m_eStatus = DetStatus_XrayCalibration;
  2565. m_bConfirmCaliRst = false; //激活增益校正,恢复初值
  2566. m_bAutoContinueCal = false; //终止校正,恢复初值
  2567. LockPixrad("XrayCalibration");
  2568. Info("Calling XRayCalibration");
  2569. error_status Err = TED_PixRad_XRayCalibration(applicationMode, gainReferenceId, dmReferenceId);
  2570. //EVT_ACTIVE_STATE(REFERENCE)->EVT_START_XRAY_CALIBRATION -> EVT_DOSE_PARAM_REQUEST(剂量有变化时才有)
  2571. if (!TestError(Err))
  2572. {
  2573. Error("Active XRay Calibration Failed");
  2574. m_eStatus = DetStatus_Standby; //增益失败,置回Standby
  2575. //UnlockPixrad("XrayCalibration");
  2576. return false;
  2577. }
  2578. Info("Active XRay Calibration OK");
  2579. m_bGainPreparing = true; //进入增益校正状态,直到收到相应回调
  2580. LockPixrad("XrayCalibration"); //等待回调(XRayCalibration执行完毕)
  2581. UnlockPixrad("XrayCalibration");
  2582. return true;
  2583. }
  2584. //增益校正触发SDK进行下一步操作
  2585. //bLock = true 比较耗时的情况,需要等回调
  2586. //rad,aed: 收到EVT_PREP_XRAY_SHOT为止,耗时约11s
  2587. //tomo: 收到EVT_WAIT_START_XRAY为止,耗时至少20s
  2588. bool TrixellCtrl::ResumeSequence(bool bLock)
  2589. {
  2590. Info("ResumeSequence bLock:{$}", bLock);
  2591. try
  2592. {
  2593. if (bLock)
  2594. {
  2595. LockPixrad("ResumeSequence");
  2596. }
  2597. Info("Calling ResumeSequence");
  2598. error_status ErrorStatus = TED_PixRad_ResumeSequence();
  2599. if (!TestError(ErrorStatus))
  2600. {
  2601. Error("Resume Sequence command Failed");
  2602. if (bLock)
  2603. {
  2604. UnlockPixrad("ResumeSequence");
  2605. }
  2606. }
  2607. else
  2608. {
  2609. Info("Resume Sequence command OK");
  2610. if (bLock)
  2611. {
  2612. LockPixrad("ResumeSequence"); //等待回调(EVT_PREP_XRAY_SHOT / EVT_WAIT_START_XRAY)
  2613. UnlockPixrad("ResumeSequence");
  2614. }
  2615. return true;
  2616. }
  2617. }
  2618. catch (...)
  2619. {
  2620. Error("Start acq crash!");
  2621. }
  2622. return false;
  2623. }
  2624. void TrixellCtrl::OnProcessImg()
  2625. {
  2626. if (m_bPreviewImg)
  2627. {
  2628. if (!m_bPreviewEnable)
  2629. {
  2630. Warn("Preview image is disable");
  2631. return;
  2632. }
  2633. if (m_nSaveRaw >= CCOS_SAVE_ORIGINAL)
  2634. {
  2635. SaveRawImage("Original_Preview_Image.raw", m_pPreImgBuffer, m_nPreviewWidth, m_nPreviewHeight);
  2636. }
  2637. DataFeedback(EVT_DATA_PREVIEW_IMAGE, m_pPreImgBuffer);
  2638. }
  2639. else
  2640. {
  2641. if (m_nSaveRaw >= CCOS_SAVE_ORIGINAL)
  2642. {
  2643. SaveRawImage("Original_Image.raw", m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight);
  2644. }
  2645. if (m_nSaveRaw)
  2646. {
  2647. SaveRawFunc(PIX_IMG_RAW, m_pRawImgBuffer);
  2648. }
  2649. if (m_nWidthOffset != 0 || m_nHeightOffset != 0)
  2650. {
  2651. Debug("Begin get effect image");
  2652. if (!GetEffectiveImage(m_pImgBuffer, m_pRawImgBuffer, m_nRawImgWidth))
  2653. {
  2654. return;
  2655. }
  2656. Debug("Get effect image over");
  2657. //通知裁剪后的大小
  2658. ConfFeedback(EVT_CONF_RAW_WIDTH, m_nCurrentPanelID, "", m_nImageWidth);
  2659. ConfFeedback(EVT_CONF_RAW_HIGHT, m_nCurrentPanelID, "", m_nImageHeight);
  2660. if (m_nSaveRaw >= CCOS_SAVE_AFTER_CROP)
  2661. {
  2662. SaveRawImage("After_Crop_Image.raw", m_pImgBuffer, m_nImageWidth, m_nImageHeight);
  2663. }
  2664. if (m_nCalibrationMode)//Trixell校正
  2665. {
  2666. }
  2667. else if (APP_STATUS_CAL_BEGIN != m_eAppStatus)
  2668. {
  2669. Info("Apply ZSKK Reference");
  2670. m_pZSKKCalib->m_nGridSuppressed = 6;
  2671. m_pZSKKCalib->ApplyZSKKReference(m_nImageHeight, m_nImageWidth, m_pImgBuffer);
  2672. }
  2673. if (APP_STATUS_CAL_BEGIN == m_eAppStatus && m_bSaveCalibrationRaw)
  2674. {
  2675. string strImageName = "Calibration_Image_" + to_string(m_nCalibCurrentCalibrationRound) + "_" + to_string(m_nCalibCurrentExposureIndex) + ".raw";
  2676. SaveRawImage(strImageName.c_str(), m_pImgBuffer, m_nImageWidth, m_nImageHeight);
  2677. }
  2678. DataFeedback(EVT_DATA_RAW_IMAGE, m_pImgBuffer);
  2679. }
  2680. else
  2681. {
  2682. //通知裁剪后的大小
  2683. ConfFeedback(EVT_CONF_RAW_WIDTH, m_nCurrentPanelID, "", m_nRawImgWidth);
  2684. ConfFeedback(EVT_CONF_RAW_HIGHT, m_nCurrentPanelID, "", m_nRawImgHeight);
  2685. if (m_nCalibrationMode)//Trixell校正
  2686. {
  2687. }
  2688. else if (APP_STATUS_CAL_BEGIN != m_eAppStatus)
  2689. {
  2690. Info("Apply ZSKK Reference");
  2691. m_pZSKKCalib->m_nGridSuppressed = 6;
  2692. m_pZSKKCalib->ApplyZSKKReference(m_nRawImgHeight, m_nRawImgWidth, m_pRawImgBuffer);
  2693. }
  2694. if (APP_STATUS_CAL_BEGIN == m_eAppStatus && m_bSaveCalibrationRaw)
  2695. {
  2696. string strImageName = "Calibration_Image_" + to_string(m_nCalibCurrentCalibrationRound) + "_" + to_string(m_nCalibCurrentExposureIndex) + ".raw";
  2697. SaveRawImage(strImageName.c_str(), m_pRawImgBuffer, m_nRawImgWidth, m_nRawImgHeight);
  2698. }
  2699. DataFeedback(EVT_DATA_RAW_IMAGE, m_pRawImgBuffer);
  2700. }
  2701. //目前程序逻辑这里的m_bAutonumousMode肯定是false
  2702. if (m_bAutonumousMode)
  2703. {
  2704. Info("m_bAutonumousMode ImageWidth: {$}, ImageHeight: {$}", to_string(m_nImageWidth), to_string(m_nImageHeight));
  2705. string strImageName = "Image" + to_string(m_nAutonumousImageIndex) + "_" + to_string(m_nImageWidth) + "_" + to_string(m_nImageHeight) + "_16_1.raw";
  2706. SaveRawImage(strImageName.c_str(), m_pImgBuffer, m_nImageWidth, m_nImageHeight);
  2707. return;
  2708. }
  2709. }
  2710. }
  2711. // pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
  2712. bool TrixellCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
  2713. {
  2714. if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
  2715. {
  2716. Error("Illegal parameter, can not get effective image");
  2717. return false;
  2718. }
  2719. try
  2720. {
  2721. for (int i = 0; i < m_nImageHeight; i++)
  2722. {
  2723. memcpy(pOutImg + i * m_nImageWidth,
  2724. pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset,
  2725. m_nImageWidth * sizeof(WORD));
  2726. }
  2727. }
  2728. catch (...)
  2729. {
  2730. Error("Get effective image crashed");
  2731. return false;
  2732. }
  2733. return true;
  2734. }
  2735. void TrixellCtrl::SaveRawFunc(eDetPixImgType eImgType, WORD* pInImg)
  2736. {
  2737. FILE* fp;
  2738. string strFileName = m_strWorkPath + "\\Image";
  2739. char szTemp[30] = { 0 };
  2740. int nImgX, nImgY;
  2741. switch (eImgType)
  2742. {
  2743. case PIX_IMG_PRE:
  2744. nImgX = m_nPreviewWidth;
  2745. nImgY = m_nPreviewHeight;
  2746. Info("Save preview image");
  2747. strFileName += "\\Preview.raw";
  2748. break;
  2749. case PIX_IMG_RAW:
  2750. nImgX = m_nRawImgWidth;
  2751. nImgY = m_nRawImgHeight;
  2752. Info("Save raw image");
  2753. strFileName += "\\Raw.raw";
  2754. break;
  2755. case PIX_IMG_FULL:
  2756. if (PIX_OM_TOMO == m_nCurrentOmMode)
  2757. {
  2758. nImgX = m_nImageWidth;
  2759. nImgY = m_nImageHeight;
  2760. Info("Save tomo image");
  2761. sprintf_s(szTemp, "\\Tomo_%d.raw", m_nTomoImgIndex);
  2762. strFileName += szTemp;
  2763. }
  2764. else
  2765. {
  2766. nImgX = m_nImageWidth;
  2767. nImgY = m_nImageHeight;
  2768. Info("Save full image");
  2769. strFileName += "\\Full.raw";
  2770. }
  2771. break;
  2772. default:
  2773. Warn("Unknown type image");
  2774. return;
  2775. }
  2776. if ((fp = fopen(strFileName.c_str(), "wb+")) == NULL)
  2777. {
  2778. DWORD dw = GetLastError();
  2779. Error("fopen {$} failed, {$}", strFileName.c_str(), dw);
  2780. return;
  2781. }
  2782. fwrite(pInImg, sizeof(WORD), nImgX * nImgY, fp);
  2783. fclose(fp);
  2784. Info("Save image over");
  2785. }
  2786. /***
  2787. * 保存RAW图像
  2788. ***/
  2789. bool TrixellCtrl::SaveRawImage(const char* pImgName, const WORD* pRawImg, int nWidth, int nHeight)
  2790. {
  2791. Info("Begin to Save {$} Image, width: {$}, height: {$}", pImgName, nWidth, nHeight);
  2792. if (pRawImg == NULL || pImgName == NULL)
  2793. {
  2794. return false;
  2795. }
  2796. string strImagePath = "";
  2797. if (m_bAutonumousMode)
  2798. {
  2799. string strImageDir = m_strWorkPath + "\\rawdata\\Autonumous\\" + m_strAutonumousMetaData;
  2800. if (GetFileAttributesA(strImageDir.c_str()) != FILE_ATTRIBUTE_DIRECTORY)
  2801. {
  2802. bool flag = CreateDirectory(strImageDir.c_str(), NULL);
  2803. Info("Create dir: {$}", strImageDir);
  2804. }
  2805. else
  2806. {
  2807. Info("{$} already exist", strImageDir);
  2808. }
  2809. strImagePath = m_strWorkPath + "\\rawdata\\Autonumous\\" + m_strAutonumousMetaData + "\\" + pImgName;
  2810. }
  2811. else
  2812. {
  2813. strImagePath = m_strWorkPath + "\\rawdata\\" + pImgName;
  2814. }
  2815. FILE* fp;
  2816. if ((fp = fopen(strImagePath.c_str(), "wb+")) == NULL)
  2817. {
  2818. DWORD dw = GetLastError();
  2819. Error("fopen {$} failed, {$}", strImagePath.c_str(), dw);
  2820. return false;
  2821. }
  2822. fwrite(pRawImg, sizeof(WORD), nWidth * nHeight, fp);
  2823. fclose(fp);
  2824. Info("End to Save Raw Image");
  2825. return true;
  2826. }
  2827. /***
  2828. ** 说明:处理dark校正完成流程
  2829. ***/
  2830. void TrixellCtrl::OnProcessDarkEnd()
  2831. {
  2832. Info("Refresh offset over");
  2833. if (!SetSystemState(STATE_QUIET)) //恢复到quiet
  2834. {
  2835. Error("Set quiet state failed");
  2836. }
  2837. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  2838. }
  2839. /***
  2840. ** 说明:输出回调名以及参数
  2841. ** 返回值:true,没有错误;false,有错误
  2842. ***/
  2843. bool TrixellCtrl::ProcessEventError(string strEventName, error_status err, int nDetectorID)
  2844. {
  2845. if (ERR_SUCCESS == err)
  2846. {
  2847. Info("strEventName:{$} success!", strEventName.c_str());
  2848. }
  2849. else
  2850. {
  2851. TestError(err, nDetectorID, strEventName);
  2852. return false;
  2853. }
  2854. return true;
  2855. }
  2856. /***
  2857. ** 说明:启动红外配对线程
  2858. ***/
  2859. void TrixellCtrl::StartModuleThread()
  2860. {
  2861. DWORD dwThreadId;
  2862. if (NULL == m_hModuleThread)
  2863. {
  2864. m_hModuleThread = CreateThread(NULL, 0, onModuleThread, this, 0, &dwThreadId);
  2865. }
  2866. else
  2867. {
  2868. Error("The module thread is running");
  2869. }
  2870. if (NULL == m_hModuleThread)
  2871. {
  2872. Error("Start Module Thread failed");
  2873. }
  2874. }
  2875. /***
  2876. ** 说明:红外配对线程
  2877. ***/
  2878. DWORD __stdcall TrixellCtrl::onModuleThread(PVOID pvoid)
  2879. {
  2880. TrixellCtrl* pOpr = (TrixellCtrl*)pvoid;
  2881. pOpr->OnModuleConnect();
  2882. CloseHandle(pOpr->m_hModuleThread);
  2883. pOpr->m_hModuleThread = NULL;
  2884. return 0;
  2885. }
  2886. /***
  2887. ** 说明:红外配对执行函数
  2888. ***/
  2889. bool TrixellCtrl::OnModuleConnect()
  2890. {
  2891. return true;
  2892. }
  2893. bool TrixellCtrl::IsConnected(string strIP)
  2894. {
  2895. Info("Check ping {$}", strIP);
  2896. CMyPingip obPingIp;
  2897. StatusFeedback(EVT_STATUS_PING, 0, "true");
  2898. if (!obPingIp.PingFunction(strIP.c_str()/*, g_pLog*/))
  2899. {
  2900. Info("ping {$} Failed", strIP);
  2901. StatusFeedback(EVT_STATUS_PING, 0, "false");
  2902. return false;
  2903. }
  2904. return true;
  2905. }
  2906. /***
  2907. ** 说明:修改SDK中探测器配置DetectorXXXX.ini
  2908. ** 修改detector.path.0项 -> 改为修改detector.path#####项,由SDK判断探测器序列号
  2909. ***/
  2910. bool TrixellCtrl::ModifyModuleFPDConf(string strDetectorIP, string strHostIP)
  2911. {
  2912. string strIniFilePath = m_strWorkPath + "\\" + m_strCfgPath;
  2913. string strDetectorIniPath = "";
  2914. string strDestPath = "";
  2915. bool bIsDRPanel = false;
  2916. if (m_strModuleType.find("3543DR") != string::npos)
  2917. {
  2918. strDetectorIniPath = strIniFilePath + str3543DRCINI;
  2919. strDestPath = strIniFilePath + str3543DRCINI_BK;
  2920. bIsDRPanel = true;
  2921. }
  2922. else if (m_strModuleType.find("2430EZ") != string::npos)
  2923. {
  2924. strDetectorIniPath = strIniFilePath + str2430EZINI;
  2925. strDestPath = strIniFilePath + str2430EZINI_BK;
  2926. }
  2927. else
  2928. {
  2929. strDetectorIniPath = strIniFilePath + str3543EZINI;
  2930. strDestPath = strIniFilePath + str3543EZINI_BK;
  2931. }
  2932. Info("{$}", strDetectorIniPath.c_str());
  2933. string strKey;
  2934. std::ostringstream ostrKey;
  2935. ostrKey << "detector.path.sn" << m_strModuleSN;
  2936. strKey = ostrKey.str();
  2937. Info("{$}", strKey.c_str());
  2938. bool bReplaceOldOne = true;
  2939. bool bRet = CIniFileCreat(strDetectorIniPath.c_str());
  2940. if (bRet)
  2941. {
  2942. bool bFind = false;
  2943. bFind = CIniFileGetValueByKey2(strKey.c_str(), strDetectorIP.c_str());
  2944. if (bFind)
  2945. {
  2946. Info("Same SN and IP setting");
  2947. CIniFileCloseWithoutWrite();
  2948. return true;
  2949. }
  2950. bRet = CIniFileSetTrixellSetting("hardware", "detector.path.sn", strKey.c_str(), strDetectorIP.c_str(), bReplaceOldOne);
  2951. if (bRet)
  2952. {
  2953. ostrKey << "Set " << strKey << " = " << strDetectorIP << "Success";
  2954. Info("{$}", ostrKey.str().c_str());
  2955. }
  2956. else
  2957. {
  2958. Error("Modify DetectorXXXX.ini file failed");
  2959. }
  2960. CIniFileClose();
  2961. if (bRet) //备份文件
  2962. {
  2963. CopyFile2Folder(strDetectorIniPath, strDestPath);
  2964. }
  2965. }
  2966. else
  2967. {
  2968. Error("Read DetectorXXXX.ini file failed");
  2969. CIniFileCloseWithoutWrite();
  2970. }
  2971. return bRet;
  2972. }
  2973. /***
  2974. ** 说明:修改探测器IP配置
  2975. ***/
  2976. bool TrixellCtrl::ModifyFPDsIPConf()
  2977. {
  2978. string strIniFilePath = m_strWorkPath + "\\" + m_strCfgPath;
  2979. string strDetectorIniPath = ""; //SDK配置文件DetectorXXXX.ini路径
  2980. string strPanelType = "";
  2981. string strDetectorIP = "";
  2982. string strHostIP = "";
  2983. bool bRet = true;
  2984. int nPanelID = 0;
  2985. for (int nID = 0; nID < m_nPanelCount; nID++)
  2986. {
  2987. try
  2988. {
  2989. strPanelType = (string)m_pStPanelStatus[nID]->objPanelConfig["ProductID"];
  2990. strDetectorIP = (string)m_pStPanelStatus[nID]->objPanelConfig["connections"]["WiredIP"];
  2991. strHostIP = (string)m_pStPanelStatus[nID]->objPanelConfig["connections"]["LocalIP"];
  2992. //轮询已轮询过的探测器类型,看和当前的是否重复,重复则nPanelID自增
  2993. nPanelID = 0; //恢复初值
  2994. for (int i = 0; i < nID; i++)
  2995. {
  2996. if (strPanelType == (string)m_pStPanelStatus[nID]->objPanelConfig["ProductID"])
  2997. {
  2998. nPanelID++;
  2999. }
  3000. }
  3001. }
  3002. catch (ResDataObjectExption &exp)
  3003. {
  3004. Error("Get configuration failed, {$}", exp.what());
  3005. return false;
  3006. }
  3007. if (strPanelType.find("3543EZh") != string::npos
  3008. && strPanelType.find("3543EZhd") == string::npos)
  3009. {
  3010. //3543EZh探测器在SDK中的类型是3543EZe
  3011. strPanelType = "3543EZe";
  3012. }
  3013. strDetectorIniPath = strIniFilePath + "\\Detector" + strPanelType;
  3014. if (nPanelID == 1)
  3015. {
  3016. strDetectorIniPath += "_A";
  3017. }
  3018. else if (nPanelID == 2)
  3019. {
  3020. strDetectorIniPath += "_B";
  3021. }
  3022. strDetectorIniPath += ".ini";
  3023. Info("{$}", strDetectorIniPath.c_str());
  3024. if (strPanelType.find("DR") != string::npos)
  3025. {
  3026. bRet = ModifyFPDIPConf(strDetectorIniPath, strDetectorIP);
  3027. }
  3028. else if (!IsPortablePanel(strPanelType))
  3029. {
  3030. if(strPanelType.find("4143") != string::npos ||
  3031. strPanelType.find("4343rc") != string::npos ||
  3032. strPanelType.find("4343rg") != string::npos)
  3033. {
  3034. //这些探测器IP只能4选1,暂不支持配置
  3035. bRet = ModifyOLDFPDIPConfEx(strDetectorIP, strDetectorIniPath);
  3036. }
  3037. else
  3038. {
  3039. bRet = ModifyOLDFPDIPConf(strDetectorIP, strDetectorIniPath, strHostIP);
  3040. }
  3041. }
  3042. else
  3043. {
  3044. bRet = ModifyFPDIPConf(strDetectorIniPath, strDetectorIP, strHostIP);
  3045. }
  3046. }
  3047. return bRet;
  3048. }
  3049. /***
  3050. ** 说明:修改探测器IP配置
  3051. ** 需要修改local和detector ip配置项
  3052. ***/
  3053. bool TrixellCtrl::ModifyFPDIPConf(string strConfPath, string strDetectorIP, string strHostIP)
  3054. {
  3055. bool bRet = CIniFileCreat(strConfPath.c_str());
  3056. if (bRet)
  3057. {
  3058. bool bFind = false;
  3059. bool bWrited = false; //true:修改了配置文件内容
  3060. bFind = CIniFileGetValueByKey2("detector.path.0", strDetectorIP.c_str());
  3061. if (bFind)
  3062. {
  3063. Info("Same IP setting");
  3064. }
  3065. else
  3066. {
  3067. string strConfigPath = "detector.path.0 = " + strDetectorIP;
  3068. bRet = CIniFileSetItemByKey("hardware", "detector.path.0", strConfigPath.c_str());
  3069. if (bRet)
  3070. {
  3071. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3072. }
  3073. else
  3074. {
  3075. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3076. }
  3077. bWrited = true;
  3078. }
  3079. if (strHostIP != "")
  3080. {
  3081. bFind = CIniFileGetValueByKey2("local.path", strHostIP.c_str());
  3082. if (bFind)
  3083. {
  3084. Info("Same IP setting");
  3085. }
  3086. else
  3087. {
  3088. string strConfigPath = "local.path = " + strHostIP;
  3089. bRet = CIniFileSetItemByKey("hardware", "local.path", strConfigPath.c_str());
  3090. if (bRet)
  3091. {
  3092. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3093. }
  3094. else
  3095. {
  3096. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3097. }
  3098. bWrited = true;
  3099. }
  3100. }
  3101. if (bWrited) //修改了内容,重新写回去
  3102. {
  3103. CIniFileClose();
  3104. }
  3105. else
  3106. {
  3107. CIniFileCloseWithoutWrite();
  3108. }
  3109. }
  3110. else
  3111. {
  3112. Error("Read DetectorXXXX.ini file failed");
  3113. CIniFileCloseWithoutWrite();
  3114. }
  3115. return bRet;
  3116. }
  3117. /***
  3118. ** 说明:修改探测器IP配置
  3119. ** 需要修改local和detector ip配置项;
  3120. ** 一般是固定板,detector ip不带.0后缀
  3121. ***/
  3122. bool TrixellCtrl::ModifyOLDFPDIPConf(string strDetectorIP, string strConfPath, string strHostIP)
  3123. {
  3124. bool bRet = CIniFileCreat(strConfPath.c_str());
  3125. if (bRet)
  3126. {
  3127. bool bFind = false;
  3128. bool bWrited = false; //true:修改了配置文件内容
  3129. bFind = CIniFileGetValueByKey2("detector.path", strDetectorIP.c_str());
  3130. if (bFind)
  3131. {
  3132. Info("Same IP setting");
  3133. }
  3134. else
  3135. {
  3136. string strConfigPath = "detector.path = " + strDetectorIP;
  3137. bRet = CIniFileSetItemByKey("hardware", "detector.path", strConfigPath.c_str());
  3138. if (bRet)
  3139. {
  3140. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3141. }
  3142. else
  3143. {
  3144. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3145. }
  3146. bWrited = true;
  3147. }
  3148. bFind = CIniFileGetValueByKey2("local.path", strHostIP.c_str());
  3149. if (bFind)
  3150. {
  3151. Info("Same IP setting");
  3152. }
  3153. else
  3154. {
  3155. string strConfigPath = "local.path = " + strHostIP;
  3156. bRet = CIniFileSetItemByKey("hardware", "local.path", strConfigPath.c_str());
  3157. if (bRet)
  3158. {
  3159. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3160. }
  3161. else
  3162. {
  3163. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3164. }
  3165. bWrited = true;
  3166. }
  3167. if (bWrited)
  3168. {
  3169. CIniFileClose();
  3170. }
  3171. else
  3172. {
  3173. CIniFileCloseWithoutWrite();
  3174. }
  3175. }
  3176. else
  3177. {
  3178. Error("Read DetectorXXXX.ini file failed");
  3179. CIniFileCloseWithoutWrite();
  3180. }
  3181. return bRet;
  3182. }
  3183. /***
  3184. ** 说明:修改探测器IP配置
  3185. ** 早先的固定板IP配置只能4选1,配置好使用的IP后需要将不用的IP加上分号注释掉
  3186. ***/
  3187. bool TrixellCtrl::ModifyOLDFPDIPConfEx(string strDetectorIP, string strConfPath)
  3188. {
  3189. bool bRet = CIniFileCreat(strConfPath.c_str());
  3190. if (bRet)
  3191. {
  3192. bool bFind = false;
  3193. bool bWrited = false; //true:修改了配置文件内容
  3194. char szIP[50];
  3195. bFind = CIniFileGetValueByKey("detector.path", szIP);
  3196. if (bFind) //有不带注释的detector.path 项
  3197. {
  3198. string strIP = szIP;
  3199. if (strIP.find(strDetectorIP) != string::npos)
  3200. {
  3201. Info("Same IP setting");
  3202. }
  3203. else //先注释掉原来的,再改新的
  3204. {
  3205. Info("Old IP setting: {$}", szIP);
  3206. string strConfigPath = "detector.path = " + strIP;
  3207. bRet = CIniFileSetItemByKey("hardware", strConfigPath.c_str(), (";" + strConfigPath).c_str());
  3208. if (bRet)
  3209. {
  3210. Info("Set configuration ({$}) succeess", (";" + strConfigPath).c_str());
  3211. strConfigPath = "detector.path = " + strDetectorIP + ":10001";
  3212. bRet = CIniFileSetItemByKey("hardware", strConfigPath.c_str(), strConfigPath.c_str());
  3213. if (bRet)
  3214. {
  3215. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3216. }
  3217. else
  3218. {
  3219. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3220. }
  3221. }
  3222. else
  3223. {
  3224. Error("Set configuration ({$}) failed", (";" + strConfigPath).c_str());
  3225. }
  3226. bWrited = true;
  3227. }
  3228. }
  3229. else //没有的话直接改
  3230. {
  3231. string strConfigPath = "detector.path = " + strDetectorIP + ":10001";
  3232. bRet = CIniFileSetItemByKey("hardware", strConfigPath.c_str(), strConfigPath.c_str());
  3233. if (bRet)
  3234. {
  3235. Info("Set configuration ({$}) succeess", strConfigPath.c_str());
  3236. }
  3237. else
  3238. {
  3239. Error("Set configuration ({$}) failed", strConfigPath.c_str());
  3240. }
  3241. bWrited = true;
  3242. }
  3243. if (bWrited)
  3244. {
  3245. CIniFileClose();
  3246. }
  3247. else
  3248. {
  3249. CIniFileCloseWithoutWrite();
  3250. }
  3251. }
  3252. else
  3253. {
  3254. Error("Read DetectorXXXX.ini file failed");
  3255. CIniFileCloseWithoutWrite();
  3256. }
  3257. return bRet;
  3258. }
  3259. /***
  3260. ** 说明:修改SDK中探测器配置ModuleXX_IR_1.ini
  3261. ** 修改module.serial.port项
  3262. ***/
  3263. bool TrixellCtrl::SetIRPort(string strDetectorType, int nPort)
  3264. {
  3265. if (nPort <= 0)
  3266. {
  3267. Error("The IR port({$}) is illegal", nPort);
  3268. return false;
  3269. }
  3270. string strModuleIRFile = "";
  3271. string strModuleIRBKFile = "";
  3272. if (strDetectorType.find("3543DR") != string::npos)
  3273. {
  3274. strModuleIRFile = m_strWorkPath + "\\" + m_strCfgPath + "\\ModuleDR_IR_1.ini";
  3275. strModuleIRBKFile = m_strWorkPath + "\\" + m_strCfgPath + "\\ModuleDR_IR_1_bk.ini";
  3276. }
  3277. else
  3278. {
  3279. strModuleIRFile = m_strWorkPath + "\\" + m_strCfgPath + "\\ModuleEZ_IR_1.ini";
  3280. strModuleIRBKFile = m_strWorkPath + "\\" + m_strCfgPath + "\\ModuleEZ_IR_1_bk.ini";
  3281. }
  3282. char szConfigValue[10] = ""; //用于获取配置文件中的串口号,e.g. com3
  3283. //先确认有配置项
  3284. DWORD dwRet = GetPrivateProfileString("hardware", "module.serial.port", "",
  3285. szConfigValue, sizeof(szConfigValue), strModuleIRFile.c_str());
  3286. if (dwRet == 0)
  3287. {
  3288. Error("Get IR port failed({$})", GetLastError());
  3289. return false;
  3290. }
  3291. Info("IR port of SDK config: {$}", szConfigValue);
  3292. string strConfigValue = szConfigValue;
  3293. strConfigValue = strConfigValue.substr(3); //截取"com"之后的字符
  3294. int nIRPort = atoi(strConfigValue.c_str());
  3295. if (nIRPort == nPort)
  3296. {
  3297. Info("Same port, return");
  3298. return true;
  3299. }
  3300. else
  3301. {
  3302. sprintf_s(szConfigValue, "com%d", nPort);
  3303. Info("Set IR port to {$}", szConfigValue);
  3304. dwRet = WritePrivateProfileString("hardware", "module.serial.port",
  3305. szConfigValue, strModuleIRFile.c_str());
  3306. if (dwRet == 0)
  3307. {
  3308. Error("Set IR port failed({$})", GetLastError());
  3309. return false;
  3310. }
  3311. }
  3312. Info("Set IR port OK");
  3313. return true;
  3314. }
  3315. /***
  3316. ** 说明:设置状态轮询使能
  3317. ***/
  3318. bool TrixellCtrl::SetStatusPolling(int nDetectorID, bool bEnable)
  3319. {
  3320. if (bEnable)
  3321. {
  3322. SetDetectorStatusPolling(nDetectorID, true);
  3323. }
  3324. else
  3325. {
  3326. SetDetectorStatusPolling(nDetectorID, false);
  3327. }
  3328. return true;
  3329. }
  3330. /***
  3331. ** 说明:调用API轮询探测器状态
  3332. ***/
  3333. bool TrixellCtrl::SetDetectorStatusPolling(int nDetectorID, bool bEnable)
  3334. {
  3335. Info("Calling DetectorStatusPolling(ID:{$} bEnable:{$})", nDetectorID, bEnable);
  3336. error_status eErrorStatus = TED_PixRad_DetectorStatusPolling(nDetectorID, bEnable);
  3337. if (!TestError(eErrorStatus))
  3338. {
  3339. Error("Get detector status polling command Failed");
  3340. return false;
  3341. }
  3342. return true;
  3343. }
  3344. /***
  3345. ** 说明:获取探测器信息(HW/WIFI)
  3346. ***/
  3347. bool TrixellCtrl::GetHardwareStatus(int nDetectorID)
  3348. {
  3349. if (m_pStPanelStatus[nDetectorID]->bConnectStatus) //只在连接状态下查询
  3350. {
  3351. GetDetectorHardwareStatus(nDetectorID); //双板的HW都要查询
  3352. string strPanelType = m_pStPanelStatus[nDetectorID]->strPanelType;
  3353. if (IsPortablePanel(strPanelType))
  3354. {
  3355. GetDetectorWifiStatus(nDetectorID);
  3356. }
  3357. }
  3358. return true;
  3359. }
  3360. /***
  3361. ** 说明:调用API获取HW信息
  3362. ***/
  3363. bool TrixellCtrl::GetDetectorHardwareStatus(int nDetectorID)
  3364. {
  3365. LockPixrad("GetDetectorHardwareStatus");
  3366. Info("Get Detector {$} Hardware Status", nDetectorID);
  3367. error_status eErrorStatus = TED_PixRad_GetDetectorHardwareStatus(nDetectorID); //EVT_HARDWARE_STATUS->EVT_ACTIVE_STATE
  3368. if (!TestError(eErrorStatus))
  3369. {
  3370. Info("Get detector hardware status command Failed");
  3371. //UnlockPixrad("GetDetectorHardwareStatus");
  3372. return true;
  3373. }
  3374. LockPixrad("GetDetectorHardwareStatus");
  3375. UnlockPixrad("GetDetectorHardwareStatus");
  3376. return false;
  3377. }
  3378. /***
  3379. ** 说明:调用API获取Wifi
  3380. ***/
  3381. bool TrixellCtrl::GetDetectorWifiStatus(int nDetectorID)
  3382. {
  3383. LockPixrad("GetDetectorWifiStatus"); //确保上一步执行完毕
  3384. m_bNeedFeedback = true;
  3385. Info("Get Detector {$} Wifi Status", nDetectorID);
  3386. error_status eErrorStatus = TED_PixRad_GetDetectorWifiStatus(nDetectorID); //EVT_WIFI_STATUS
  3387. if (!TestError(eErrorStatus))
  3388. {
  3389. Error("Get detector wifi status fail!");
  3390. m_bNeedFeedback = false;
  3391. return false;
  3392. }
  3393. LockPixrad("GetDetectorWifiStatus"); //等待反馈
  3394. UnlockPixrad("GetDetectorWifiStatus");
  3395. return true;
  3396. }
  3397. /***
  3398. ** 说明:调用API获取shock sensor和Voltage
  3399. ***/
  3400. bool TrixellCtrl::GetDetectorInformation(int nDetectorID, bool bRequireVoltage)
  3401. {
  3402. Info("Getting Detector Info");
  3403. if (m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3404. {
  3405. if (!SetSystemState(STATE_QUIET))
  3406. {
  3407. Error("Set Quiet State Failed");
  3408. return false;
  3409. }
  3410. else
  3411. {
  3412. Info("Set Quiet State OK");
  3413. }
  3414. LockPixrad("GetDetectorInformation"); //确保上一步执行完毕
  3415. Info("Get Detector {$} Shock Sensor", nDetectorID);
  3416. error_status eErrorStatus = TED_PixRad_GetDetectorInformation(DI_SHOCK_SENSOR); //EVT_DETECTOR_INFORMATION
  3417. if (!TestError(eErrorStatus))
  3418. {
  3419. Info("Get detector Information command Failed");
  3420. //UnlockPixrad("GetDetectorInformation");
  3421. return false;
  3422. }
  3423. LockPixrad("GetDetectorInformation"); //等回调
  3424. UnlockPixrad("GetDetectorInformation");
  3425. if (bRequireVoltage)
  3426. {
  3427. LockPixrad("GetVoltage");
  3428. Info("Get Detector {$} Voltage", nDetectorID);
  3429. eErrorStatus = TED_PixRad_GetVoltage(); //EVT_END_VOLTAGES
  3430. if (!TestError(eErrorStatus))
  3431. {
  3432. Info("Get detector Voltage Failed");
  3433. //UnlockPixrad("GetVoltage");
  3434. return false;
  3435. }
  3436. LockPixrad("GetVoltage"); //等回调
  3437. UnlockPixrad("GetVoltage");
  3438. }
  3439. }
  3440. else
  3441. {
  3442. Info("Not connect, return");
  3443. }
  3444. return false;
  3445. }
  3446. /***
  3447. ** 说明:上传文件到探测器内部
  3448. ** 在RAD3中由上层流程触发,此处触发方式待定
  3449. ***/
  3450. bool TrixellCtrl::UploadSensitivity(int nDetectorID)
  3451. {
  3452. if (-1 == nDetectorID)
  3453. {
  3454. nDetectorID = m_nCurrentPanelID;
  3455. }
  3456. if (m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3457. {
  3458. Warn("Communication error, not upload file");
  3459. return true;
  3460. }
  3461. string strFileName = m_pStPanelStatus[nDetectorID]->strPanelSN + "_Sensitivity.txt";
  3462. string strLocalPath = m_strWorkPath + "\\references\\" + strFileName;
  3463. string strDestPath = m_pStPanelStatus[nDetectorID]->strPanelSN + "\\references\\CalibrationData\\";
  3464. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strFileName;
  3465. CopyFile2Folder(strLocalPath, strDestPath);
  3466. bool bResult = UploadtoDetector(strLocalPath, strFileName);
  3467. return bResult;
  3468. }
  3469. /***
  3470. ** 说明:下载探测器内部的文件
  3471. ** 应用在attach流程
  3472. ***/
  3473. bool TrixellCtrl::DownloadSensitivity(int nDetectorID)
  3474. {
  3475. return true;
  3476. }
  3477. bool TrixellCtrl::UploadReferences(int nDetectorID)
  3478. {
  3479. return true;
  3480. }
  3481. bool TrixellCtrl::RestoreCalibrationData(bool bLTEenable, int nDetectorID)
  3482. {
  3483. return true;
  3484. }
  3485. /***
  3486. ** 说明:从探测器中下载校正文件和报告
  3487. ***/
  3488. bool TrixellCtrl::DownloadReferences(bool bLTEenable, int nDetectorID)
  3489. {
  3490. if (-1 == nDetectorID)
  3491. {
  3492. nDetectorID = m_nCurrentPanelID;
  3493. }
  3494. string strGainFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_GainFILE;
  3495. string strDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_FXDFILE;
  3496. //add20210402 长曝光 下载gain文件、defect文件
  3497. if (bLTEenable)
  3498. {
  3499. strGainFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_GainFILEL;
  3500. strDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_FXDFILEL;
  3501. }//addend
  3502. string strLocalPath = m_strWorkPath + "\\references\\" + strGainFile;
  3503. DownloadfromDetector(strLocalPath, strGainFile);
  3504. string strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3505. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strGainFile;
  3506. CopyFile2Folder(strLocalPath, strDestPath);
  3507. strLocalPath = m_strWorkPath + "\\references\\" + strDefectFile;
  3508. DownloadfromDetector(strLocalPath, strDefectFile);
  3509. strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3510. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strDefectFile;
  3511. CopyFile2Folder(strLocalPath, strDestPath);
  3512. string strManualDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_Manual_DefectFILE;
  3513. //add20210402 长曝光 下载manual defect文件
  3514. if (bLTEenable) //0:STE; 1:LTE
  3515. {
  3516. strManualDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_Manual_DefectFILEL;
  3517. }//addend
  3518. strLocalPath = m_strWorkPath + "\\references\\" + strManualDefectFile;
  3519. DownloadfromDetector(strLocalPath, strManualDefectFile);
  3520. strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3521. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strManualDefectFile;
  3522. CopyFile2Folder(strLocalPath, strManualDefectFile);
  3523. string strPanelType = "3543dr";
  3524. string strTemp = m_pStPanelStatus[nDetectorID]->strPanelType;
  3525. if (strTemp.find("3543EZ") != string::npos)
  3526. {
  3527. strPanelType = "3543ezh";
  3528. }
  3529. else if (strTemp.find("2430EZ") != string::npos)
  3530. {
  3531. strPanelType = "2430ez";
  3532. }
  3533. string strReferenceFile = "";
  3534. char szReferenceFile[50];
  3535. sprintf_s(szReferenceFile, "FDCalibReport_%s_fd%s_30.xml",
  3536. m_pStPanelStatus[nDetectorID]->strPanelSN.c_str(), strPanelType.c_str());
  3537. //长曝光 下载校正报告
  3538. if (bLTEenable) //0:STE; 1:LTE
  3539. {
  3540. sprintf_s(szReferenceFile, "FDCalibReport_%s_fd%s_31.xml",
  3541. m_pStPanelStatus[nDetectorID]->strPanelSN.c_str(), strPanelType.c_str());
  3542. }
  3543. strReferenceFile = szReferenceFile;
  3544. strLocalPath = m_strWorkPath + "\\references\\" + strReferenceFile;
  3545. DownloadfromDetector(strLocalPath, strReferenceFile);
  3546. strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3547. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strReferenceFile;
  3548. CopyFile2Folder(strLocalPath, strDestPath);
  3549. return true;
  3550. }
  3551. /***
  3552. ** 说明:上传manual defect map
  3553. ** 在RAD3中由上层流程触发,此处触发方式待定
  3554. ***/
  3555. bool TrixellCtrl::UploadDefectCalibrationFiles(int nDetectorID)
  3556. {
  3557. if (-1 == nDetectorID)
  3558. {
  3559. nDetectorID = m_nCurrentPanelID;
  3560. }
  3561. Info("Upload Defect Calibration Files");
  3562. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_START);
  3563. bool bResult = false;
  3564. if ((m_pStPanelStatus[nDetectorID]->strPanelSN == "") ||
  3565. !m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3566. {
  3567. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END_ERROR);
  3568. Info("Omit Upload Defect Files");
  3569. return false;
  3570. }
  3571. string strDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_Manual_DefectFILE;
  3572. //长曝光 上传manual defect
  3573. if (m_bLTEenable) //0:STE; 1:LTE
  3574. {
  3575. strDefectFile = m_pStPanelStatus[nDetectorID]->strPanelSN + STR_Manual_DefectFILEL;
  3576. }//addend
  3577. string strLocalPath = m_strWorkPath + "\\references\\" + strDefectFile;
  3578. string strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3579. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strDefectFile;
  3580. CopyFile2Folder(strLocalPath, strDestPath);
  3581. bResult = UploadtoDetector(strLocalPath, strDefectFile);
  3582. if (!bResult)
  3583. {
  3584. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END_ERROR);
  3585. return false;
  3586. }
  3587. bResult = UploadDefectMap();
  3588. if (bResult)
  3589. {
  3590. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END);
  3591. }
  3592. else
  3593. {
  3594. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END_ERROR);
  3595. }
  3596. return true;
  3597. }
  3598. /***
  3599. ** 说明:上传defect map和校正报告
  3600. ***/
  3601. bool TrixellCtrl::UploadDefectMap(int nDetectorID)
  3602. {
  3603. if (-1 == nDetectorID)
  3604. {
  3605. nDetectorID = m_nCurrentPanelID;
  3606. }
  3607. //目前没有_Defect.map,先去掉这个流程
  3608. string strDefectMap = "";
  3609. string strLocalPath = "";
  3610. //string strDefectMap = m_pStPanelStatus[nDetectorID]->strPanelSN + "_Defect.map";
  3611. //string strLocalPath = m_strWorkPath + "\\references\\" + strDefectMap;
  3612. if (!m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3613. {
  3614. StatusFeedback(EVT_STATUS_SAVEDEFECT, PANEL_EVENT_END_ERROR);
  3615. Error("Detector is disconnected, Save defect delta map failed");
  3616. return false;
  3617. }
  3618. string strDestPath = "";
  3619. //string strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3620. //strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strDefectMap;
  3621. //CopyFile2Folder(strLocalPath, strDestPath);
  3622. bool bResult = false;
  3623. //bool bResult = UploadtoDetector(strLocalPath, strDefectMap);
  3624. string strPanelType = "3543dr";
  3625. string strTemp = m_pStPanelStatus[nDetectorID]->strPanelType;
  3626. if (strTemp.find("3543EZ") != string::npos)
  3627. {
  3628. strPanelType = "3543ezh";
  3629. }
  3630. else if (strTemp.find("2430EZ") != string::npos)
  3631. {
  3632. strPanelType = "2430ez";
  3633. }
  3634. string strReferenceFile = "";
  3635. char szReferenceFile[50] = { 0 };
  3636. sprintf_s(szReferenceFile, "FDCalibReport_%s_fd%s_30.xml",
  3637. m_pStPanelStatus[nDetectorID]->strPanelSN.c_str(), strPanelType.c_str());
  3638. //长曝光 上传校正报告
  3639. if (m_bLTEenable) //0:STE; 1:LTE
  3640. {
  3641. sprintf_s(szReferenceFile, "FDCalibReport_%s_fd%s_31.xml",
  3642. m_pStPanelStatus[nDetectorID]->strPanelSN.c_str(), strPanelType.c_str());
  3643. }
  3644. strReferenceFile = szReferenceFile;
  3645. strLocalPath = m_strWorkPath + "\\references\\" + szReferenceFile;
  3646. strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3647. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + szReferenceFile;
  3648. CopyFile2Folder(strLocalPath, strDestPath);
  3649. bResult = UploadtoDetector(strLocalPath, strReferenceFile);
  3650. if (!bResult)
  3651. {
  3652. return false;
  3653. }
  3654. return true;
  3655. }
  3656. /***
  3657. ** 说明:下载defect map
  3658. ***/
  3659. bool TrixellCtrl::DownloadDefectMap(int nDetectorID)
  3660. {
  3661. if (-1 == nDetectorID)
  3662. {
  3663. nDetectorID = m_nCurrentPanelID;
  3664. }
  3665. string strDefectMap = m_pStPanelStatus[nDetectorID]->strPanelSN + "_Defect.map";
  3666. string strLocalPath = m_strWorkPath + "\\references\\" + strDefectMap;
  3667. DownloadfromDetector(strLocalPath, strDefectMap, nDetectorID);
  3668. string strDestPath = m_strWorkPath + "\\references\\CalibrationData\\";
  3669. strDestPath += m_pStPanelStatus[nDetectorID]->strPanelSN + "\\" + strDefectMap;
  3670. CopyFile2Folder(strLocalPath, strDestPath);
  3671. return true;
  3672. }
  3673. /***
  3674. ** 说明:调用API,上传文件到探测器内部
  3675. ***/
  3676. bool TrixellCtrl::UploadtoDetector(string strFilePath, string strFileName, int nDetectorID)
  3677. {
  3678. if (-1 == nDetectorID)
  3679. {
  3680. nDetectorID = m_nCurrentPanelID;
  3681. }
  3682. bool bResult = false;
  3683. LockPixrad("OpenRemoteStorageSession"); //确保上一步执行完毕
  3684. Info("Calling OpenRemoteStorageSession");
  3685. error_status eErrorStatus = TED_PixRad_OpenRemoteStorageSession(); //EVT_START_REMOTE_STORAGE_SESSION
  3686. if (!TestError(eErrorStatus))
  3687. {
  3688. Error("OpenRemoteStorageSession failed");
  3689. //UnlockPixrad("OpenRemoteStorageSession");
  3690. return false;
  3691. }
  3692. LockPixrad("OpenRemoteStorageSession"); //等待SessionID
  3693. UnlockPixrad("OpenRemoteStorageSession");
  3694. Info("Calling RemoteStorageCreateDirectory");
  3695. rs_error_status rsErrorStatus = TED_PixRad_RemoteStorageCreateDirectory(m_nSessionID, "RAD3\\"); //双层目录,创建两次就可以了
  3696. if (!TestRSError(rsErrorStatus))
  3697. {
  3698. Error("RemoteStorageCreateDirectory failed");
  3699. //return false; //这块应该一直是失败的(session error -31 'SFTP Protocol Error 4'),不影响
  3700. }
  3701. string strRemotePath = "RAD3\\" + strFileName;
  3702. Info("Calling Upload File:{$} To {$}", strFilePath.c_str(), strRemotePath.c_str());
  3703. rsErrorStatus = TED_PixRad_RemoteStorageUploadFile(m_nSessionID, strFilePath.c_str(),
  3704. strRemotePath.c_str(), RsprogressCallback, 0);
  3705. if (!TestRSError(rsErrorStatus))
  3706. {
  3707. Error("RemoteStorageUploadFile failed");
  3708. bResult = false;
  3709. }
  3710. else
  3711. {
  3712. bResult = true;
  3713. }
  3714. LockPixrad("CloseRemoteStorageSession"); //确保上一步执行完毕
  3715. Info("Calling CloseRemoteStorageSession");
  3716. eErrorStatus = TED_PixRad_CloseRemoteStorageSession();
  3717. if (!TestError(eErrorStatus))
  3718. {
  3719. Error("CloseRemoteStorageSession failed");
  3720. //UnlockPixrad("CloseRemoteStorageSession");
  3721. return false;
  3722. }
  3723. LockPixrad("CloseRemoteStorageSession");
  3724. UnlockPixrad("CloseRemoteStorageSession");
  3725. if (bResult)
  3726. {
  3727. Info("Upload files to detector success");
  3728. }
  3729. else
  3730. {
  3731. Error("Upload files to detector failed");
  3732. }
  3733. return bResult;
  3734. }
  3735. /***
  3736. ** 说明:调用API,下载探测器内部的文件
  3737. ***/
  3738. bool TrixellCtrl::DownloadfromDetector(string strFilePath, string strFileName, int nDetectorID)
  3739. {
  3740. if (-1 == nDetectorID)
  3741. {
  3742. nDetectorID = m_nCurrentPanelID;
  3743. }
  3744. LockPixrad("OpenRemoteStorageSession"); //确保上一步执行完毕
  3745. Info("Calling OpenRemoteStorageSession");
  3746. error_status eErrorStatus = TED_PixRad_OpenRemoteStorageSession(); //EVT_START_REMOTE_STORAGE_SESSION
  3747. if (!TestError(eErrorStatus))
  3748. {
  3749. Error("OpenRemoteStorageSession failed");
  3750. //UnlockPixrad("OpenRemoteStorageSession");
  3751. return false;
  3752. }
  3753. LockPixrad("OpenRemoteStorageSession");
  3754. UnlockPixrad("OpenRemoteStorageSession");
  3755. string strRemotePath = "RAD3\\" + strFileName;
  3756. Info("Calling Download File:{$} from {$}", strFilePath.c_str(), strRemotePath.c_str());
  3757. rs_error_status rsErrorStatus = TED_PixRad_RemoteStorageDownloadFile(m_nSessionID,
  3758. strRemotePath.c_str(), strFilePath.c_str(), RsprogressCallback, 0);
  3759. if (!TestRSError(rsErrorStatus))
  3760. {
  3761. Error("RemoteStorageDownloadFile failed");
  3762. }
  3763. LockPixrad("CloseRemoteStorageSession"); //确保上一步执行完毕
  3764. Info("Calling CloseRemoteStorageSession");
  3765. eErrorStatus = TED_PixRad_CloseRemoteStorageSession(); //EVT_END_REMOTE_STORAGE_SESSION->EVT_ACTIVE_STATE(xxx) 恢复到操作之前的state
  3766. if (!TestError(eErrorStatus))
  3767. {
  3768. Error("CloseRemoteStorageSession failed");
  3769. return false;
  3770. }
  3771. Info("Download files from detector over");
  3772. LockPixrad("CloseRemoteStorageSession"); //等待回调EVT_ACTIVE_STATE(STATE_PATIENT)
  3773. UnlockPixrad("CloseRemoteStorageSession");
  3774. return true;
  3775. }
  3776. /***
  3777. ** 说明:加载校正文件
  3778. ***/
  3779. bool TrixellCtrl::FactoryCorrectionActive(bool bAttachProcess, int nDetectorID)
  3780. {
  3781. Info("FactoryCorrectionActive bAttachProcess:{$},nDetectorID:{$}", bAttachProcess, nDetectorID);
  3782. if (-1 == nDetectorID)
  3783. {
  3784. nDetectorID = m_nCurrentPanelID;
  3785. }
  3786. if (m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3787. {
  3788. if (!SetSystemState(STATE_QUIET))
  3789. {
  3790. Error("Set Quiet State Failed");
  3791. return false;
  3792. }
  3793. else
  3794. {
  3795. Info("Set Quiet State OK");
  3796. }
  3797. //1. 先同步本地和探测器端校正文件
  3798. if (bAttachProcess && nDetectorID == m_nAttachFPDID)
  3799. {
  3800. DownloadReferences();
  3801. DownloadReferences(true); //下载长曝光模式校正文件
  3802. DownloadDefectMap();
  3803. }
  3804. //2. 再加载本地校正文件
  3805. int nMode = g_nRADmode;
  3806. if (SYNC_AED == m_stDeviceIndex[m_nCurrentPanelID].nSyncMode)
  3807. {
  3808. nMode = g_nAEDmode;
  3809. }
  3810. bool bResult = LoadReference(nMode, nDetectorID);
  3811. if (!bResult) //同步校正文件后,再次加载校正文件
  3812. {
  3813. Error("Load All Reference File Failed");
  3814. }
  3815. else
  3816. {
  3817. Info("Load All Reference File OK");
  3818. }
  3819. //3. 重设状态
  3820. if (!SetSystemState(STATE_QUIET))
  3821. {
  3822. Error("Set Quiet State Failed");
  3823. }
  3824. else
  3825. {
  3826. Info("Set Quiet State OK");
  3827. }
  3828. return bResult;
  3829. }
  3830. return false;
  3831. }
  3832. /***
  3833. ** 说明:探测器自检
  3834. ***/
  3835. bool TrixellCtrl::SelfTestFPD(int nDetectorID)
  3836. {
  3837. if (-1 == nDetectorID)
  3838. {
  3839. nDetectorID = m_nCurrentPanelID;
  3840. }
  3841. if (m_pStPanelStatus[nDetectorID]->bConnectStatus)
  3842. {
  3843. LockPixrad("PerformDetectorSelfTest"); //确保上一步执行完毕
  3844. Info("Calling PerformDetectorSelfTest");
  3845. error_status eErrorStatus = TED_PixRad_PerformDetectorSelfTest(); // EVT_END_SELF_TEST
  3846. if (!TestError(eErrorStatus))
  3847. {
  3848. Error("Perform Detector SelfTest Error");
  3849. //UnlockPixrad("PerformDetectorSelfTest");
  3850. return false;
  3851. }
  3852. Info("Perform Detector SelfTest OK");
  3853. LockPixrad("PerformDetectorSelfTest");
  3854. UnlockPixrad("PerformDetectorSelfTest");
  3855. StatusFeedback(EVT_STATUS_SELFTEST, nDetectorID, m_SelfTest.encode());
  3856. }
  3857. return true;
  3858. }
  3859. /***
  3860. ** 说明:获取校正时间
  3861. ** 连接成功后,校正完成后 获取
  3862. ***/
  3863. bool TrixellCtrl::GetCalibrationTime(int nDetectorID)
  3864. {
  3865. if (nDetectorID == -1)
  3866. {
  3867. nDetectorID = m_nCurrentPanelID;
  3868. }
  3869. SystemCalibrationTimeStatus stSystemCalibrationTimeStatus;
  3870. error_status eErrorStatus = TED_PixRad_GetSystemCalibrationTimeStatus(stSystemCalibrationTimeStatus);
  3871. if (TestError(eErrorStatus))
  3872. {
  3873. Info("CalibrationTimeStatus Detector Number:{$}", stSystemCalibrationTimeStatus.nbDetectors);
  3874. for (int i = 0; i < stSystemCalibrationTimeStatus.nbDetectors; ++i)
  3875. {
  3876. if (i != nDetectorID)
  3877. {
  3878. continue;
  3879. }
  3880. int nMode = 0;
  3881. for (; nMode < stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].nbApplicationModes; ++nMode)
  3882. {
  3883. __platform_time_t nOffsetCalibrationTime = stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].applicationModeCalibrationTimeStatus[nMode].offsetCalibrationTime;
  3884. __platform_time_t nPixelsClusterDefectCalibrationTime = stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].applicationModeCalibrationTimeStatus[nMode].pixelsClusterDefectCalibrationTime;
  3885. __platform_time_t nGainCalibrationTime = stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].applicationModeCalibrationTimeStatus[nMode].gainCalibrationTime;
  3886. __platform_time_t nGefectMapCalibrationTime = stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].applicationModeCalibrationTimeStatus[nMode].defectMapCalibrationTime;
  3887. __platform_time_t* pnDefectTime = &nGefectMapCalibrationTime;
  3888. __platform_time_t nPreviewOffsetCalibrationTime = stSystemCalibrationTimeStatus.detectorCalibrationTimeStatus[i].applicationModeCalibrationTimeStatus[nMode].previewOffsetCalibrationTime;
  3889. __platform_time_t* pnPreviewOffsetTime = &nPreviewOffsetCalibrationTime;
  3890. char szCalibTime[MAX_STRING] = { 0 };
  3891. errno_t nResult = _ctime64_s(szCalibTime, pnDefectTime);
  3892. string strInitCalibTime = szCalibTime;
  3893. Info("{$}", strInitCalibTime.c_str());
  3894. string strYear = "";
  3895. string strMonth = "01";
  3896. string strDay = "";
  3897. string strTime = "0";
  3898. int nIndex = 0, nTemp = 0;
  3899. string str;
  3900. for (int i = 0; i < strInitCalibTime.length(); i++)
  3901. {
  3902. //Thu Jan 01 08:00:00 1970 //c++11里,1号显示为01
  3903. //Sat Jan 2 14:00:01 2021 //c++高版本,1号显示为 1
  3904. if (szCalibTime[i] != ' ')
  3905. {
  3906. str += szCalibTime[i];
  3907. if (i == strInitCalibTime.length() - 1)
  3908. {
  3909. strYear = strInitCalibTime.substr(strInitCalibTime.length() - 5, 4);
  3910. }
  3911. }
  3912. else
  3913. {
  3914. //printf("%s* \r\n", str.c_str());
  3915. if (str != "")
  3916. {
  3917. nTemp++;
  3918. if (nTemp == 2)
  3919. {
  3920. strMonth = str;
  3921. }
  3922. if (nTemp == 3)
  3923. {
  3924. strDay = str;
  3925. }
  3926. str.clear();
  3927. }
  3928. }
  3929. }
  3930. if (strMonth.find("Jan") != string::npos)
  3931. {
  3932. strMonth = "01";
  3933. }
  3934. else if (strMonth.find("Feb") != string::npos)
  3935. {
  3936. strMonth = "02";
  3937. }
  3938. else if (strMonth.find("Mar") != string::npos)
  3939. {
  3940. strMonth = "03";
  3941. }
  3942. else if (strMonth.find("Apr") != string::npos)
  3943. {
  3944. strMonth = "04";
  3945. }
  3946. else if (strMonth.find("May") != string::npos)
  3947. {
  3948. strMonth = "05";
  3949. }
  3950. else if (strMonth.find("Jun") != string::npos)
  3951. {
  3952. strMonth = "06";
  3953. }
  3954. else if (strMonth.find("Jul") != string::npos)
  3955. {
  3956. strMonth = "07";
  3957. }
  3958. else if (strMonth.find("Aug") != string::npos)
  3959. {
  3960. strMonth = "08";
  3961. }
  3962. else if (strMonth.find("Sep") != string::npos)
  3963. {
  3964. strMonth = "09";
  3965. }
  3966. else if (strMonth.find("Oct") != string::npos)
  3967. {
  3968. strMonth = "10";
  3969. }
  3970. else if (strMonth.find("Nov") != string::npos)
  3971. {
  3972. strMonth = "11";
  3973. }
  3974. else if (strMonth.find("Dec") != string::npos)
  3975. {
  3976. strMonth = "12";
  3977. }
  3978. strTime = strYear + strMonth + strDay;
  3979. Info("Calibration Time:{$}", strTime.c_str());
  3980. if (g_nRADmode - 1 == nMode)
  3981. {
  3982. InfoFeedback(EVT_INFO_CALIBRATIOIN_TIME,
  3983. nDetectorID, 0, 0, strTime.c_str());
  3984. }
  3985. else if (g_nRADLTEmode - 1 == nMode)
  3986. {
  3987. InfoFeedback(EVT_INFO_CALIBRATIOIN_TIMEL,
  3988. nDetectorID, 0, 0, strTime.c_str());
  3989. }
  3990. }
  3991. }
  3992. }
  3993. else
  3994. {
  3995. InfoFeedback(EVT_INFO_CALIBRATIOIN_TIME, nDetectorID, 0, 0, "0");
  3996. InfoFeedback(EVT_INFO_CALIBRATIOIN_TIMEL, nDetectorID, 0, 0, "0");
  3997. }
  3998. return true;
  3999. }
  4000. /***
  4001. ** 说明:调用API,激活探测器
  4002. ***/
  4003. bool TrixellCtrl::SetActiveDetector(unsigned short usDetectorID)
  4004. {
  4005. Info("Activing Panel ID: {$}", usDetectorID);
  4006. if (m_nPanelCount == 1)
  4007. {
  4008. Info("Set the only one Panel Active OK");
  4009. return true;
  4010. }
  4011. unsigned short nCurrentDetector = -1;
  4012. if (!GetActiveDetector(nCurrentDetector))
  4013. {
  4014. Error("Get Active Detector Failed");
  4015. return false;
  4016. }
  4017. if (nCurrentDetector == usDetectorID)
  4018. {
  4019. m_nCurrentPanelID = usDetectorID;
  4020. Info("The Detector is already actived");
  4021. return true;
  4022. }
  4023. LockPixrad("SetActiveDetector");
  4024. error_status ErrorStatus = TED_PixRad_SetActiveDetector(usDetectorID); // EVT_ACTIVE_DETECTOR
  4025. if (!TestError(ErrorStatus))
  4026. {
  4027. Error("Set Active Detector command Failed");
  4028. //UnlockPixrad("SetActiveDetector");
  4029. return false;
  4030. }
  4031. Info("Set Active Detector command OK");
  4032. LockPixrad("SetActiveDetector");
  4033. UnlockPixrad("SetActiveDetector");
  4034. m_nCurrentPanelID = usDetectorID;
  4035. return true;
  4036. }
  4037. /***
  4038. ** 说明:调用API,获取当前激活探测器的ID
  4039. ***/
  4040. bool TrixellCtrl::GetActiveDetector(unsigned short& usDetectorID)
  4041. {
  4042. error_status ErrorStatus = TED_PixRad_GetActiveDetector(usDetectorID);
  4043. if (!TestError(ErrorStatus))
  4044. {
  4045. Error("Get Active Detector command Failed");
  4046. return false;
  4047. }
  4048. else
  4049. {
  4050. Info("Get Active Detector command OK");
  4051. Info("Current Active Detector is {$}", usDetectorID);
  4052. return true;
  4053. }
  4054. }
  4055. /***
  4056. * 说明:发送模拟的shock信息
  4057. * modify20220119 与客户端统一json格式,便于客户端解析
  4058. ***/
  4059. void TrixellCtrl::SimulateShockSensor(int nDetectorID, bool bSend)
  4060. {
  4061. }
  4062. /***
  4063. ** 说明:解析字符串,读取应用模式和采集模式的对应关系
  4064. ** 应用模式,例如 101 201 501... 和rad、pf、cf、tomo等模式对应
  4065. ** 采集模式,1,2,3... 取自探测器配置文件
  4066. ***/
  4067. bool TrixellCtrl::GetModeMatchInfo()
  4068. {
  4069. string strModeMatch = "";
  4070. strModeMatch = (string)m_ModeConfig[FPDModeMatch];
  4071. strModeMatch = strModeMatch.substr(1, strModeMatch.length() - 2); //去掉前后括号
  4072. bool bFindComma = false;
  4073. int nPos = (int)strModeMatch.find(":");
  4074. if (nPos == string::npos)
  4075. {
  4076. return false;
  4077. }
  4078. while (nPos > 0)
  4079. {
  4080. int n = (int)strModeMatch.find(",");
  4081. if (n > 0) //说明还有下一组match关系
  4082. {
  4083. bFindComma = true;
  4084. }
  4085. //拿到ExamMode
  4086. string strExamMode = strModeMatch.substr(0, nPos); // \"101\"
  4087. n = (int)strExamMode.find("\"");
  4088. strExamMode = strExamMode.substr(n + 1); //去掉key前的引号
  4089. n = (int)strExamMode.find("\"");
  4090. strExamMode = strExamMode.substr(0, n);
  4091. //拿到LogicMode
  4092. string strLogicMode = "";
  4093. if (bFindComma)
  4094. {
  4095. n = (int)strModeMatch.find(",");
  4096. strLogicMode = strModeMatch.substr(nPos + 1, n - nPos - 1);
  4097. //去掉逗号前的match关系
  4098. strModeMatch = strModeMatch.substr(n + 1);
  4099. //例 \"501\":2,\"302\":2
  4100. }
  4101. else
  4102. {
  4103. strLogicMode = strModeMatch.substr(nPos + 1);
  4104. //去掉冒号前的match关系
  4105. strModeMatch = strModeMatch.substr(nPos + 1);
  4106. }
  4107. m_ModeMatch.add(strExamMode.c_str(), strLogicMode.c_str());
  4108. //printf("ExamMode: %s LogicMode: %s \n", strExamMode.c_str(), strLogicMode.c_str());
  4109. nPos = (int)strModeMatch.find(":");
  4110. bFindComma = false; //恢复初值
  4111. }
  4112. return true;
  4113. }
  4114. bool TrixellCtrl::IsPortablePanel(string strPanelType)
  4115. {
  4116. if ((strPanelType.find("3543EZ") != string::npos) ||
  4117. (strPanelType.find("3543DR") != string::npos) ||
  4118. (strPanelType.find("2430EZ") != string::npos))
  4119. {
  4120. return true;
  4121. }
  4122. return false;
  4123. }
  4124. bool TrixellCtrl::CopyFile2Folder(string strSrcPath, string strDstPath)
  4125. {
  4126. //MSDN: This string must be double-null terminated
  4127. strSrcPath += '\0';
  4128. strDstPath += '\0';
  4129. Info("Copy {$} to {$}", strSrcPath.c_str(), strDstPath.c_str());
  4130. SHFILEOPSTRUCT sfo;
  4131. sfo.hwnd = NULL;
  4132. sfo.wFunc = FO_COPY;//FO_MOVE;
  4133. sfo.pFrom = strSrcPath.c_str();
  4134. sfo.pTo = strDstPath.c_str();
  4135. sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO; //| FOF_NOCONFIRMMKDIR;
  4136. // FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件;
  4137. //FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。
  4138. int nRet = SHFileOperation(&sfo);
  4139. Info("Copy File to Folder over, {$}", nRet);
  4140. return true;
  4141. }
  4142. /***
  4143. ** 检查文件是否存在
  4144. ***/
  4145. bool TrixellCtrl::CheckFileExits(string strPath, string strFile)
  4146. {
  4147. vector<string> filelist;
  4148. if (!FindSubFiles(strPath, filelist))
  4149. {
  4150. Info("{$} is a null path", strPath.c_str());
  4151. return false;
  4152. }
  4153. for (DWORD dw = 0; dw < filelist.size(); dw++)
  4154. {
  4155. string strTemp = filelist[dw];
  4156. if (strTemp == strFile)
  4157. {
  4158. return true;
  4159. }
  4160. }
  4161. return false;
  4162. }
  4163. /***
  4164. ** 完成校正的处理
  4165. ** DPC生成校正报告后调用
  4166. ***/
  4167. void TrixellCtrl::OnEndCalibraion()
  4168. {
  4169. Info("OnEndCalibraion");
  4170. StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_START);
  4171. bool bResult = true;
  4172. //bool bResult = UploadReferences(); //no use for droc
  4173. //bResult = bResult && UploadDefectMap();
  4174. GetCalibrationTime();
  4175. if (!SetSystemState(STATE_QUIET))
  4176. {
  4177. Warn("Set Quiet State Failed");
  4178. }
  4179. else
  4180. {
  4181. Info("Set Quiet State OK");
  4182. }
  4183. if (bResult)
  4184. {
  4185. StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END);
  4186. //StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK); //改为收到SDK回调时处理
  4187. }
  4188. else
  4189. {
  4190. StatusFeedback(EVT_STATUS_SAVECALIB, PANEL_EVENT_END_ERROR);
  4191. //StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR); //改为收到SDK回调时处理
  4192. }
  4193. }
  4194. void TrixellCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  4195. {
  4196. if (-1 == nDetectorID)
  4197. {
  4198. nDetectorID = m_nCurrentPanelID;
  4199. }
  4200. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4201. }
  4202. void TrixellCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  4203. {
  4204. if (-1 == nDetectorID)
  4205. {
  4206. nDetectorID = m_nCurrentPanelID;
  4207. }
  4208. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4209. }
  4210. void TrixellCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  4211. {
  4212. if (-1 == nDetectorID)
  4213. {
  4214. nDetectorID = m_nCurrentPanelID;
  4215. }
  4216. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4217. }
  4218. void TrixellCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  4219. {
  4220. if (-1 == nDetectorID)
  4221. {
  4222. nDetectorID = m_nCurrentPanelID;
  4223. }
  4224. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4225. }
  4226. void TrixellCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  4227. {
  4228. if (-1 == nDetectorID)
  4229. {
  4230. nDetectorID = m_nCurrentPanelID;
  4231. }
  4232. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4233. }
  4234. void TrixellCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  4235. {
  4236. if (-1 == nDetectorID)
  4237. {
  4238. nDetectorID = m_nCurrentPanelID;
  4239. }
  4240. ((FPDDeviceTrixell*)(*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  4241. }
  4242. /***
  4243. ** 说明:红外功能设置
  4244. ** 参数:bModifyConfig,是否修改配置文件
  4245. ** bInvokeAPI,是否调用接口
  4246. ** 根据配置文件,设置COM口,使能红外监控扫描
  4247. ***/
  4248. bool TrixellCtrl::IRFuncSetting(bool bModifyConfig, bool bInvokeAPI)
  4249. {
  4250. int nModuleEnable = 0;
  4251. bool bSetDRIRPort = true; //设置DR类型探测器的红外com口配置
  4252. bool bSetEZIRPort = true; //设置EZ类型探测器的红外com口配置
  4253. string strPanelType = "";
  4254. int nPort = -1;
  4255. //通过循环,读取所有探测器配置的红外使能配置,有一个使能,则使能SDK红外扫描功能
  4256. try
  4257. {
  4258. bool bModuleEnable = false;
  4259. for (int i = 0; i < m_nPanelCount; i++)
  4260. {
  4261. int nTemp = (int)m_pStPanelStatus[i]->objPanelConfig["ModuleEnable"];
  4262. if (nTemp > 0)
  4263. {
  4264. bModuleEnable = true;
  4265. }
  4266. }
  4267. //修改com口配置
  4268. if (bModuleEnable && bModifyConfig)
  4269. {
  4270. Info("Detector enable module polling");
  4271. nPort = (int)m_pStPanelStatus[0]->objPanelConfig["connections"]["port"];
  4272. if (!SetIRPort("3543EZ", nPort)) //类型临时写死,等加入多板的时候再考虑完善方案
  4273. {
  4274. SetIRPort("3543EZ", nPort);
  4275. }
  4276. }
  4277. if (!bModuleEnable)
  4278. {
  4279. Info("Detector disable module polling");
  4280. }
  4281. //使能红外扫描
  4282. if (bModuleEnable && bInvokeAPI)
  4283. {
  4284. LockPixrad("ModulePolling");
  4285. Info("Calling ModulePolling(enable)");
  4286. error_status Err = TED_PixRad_ModulePolling(true); //同步函数 //EVT_MODULE_POLLING_CHANGED
  4287. if (!TestError(Err))
  4288. {
  4289. Error("Enable module polling command Failed");
  4290. //UnlockPixrad("ModulePolling");
  4291. }
  4292. else
  4293. {
  4294. Info("Enable module polling command OK");
  4295. LockPixrad("ModulePolling");
  4296. UnlockPixrad("ModulePolling");
  4297. }
  4298. }
  4299. }
  4300. catch (ResDataObjectExption& exp)
  4301. {
  4302. Error("Get configuration failed, {$}", exp.what());
  4303. return false;
  4304. }
  4305. return true;
  4306. }
  4307. DWORD __stdcall TrixellCtrl::onFPDScanThread(PVOID pvoid)
  4308. {
  4309. TrixellCtrl* pOpr = (TrixellCtrl*)pvoid;
  4310. Info("Enter Scan Thread");
  4311. bool bExit = false;
  4312. int nTimecout = 0; //查询探测器状态的计时器
  4313. DWORD dwTimeout = INFINITE;
  4314. while (!bExit)
  4315. {
  4316. DWORD dwRet = WaitForMultipleObjects(7, pOpr->m_hArrayEvent, FALSE, dwTimeout);
  4317. if (WAIT_TIMEOUT == dwRet)
  4318. {
  4319. nTimecout += 5;
  4320. if (nTimecout > pOpr->m_nStatusTimeout)
  4321. {
  4322. pOpr->RefreshHWStatus();
  4323. nTimecout = 0;
  4324. }
  4325. }
  4326. else if (WAIT_OBJECT_0 == dwRet) //m_hStopScanEvent
  4327. {
  4328. bExit = true;
  4329. }
  4330. else if (WAIT_OBJECT_0 + 1 == dwRet) //m_hProcessImgEvent
  4331. {
  4332. pOpr->OnProcessImg();
  4333. }
  4334. else if (WAIT_OBJECT_0 + 2 == dwRet) //m_hXWinOnEvent
  4335. {
  4336. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  4337. }
  4338. else if (WAIT_OBJECT_0 + 3 == dwRet) //m_hXWinOffEvent
  4339. {
  4340. pOpr->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  4341. }
  4342. else if (WAIT_OBJECT_0 + 4 == dwRet) //m_hEndCalibEvent
  4343. {
  4344. pOpr->OnEndCalibraion();
  4345. }
  4346. else if (WAIT_OBJECT_0 + 5 == dwRet) //m_hDarkEndEvent
  4347. {
  4348. pOpr->OnProcessDarkEnd();
  4349. }
  4350. else if (WAIT_OBJECT_0 + 6 == dwRet) //m_hClosePollingEvent
  4351. {
  4352. Info("Get m_hClosePollingEvent SetDetectorStatusPolling == false");
  4353. pOpr->SetDetectorStatusPolling(pOpr->m_nStopPollingIndex, false);
  4354. }
  4355. else
  4356. {
  4357. Error("Scan Thread Failed, {$}", dwRet);
  4358. }
  4359. }
  4360. Info("Exit Scan Thread");
  4361. SetEvent(pOpr->m_hToggleEvent);
  4362. return 0;
  4363. }
  4364. DWORD __stdcall TrixellCtrl::onCheckShockThread(PVOID pvoid)
  4365. {
  4366. TrixellCtrl* pOpr = (TrixellCtrl*)pvoid;
  4367. Info("Enter CheckShock Thread");
  4368. while (!pOpr->m_bExitShockCheck)
  4369. {
  4370. Info("Waiting check shock information");
  4371. DWORD nResult = WaitForSingleObject(pOpr->m_hCheckShockEvent, INFINITE);
  4372. if (WAIT_OBJECT_0 == nResult) //偶尔会出现EVT_HARDWARE太慢的情况
  4373. {
  4374. if (!pOpr->m_bExitShockCheck)
  4375. {
  4376. if ((DetStatus_Acquire != pOpr->m_eStatus) &&
  4377. (DetStatus_Offset != pOpr->m_eStatus) &&
  4378. (DetStatus_XrayCalibration != pOpr->m_eStatus))
  4379. {
  4380. pOpr->Thread_Lock();
  4381. int nDetectorID = pOpr->m_nShockFPDID;
  4382. pOpr->Thread_UnLock();
  4383. Info("Call GetDetectorInformation(ID: {$})", nDetectorID);
  4384. pOpr->GetDetectorInformation(nDetectorID, false);
  4385. }
  4386. else
  4387. {
  4388. Warn("Work status, Omit GetDetectorInformation"); //退出检查时会check
  4389. }
  4390. }
  4391. else
  4392. {
  4393. Info("Quit GetDetectorInformation");
  4394. break;
  4395. }
  4396. }
  4397. }
  4398. Info("Exit CheckShock Thread");
  4399. return 0;
  4400. }
  4401. /***
  4402. ** 说明:停止线程
  4403. ** 退出时调用
  4404. ***/
  4405. void TrixellCtrl::StopThread()
  4406. {
  4407. m_bExitShockCheck = true;
  4408. SetEvent(m_hCheckShockEvent); //关闭check线程
  4409. m_hCheckShockThread = NULL;
  4410. if (m_hFPDScanThread != NULL)
  4411. {
  4412. ResetEvent(m_hToggleEvent);
  4413. SetEvent(m_hStopScanEvent);
  4414. DWORD result = WaitForSingleObject(m_hToggleEvent, 5000);
  4415. if (result == WAIT_OBJECT_0)
  4416. {
  4417. Info("Leave Thread Over");
  4418. }
  4419. else if (result == WAIT_TIMEOUT)
  4420. {
  4421. Warn("Till time out");
  4422. }
  4423. m_hFPDScanThread = NULL;
  4424. }
  4425. SetEvent(m_hQuitAdaptEvent);
  4426. Info("Quit apdat thread");
  4427. /*if (m_hRespondEvent)
  4428. {
  4429. CloseHandle(m_hRespondEvent);
  4430. m_hRespondEvent = NULL;
  4431. }*/
  4432. /*if (m_hStopScanEvent)
  4433. {
  4434. CloseHandle(m_hStopScanEvent);
  4435. m_hStopScanEvent = NULL;
  4436. }*/
  4437. /*if (m_hProcessImgEvent)
  4438. {
  4439. CloseHandle(m_hProcessImgEvent);
  4440. m_hProcessImgEvent = NULL;
  4441. }*/
  4442. /*if (m_hXWinOnEvent)
  4443. {
  4444. CloseHandle(m_hXWinOnEvent);
  4445. m_hXWinOnEvent = NULL;
  4446. }
  4447. if (m_hXWinOffEvent)
  4448. {
  4449. CloseHandle(m_hXWinOffEvent);
  4450. m_hXWinOffEvent = NULL;
  4451. }
  4452. if (m_hEndCalibEvent)
  4453. {
  4454. CloseHandle(m_hEndCalibEvent);
  4455. m_hEndCalibEvent = NULL;
  4456. }
  4457. if (m_hDarkEndEvent)
  4458. {
  4459. CloseHandle(m_hDarkEndEvent);
  4460. m_hDarkEndEvent = NULL;
  4461. }
  4462. if (m_hCheckShockEvent)
  4463. {
  4464. CloseHandle(m_hCheckShockEvent);
  4465. m_hCheckShockEvent = NULL;
  4466. }
  4467. if (m_hToggleEvent)
  4468. {
  4469. CloseHandle(m_hToggleEvent);
  4470. m_hToggleEvent = NULL;
  4471. }
  4472. if (m_hQuitAdaptEvent)
  4473. {
  4474. CloseHandle(m_hQuitAdaptEvent);
  4475. m_hQuitAdaptEvent = NULL;
  4476. }*/
  4477. }
  4478. /***
  4479. ** 说明:升级固件接口
  4480. ***/
  4481. void TrixellCtrl::UpdateFirmware(int nDetectorID)
  4482. {
  4483. Info("Update firmware manually");
  4484. m_bUpdateFirmwareDirect = true;
  4485. m_nUpdateFPDID = nDetectorID;
  4486. HANDLE hUpdateThread;
  4487. DWORD unThreadID;
  4488. hUpdateThread = CreateThread(NULL, 0, onUpdateFWThread, this, 0, &unThreadID);
  4489. if (hUpdateThread == NULL)
  4490. {
  4491. Error("Start Update Firmware Thread Error");
  4492. }
  4493. }
  4494. /***
  4495. ** 说明:升级固件线程
  4496. ***/
  4497. DWORD __stdcall TrixellCtrl::onUpdateFWThread(PVOID pvoid)
  4498. {
  4499. TrixellCtrl* pOpr = (TrixellCtrl*)pvoid;
  4500. Info("Firmware update thread");
  4501. return pOpr->onUpdateFirmware();
  4502. }
  4503. /***
  4504. ** 说明:升级固件执行函数
  4505. ***/
  4506. bool TrixellCtrl::onUpdateFirmware()
  4507. {
  4508. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_START, "", m_nUpdateFPDID);
  4509. if (!m_pStPanelStatus[m_nUpdateFPDID]->bConnectStatus
  4510. || m_pStPanelStatus[m_nUpdateFPDID]->nBattery < 50)
  4511. {
  4512. Error("Detector isn't connect or Battery value<50");
  4513. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID);
  4514. return false;
  4515. }
  4516. string strFWVersion = "";
  4517. if (!GetFWVersion(m_pStPanelStatus[m_nUpdateFPDID]->strPartNumber,
  4518. strFWVersion, m_nUpdateFPDID))
  4519. {
  4520. Error("Cannot Get new FW Version");
  4521. if (m_bUpdateFirmwareDirect)
  4522. {
  4523. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID);
  4524. }
  4525. m_bUpdateFirmwareDirect = false;
  4526. return false;
  4527. }
  4528. CloseDetector();
  4529. ModifyFirmwareLogPath(m_nUpdateFPDID);
  4530. Sleep(1000); //参照RAD3,休眠1s
  4531. //printf("Executing EXE... \n");
  4532. int nProcID = CallAdapter(strFWVersion, m_pStPanelStatus[m_nUpdateFPDID]->strModuleIP, m_nUpdateFPDID);
  4533. if (nProcID > 0)
  4534. {
  4535. bool bExitMonitorAdapt = true;
  4536. while (bExitMonitorAdapt)
  4537. {
  4538. DWORD dwResult = WaitForSingleObject(m_hQuitAdaptEvent, 5000);
  4539. if (dwResult == WAIT_OBJECT_0)
  4540. {
  4541. Info("Leave Thread Over");
  4542. if (m_bUpdateFirmwareDirect)
  4543. {
  4544. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID);
  4545. }
  4546. m_bUpdateFirmwareDirect = false;
  4547. return true;
  4548. }
  4549. else if (dwResult == WAIT_TIMEOUT) //failed to change state to quiet
  4550. {
  4551. Warn("Checking Adept.exe status");
  4552. nProcID = GetProcessidFromName("ADEPT.exe");
  4553. if (nProcID > 0)
  4554. {
  4555. Info("Find Adept.exe");
  4556. //printf("Updating... \n");
  4557. }
  4558. else //升级结束
  4559. {
  4560. Info("Adept.exe is not exist");
  4561. //printf("Over \n");
  4562. bExitMonitorAdapt = false; //退出循环
  4563. }
  4564. }
  4565. }
  4566. int nPingTotalTime = 15;//ping不通,一次约6s,共15次,2分钟左右超时
  4567. int nPingTimes = 0;
  4568. Info("onUpdateFirmware strModuleIP:{$}", m_pStPanelStatus[m_nUpdateFPDID]->strModuleIP);
  4569. for (; nPingTimes < nPingTotalTime; nPingTimes++)
  4570. {
  4571. bool bConnect = IsConnected(m_pStPanelStatus[m_nUpdateFPDID]->strModuleIP); //有ping权限么?
  4572. if (bConnect)
  4573. {
  4574. Info("Ping Detector successfully");
  4575. //printf("Ping Detector successfully\n");
  4576. break;
  4577. }
  4578. Sleep(2000);
  4579. }
  4580. //ping不通的话,加个输出
  4581. if (nPingTotalTime == nPingTimes)
  4582. {
  4583. Warn("Ping Detector IP Failed");
  4584. //printf("Ping Detector IP Failed\n");
  4585. }
  4586. }
  4587. else
  4588. {
  4589. Warn("Executing ADEPT.exe Failed");
  4590. //printf("Executing EXE Failed\n");
  4591. }
  4592. m_pStPanelStatus[m_nUpdateFPDID]->bNeedUpdateFW = false; //不知道它的作用
  4593. m_bModuleConnecting = true;
  4594. int nResult = InitDetector(!m_bUpdateFirmwareDirect, m_nUpdateFPDID);
  4595. if (nResult != INIT_FIRMWARE)
  4596. {
  4597. if (m_pStPanelStatus[m_nUpdateFPDID]->bConnectStatus) //升级成功
  4598. {
  4599. if (m_bUpdateFirmwareDirect)
  4600. {
  4601. Info("Update firmware success");
  4602. m_bModuleConnecting = false;
  4603. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_SUCCESS, "", m_nUpdateFPDID);
  4604. }
  4605. else
  4606. {
  4607. Info("Attach success");
  4608. UpdatePanelSerialFile(m_strModuleType, m_strModuleSN,
  4609. m_pStPanelStatus[m_nUpdateFPDID]->strModuleIP, "", true);
  4610. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_OK, "", m_nUpdateFPDID);
  4611. //StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "", m_nUpdateFPDID); //init反馈改为连接探测器使用
  4612. m_bModuleConnecting = false;
  4613. }
  4614. m_bUpdateFirmwareDirect = false;
  4615. return true;
  4616. }
  4617. }
  4618. else //INIT_FIRMWARE
  4619. {
  4620. // 只可能是固件升级失败;
  4621. }
  4622. m_bModuleConnecting = false;
  4623. if (m_bUpdateFirmwareDirect)
  4624. {
  4625. Info("Update firmware failed");
  4626. m_bModuleConnecting = false;
  4627. StatusFeedback(EVT_STATUS_UPDATE_FIRMWARE, PANEL_EVENT_END_ERROR, "", m_nUpdateFPDID);
  4628. }
  4629. else
  4630. {
  4631. Info("Attach failed");
  4632. DisconnectDetector(m_nUpdateFPDID);
  4633. StatusFeedback(EVT_STATUS_DETECTORSHARE, PANEL_CONNECT_ERROR, "", m_nUpdateFPDID);
  4634. }
  4635. m_bUpdateFirmwareDirect = false;
  4636. return true;
  4637. }
  4638. /***
  4639. ** 说明:读取配置文件,获取固件版本
  4640. ***/
  4641. bool TrixellCtrl::GetFWVersion(string strPNCode, string& strFirmwareVersion, int nDetectorID)
  4642. {
  4643. return true;
  4644. }
  4645. /***
  4646. ** 说明:修改固件升级的log路径
  4647. ***/
  4648. bool TrixellCtrl::ModifyFirmwareLogPath(int nDetectorID)
  4649. {
  4650. return true;
  4651. }
  4652. /***
  4653. ** 说明:编辑命令行参数,获取执行exe后的进程号
  4654. ***/
  4655. int TrixellCtrl::CallAdapter(string strFirmwareVersion, string strIPAddress, int nDetectorID)
  4656. {
  4657. return 0;
  4658. }
  4659. /***
  4660. ** 说明:执行ADEPT.exe程序
  4661. ***/
  4662. UINT TrixellCtrl::ExecuteEXE(string strExeName, string strParameters, DWORD& hProcID)
  4663. {
  4664. UINT iReturnVal = 0;
  4665. hProcID = 0;
  4666. TCHAR ptszParam[MAX_PATH];
  4667. memset(ptszParam, 0, MAX_PATH);
  4668. sprintf(ptszParam, "%s %s", strExeName.c_str(), strParameters.c_str());
  4669. //sprintf(ptszParam, "%s", strExeName.c_str()); //test只启动exe,不执行操作
  4670. Debug("Execute {$}", ptszParam);
  4671. PROCESS_INFORMATION pinfo;
  4672. ZeroMemory(&pinfo, sizeof(pinfo));
  4673. STARTUPINFO si/* = {sizeof(si)}*/;
  4674. ZeroMemory(&si, sizeof(si));
  4675. si.cb = sizeof(si);
  4676. //si.lpTitle = "ADEPT.exe";
  4677. si.dwFlags = STARTF_USESHOWWINDOW;
  4678. si.wShowWindow = SW_HIDE;
  4679. if (!CreateProcess(NULL, // No module name (use command line)
  4680. ptszParam, // Command line
  4681. NULL, // Process handle not inheritable
  4682. NULL, // Thread handle not inheritable
  4683. FALSE, // Set handle inheritance to FALSE
  4684. NULL, //CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE, // No creation flags
  4685. NULL, // Use parent's environment block
  4686. NULL, //"C:\\Addon\\IC\\Detectortools\\SW_Update\\3543DR\\ADEPT", // lpCurrentDirectory
  4687. &si, // Pointer to STARTUPINFO structure
  4688. &pinfo) // Pointer to PROCESS_INFORMATION structure
  4689. )
  4690. {
  4691. //printf("CreateProcess failed (%d).\n", GetLastError());
  4692. iReturnVal = GetLastError();
  4693. }
  4694. else
  4695. {
  4696. hProcID = pinfo.dwProcessId;
  4697. }
  4698. CloseHandle(pinfo.hProcess);
  4699. CloseHandle(pinfo.hThread);
  4700. return iReturnVal;
  4701. }
  4702. DWORD TrixellCtrl::GetProcessidFromName(string strProcName)
  4703. {
  4704. PROCESSENTRY32 ProcEntry;
  4705. DWORD ProcID = 0;
  4706. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  4707. ProcEntry.dwSize = sizeof(PROCESSENTRY32);
  4708. if (!Process32First(hSnapshot, &ProcEntry))
  4709. {
  4710. return 0;
  4711. }
  4712. while (1)
  4713. {
  4714. ProcEntry.dwSize = sizeof(PROCESSENTRY32W);
  4715. if (Process32Next(hSnapshot, &ProcEntry) == FALSE)
  4716. {
  4717. break;
  4718. }
  4719. if (strcmp(ProcEntry.szExeFile, strProcName.c_str()) == 0)
  4720. {
  4721. ProcID = ProcEntry.th32ProcessID;
  4722. break;
  4723. }
  4724. }
  4725. CloseHandle(hSnapshot);
  4726. return ProcID;
  4727. }
  4728. /***
  4729. ** 说明:检查探测器状态线程
  4730. ***/
  4731. DWORD __stdcall TrixellCtrl::onFPDStatusThread(PVOID pvoid)
  4732. {
  4733. TrixellCtrl* pOpr = (TrixellCtrl*)pvoid;
  4734. Info("Enter FPD status thread");
  4735. bool bExit = false;
  4736. while (!bExit)
  4737. {
  4738. DWORD dwRet = WaitForSingleObject(pOpr->m_hQuitStatusEvent, 5000);
  4739. if (WAIT_TIMEOUT == dwRet)
  4740. {
  4741. pOpr->onCheckFPDStatus();
  4742. }
  4743. else if (WAIT_OBJECT_0 == dwRet)
  4744. {
  4745. bExit = true;
  4746. }
  4747. }
  4748. SetEvent(pOpr->m_hToggleEvent);
  4749. Info("Exit check FPD status thread");
  4750. return 0;
  4751. }
  4752. /***
  4753. ** 说明:检查探测器状态
  4754. ** 温度、电量、wifi、连接状态
  4755. ***/
  4756. bool TrixellCtrl::onCheckFPDStatus()
  4757. {
  4758. //*//一个平板的时候,重连的限制条件会少一些
  4759. if (m_nPanelCount == 1)
  4760. {
  4761. if (GetConnectConf(0) && !m_pStPanelStatus[0]->bInitOK //attach过了但没初始化成功
  4762. && m_bOpened //不是加载dll,初始化SDK等的错误导致的连接失败
  4763. && !m_bModuleConnecting //attach连接时,上述条件都会是true
  4764. && !m_bAttaching
  4765. )
  4766. {
  4767. string strIP = (string)m_pStPanelStatus[0]->objPanelConfig["connections"]["WiredIP"];
  4768. Info("onCheckFPDStatus strIP:{$} m_nPanelCount == 1", strIP);
  4769. bool bConnect = IsConnected(strIP);
  4770. if (!bConnect)
  4771. {
  4772. Trace("Ping Detector failed");
  4773. return false;
  4774. }
  4775. //提前发送重连开始的消息,减少用户进行其它操作的可能性
  4776. m_bReInitialize = true;
  4777. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, "", 0);
  4778. Info("Calling Connect(ID: 0)");
  4779. error_status ErrorStatus = TED_PixRad_Connect(0, "");
  4780. TestError(ErrorStatus);
  4781. if (!WaitRespond(g_nConnectTimeout, "Connect")) //设置一个10秒的连接超时
  4782. {
  4783. Error("Connect detector timeout");
  4784. }
  4785. if (m_pStPanelStatus[0]->bConnectStatus)
  4786. {
  4787. Info("Connect Detector success");
  4788. }
  4789. else
  4790. {
  4791. m_bReInitialize = false;
  4792. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "", 0);
  4793. Warn("Connect Detector failed");
  4794. return false;
  4795. }
  4796. GetConfigParameters(0);
  4797. Info("onCheckFPDStatus SetDetectorStatusPolling == true 111");
  4798. SetDetectorStatusPolling(0, true); //重连成功,置为true
  4799. //以下流程部分为不区分探测器的接口,此处先切换探测器
  4800. if (!SetActiveDetector(0))
  4801. {
  4802. m_bReInitialize = false;
  4803. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "", 0);
  4804. return false;
  4805. }
  4806. GetDetectorInformation(0, true);
  4807. FactoryCorrectionActive(false, 0);
  4808. if (!m_pStPanelStatus[0]->bSelftested)
  4809. {
  4810. SelfTestFPD(0);
  4811. }
  4812. GetCalibrationTime(0);
  4813. if (m_pStPanelStatus[0]->bConnectStatus)
  4814. {
  4815. if (!m_pStPanelStatus[0]->bDarkCalibDone)
  4816. {
  4817. m_nRefreshOftMode = g_nRADmode;
  4818. RefreshOffset(true, PIX_OM_RAD, g_nRADmode);
  4819. }
  4820. if (!m_pStPanelStatus[0]->bLTEDarkCalibDone)
  4821. {
  4822. m_nRefreshOftMode = g_nRADLTEmode;
  4823. RefreshOffset(true, PIX_OM_RAD, g_nRADLTEmode);
  4824. }
  4825. }
  4826. m_bReInitialize = false;
  4827. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "", 0);
  4828. ErrorFeedback(EVT_ERR_COMMUNICATE, "false", 0);
  4829. }
  4830. return true;
  4831. }
  4832. //*/
  4833. //modify20211220 双板时去掉当前平板的工作界面限制
  4834. bool bNotInWork = m_eAppStatus != APP_STATUS_WORK_BEGIN && m_eAppStatus != APP_STATUS_CAL_BEGIN && //检查、校正界面不执行
  4835. DetStatus_Acquire != m_eStatus && DetStatus_Offset != m_eStatus && DetStatus_XrayCalibration != m_eStatus; //检查、校正状态不执行
  4836. //和DPC模块确认的新逻辑,不依靠connect做先启动软件后启动硬件的重连
  4837. for (int nID = 0; nID < m_nPanelCount; nID++)
  4838. {
  4839. if ((bNotInWork || (!bNotInWork && nID == m_nCurrentPanelID)) //不在工作界面 或 在工作界面的当前探测器
  4840. && GetConnectConf(nID) && !m_pStPanelStatus[nID]->bInitOK //attach过了但没初始化成功
  4841. && m_bOpened //不是加载dll,初始化SDK等的错误导致的连接失败
  4842. && !m_bModuleConnecting
  4843. && !m_bAttaching)
  4844. {
  4845. string strIP = (string)m_pStPanelStatus[nID]->objPanelConfig["connections"]["WiredIP"];
  4846. Info("onCheckFPDStatus strIP:{$} 222", strIP);
  4847. bool bConnect = IsConnected(strIP);
  4848. if (!bConnect)
  4849. {
  4850. Trace("Ping Detector failed");
  4851. continue; //一块连接失败,继续连接其它的,不要互相影响
  4852. }
  4853. //提前发送重连开始的消息,减少用户进行其它操作的可能性
  4854. m_bReInitialize = true;
  4855. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, "", nID);
  4856. Info("Calling Connect(ID: {$})", nID);
  4857. error_status ErrorStatus = TED_PixRad_Connect(nID, "");
  4858. TestError(ErrorStatus);
  4859. if (!WaitRespond(g_nConnectTimeout, "Connect")) //设置一个10秒的连接超时
  4860. {
  4861. Error("Connect detector timeout");
  4862. continue;
  4863. }
  4864. if (m_pStPanelStatus[nID]->bConnectStatus)
  4865. {
  4866. Info("Connect Detector success");
  4867. }
  4868. else
  4869. {
  4870. m_bReInitialize = false;
  4871. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "", nID);
  4872. Warn("Connect Detector failed");
  4873. continue; //一块连接失败,继续连接其它的,不要互相影响
  4874. }
  4875. GetConfigParameters(nID);
  4876. Info("onCheckFPDStatus SetDetectorStatusPolling == true 222");
  4877. SetDetectorStatusPolling(nID, true); //重连成功,置为true
  4878. //以下流程部分为不区分探测器的接口,此处先切换探测器
  4879. if (!SetActiveDetector(nID))
  4880. {
  4881. m_bReInitialize = false;
  4882. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "", nID);
  4883. continue;
  4884. }
  4885. GetDetectorInformation(nID, true);
  4886. FactoryCorrectionActive(false, nID);
  4887. if (!m_pStPanelStatus[nID]->bSelftested)
  4888. {
  4889. SelfTestFPD(nID);
  4890. }
  4891. GetCalibrationTime(nID);
  4892. if (m_pStPanelStatus[nID]->bConnectStatus)
  4893. {
  4894. if (!m_pStPanelStatus[nID]->bDarkCalibDone)
  4895. {
  4896. m_nRefreshOftMode = g_nRADmode;
  4897. RefreshOffset(true, PIX_OM_RAD, g_nRADmode);
  4898. }
  4899. if (!m_pStPanelStatus[nID]->bLTEDarkCalibDone)
  4900. {
  4901. m_nRefreshOftMode = g_nRADLTEmode;
  4902. RefreshOffset(true, PIX_OM_RAD, g_nRADLTEmode);
  4903. }
  4904. }
  4905. m_bReInitialize = false;
  4906. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "", nID);
  4907. ErrorFeedback(EVT_ERR_COMMUNICATE, "false", nID);
  4908. }
  4909. }
  4910. return true;
  4911. }
  4912. bool TrixellCtrl::InDetectorShare()
  4913. {
  4914. if (APP_STATUS_DETSHARE_BEGIN == m_eAppStatus)
  4915. {
  4916. return true;
  4917. }
  4918. else
  4919. {
  4920. Error("Not In Detector Share Window");
  4921. return false;
  4922. }
  4923. }
  4924. /***
  4925. ** 说明:设置连接配置
  4926. ** 修改subDPC中的Reconnect配置项,该配置项为true时调用API,连接探测器
  4927. ***/
  4928. bool TrixellCtrl::SetConnectConf(bool bConnect, int nDetectorID)
  4929. {
  4930. return true;
  4931. }
  4932. /***
  4933. ** 说明:获取连接配置
  4934. ** 获取subDPC中的Reconnect配置项,该配置项为true时调用API,连接探测器
  4935. ** 返回值:true,表示连接;false,表示不连接
  4936. ***/
  4937. bool TrixellCtrl::GetConnectConf(int nDetectorID)
  4938. {
  4939. bool bConnect = false;
  4940. try
  4941. {
  4942. int nTemp = m_ModeConfig[CcosDetectorAttachedFlag];
  4943. if (nTemp > 0)
  4944. {
  4945. bConnect = true;
  4946. }
  4947. }
  4948. catch (ResDataObjectExption& exp)
  4949. {
  4950. Error("Get configuration failed, {$}", exp.what());
  4951. }
  4952. return bConnect;
  4953. }
  4954. string TrixellCtrl::GetPanelResource(string strKey)
  4955. {
  4956. string strPanelResPath;
  4957. strPanelResPath = m_strWorkPath + "\\OEMDrivers\\Detector\\Trixell\\TrixellDRDetector\\CCOSLogInfor.xml";
  4958. Info("{$}", strPanelResPath.c_str());
  4959. string strMsgText = "";
  4960. GetValueByKeyA(strPanelResPath.c_str(), strKey.c_str(), strMsgText);
  4961. return strMsgText;
  4962. }
  4963. /***
  4964. ** 说明:更新PanelSerial.xml列表
  4965. ***/
  4966. bool TrixellCtrl::UpdatePanelSerialFile(string strPanelType, string strSN, string strSetIP, string strDate, bool bActive)
  4967. {
  4968. PanelSerialList stPanelInfo;
  4969. string strCalibDate = "0";
  4970. string strIP = "";
  4971. int nID = 0;
  4972. bool bResult = GetPanelSNList(strSN, stPanelInfo);
  4973. if (!bResult)
  4974. {
  4975. if (!bActive)
  4976. {
  4977. Info("Omit Update SN List");
  4978. return true;
  4979. }
  4980. //如果没有找到SN,赋新值,加入列表
  4981. stPanelInfo.strPanelType = "3543";
  4982. stPanelInfo.strPanelSize = "L";
  4983. if (strPanelType.find("3543") == string::npos)
  4984. {
  4985. stPanelInfo.strPanelType = "2430";
  4986. stPanelInfo.strPanelSize = "S";
  4987. }
  4988. stPanelInfo.strPanelSN = strSN;
  4989. stPanelInfo.strIPAddress = strSetIP;
  4990. }
  4991. else //更新校正日期
  4992. {
  4993. //
  4994. }
  4995. if (strDate != "")
  4996. {
  4997. stPanelInfo.strCalibDate = strDate;
  4998. }
  4999. else
  5000. {
  5001. stPanelInfo.strCalibDate = "null"; //填空字符串会导致日志记录乱码+无用内容,所以改为null
  5002. }
  5003. //else 保留读取的值
  5004. if (bActive)
  5005. {
  5006. stPanelInfo.strActive = "true";
  5007. }
  5008. else
  5009. {
  5010. stPanelInfo.strActive = "false";
  5011. }
  5012. Debug("{$}", stPanelInfo.strPanelType.c_str());
  5013. Debug("{$}", stPanelInfo.strPanelSN.c_str());
  5014. Info("{$}", stPanelInfo.strActive.c_str());
  5015. Debug("{$}", stPanelInfo.strIPAddress.c_str());
  5016. Debug("{$}", stPanelInfo.strCalibDate.c_str());
  5017. Debug("{$}", stPanelInfo.strPanelSize.c_str());
  5018. bResult = m_objSNlist.AddNewPanelSerial(stPanelInfo);
  5019. if (bResult)
  5020. {
  5021. Info("Update PanelSerial.xml Success");
  5022. return true;
  5023. }
  5024. else
  5025. {
  5026. Info("Update PanelSerial.xml Failed");
  5027. return false;
  5028. }
  5029. }
  5030. /***
  5031. ** 说明:更新PanelSerial.xml列表
  5032. ***/
  5033. bool TrixellCtrl::GetPanelSNList(string strPanelSerial, PanelSerialList& stpanelInfo)
  5034. {
  5035. list<PanelSerialList> obListPanel;
  5036. list<PanelSerialList>::iterator iter;
  5037. bool bResult = m_objSNlist.GetPanelSerialList(obListPanel);
  5038. if (!bResult)
  5039. {
  5040. Error("PanelSerial.xml is NULL");
  5041. return false;
  5042. }
  5043. Info("{$}", strPanelSerial.c_str());
  5044. for (iter = obListPanel.begin(); iter != obListPanel.end(); iter++)
  5045. {
  5046. if (strPanelSerial.find(iter->strPanelSN) != string::npos)
  5047. {
  5048. Info("{$}", iter->strPanelType.c_str());
  5049. Info("{$}", iter->strPanelSN.c_str());
  5050. Info("{$}", iter->strActive.c_str());
  5051. Info("{$}", iter->strIPAddress.c_str());
  5052. Info("{$}", iter->strCalibDate.c_str());
  5053. Info("{$}", iter->strPanelSize.c_str());
  5054. stpanelInfo = *iter;
  5055. Info("Find Detector SN Success");
  5056. return true;
  5057. }
  5058. else
  5059. {
  5060. Info("{$}", iter->strPanelSN.c_str());
  5061. }
  5062. }
  5063. return false;
  5064. }
  5065. /***
  5066. ** 定时查询每个探测器的状态
  5067. ** 如果使用polling功能,会影响SDK休眠
  5068. ***/
  5069. void TrixellCtrl::RefreshHWStatus()
  5070. {
  5071. if ((m_eAppStatus != APP_STATUS_WORK_BEGIN && m_eAppStatus != APP_STATUS_CAL_BEGIN) //检查、校正界面不执行
  5072. && (DetStatus_Acquire != m_eStatus) && (DetStatus_Offset != m_eStatus) && (DetStatus_XrayCalibration != m_eStatus))
  5073. {
  5074. //非检查、校正界面,定期获取全部平板的状态
  5075. for (int index = 0; index < m_nPanelCount; index++)
  5076. {
  5077. GetHardwareStatus(index);
  5078. }
  5079. }
  5080. else
  5081. {
  5082. for (int index = 0; index < m_nPanelCount; index++)
  5083. {
  5084. if (index != m_nCurrentPanelID) //检查界面只刷新非当前平板的状态
  5085. {
  5086. Info("RefreshHWStatus SetDetectorStatusPolling == true");
  5087. SetDetectorStatusPolling(index, true);
  5088. Sleep(50); //确保开启polling
  5089. }
  5090. }
  5091. }
  5092. }
  5093. void TrixellCtrl::ProcessEvent(const event_id eventID, const Event *eventData)
  5094. {
  5095. int nDetectorID = eventData->detector; //并一定是针对探测器的消息,所以此值不一定是0或者1,2
  5096. Info("{$}[CB {$}]", nDetectorID, (int)eventID);
  5097. switch (eventID)
  5098. {
  5099. case EVT_START_DARK_CALIBRATION:
  5100. ProcessEventError("EVT_START_DARK_CALIBRATION", eventData->error, nDetectorID);
  5101. break;
  5102. case EVT_END_DARK_CALIBRATION:
  5103. //先参照增益流程增加calibrationstatus的callback
  5104. if (!ProcessEventError("EVT_END_DARK_CALIBRATION", eventData->error, nDetectorID))
  5105. {
  5106. if (ERR_SEQUENCE_CANCELED == eventData->error)
  5107. {
  5108. Info("ERR_SEQUENCE_CANCELED"); // 校正取消
  5109. }
  5110. else if (ERR_RESUME_TIMEOUT == eventData->error)
  5111. {
  5112. Info("ERR_RESUME_TIMEOUT"); // 校正超时
  5113. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_TIMEOUT);
  5114. }
  5115. else if (ERR_CALIBRATION_ACQUISITION == eventData->error)
  5116. {
  5117. Info("ERR_CALIBRATION_ACQUISITION"); // 校正超时
  5118. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR);
  5119. }
  5120. }
  5121. else
  5122. {
  5123. if (g_nRADmode == m_nRefreshOftMode)
  5124. {
  5125. m_pStPanelStatus[nDetectorID]->bDarkCalibDone = true;
  5126. }
  5127. else if (g_nRADLTEmode == m_nRefreshOftMode)
  5128. {
  5129. m_pStPanelStatus[nDetectorID]->bLTEDarkCalibDone = true;
  5130. }
  5131. }
  5132. m_eStatus = DetStatus_Standby; //Dark校正结束,置为Standby
  5133. break;
  5134. case EVT_START_XRAY_CALIBRATION:
  5135. ProcessEventError("EVT_START_XRAY_CALIBRATION", eventData->error, nDetectorID);
  5136. m_bPrepShot = false; //校正开始,置回初值
  5137. break;
  5138. case EVT_END_XRAY_CALIBRATION:
  5139. if (!ProcessEventError("EVT_END_XRAY_CALIBRATION", eventData->error, nDetectorID))
  5140. {
  5141. if (ERR_SEQUENCE_CANCELED == eventData->error)
  5142. {
  5143. Info("ERR_SEQUENCE_CANCELED"); // 校正取消
  5144. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  5145. }
  5146. else if (ERR_RESUME_TIMEOUT == eventData->error)
  5147. {
  5148. Info("ERR_RESUME_TIMEOUT"); // 校正超时
  5149. string strLastError = GetPanelResource("CalibrationTimeOut");
  5150. Info("{$}", strLastError.c_str());
  5151. StatusFeedback(EVT_STATUS_SINGLEEXP, EVT_STATUS_LASTERROR, strLastError.c_str());
  5152. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_TIMEOUT);
  5153. }
  5154. else if (ERR_CALIBRATION_ACQUISITION == eventData->error)
  5155. {
  5156. Info("ERR_CALIBRATION_ACQUISITION"); // 校正超时
  5157. string strLastError = GetPanelResource("CalibrationAcqFailed");
  5158. Info("{$}", strLastError.c_str());
  5159. StatusFeedback(EVT_STATUS_SINGLEEXP, EVT_STATUS_LASTERROR, strLastError.c_str());
  5160. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_ERROR);
  5161. }
  5162. }
  5163. else
  5164. {
  5165. StatusFeedback(EVT_STATUS_CALIBRATIOIN, PANEL_EVENT_END_OK);
  5166. }
  5167. m_bPrepShot = false; //校正结束,置回初值
  5168. m_eStatus = DetStatus_Standby; //增益校正结束,置为Standby
  5169. break;
  5170. case EVT_START_GAIN_CALIBRATION: //! Sent when the gain only calibration begins
  5171. ProcessEventError("EVT_START_GAIN_CALIBRATION", eventData->error, nDetectorID);
  5172. break;
  5173. case EVT_END_GAIN_CALIBRATION:
  5174. ProcessEventError("EVT_END_GAIN_CALIBRATION", eventData->error, nDetectorID);
  5175. break;
  5176. case EVT_START_REFRESH_CALIBRATION: //! Sent when the refresh calibration begins
  5177. ProcessEventError("EVT_START_REFRESH_CALIBRATION", eventData->error, nDetectorID);
  5178. break;
  5179. case EVT_END_REFRESH_CALIBRATION:
  5180. ProcessEventError("EVT_END_REFRESH_CALIBRATION", eventData->error, nDetectorID);
  5181. break;
  5182. case EVT_START_LOAD_REFERENCES:
  5183. ProcessEventError("EVT_START_LOAD_REFERENCES", eventData->error, nDetectorID);
  5184. break;
  5185. case EVT_END_LOAD_REFERENCES:
  5186. if (!ProcessEventError("EVT_END_LOAD_REFERENCES", eventData->error, nDetectorID))
  5187. {
  5188. m_eCorrectionType = CT_OFFSET;
  5189. }
  5190. else
  5191. {
  5192. m_eCorrectionType = CT_ALL;
  5193. }
  5194. break;
  5195. case EVT_START_LOAD_GAIN_REFERENCE:
  5196. ProcessEventError("EVT_START_LOAD_GAIN_REFERENCE", eventData->error, nDetectorID);
  5197. break;
  5198. case EVT_END_LOAD_GAIN_REFERENCE:
  5199. ProcessEventError("EVT_END_LOAD_GAIN_REFERENCE", eventData->error, nDetectorID);
  5200. break;
  5201. case EVT_START_UNLOAD_REFERENCES:
  5202. ProcessEventError("EVT_START_UNLOAD_REFERENCES", eventData->error, nDetectorID);
  5203. break;
  5204. case EVT_END_UNLOAD_REFERENCES:
  5205. ProcessEventError("EVT_END_UNLOAD_REFERENCES", eventData->error, nDetectorID);
  5206. break;
  5207. case EVT_START_DARK_ACCEPTANCE_TEST: //! Sent when the dark acceptance test begins
  5208. ProcessEventError("EVT_START_DARK_ACCEPTANCE_TEST", eventData->error, nDetectorID);
  5209. break;
  5210. case EVT_END_DARK_ACCEPTANCE_TEST:
  5211. ProcessEventError("EVT_END_DARK_ACCEPTANCE_TEST", eventData->error, nDetectorID);
  5212. break;
  5213. case EVT_START_XRAY_ACCEPTANCE_TEST:
  5214. ProcessEventError("EVT_START_XRAY_ACCEPTANCE_TEST", eventData->error, nDetectorID);
  5215. break;
  5216. case EVT_END_XRAY_ACCEPTANCE_TEST:
  5217. ProcessEventError("EVT_END_XRAY_ACCEPTANCE_TEST", eventData->error, nDetectorID);
  5218. break;
  5219. case EVT_START_VOLTAGES: //! Sent when the current voltages request of detector begins
  5220. ProcessEventError("EVT_START_VOLTAGES", eventData->error, nDetectorID);
  5221. break;
  5222. case EVT_END_VOLTAGES:
  5223. if (ProcessEventError("EVT_END_VOLTAGES", eventData->error, nDetectorID))
  5224. {
  5225. HardwareVoltage* pData = static_cast<HardwareVoltage*>(eventData->data);
  5226. //ResDataObject jsParamList;
  5227. string strVoltageList = "[";
  5228. string strVoltageItem = "";
  5229. for (int i = 0; i < pData->nbPods; ++i)
  5230. {
  5231. for (int j = 0; j < pData->pod[i].nbChannel; ++j)
  5232. {
  5233. int nFlag = pData->pod[i].channel[j].flag;
  5234. string strName = pData->pod[i].channel[j].name;
  5235. float fValue = pData->pod[i].channel[j].value;
  5236. Info("Voltage channel:{$} Flag:{$},Name:{$},Value:{$}", j, nFlag, strName.c_str(), fValue);
  5237. std::ostringstream strVoltageKey;
  5238. strVoltageKey << "FDVoltage_Pod" << i << "_Channel" << strName;
  5239. std::ostringstream strVoltageValue;
  5240. strVoltageValue << fValue;
  5241. //jsParamList.add(strVoltageKey.str().c_str(), strVoltageValue.str().c_str());
  5242. strVoltageItem += strVoltageKey.str();
  5243. strVoltageItem += ":";
  5244. strVoltageItem += strVoltageValue.str();
  5245. strVoltageList = strVoltageList + strVoltageItem + "\r\n";
  5246. strVoltageItem = ""; //恢复初值
  5247. }
  5248. }
  5249. strVoltageList = strVoltageList.substr(0, strVoltageList.length() - 2);
  5250. strVoltageList += "]";
  5251. //Info( jsParamList.encode());
  5252. Debug("{$}", strVoltageList.c_str());
  5253. InfoFeedback(EVT_INFO_FPVOLTAGE, nDetectorID, 0, 0, strVoltageList.c_str()/*jsParamList.encode()*/);
  5254. }
  5255. UnlockPixrad("EVT_END_VOLTAGES");
  5256. break;
  5257. case EVT_START_LAST_ACQUISITION_DATA: //! Sent when the storage of last acquisition data begins
  5258. ProcessEventError("EVT_START_LAST_ACQUISITION_DATA", eventData->error, nDetectorID);
  5259. break;
  5260. case EVT_END_LAST_ACQUISITION_DATA:
  5261. ProcessEventError("EVT_END_LAST_ACQUISITION_DATA", eventData->error, nDetectorID);
  5262. break;
  5263. case EVT_START_RESET_DETECTOR:
  5264. ProcessEventError("EVT_START_RESET_DETECTOR", eventData->error, nDetectorID);
  5265. break;
  5266. case EVT_END_RESET_DETECTOR:
  5267. ProcessEventError("EVT_END_RESET_DETECTOR", eventData->error, nDetectorID);
  5268. break;
  5269. case EVT_START_SELF_TEST: //! Sent when the self test of detector begins
  5270. ProcessEventError("EVT_START_SELF_TEST", eventData->error, nDetectorID);
  5271. break;
  5272. case EVT_END_SELF_TEST:
  5273. if (ProcessEventError("EVT_END_SELF_TEST", eventData->error, nDetectorID))
  5274. {
  5275. SelfTestResult* pSelfTest = static_cast<SelfTestResult*>(eventData->data);
  5276. ResDataObject jsParamList;
  5277. for (int i = 0; i < pSelfTest->nbTests; ++i)
  5278. {
  5279. SelfTestResult::TestResult result = pSelfTest->testResult[i];
  5280. Info("test[{$}] - {$} - : {$}", result.id, result.name, result.value ? "passed" : "failed");
  5281. string strResultName = result.name;
  5282. for (size_t i = 0; i < strResultName.length() - 1; i++)
  5283. {
  5284. if (strResultName[i] == ' ')
  5285. {
  5286. strResultName[i] = '_';
  5287. }
  5288. }
  5289. if (strResultName[strResultName.length() - 1] == ' ')
  5290. {
  5291. strResultName = strResultName.substr(0, strResultName.length() - 1);
  5292. }
  5293. jsParamList.add(strResultName.c_str(), result.value ? "pass" : "failed");
  5294. }
  5295. //DPC处理Selftest有耗时,改到接口调用处反馈selftest
  5296. //StatusFeedback(EVT_STATUS_SELFTEST, nDetectorID, jsParamList.encode());
  5297. m_SelfTest.clear();
  5298. m_SelfTest = jsParamList;
  5299. m_pStPanelStatus[nDetectorID]->bSelftested = true;
  5300. }
  5301. UnlockPixrad("EVT_END_SELF_TEST");
  5302. break;
  5303. case EVT_START_LAST_IMAGE_RECOVERY:
  5304. ProcessEventError("EVT_START_LAST_IMAGE_RECOVERY", eventData->error, nDetectorID);
  5305. m_bIsImageRecovering = false;
  5306. break;
  5307. case EVT_END_LAST_IMAGE_RECOVERY:
  5308. if (ProcessEventError("EVT_END_LAST_IMAGE_RECOVERY", eventData->error, nDetectorID))
  5309. {
  5310. ErrorFeedback(EVT_ERR_GET_IMAGE, "false"); //图像recover成功
  5311. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  5312. }
  5313. else
  5314. {
  5315. if (!m_bTransImageSuccess)
  5316. {
  5317. ErrorFeedback(EVT_ERR_GET_IMAGE, "true"); //图像recover失败
  5318. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  5319. }
  5320. }
  5321. UnlockPixrad("EVT_END_LAST_IMAGE_RECOVERY");
  5322. break;
  5323. case EVT_WIFI_PARAMETERS_CHANGED:
  5324. ProcessEventError("EVT_WIFI_PARAMETERS_CHANGED", eventData->error, nDetectorID);
  5325. break;
  5326. case EVT_IMAGE_PATTERN_CHANGED: //! Sent when the change of pattern of the detector finishes
  5327. ProcessEventError("EVT_IMAGE_PATTERN_CHANGED", eventData->error, nDetectorID);
  5328. break;
  5329. case EVT_HARDWARE_STATUS: //! Sent when hardware status has been performed
  5330. if (ProcessEventError("EVT_HARDWARE_STATUS", eventData->error, nDetectorID))
  5331. {
  5332. //如果断线了,获取一次configparameters
  5333. m_pStPanelStatus[nDetectorID]->bConnectStatus = true; //收到hw回调
  5334. HardwareStatus* pData = reinterpret_cast<HardwareStatus*>(eventData->data);
  5335. if (NULL == pData)
  5336. {
  5337. return;
  5338. }
  5339. /***
  5340. ** GetHardwareStatus时是获取某一块平板的状态,此时callback只有一个平板的信息,
  5341. ** 所以以下向上层反馈信息时,ID不能用for循环下标,得用回调中的DetectorID
  5342. ***/
  5343. float fTemperature;
  5344. for (int i = 0; i < pData->nbDetectors; i++)
  5345. {
  5346. fTemperature = pData->detectorStatus[i].temperature;
  5347. Info("detector {$} temperature: {$}", nDetectorID, fTemperature);
  5348. StatusFeedback(EVT_STATUS_TEMPERATURE, 0, "", nDetectorID, fTemperature);
  5349. #pragma region DetectorState
  5350. int nDetectorState = pData->detectorStatus[i].state;
  5351. switch (nDetectorState)
  5352. {
  5353. case DS_OPERATION:
  5354. Info("Detector state: DS_OPERATION");
  5355. break;
  5356. case DS_SERVICE:
  5357. Info("Detector state: DS_SERVICE");
  5358. break;
  5359. case DS_DOWNLOAD:
  5360. Info("Detector state: DS_DOWNLOAD");
  5361. break;
  5362. case DS_STANDBY:
  5363. Info("Detector state: DS_STANDBY");
  5364. break;
  5365. case DS_BOOT:
  5366. Info("Detector state: DS_BOOT");
  5367. break;
  5368. case DS_SLEEP:
  5369. Info("Detector state: DS_SLEEP");
  5370. break;
  5371. case DS_ERROR:
  5372. Info("Detector state: DS_ERROR");
  5373. break;
  5374. case DS_AUTOTRIGGER:
  5375. Info("Detector state: DS_AUTOTRIGGER");
  5376. break;
  5377. case DS_IMAGE_PENDING:
  5378. Info("Detector state: DS_IMAGE_PENDING");
  5379. break;
  5380. case DS_LICENSE_LOCKED:
  5381. Info("Detector state: DS_LICENSE_LOCKED");
  5382. break;
  5383. case DS_NOTDEFINED:
  5384. Info("Detector state: DS_NOTDEFINED");
  5385. break;
  5386. default:
  5387. break;
  5388. }
  5389. if (DS_IMAGE_PENDING == nDetectorState)
  5390. {
  5391. StatusFeedback(EVT_STATUS_IMAGEPENDING, 0, "true", nDetectorID);
  5392. }
  5393. else
  5394. {
  5395. StatusFeedback(EVT_STATUS_IMAGEPENDING, 0, "false", nDetectorID);
  5396. }
  5397. #pragma endregion
  5398. #pragma region battery
  5399. //获取电量信息
  5400. if (pData->detectorStatus[i].energyStatus != 0)
  5401. {
  5402. int nPowerSource = pData->detectorStatus[i].energyStatus->powerSource;
  5403. if (PS_BACKUP_CABLE == nPowerSource)
  5404. {
  5405. Info("front-end power source: BACKUPCABLE");
  5406. StatusFeedback(EVT_STATUS_BATTERY_CHARGING, 0, "true", nDetectorID);
  5407. }
  5408. else if (PS_BATTERY == nPowerSource)
  5409. {
  5410. Info("front-end power source: BATTERY");
  5411. StatusFeedback(EVT_STATUS_BATTERY_CHARGING, 0, "false", nDetectorID);
  5412. }
  5413. int nFullChargeCapacity = pData->detectorStatus[i].energyStatus->batteryStatus.fullChargeCapacity;
  5414. Info("Detector({$}) full charge capacity of the battery: {$}", nDetectorID, nFullChargeCapacity);
  5415. InfoFeedback(EVT_INFO_BATTERY_CAPACITY, nDetectorID, nFullChargeCapacity);
  5416. m_pStPanelStatus[nDetectorID]->nBattery = pData->detectorStatus[i].energyStatus->batteryStatus.charge;
  5417. StatusFeedback(EVT_STATUS_BATTERY_VALUE, pData->detectorStatus[i].energyStatus->batteryStatus.charge, "", nDetectorID);
  5418. float fBatteryTemperature = pData->detectorStatus[i].energyStatus->batteryStatus.temperature;
  5419. Info("temperature of the battery: {$}", fBatteryTemperature);
  5420. InfoFeedback(EVT_INFO_BATTERY_TEMPERATURE, nDetectorID, 0, fBatteryTemperature);
  5421. int nBatteryCycles = pData->detectorStatus[i].energyStatus->batteryStatus.chargeCycles;
  5422. Info("number of charge/discharge cycles: {$}", nBatteryCycles);
  5423. InfoFeedback(EVT_INFO_BATTERY_CHARGES, nDetectorID, nBatteryCycles);
  5424. }
  5425. #pragma endregion
  5426. #if 0
  5427. //获取gridstatus
  5428. if (pData->detectorStatus[i].gridStatus != 0)
  5429. {
  5430. int nGrid = pData->detectorStatus[i].gridStatus->grid;
  5431. Info("Pixrad Grid Status: {$}", nGrid);
  5432. }
  5433. int nLifeTime = pData->detectorStatus[i].counterStatus.lifeTime;
  5434. Info("Life Time: {$}", nLifeTime);
  5435. ConfFeedback(EVT_CONF_LIFETIME, nDetectorID, "", nLifeTime);
  5436. int nPowerOn = pData->detectorStatus[i].counterStatus.powerOn;
  5437. InfoFeedback(EVT_INFO_POWER_ON, nDetectorID, nPowerOn);
  5438. if (pData->detectorStatus[i].shockStatus != 0)
  5439. {
  5440. int nbCounter = pData->detectorStatus[i].shockStatus->nbCounters;
  5441. int nShockNumbers = 0;
  5442. for (int j = 0; j < nbCounter; ++j)
  5443. {
  5444. nShockNumbers += pData->detectorStatus[i].shockStatus->counters[j];
  5445. }
  5446. Info("Shock Number: {$}", nShockNumbers);
  5447. if (nShockNumbers == 0)
  5448. {
  5449. if (m_pStPanelStatus[i]->nTotalShockNumber <= 0)
  5450. {
  5451. SimulateShockSensor(i, false);
  5452. }
  5453. else
  5454. {
  5455. Fatal("Detector is dropping down");
  5456. }
  5457. }
  5458. else
  5459. {
  5460. if ((m_pStPanelStatus[i]->nTotalShockNumber != -1) &&
  5461. (nShockNumbers > m_pStPanelStatus[i]->nTotalShockNumber))
  5462. {
  5463. Info("Need Get ShockSensor Information");
  5464. Thread_Lock();
  5465. m_nShockFPDID = i;
  5466. Thread_UnLock();
  5467. SetEvent(m_hCheckShockEvent);
  5468. }
  5469. m_pStPanelStatus[i]->nTotalShockNumber = nShockNumbers;
  5470. }
  5471. }
  5472. #pragma region motionStatus
  5473. if (pData->detectorStatus[i].motionStatus != 0)
  5474. {
  5475. int nOrientation = pData->detectorStatus[i].motionStatus->orientation;
  5476. string strOrientation = "";
  5477. if (DET_MOVING == nOrientation)
  5478. {
  5479. strOrientation = "DET_MOVING";
  5480. Info("Orientation:DET_MOVING");
  5481. }
  5482. else if (DET_HORIZONTAL_RIGHT_SIDE == nOrientation)
  5483. {
  5484. strOrientation = "DET_HORIZONTAL_RIGHT_SIDE";
  5485. Info("Orientation:DET_HORIZONTAL_RIGHT_SIDE");
  5486. }
  5487. else if (DET_HORIZONTAL_UPSIDE_DOWN == nOrientation)
  5488. {
  5489. strOrientation = "DET_HORIZONTAL_UPSIDE_DOWN";
  5490. Info("Orientation:DET_HORIZONTAL_UPSIDE_DOWN");
  5491. }
  5492. else if (DET_IN_BETWEEN_PORTRAIT_RIGHT_SIDE == nOrientation)
  5493. {
  5494. strOrientation = "DET_IN_BETWEEN_PORTRAIT_RIGHT_SIDE";
  5495. Info("Orientation:DET_IN_BETWEEN_PORTRAIT_RIGHT_SIDE");
  5496. }
  5497. else if (DET_IN_BETWEEN_PORTRAIT_UPSIDE_DOWN == nOrientation)
  5498. {
  5499. strOrientation = "DET_IN_BETWEEN_PORTRAIT_UPSIDE_DOWN";
  5500. Info("Orientation:DET_IN_BETWEEN_PORTRAIT_UPSIDE_DOWN");
  5501. }
  5502. else if (DET_IN_BETWEEN_LANDSCAPE_RIGHT == nOrientation)
  5503. {
  5504. strOrientation = "DET_IN_BETWEEN_LANDSCAPE_RIGHT";
  5505. Info("Orientation:DET_IN_BETWEEN_LANDSCAPE_RIGHT");
  5506. }
  5507. else if (DET_IN_BETWEEN_LANDSCAPE_LEFT == nOrientation)
  5508. {
  5509. strOrientation = "DET_IN_BETWEEN_LANDSCAPE_LEFT";
  5510. Info("Orientation:DET_IN_BETWEEN_LANDSCAPE_LEFT");
  5511. }
  5512. else if (DET_IN_BETWEEN_UNDEFINED == nOrientation)
  5513. {
  5514. strOrientation = "DET_IN_BETWEEN_UNDEFINED";
  5515. Info("Orientation:DET_IN_BETWEEN_UNDEFINED");
  5516. }
  5517. else if (DET_VERTICAL_PORTRAIT_RIGHT_SIDE == nOrientation)
  5518. {
  5519. strOrientation = "DET_VERTICAL_PORTRAIT_RIGHT_SIDE";
  5520. Info("Orientation:DET_VERTICAL_PORTRAIT_RIGHT_SIDE");
  5521. }
  5522. else if (DET_VERTICAL_PORTRAIT_UPSIDE_DOWN == nOrientation)
  5523. {
  5524. strOrientation = "DET_VERTICAL_PORTRAIT_UPSIDE_DOWN";
  5525. Info("Orientation:DET_VERTICAL_PORTRAIT_UPSIDE_DOWN");
  5526. }
  5527. else if (DET_VERTICAL_LANDSCAPE_RIGHT == nOrientation)
  5528. {
  5529. strOrientation = "DET_VERTICAL_LANDSCAPE_RIGHT";
  5530. Info("Orientation:DET_VERTICAL_LANDSCAPE_RIGHT");
  5531. }
  5532. else if (DET_VERTICAL_LANDSCAPE_LEFT == nOrientation)
  5533. {
  5534. strOrientation = "DET_VERTICAL_LANDSCAPE_LEFT";
  5535. Info("Orientation:DET_VERTICAL_LANDSCAPE_LEFT");
  5536. }
  5537. else if (DET_VERTICAL_UNDEFINED == nOrientation)
  5538. {
  5539. strOrientation = "DET_VERTICAL_UNDEFINED";
  5540. Info("Orientation:DET_VERTICAL_UNDEFINED");
  5541. }
  5542. else
  5543. {
  5544. strOrientation = "UNKNOWN";
  5545. Info("Orientation:UNKNOWN");
  5546. }
  5547. float fpitch = pData->detectorStatus[i].motionStatus->pitch;
  5548. float froll = pData->detectorStatus[i].motionStatus->roll;
  5549. float fyaw = pData->detectorStatus[i].motionStatus->yaw;
  5550. char szPitch[8] = { 0 }; sprintf_s(szPitch, "%.2f", fpitch);
  5551. char szRoll[8] = { 0 }; sprintf_s(szRoll, "%.2f", froll);
  5552. char szYaw[8] = { 0 }; sprintf_s(szYaw, "%.2f", fyaw);
  5553. ResDataObject jsParamList;
  5554. jsParamList.add("DetectorOrientation", strOrientation.c_str());
  5555. jsParamList.add("DetectorPitch", szPitch);
  5556. jsParamList.add("DetectorRoll", szRoll);
  5557. jsParamList.add("DetectorYaw", szYaw);
  5558. StatusFeedback(EVT_STATUS_MOTION, nDetectorID, jsParamList.encode());
  5559. }
  5560. #pragma endregion
  5561. #endif
  5562. }
  5563. ErrorFeedback(EVT_ERR_COMMUNICATE, "false", nDetectorID); //hw callback清错
  5564. }
  5565. if (!m_pStPanelStatus[nDetectorID]->bIsPortable) //非移动板没有wifi回调,在此处停止查询状态
  5566. {
  5567. if (nDetectorID != m_nCurrentPanelID)
  5568. {
  5569. //非当前平板是靠开启polling功能实现查询状态的,查询一次后,停止查询
  5570. m_nStopPollingIndex = nDetectorID;
  5571. SetEvent(m_hClosePollingEvent);
  5572. }
  5573. }
  5574. break;
  5575. case EVT_START_ACQUISITION:
  5576. ProcessEventError("EVT_START_ACQUISITION", eventData->error, nDetectorID);
  5577. m_bPreviewImg = false; //采集开始,恢复初值
  5578. m_bIsExpInAuto = false; //采集开始,恢复初值
  5579. ErrorFeedback(EVT_ERR_EXP_REQUEST, "false"); //开始采集,清除
  5580. break;
  5581. case EVT_END_ACQUISITION: //! Sent when an acquisition is finished with the acquired image
  5582. m_bPreviewImg = false; //采集结束,恢复初值
  5583. if (m_bWaitAcqEnd)
  5584. {
  5585. m_bWaitAcqEnd = false;
  5586. UnlockPixrad("EVT_END_ACQUISITION");
  5587. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  5588. }
  5589. if (m_eStatus == DetStatus_Acquire) //如果回调早于stopacquisition接口调用,则置为DETECTOR_STATUS_STANDBY
  5590. {
  5591. m_eStatus = DetStatus_Standby; //停止采集,置回Standby
  5592. }
  5593. else if(m_eStatus == DetStatus_XrayCalibration)
  5594. {
  5595. UnlockPixrad("EVT_END_ACQUISITION");
  5596. }
  5597. StatusFeedback(EVT_STATUS_PANEL, PANEL_STANDBY);
  5598. if (!ProcessEventError("EVT_END_ACQUISITION", eventData->error, nDetectorID))
  5599. {
  5600. if (!m_bTransImageSuccess) //曝光了但没拿到图像
  5601. {
  5602. ErrorFeedback(EVT_ERR_GET_IMAGE, "true"); //曝光没拿到图像
  5603. }
  5604. else if (ERR_DETECTOR_IMAGE_PENDING == eventData->error)
  5605. {
  5606. ErrorFeedback(EVT_ERR_GET_IMAGE, "true"); //探测器反馈有图
  5607. }
  5608. else
  5609. {
  5610. ErrorFeedback(EVT_ERR_EXP_REQUEST, "true");
  5611. }
  5612. }
  5613. break;
  5614. case EVT_PREVIEW:
  5615. Info("Pre Image Arrived!");
  5616. m_bPreviewImg = true;
  5617. if (ProcessEventError("EVT_PREVIEW", eventData->error, nDetectorID) && m_bPreviewEnable)
  5618. {
  5619. if (m_bAutonumousMode)
  5620. {
  5621. Info("Current in Autonumous Mode, omit preview image");
  5622. break;
  5623. }
  5624. AcquisitionImage* pAcquisitionImage = static_cast<AcquisitionImage*>(eventData->data);
  5625. memcpy(m_pPreImgBuffer, pAcquisitionImage->imgPtr, m_nPreviewWidth * m_nPreviewHeight * sizeof(WORD));
  5626. Info("copy buffer over");
  5627. SetEvent(m_hProcessImgEvent);
  5628. Info("set ProcessImgEvent over");
  5629. }
  5630. break;
  5631. case EVT_IMAGE_AVAILABLE:
  5632. {
  5633. Info("Image Arrived!");
  5634. //tomo时 EVT_IMAGE_AVAILABLE到下一次EVT_START_TRANSMIT,约18ms
  5635. m_bPreviewImg = false; //收到大图,恢复初值
  5636. if (m_nIgnoreImgNum < m_nIgnoreImgCount)
  5637. {
  5638. Info("EVT_IMAGE_AVAILABLE Ignore ({$}/{$}) Image", m_nIgnoreImgNum + 1, m_nIgnoreImgCount);
  5639. m_nIgnoreImgNum++;
  5640. break;
  5641. }
  5642. if (ProcessEventError("EVT_IMAGE_AVAILABLE", eventData->error, nDetectorID))
  5643. {
  5644. m_bTransImageSuccess = true; //表明图像已获取成功
  5645. ErrorFeedback(EVT_ERR_GET_IMAGE, "false"); //拿到图像
  5646. AcquisitionImage* pAcquisitionImage = static_cast<AcquisitionImage*>(eventData->data);
  5647. Info("Get Acquisition Image");
  5648. if (pAcquisitionImage->imgPtr == NULL)
  5649. {
  5650. Error("Get Image is NULL");
  5651. }
  5652. else
  5653. {
  5654. struct tm stLocalTime;
  5655. char szTemp[100] = { 0 };
  5656. stLocalTime = *localtime(&pAcquisitionImage->imgParam.acquisitionTime);
  5657. strftime(szTemp, sizeof(szTemp), "%Y-%m-%d %H:%M:%S", &stLocalTime);
  5658. m_nTomoImgIndex = pAcquisitionImage->imgParam.number;
  5659. Info("Acquire Image SizeX: {$}, SizeY: {$}, Index: {$}, AcquireT: {$}", pAcquisitionImage->imgParam.sizeX, pAcquisitionImage->imgParam.sizeY, pAcquisitionImage->imgParam.number, szTemp);
  5660. correction_type correctType = pAcquisitionImage->imgParam.correctionType;
  5661. switch (correctType)
  5662. {
  5663. case CT_NONE:
  5664. Info("CorrectionType:NONE");
  5665. break;
  5666. case CT_OFFSET:
  5667. Info("CorrectionType:OFFSET");
  5668. break;
  5669. case CT_GAIN:
  5670. Info("CorrectionType:GAIN");
  5671. break;
  5672. case CT_DEFECT:
  5673. Info("CorrectionType:DEFECT");
  5674. break;
  5675. case CT_ALL:
  5676. Info("CorrectionType:ALL");
  5677. break;
  5678. default:
  5679. Info("CorrectionType:{$}", (int)correctType);
  5680. break;
  5681. }
  5682. if (m_nWidthOffset != 0 || m_nHeightOffset != 0)
  5683. {
  5684. Info("m_nWidthOffset != 0 || m_nHeightOffset != 0");
  5685. memcpy(m_pRawImgBuffer, pAcquisitionImage->imgPtr, m_nRawImgHeight * m_nRawImgWidth * sizeof(WORD));
  5686. }
  5687. else
  5688. {
  5689. if (m_bAutonumousMode)
  5690. {
  5691. Info("m_bAutonumousMode == true");
  5692. m_nImageWidth = pAcquisitionImage->imgParam.sizeX;
  5693. m_nImageHeight = pAcquisitionImage->imgParam.sizeY;
  5694. if (m_pImgBuffer)
  5695. {
  5696. delete m_pImgBuffer;
  5697. m_pImgBuffer = NULL;
  5698. }
  5699. Info("m_bAutonumousMode image width:{$} height:{$}", m_nImageWidth, m_nImageHeight);
  5700. m_pImgBuffer = new WORD[m_nImageWidth * m_nImageHeight];
  5701. memcpy(m_pImgBuffer, pAcquisitionImage->imgPtr, m_nImageHeight * m_nImageWidth * sizeof(WORD));
  5702. }
  5703. }
  5704. //memcpy(m_pImgBuffer, pAcquisitionImage->imgPtr, m_nImageHeight * m_nImageWidth * sizeof(WORD));
  5705. Info("copy buffer over");
  5706. StatusFeedback(EVT_STATUS_PANEL, PANEL_GET_IMAGE);
  5707. SetEvent(m_hProcessImgEvent);
  5708. Info("set ProcessImgEvent over");
  5709. }
  5710. }
  5711. SetEvent(m_hXWinOffEvent);
  5712. }
  5713. break;
  5714. case EVT_FRAME_DONE: //! Sent when an image has been taken with the TED_PixRad_StartFrame function
  5715. ProcessEventError("EVT_FRAME_DONE", eventData->error, nDetectorID);
  5716. break;
  5717. case EVT_READY:
  5718. if (ProcessEventError("EVT_READY", eventData->error, nDetectorID))
  5719. {
  5720. //aed模式刷新暗场也会有ready回调,但此时不能解锁,要等end dark回调解锁
  5721. if (PIX_OM_AED == m_nCurrentOmMode && !m_bRefreshing)
  5722. {
  5723. UnlockPixrad("EVT_READY"); //aed模式进入ready状态,解锁
  5724. }
  5725. }
  5726. break;
  5727. case EVT_XRAY_ON:
  5728. Info("EVT_XRAY_ON index: {$}", m_nXwinOnIndex);
  5729. //printf("EVT_XRAY_ON \n");
  5730. /***
  5731. ** modify20210202
  5732. ** SMS项目TOMO采集时,由于机架需要固定的时间来达到匀速,
  5733. ** 所以第m_nXwinOnIndex个EVT_XRAY_ON向子系统发送ACQ消息
  5734. ** (开始采集到第一个XRAY_ON耗时不固定,但两个EVT_XRAY_ON的间隔时间是固定的)
  5735. ***/
  5736. //if (DetStatus_Acquire == m_eStatus)
  5737. //{
  5738. // if (m_nXwinOnIndex + 1 > m_nIgnoreImgCount)
  5739. // {
  5740. // SetEvent(m_hXWinOnEvent);
  5741. // m_bIsExpInAuto = true; //开窗,置为true
  5742. // }
  5743. // else //忽略WindowOn分支
  5744. // {
  5745. // if (m_nXwinOnIndex == 0)
  5746. // {
  5747. // UnlockPixrad("EVT_XRAY_ON"); //收到WindowOn,解锁,使FrameStart执行完毕
  5748. // }
  5749. // Info("Ignore ({$}/{$}) XrayOn", m_nXwinOnIndex + 1, m_nIgnoreImgCount);
  5750. // }
  5751. //}
  5752. //else
  5753. //{
  5754. // SetEvent(m_hXWinOnEvent);
  5755. // //if (DetStatus_XrayCalibration == m_eStatus)
  5756. // {
  5757. // m_bGainProcess = true; //开窗,进入增益曝光的一个小循环
  5758. // //m_nGainExpIndex++;
  5759. // m_bPrepShot = false; //开窗,恢复初值
  5760. // }
  5761. //}
  5762. //m_nXwinOnIndex++;
  5763. if (PIX_OM_AED == m_nCurrentOmMode) //AED+Demo发送XWindowOnNotify通知
  5764. {
  5765. StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_ON);
  5766. }
  5767. SetEvent(m_hXWinOnEvent);
  5768. m_bIsExpInAuto = true;
  5769. break;
  5770. case EVT_XRAY_OFF:
  5771. ProcessEventError("EVT_XRAY_OFF", eventData->error, nDetectorID);
  5772. //if (DetStatus_Acquire == m_eStatus)
  5773. //{
  5774. // if (m_nXwinOnIndex + 1 > m_nIgnoreImgCount)
  5775. // {
  5776. // SetEvent(m_hXWinOffEvent);
  5777. // }
  5778. //}
  5779. //else if (DetStatus_XrayCalibration == m_eStatus)
  5780. //{
  5781. // if (m_nXwinOnIndex + 1 > m_nIgnoreImgCount)
  5782. // {
  5783. // SetEvent(m_hXWinOffEvent);
  5784. // }
  5785. // m_bConfirmCaliRst = true; //增益校正曝光,默认接受结果
  5786. //}
  5787. if (PIX_OM_AED == m_nCurrentOmMode)
  5788. {
  5789. StatusFeedback(EVT_STATUS_PANEL, PANEL_AED_XRAY_OFF);
  5790. }
  5791. m_bTransImageSuccess = false; //关窗,置为false,等待图像
  5792. break;
  5793. case EVT_START_TRANSMIT:
  5794. ProcessEventError("EVT_START_TRANSMIT", eventData->error, nDetectorID);
  5795. break;
  5796. case EVT_END_TRANSMIT:
  5797. ProcessEventError("EVT_END_TRANSMIT", eventData->error, nDetectorID);
  5798. break;
  5799. case EVT_DOSE_PARAM_REQUEST: //! Indicates the PixRad is requesting a dose setting before the next image/sequence to acquire
  5800. {
  5801. DoseParameters* pDoseParameters = static_cast<DoseParameters*>(eventData->data);
  5802. m_fDose = pDoseParameters->dose;
  5803. Info("EVT_DOSE_PARAM_REQUEST {$}", m_fDose);
  5804. DataFeedback(EVT_DATA_DOSEPARAM, NULL, 0, m_fDose);
  5805. m_bConfirmCaliRst = false; //收到增益dose要求,恢复初值
  5806. m_bAutoContinueCal = false; //收到增益dose要求,恢复初值
  5807. if (m_bGainPreparing)
  5808. {
  5809. m_bGainPreparing = false;
  5810. UnlockPixrad("EVT_DOSE_PARAM_REQUEST"); //进入增益校正状态,解锁
  5811. }
  5812. if (!m_bGainPreparing && m_fCurrentDose != m_fDose) //需要切换给上层的Dose
  5813. {
  5814. UnlockPixrad("EVT_DOSE_PARAM_REQUEST");
  5815. }
  5816. }
  5817. break;
  5818. case EVT_PREP_XRAY_SHOT: //! Indicates a xray shot will happened in a few seconds (delay fixed in .ini file)
  5819. ProcessEventError("EVT_PREP_XRAY_SHOT", eventData->error, nDetectorID);
  5820. if (!m_bPrepShot)
  5821. {
  5822. m_bPrepShot = true; //收到回调
  5823. }
  5824. if (m_nCurrentOmMode != PIX_OM_TOMO)
  5825. {
  5826. UnlockPixrad("EVT_PREP_XRAY_SHOT"); //校正FramePrep时的Resuming执行完毕
  5827. }
  5828. break;
  5829. case EVT_OFFSET_INVALID: //! Indicates that the offset acquisition is not valid
  5830. ProcessEventError("EVT_OFFSET_INVALID", eventData->error, nDetectorID);
  5831. break;
  5832. case EVT_X_DOSE_LEVEL: //! Indicates that the measured level
  5833. {
  5834. m_bTransImageSuccess = true; //表明图像已获取成功
  5835. m_bConfirmCaliRst = false; //剂量不合适,不接受增益结果
  5836. m_bAutoContinueCal = false; //剂量不合适,需要手动触发下一次增益
  5837. if (ProcessEventError("EVT_X_DOSE_LEVEL", eventData->error, nDetectorID))
  5838. {
  5839. DoseLevelError doseLevel = *(static_cast<DoseLevelError*>(eventData->data));
  5840. dose_level nDoseLevel = *(static_cast<dose_level*>(eventData->data));
  5841. string strCurDose = GetPanelResource("CurrentDose");
  5842. if (DL_HIGH == nDoseLevel)
  5843. {
  5844. string strDoseNote = GetPanelResource("DoseTooHigh");
  5845. char szValue[MAX_PATH] = { 0 };
  5846. sprintf_s(szValue, "%s %.1f %s [%.1f - %.1f]", strCurDose.c_str(), doseLevel.measured_level, strDoseNote.c_str(), doseLevel.min_threshold, doseLevel.max_threshold);
  5847. string strLastError = szValue;
  5848. Info("{$}", strLastError.c_str());
  5849. StatusFeedback(EVT_STATUS_SINGLEEXP, EVT_STATUS_LASTERROR, strLastError.c_str());
  5850. StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_HIGH);
  5851. }
  5852. else
  5853. {
  5854. string strDoseNote = GetPanelResource("DoseTooLow");
  5855. char szValue[MAX_PATH] = { 0 };
  5856. sprintf_s(szValue, "%s %.1f %s [%.1f - %.1f]", strCurDose.c_str(), doseLevel.measured_level, strDoseNote.c_str(), doseLevel.min_threshold, doseLevel.max_threshold);
  5857. string strLastError = szValue;
  5858. Info("{$}", strLastError.c_str());
  5859. StatusFeedback(EVT_STATUS_SINGLEEXP, EVT_STATUS_LASTERROR, strLastError.c_str());
  5860. StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_TOO_LOW);
  5861. }
  5862. if (m_bGainProcess)
  5863. {
  5864. //m_nGainExpIndex--; //曝光不合格,次数减一
  5865. m_bGainProcess = false; //SDK返回当前增益曝光结果(剂量不合适),结束增益曝光小循环
  5866. UnlockPixrad("EVT_X_DOSE_LEVEL"); //得到当前增益曝光结果
  5867. }
  5868. m_nCaliFailedCount++;
  5869. if (m_nCaliFailedCount > 10)
  5870. {
  5871. //失败次数过多,停止校正,避免无法终止 ys
  5872. Warn("The gain failed too many times, stop it");
  5873. m_nCaliFailedCount = 0;
  5874. //(*m_pPanelID2DPC)[m_nCurrentPanelID]->StopCalibration();
  5875. }
  5876. }
  5877. }
  5878. break;
  5879. case EVT_X_OBJECT_DETECTED: //! Indicates that an object has been detected on the image
  5880. {
  5881. m_bConfirmCaliRst = false; //检测到物体,不接受增益结果
  5882. m_bAutoContinueCal = false; //检测到物体,需要手动触发下一次增益
  5883. m_bTransImageSuccess = true; //表明图像已获取成功
  5884. ProcessEventError("EVT_X_OBJECT_DETECTED", eventData->error, nDetectorID);
  5885. //printf("EVT_X_OBJECT_DETECTED \n"); //test
  5886. string strLastError = GetPanelResource("ObjectInDetector");
  5887. Info("{$}", strLastError.c_str());
  5888. StatusFeedback(EVT_STATUS_SINGLEEXP, EVT_STATUS_LASTERROR, strLastError.c_str());
  5889. StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_OBJECT);
  5890. if (m_bGainProcess)
  5891. {
  5892. //m_nGainExpIndex--; //曝光不合格,次数减一
  5893. m_bGainProcess = false; //SDK返回当前增益曝光结果(有物体),结束增益曝光小循环
  5894. UnlockPixrad("EVT_X_OBJECT_DETECTED"); //得到当前增益曝光结果
  5895. }
  5896. m_nCaliFailedCount++;
  5897. }
  5898. break;
  5899. case EVT_REMAINING_TIME: //! Event for display elapsed time in seconds for calibration
  5900. {
  5901. DataCalibration* pData = static_cast<DataCalibration*>(eventData->data);
  5902. Info("EVT_REMAINING_TIME : total = {$}, remaining = {$} [{$}%%]", pData->totalTime, pData->remainingTime, pData->percentageDone);
  5903. if (m_bConfirmCaliRst)
  5904. {
  5905. //printf("EVT_REMAINING_TIME : total = %d, remaining = %d [%d%%] \n", pData->totalTime, pData->remainingTime, pData->percentageDone); //test
  5906. m_bConfirmCaliRst = false; //接受图像,恢复初值
  5907. m_bAutoContinueCal = true; //当前增益OK,自动触发下一次增益
  5908. StatusFeedback(EVT_STATUS_SINGLEEXP, DOSE_ACCEPT);
  5909. Info("ConfirmCaliRst true");
  5910. }
  5911. if (m_bGainProcess)
  5912. {
  5913. Info("Gain process true");
  5914. m_bTransImageSuccess = true; //表明图像已获取成功
  5915. m_bGainProcess = false; //SDK返回当前增益曝光结果(接受),结束增益曝光小循环
  5916. UnlockPixrad("EVT_REMAINING_TIME"); //得到当前增益曝光结果
  5917. }
  5918. }
  5919. break;
  5920. case EVT_STANDBY_REFRESH: //! Event sent during the standby state calibration
  5921. ProcessEventError("EVT_STANDBY_REFRESH", eventData->error, nDetectorID);
  5922. break;
  5923. case EVT_ACTIVE_STATE: //! Indicates the system state has changed
  5924. {
  5925. if (!ProcessEventError("EVT_ACTIVE_STATE", eventData->error, nDetectorID))
  5926. {
  5927. Error("Failed to set active state");
  5928. UnlockPixrad("EVT_ACTIVE_STATE");
  5929. }
  5930. else
  5931. {
  5932. system_state* pState = static_cast<system_state*>(eventData->data);
  5933. m_currentState = *pState;
  5934. if (m_currentState == STATE_PATIENT)
  5935. {
  5936. Info("Current state: STATE_PATIENT");
  5937. UnlockPixrad("EVT_ACTIVE_STATE");
  5938. }
  5939. else if (m_currentState == STATE_QUIET)
  5940. {
  5941. Info("Current state: STATE_QUIET");
  5942. UnlockPixrad("EVT_ACTIVE_STATE");
  5943. }
  5944. else if (m_currentState == STATE_REFERENCE)
  5945. {
  5946. Info("Current state: STATE_REFERENCE");
  5947. }
  5948. else if (m_currentState == STATE_STAND_BY)
  5949. {
  5950. Info("Current state: STATE_STAND_BY");
  5951. //dark calibration不锁线程,完成后在子线程处理结束流程
  5952. if (CCOS_CALIBRATION_TYPE_DARK == m_eCaliType)
  5953. {
  5954. SetEvent(m_hDarkEndEvent);
  5955. }
  5956. else //一般刷新时锁线程,在此处解锁EVT_END_XRAY_CALIBRATION
  5957. {
  5958. UnlockPixrad("EVT_ACTIVE_STATE"); //offset刷新完成
  5959. }
  5960. }
  5961. else
  5962. {
  5963. Info("Current state: {$}", (int)m_currentState);
  5964. }
  5965. }
  5966. }
  5967. break;
  5968. case EVT_ACTIVE_DETECTOR: //! Indicates that the active detector has changed
  5969. ProcessEventError("EVT_ACTIVE_DETECTOR", eventData->error, nDetectorID);
  5970. UnlockPixrad("EVT_ACTIVE_DETECTOR");
  5971. break;
  5972. case EVT_OFFSET_REQUEST:
  5973. //! Indicates delay without offset is exceeded.
  5974. //Require the main software to acquire an offset image
  5975. ProcessEventError("EVT_OFFSET_REQUEST", eventData->error, nDetectorID);
  5976. break;
  5977. case EVT_TIMEOUT_PATIENT: //! Indicates delay timeout without offset image
  5978. ProcessEventError("EVT_TIMEOUT_PATIENT", eventData->error, nDetectorID);
  5979. break;
  5980. case EVT_TEMPERATURE_LIMIT: //! Indicates a temperature of detector is too high
  5981. ProcessEventError("EVT_TEMPERATURE_LIMIT", eventData->error, nDetectorID);
  5982. break;
  5983. case EVT_OFFSET_VALID_LIMIT:
  5984. //! Indicates that the number of successive non valid offsets has exceed the allowed value
  5985. ProcessEventError("EVT_OFFSET_VALID_LIMIT", eventData->error, nDetectorID);
  5986. break;
  5987. case EVT_WIFI_STATUS:
  5988. if (ProcessEventError("EVT_WIFI_STATUS", eventData->error, nDetectorID))
  5989. {
  5990. WifiStatus* pData = static_cast<WifiStatus*>(eventData->data);
  5991. for (int i = 0; i < pData->nbDetectors; ++i)
  5992. {
  5993. if (pData->detectorStatus[i].wifiInfo != 0)
  5994. {
  5995. int nWifiChannel = pData->detectorStatus[i].wifiInfo->frontEndStatus.channel;
  5996. Info("channel of frontEndStatus is {$}", nWifiChannel);
  5997. Debug("power of frontEndStatus is {$}", pData->detectorStatus[i].wifiInfo->frontEndStatus.power);
  5998. InfoFeedback(EVT_INFO_WIFI_CHANNEL, nDetectorID, nWifiChannel);
  5999. if (pData->detectorStatus[i].wifiInfo->frontEndStatus.extendedStatus != 0)
  6000. {
  6001. int nWifiSignalPower = pData->detectorStatus[i].wifiInfo->frontEndStatus.extendedStatus->signalPower;
  6002. Info("Detector({$} )signalPower of frontEndStatus extendedStatus is {$}", nDetectorID, nWifiSignalPower);
  6003. InfoFeedback(EVT_INFO_WIFI_SIGNALPOWER, nDetectorID, nWifiSignalPower);
  6004. int nWifiNoisePower = pData->detectorStatus[i].wifiInfo->frontEndStatus.extendedStatus->noisePower;
  6005. Info("noisePower of frontEndStatus extendedStatus is {$}", nWifiNoisePower);
  6006. InfoFeedback(EVT_INFO_WIFI_NOISEPOWER, nDetectorID, nWifiNoisePower);
  6007. int nWifiDataRate = pData->detectorStatus[i].wifiInfo->frontEndStatus.extendedStatus->dataRate;
  6008. Info("dataRate of frontEndStatus extendedStatus is {$}", nWifiDataRate);
  6009. InfoFeedback(EVT_INFO_WIFI_DATARATE, nDetectorID, nWifiDataRate);
  6010. int nRawLinkQuality = pData->detectorStatus[i].wifiInfo->frontEndStatus.extendedStatus->rawLinkQuality;
  6011. StatusFeedback(EVT_STATUS_WIFI, nRawLinkQuality, "", nDetectorID);
  6012. }
  6013. }
  6014. }
  6015. }
  6016. if (m_bNeedFeedback)
  6017. {
  6018. UnlockPixrad("EVT_WIFI_STATUS");
  6019. }
  6020. if (m_pStPanelStatus[nDetectorID]->bIsPortable)
  6021. {
  6022. if (nDetectorID != m_nCurrentPanelID)
  6023. {
  6024. //非当前平板是靠开启polling功能实现查询状态的,查询一次后,停止查询
  6025. m_nStopPollingIndex = nDetectorID;
  6026. SetEvent(m_hClosePollingEvent);
  6027. }
  6028. }
  6029. break;
  6030. case EVT_START_BATTERY_CALIBRATION: //! Sent when the detector battery calibration begins
  6031. ProcessEventError("EVT_START_BATTERY_CALIBRATION", eventData->error, nDetectorID);
  6032. break;
  6033. case EVT_END_BATTERY_CALIBRATION:
  6034. ProcessEventError("EVT_END_BATTERY_CALIBRATION", eventData->error, nDetectorID);
  6035. break;
  6036. case EVT_DETECTOR_CONTROL_CHANGED: //! Sent when the detector control has been enabled/disabled
  6037. {
  6038. if (ProcessEventError("EVT_DETECTOR_CONTROL_CHANGED", eventData->error, nDetectorID))
  6039. {
  6040. DetectorControlValue* pCtrlType = static_cast<DetectorControlValue*>(eventData->data);
  6041. string strEnable = "DISABLE";
  6042. if (pCtrlType->enable)
  6043. {
  6044. strEnable = "ENABLE";
  6045. }
  6046. switch (pCtrlType->type)
  6047. {
  6048. case DC_DOCKING_STATION_SAPM_CONTACTS:
  6049. Info("DC_DOCKING_STATION_SAPM_CONTACTS {$}", strEnable.c_str());
  6050. break;
  6051. case DC_FRONTEND_LEDS_SCROLLING:
  6052. Info("DC_FRONTEND_LEDS_SCROLLING {$}", strEnable.c_str());
  6053. break;
  6054. case DC_FRONTEND_POWEROFF:
  6055. Info("DC_FRONTEND_POWEROFF {$}", strEnable.c_str());
  6056. ErrorFeedback(EVT_ERR_POWER_OFF, "true");
  6057. m_pStPanelStatus[nDetectorID]->bConnectStatus = false;
  6058. break;
  6059. case DC_FRONTEND_LOWPOWER:
  6060. Info("DC_FRONTEND_LOWPOWER {$}", strEnable.c_str());
  6061. if (pCtrlType->enable)
  6062. {
  6063. if ((m_eAppStatus != APP_STATUS_WORK_BEGIN && m_eAppStatus != APP_STATUS_CAL_BEGIN) //检查、校正界面不执行
  6064. && (DetStatus_Acquire != m_eStatus) && (DetStatus_Offset != m_eStatus) && (DetStatus_XrayCalibration != m_eStatus))
  6065. {
  6066. Warn("Do not sent sleep msg to upper in status({$} {$})", (int)m_eAppStatus, (int)m_eStatus);
  6067. }
  6068. else
  6069. {
  6070. StatusFeedback(EVT_STATUS_SLEEP, 0, "true", nDetectorID);
  6071. }
  6072. }
  6073. break;
  6074. case DC_IMAGE_STORAGE:
  6075. Info("DC_IMAGE_STORAGE {$}", strEnable.c_str());
  6076. break;
  6077. case DC_AUTOTRIGGER_LOWEST:
  6078. Info("DC_AUTOTRIGGER_LOWEST {$}", strEnable.c_str());
  6079. UnlockPixrad("DC_AUTOTRIGGER_LOWEST"); //启动、关闭aed成功
  6080. break;
  6081. case DC_AUTOTRIGGER_LOW:
  6082. Info("DC_AUTOTRIGGER_LOW {$}", strEnable.c_str());
  6083. UnlockPixrad("DC_AUTOTRIGGER_LOW"); //启动、关闭aed成功
  6084. break;
  6085. case DC_AUTOTRIGGER_NORMAL:
  6086. Info("DC_AUTOTRIGGER_NORMAL {$}", strEnable.c_str());
  6087. m_pStPanelStatus[nDetectorID]->bDC_AED = true;
  6088. SendRespond("Control");
  6089. UnlockPixrad("DC_AUTOTRIGGER_NORMAL"); //启动、关闭aed成功
  6090. break;
  6091. case DC_AUTOTRIGGER_INTERMEDIATE:
  6092. Info("DC_AUTOTRIGGER_INTERMEDIATE {$}", strEnable.c_str());
  6093. UnlockPixrad("DC_AUTOTRIGGER_INTERMEDIATE"); //启动、关闭aed成功
  6094. break;
  6095. case DC_AUTOTRIGGER_HIGH:
  6096. Info("DC_AUTOTRIGGER_HIGH {$}", strEnable.c_str());
  6097. UnlockPixrad("DC_AUTOTRIGGER_HIGH"); //启动、关闭aed成功
  6098. break;
  6099. case DC_WIFI:
  6100. Info("DC_WIFI {$}", strEnable.c_str());
  6101. break;
  6102. case DC_HOST_LOCK:
  6103. Info("DC_HOST_LOCK {$}", strEnable.c_str());
  6104. break;
  6105. case DC_QUATERNION_CALCULATION:
  6106. Info("DC_QUATERNION_CALCULATION {$}", strEnable.c_str());
  6107. break;
  6108. case DC_DETECTOR_READY:
  6109. Info("DC_DETECTOR_READY {$}", strEnable.c_str());
  6110. break;
  6111. case DC_DIGITAL_TOMO:
  6112. Info("DC_DIGITAL_TOMO {$}", strEnable.c_str());
  6113. UnlockPixrad("DC_DIGITAL_TOMO"); //启动、关闭tomo成功
  6114. break;
  6115. case DC_SYNCHRONIZATION:
  6116. Info("DC_SYNCHRONIZATION {$}", strEnable.c_str());
  6117. UnlockPixrad("DC_SYNCHRONIZATION"); //启动、关闭sync成功
  6118. break;
  6119. default:
  6120. Info("Control changed: {$} {$}", (int)pCtrlType->type, strEnable.c_str());
  6121. break;
  6122. }
  6123. }
  6124. else
  6125. {
  6126. UnlockPixrad("EVT_DETECTOR_CONTROL_CHANGED");
  6127. }
  6128. }
  6129. break;
  6130. case EVT_ACCEPTANCE_TEST_RESULT: //! Sent when the acceptance test has been computed
  6131. ProcessEventError("EVT_ACCEPTANCE_TEST_RESULT", eventData->error, nDetectorID);
  6132. break;
  6133. case EVT_WAIT_START_XRAY: //! Sent to request the start of the x-ray generator
  6134. ProcessEventError("EVT_WAIT_START_XRAY", eventData->error, nDetectorID);
  6135. if (m_nCurrentOmMode == PIX_OM_TOMO)
  6136. {
  6137. UnlockPixrad("EVT_WAIT_START_XRAY"); //校正FramePrep时的Resuming执行完毕
  6138. }
  6139. break;
  6140. case EVT_WAIT_STOP_XRAY: //! Sent to request the stop of the x-ray generator
  6141. {
  6142. ProcessEventError("EVT_WAIT_STOP_XRAY", eventData->error, nDetectorID);
  6143. try
  6144. {
  6145. Info("Calling ResumeSequence");
  6146. error_status ErrorStatus = TED_PixRad_ResumeSequence();
  6147. if (!TestError(ErrorStatus))
  6148. {
  6149. Error("Resume Sequence command Failed");
  6150. }
  6151. else
  6152. {
  6153. Info("Resume Sequence command OK");
  6154. }
  6155. }
  6156. catch (...)
  6157. {
  6158. Error("Start acq crash!");
  6159. m_eStatus = DetStatus_Standby;
  6160. }
  6161. }
  6162. break;
  6163. case EVT_DETECTOR_INIT: //! Sent when detector init has been performed
  6164. if (ProcessEventError("EVT_DETECTOR_INIT", eventData->error, nDetectorID))
  6165. {
  6166. char** path = static_cast<char**>(eventData->data);
  6167. Info("SUCCESSFULLY CONNECTED TO {$}", *path);
  6168. m_pStPanelStatus[nDetectorID]->strModuleIP = *path; //收到init回调,记录下IP,用于固件升级
  6169. m_pStPanelStatus[nDetectorID]->bInitOK = true;
  6170. //m_nInitFPDCount++;
  6171. m_pStPanelStatus[nDetectorID]->bConnectStatus = true; //收到init回调且没有错误,置为true
  6172. ErrorFeedback(EVT_ERR_COMMUNICATE, "false", nDetectorID);
  6173. }
  6174. else
  6175. {
  6176. m_pStPanelStatus[nDetectorID]->bConnectStatus = false;
  6177. }
  6178. SendRespond("Connect");
  6179. break;
  6180. case EVT_DETECTOR_CLOSE:
  6181. ProcessEventError("EVT_DETECTOR_CLOSE", eventData->error, nDetectorID);
  6182. break;
  6183. case EVT_DETECTOR_RECONNECTED:
  6184. ProcessEventError("EVT_DETECTOR_RECONNECTED", eventData->error, nDetectorID);
  6185. ErrorFeedback(EVT_ERR_POWER_OFF, "false");
  6186. m_pStPanelStatus[nDetectorID]->bConnectStatus = true;
  6187. break;
  6188. case EVT_TRANSMIT_PROGRESS: //! Indicates the image transmission progress
  6189. {
  6190. unsigned short progress = *(static_cast<unsigned short*>(eventData->data));
  6191. Info("EVT_TRANSMIT_PROGRESS -{$}", progress);
  6192. }
  6193. break;
  6194. case EVT_START_SCAN_DETECTORS:
  6195. ProcessEventError("EVT_START_SCAN_DETECTORS", eventData->error, nDetectorID);
  6196. break;
  6197. case EVT_END_SCAN_DETECTORS:
  6198. ProcessEventError("EVT_END_SCAN_DETECTORS", eventData->error, nDetectorID);
  6199. break;
  6200. case EVT_SEQUENCE_FAILURE:
  6201. ProcessEventError("EVT_SEQUENCE_FAILURE", eventData->error, nDetectorID);
  6202. break;
  6203. case EVT_DETECTOR_SSID_SWITCHED: //! Sent when detector connection SSID has been switched
  6204. ProcessEventError("EVT_DETECTOR_SSID_SWITCHED", eventData->error, nDetectorID);
  6205. break;
  6206. case EVT_DETECTOR_LOW_BATTERY:
  6207. ProcessEventError("EVT_DETECTOR_LOW_BATTERY", eventData->error, nDetectorID);
  6208. break;
  6209. case EVT_DETECTOR_BUTTON: //! Sent when detector button is pushed or released
  6210. ProcessEventError("EVT_DETECTOR_BUTTON", eventData->error, nDetectorID);
  6211. break;
  6212. case EVT_DETECTOR_IR_ID: //! Sent when detector infrared id is changed
  6213. ProcessEventError("EVT_DETECTOR_IR_ID", eventData->error, nDetectorID);
  6214. break;
  6215. case EVT_MODULE_POLLING_CHANGED: //! Sent when module polling activation status has changed
  6216. if (ProcessEventError("EVT_MODULE_POLLING_CHANGED", eventData->error, nDetectorID))
  6217. {
  6218. bool* enable = static_cast<bool*>(eventData->data);
  6219. if (*enable)
  6220. {
  6221. Info("Module polling is enabled");
  6222. }
  6223. else
  6224. {
  6225. Info("Module polling is disabled");
  6226. }
  6227. }
  6228. UnlockPixrad("EVT_MODULE_POLLING_CHANGED");
  6229. break;
  6230. case EVT_MODULE_PRESENCE_CHANGED: //! Sent when module presence status has changed
  6231. if (ProcessEventError("EVT_MODULE_PRESENCE_CHANGED", eventData->error, nDetectorID))
  6232. {
  6233. bool* present = static_cast<bool*>(eventData->data);
  6234. if (*present)
  6235. {
  6236. m_bModulePresent = true;
  6237. Info("Moudle({$}) is present", eventData->module);
  6238. if (m_bAttaching)
  6239. {
  6240. Warn("FPD is Attaching, return");
  6241. return;
  6242. }
  6243. ErrorFeedback(EVT_ERR_MAX_NUMBER, "false");
  6244. if (APP_STATUS_DETSHARE_BEGIN == m_eAppStatus) //需要考虑增加界面
  6245. {
  6246. if (!m_bModuleConnecting) //探测器没有在连接过程中,可以执行attach
  6247. {
  6248. Info("Start IR infrared Module");
  6249. }
  6250. else
  6251. {
  6252. Info("In Detector Sharing Process");
  6253. }
  6254. }
  6255. else //如果不在检查中,不响应
  6256. {
  6257. Warn("Not in Detector Share Window");
  6258. }
  6259. }
  6260. else
  6261. {
  6262. m_bModulePresent = false;
  6263. Info("Module({$}) is now missing", eventData->module);
  6264. }
  6265. }
  6266. break;
  6267. case EVT_MODULE_INFORMATION: //! Sent when module info is available
  6268. if (ProcessEventError("EVT_MODULE_INFORMATION", eventData->error, nDetectorID))
  6269. {
  6270. ModuleInformation* moduleInfo = static_cast<ModuleInformation*>(eventData->data);
  6271. switch (moduleInfo->infoType)
  6272. {
  6273. case DETECTOR_SERIAL_NUMBER:
  6274. m_strModuleSN = moduleInfo->info;
  6275. Info("detector serial number:{$}", m_strModuleSN.c_str());
  6276. //ConfFeedback(EVT_CONF_MODULE_SN, m_nCurrentPanelID/*nDetectorID*/, m_strModuleSN.c_str());
  6277. break;
  6278. case DETECTOR_IP:
  6279. m_strModuleIP = moduleInfo->info;
  6280. Info("Detector IP Address:{$}", m_strModuleIP.c_str());
  6281. //ConfFeedback(EVT_CONF_MODULE_IP, m_nCurrentPanelID, m_strModuleIP.c_str()); //把配置文件中的反馈上去
  6282. break;
  6283. case DETECTOR_TYPE:
  6284. {
  6285. string strModuleType = moduleInfo->info;
  6286. if (strModuleType.find("3543DR") != string::npos) //3543DRcs
  6287. {
  6288. m_strModuleType = "PIXIUM3543DR";
  6289. }
  6290. else if (strModuleType.find("3543EZ") != string::npos)
  6291. {
  6292. m_strModuleType = "PIXIUM3543EZh";
  6293. }
  6294. else if (strModuleType.find("2430EZ") != string::npos)
  6295. {
  6296. m_strModuleType = "PIXIUM2430EZ";
  6297. }
  6298. Info("Detector {$} Type:{$}", nDetectorID, strModuleType.c_str());
  6299. /*ConfFeedback(EVT_CONF_MODULE_TYPE, m_nCurrentPanelID, m_strModuleType.c_str());*/
  6300. }
  6301. break;
  6302. case DETECTOR_SSID:
  6303. m_strModuleSSID = moduleInfo->info;
  6304. Info("Detector SSID Name:{$}", m_strModuleSSID.c_str());
  6305. break;
  6306. case DETECTOR_HOST_IP:
  6307. {
  6308. string strModuleHostIP = moduleInfo->info;
  6309. Info("Detector Host IP Address:{$}", strModuleHostIP.c_str());
  6310. }
  6311. break;
  6312. default:
  6313. break;
  6314. }
  6315. }
  6316. UnlockPixrad("EVT_MODULE_INFORMATION");
  6317. break;
  6318. case EVT_MODULE_IR_ID: //! Sent to inform of current infrared id (after set/get)
  6319. ProcessEventError("EVT_MODULE_IR_ID", eventData->error, nDetectorID);
  6320. break;
  6321. case EVT_MODULE_IP_CONFIG_CHANGED: //! Sent when module has changed ip configuration
  6322. if (ProcessEventError("EVT_MODULE_IP_CONFIG_CHANGED", eventData->error, nDetectorID))
  6323. {
  6324. ModuleIpConfig* moduleIpConfig = static_cast<ModuleIpConfig*>(eventData->data);
  6325. Info("Module {$} IP configuration changed to : detector={$} host={$}", eventData->module, moduleIpConfig->detectorIp, moduleIpConfig->hostIp);
  6326. }
  6327. UnlockPixrad("EVT_MODULE_IP_CONFIG_CHANGED");
  6328. break;
  6329. case EVT_MODULE_SSID_SWITCHED: //! Sent when module has switched ssid
  6330. if (ProcessEventError("EVT_MODULE_SSID_SWITCHED", eventData->error, nDetectorID))
  6331. {
  6332. char** ssid = static_cast<char**>(eventData->data);
  6333. Info("Module {$} switched SSID to: {$}", eventData->module, *ssid);
  6334. }
  6335. UnlockPixrad("EVT_MODULE_SSID_SWITCHED");
  6336. break;
  6337. case EVT_IMAGE_METADATA_CHANGED: //! Indicates image metadata has been changed
  6338. ProcessEventError("EVT_IMAGE_METADATA_CHANGED", eventData->error, nDetectorID);
  6339. break;
  6340. case EVT_START_REMOTE_STORAGE_SESSION: //! Indicates the remote storage session begins
  6341. if (ProcessEventError("EVT_START_REMOTE_STORAGE_SESSION", eventData->error, nDetectorID))
  6342. {
  6343. m_nSessionID = *static_cast<unsigned int*>(eventData->data);
  6344. Info("Remote storage session open with id {$}", m_nSessionID);
  6345. }
  6346. UnlockPixrad("EVT_START_REMOTE_STORAGE_SESSION");
  6347. break;
  6348. case EVT_END_REMOTE_STORAGE_SESSION:
  6349. if (!ProcessEventError("EVT_END_REMOTE_STORAGE_SESSION", eventData->error, nDetectorID))
  6350. {
  6351. UnlockPixrad("EVT_END_REMOTE_STORAGE_SESSION"); //出错的情况下,等不到后面的EVT_ACTIVE_STATE解锁了,所以这里自己解锁一下
  6352. }
  6353. break;
  6354. case EVT_START_STOREDIMAGE_LIST: //! Sent when get stored image list begins
  6355. ProcessEventError("EVT_START_STOREDIMAGE_LIST", eventData->error, nDetectorID);
  6356. break;
  6357. case EVT_END_STOREDIMAGE_LIST:
  6358. ProcessEventError("EVT_END_STOREDIMAGE_LIST", eventData->error, nDetectorID);
  6359. if (TestError(eventData->error))
  6360. {
  6361. ImageInfosList* pData = static_cast<ImageInfosList*>(eventData->data);
  6362. for (int i = 0; i < pData->nbImages; ++i)
  6363. {
  6364. ImageInfos imageInfos = pData->imageInfos[i];
  6365. //m_StoredImageList.push_back( imageInfos );
  6366. if (imageInfos.imgParam.metadata != NULL)
  6367. {
  6368. string strData = imageInfos.imgParam.metadata->data;
  6369. int nSize = imageInfos.imgParam.metadata->dataSize;
  6370. Info("{$} | {$}", strData, nSize);
  6371. if (strData == "") //图像头为空的不处理
  6372. {
  6373. Error("Illegal Image Header!");
  6374. continue;
  6375. }
  6376. string strBarcode = RecognizeBarcode(strData, nSize);
  6377. m_StoredImageMetaDataList.push_back(strBarcode);
  6378. Info("Index: {$}; Barcode: {$}", i, strBarcode);
  6379. if (m_vecStorageList.size() == 0)
  6380. {
  6381. Info("New first Patient ID");
  6382. m_vecStorageList.push_back(strBarcode);
  6383. }
  6384. else
  6385. {
  6386. bool bSamePatientID = false;
  6387. for (int j = 0; j < m_vecStorageList.size(); j++)
  6388. {
  6389. /*if (m_vecStorageList[i].Find(strBarcode) >= 0)*/
  6390. if (m_vecStorageList[j] == strBarcode)//修改比对cstring的方式,原方式记录形如“abcd”的条形码后会漏掉“abc”条形码
  6391. {
  6392. bSamePatientID = true;
  6393. break;
  6394. }
  6395. }
  6396. if (!bSamePatientID)
  6397. {
  6398. Info("New Patient ID");
  6399. m_vecStorageList.push_back(strBarcode);
  6400. }
  6401. }
  6402. } //end if
  6403. }
  6404. }
  6405. else
  6406. {
  6407. Error("Get StoredImageList Error");
  6408. }
  6409. UnlockPixrad("EVT_END_STOREDIMAGE_LIST");
  6410. break;
  6411. case EVT_START_STOREDIMAGE: //! Sent when get stored image begins
  6412. ProcessEventError("EVT_START_STOREDIMAGE", eventData->error, nDetectorID);
  6413. break;
  6414. case EVT_END_STOREDIMAGE:
  6415. ProcessEventError("EVT_END_STOREDIMAGE", eventData->error, nDetectorID);
  6416. SendRespond("GetStoredImage");
  6417. break;
  6418. case EVT_STOREDIMAGE_REMOVED: //! Indicates the stored image has been removed
  6419. ProcessEventError("EVT_STOREDIMAGE_REMOVED", eventData->error, nDetectorID);
  6420. SendRespond("RemoveStoredImage");
  6421. break;
  6422. case EVT_START_SYNCHRO_REFERENCES: //! Sent when the references synchronization begins
  6423. ProcessEventError("EVT_START_SYNCHRO_REFERENCES", eventData->error, nDetectorID);
  6424. break;
  6425. case EVT_END_SYNCHRO_REFERENCES:
  6426. ProcessEventError("EVT_END_SYNCHRO_REFERENCES", eventData->error, nDetectorID);
  6427. break;
  6428. case EVT_SYNCHRO_REFERENCES_PROGRESS: //! Indicates the references sycnhronization progress
  6429. ProcessEventError("EVT_SYNCHRO_REFERENCES_PROGRESS", eventData->error, nDetectorID);
  6430. break;
  6431. case EVT_START_CLEAR_SYNCHRO_REFERENCES: //! Sent when the references removal begins
  6432. ProcessEventError("EVT_START_CLEAR_SYNCHRO_REFERENCES", eventData->error, nDetectorID);
  6433. break;
  6434. case EVT_END_CLEAR_SYNCHRO_REFERENCES:
  6435. ProcessEventError("EVT_END_CLEAR_SYNCHRO_REFERENCES", eventData->error, nDetectorID);
  6436. break;
  6437. case EVT_CLEAR_SYNCHRO_REFERENCES_PROGRESS: //! Indicates the references removal progress
  6438. ProcessEventError("EVT_CLEAR_SYNCHRO_REFERENCES_PROGRESS", eventData->error, nDetectorID);
  6439. break;
  6440. case EVT_DETECTOR_PARAMETER_VALUE: //! Sent when a detector parameter value has been set/get
  6441. ProcessEventError("EVT_DETECTOR_PARAMETER_VALUE", eventData->error, nDetectorID);
  6442. break;
  6443. case EVT_STATUS_POLLING_CHANGED: //! Sent when detector status polling activation status has changed
  6444. {
  6445. if (TestError(eventData->error))
  6446. {
  6447. bool enable = *static_cast<bool*>(eventData->data);
  6448. string strEnable = "DISABLE";
  6449. if (enable)
  6450. {
  6451. strEnable = "ENABLE";
  6452. }
  6453. Info("EVT_STATUS_POLLING_CHANGED {$}", strEnable);
  6454. }
  6455. else
  6456. {
  6457. Info("EVT_STATUS_POLLING_CHANGED ERROR");
  6458. }
  6459. }
  6460. break;
  6461. case EVT_DETECTOR_INFORMATION: //! Sent when a detector information has been set/get
  6462. if (ProcessEventError("EVT_DETECTOR_INFORMATION", eventData->error, nDetectorID))
  6463. {
  6464. DetectorInformationValue* pstInformationValue = static_cast<DetectorInformationValue*>(eventData->data);
  6465. switch (pstInformationValue->type)
  6466. {
  6467. case DI_SHOCK_SENSOR:
  6468. {
  6469. Info("SHOCK SENSOR INFORMATION : ");
  6470. if (pstInformationValue->data != 0)
  6471. {
  6472. ShockEvents* stShock = static_cast<ShockEvents*>(pstInformationValue->data);
  6473. time_t lDate = (time_t)stShock->resetDate;
  6474. struct tm stLocalTime;
  6475. char szTemp[100] = { 0 };
  6476. stLocalTime = *localtime(&lDate);
  6477. strftime(szTemp, sizeof(szTemp), "%Y-%m-%d %H:%M:%S", &stLocalTime);
  6478. Info("Reset Date:{$}", szTemp);
  6479. int nShockNumbers = stShock->nbEvents;
  6480. Info("Shock Event Numbers:{$}", nShockNumbers);
  6481. if (stShock->nbEvents == 0)
  6482. {
  6483. SimulateShockSensor(nDetectorID);
  6484. break;
  6485. }
  6486. string strShockList = "{";
  6487. for (int nEvent = 0; nEvent < stShock->nbEvents; ++nEvent)
  6488. {
  6489. string strLevels = "";
  6490. int nLastLevel = 0;
  6491. for (int nLevel = 0; nLevel < stShock->events[nEvent].nbLevels; ++nLevel)
  6492. {
  6493. for (int k = 0; k < stShock->events[nEvent].levels[nLevel].nbGroups; ++k)
  6494. {
  6495. if (stShock->events[nEvent].levels[nLevel].groups[k].triggered)
  6496. {
  6497. nLastLevel = nLevel + 1;
  6498. Info("Event Level:{$},Groups:{$} is Trigged", nLastLevel, k);
  6499. //Event:0,Date:1481060292,Levels:1=xx
  6500. }
  6501. }
  6502. }
  6503. time_t lDate = (time_t)stShock->events[nEvent].date;
  6504. struct tm stLocalTime;
  6505. char szTemp[100] = { 0 };
  6506. stLocalTime = *localtime(&lDate);
  6507. strftime(szTemp, sizeof(szTemp), "%Y-%m-%d %H:%M:%S", &stLocalTime);
  6508. Info("Event:{$},Date:{$},Levels:{$}", nEvent, szTemp, nLastLevel);
  6509. //Event:0,Date:1481060292,Levels:1=xx
  6510. auto strInfo = to_string(nEvent);
  6511. auto strLevel = to_string(nLastLevel);
  6512. std::ostringstream ostrShockData;
  6513. ostrShockData << R"("Shock)" << strInfo
  6514. << R"(":{"SN":")" << m_pStPanelStatus[nDetectorID]->strPanelSN
  6515. << R"(","Time":")" << szTemp
  6516. << R"(","Level":")" << strLevel << R"("},)";
  6517. //e.g. "Shock1":{"SN":"%s","Time":"%s","Level":"%s"},"
  6518. Info("{$}", ostrShockData.str().c_str());
  6519. strShockList += ostrShockData.str();
  6520. }
  6521. strShockList = strShockList.substr(0, strShockList.length() - 1); //最后一个不加逗号
  6522. strShockList += "}";
  6523. InfoFeedback(EVT_INFO_SHOCKSENSOR_INFO, nDetectorID, 0, 0, strShockList.c_str());
  6524. Info("{$}", strShockList.c_str());
  6525. StatusFeedback(EVT_STATUS_SHOCK_SENSOR, nShockNumbers, "", nDetectorID);
  6526. }
  6527. }
  6528. break;
  6529. default:
  6530. break;
  6531. }
  6532. }
  6533. UnlockPixrad("EVT_DETECTOR_INFORMATION");
  6534. break;
  6535. case EVT_DETECTOR_LOW_BATTERY_FOR_IMAGE: //! Sent when detector battery level is too low for acquiring an image
  6536. ProcessEventError("EVT_DETECTOR_LOW_BATTERY_FOR_IMAGE", eventData->error, nDetectorID);
  6537. m_bPreviewImg = false; //电量低,采集结束,恢复初值
  6538. //(*m_pPanelID2DPC)[m_nCurrentPanelID]->AddErrMsg(4);
  6539. if (m_eStatus == DetStatus_Acquire) //如果回调早于stopacquisition接口调用,则置为DETECTOR_STATUS_STANDBY
  6540. {
  6541. //(*m_pPanelID2DPC)[m_nCurrentPanelID]->SetDetectorStatus(DETECTOR_STATUS_STANDBY); //电量低,SDK采集流程结束,设置状态
  6542. m_eStatus = DetStatus_Standby; //电量低,停止采集,置回Standby
  6543. }
  6544. break;
  6545. case EVT_APPLICATION_PARAMETERS_STATUS: //! Sent when the application mode parameters have been set
  6546. ProcessEventError("EVT_APPLICATION_PARAMETERS_STATUS", eventData->error, nDetectorID);
  6547. break;
  6548. case EVT_START_TRANSFER_STOREDIMAGES: //! Sent when the transfer of all stored images begins
  6549. ProcessEventError("EVT_START_TRANSFER_STOREDIMAGES", eventData->error, nDetectorID);
  6550. break;
  6551. case EVT_END_TRANSFER_STOREDIMAGES:
  6552. ProcessEventError("EVT_END_TRANSFER_STOREDIMAGES", eventData->error, nDetectorID);
  6553. UnlockPixrad("EVT_END_TRANSFER_STOREDIMAGES");
  6554. break;
  6555. case EVT_START_REMOVE_ALL_STOREDIMAGES:
  6556. ProcessEventError("EVT_START_REMOVE_ALL_STOREDIMAGES", eventData->error, nDetectorID);
  6557. SendRespond("RemoveAutonumousAll");
  6558. break;
  6559. case EVT_END_REMOVE_ALL_STOREDIMAGES:
  6560. ProcessEventError("EVT_END_REMOVE_ALL_STOREDIMAGES", eventData->error, nDetectorID);
  6561. break;
  6562. case EVT_APPLICATION_CONTROL_CHANGED: //! Sent when the mode has been activated
  6563. ProcessEventError("EVT_APPLICATION_CONTROL_CHANGED", eventData->error, nDetectorID);
  6564. SendRespond("AutononousOffline");
  6565. break;
  6566. case EVT_DETECTOR_CONNECTION_REFUSED:
  6567. //! Sent when the detector has refused an incoming connection request from another host
  6568. ProcessEventError("EVT_DETECTOR_CONNECTION_REFUSED", eventData->error, nDetectorID);
  6569. break;
  6570. case EVT_DETECTOR_CONNECTION_ABORTED: //! Sent when another host connects to the detector
  6571. ProcessEventError("EVT_DETECTOR_CONNECTION_ABORTED", eventData->error, nDetectorID);
  6572. break;
  6573. case EVT_DETECTOR_SCAN_STATUS: //! Sent during a status scan when a detector status is available
  6574. ProcessEventError("EVT_DETECTOR_SCAN_STATUS", eventData->error, nDetectorID);
  6575. break;
  6576. case EVT_MODULE_NETWORK_CONFIG_CHANGED: //! Sent when module has changed network configuration (SSID + IPs)
  6577. if (ProcessEventError("EVT_MODULE_NETWORK_CONFIG_CHANGED", eventData->error, nDetectorID))
  6578. {
  6579. ModuleNetworkConfig* moduleNetConfig = static_cast<ModuleNetworkConfig*>(eventData->data);
  6580. Info("Module {$} network configuration changed to : ssid={$} detector={$} host={$}", eventData->module, moduleNetConfig->ssid, moduleNetConfig->ipConfig.detectorIp, moduleNetConfig->ipConfig.hostIp);
  6581. }
  6582. UnlockPixrad("EVT_MODULE_NETWORK_CONFIG_CHANGED");
  6583. break;
  6584. case EVT_START_DETECTOR_CONFIG: //! Sent when a new detector config begins
  6585. ProcessEventError("EVT_START_DETECTOR_CONFIG", eventData->error, nDetectorID);
  6586. break;
  6587. case EVT_END_DETECTOR_CONFIG:
  6588. ProcessEventError("EVT_END_DETECTOR_CONFIG", eventData->error, nDetectorID);
  6589. break;
  6590. case EVT_DETECTOR_LICENSE_SESSION_ID: //! Sent when detector license id has been requested
  6591. ProcessEventError("EVT_DETECTOR_LICENSE_SESSION_ID", eventData->error, nDetectorID);
  6592. break;
  6593. case EVT_END_DETECTOR_LICENSE_SESSION_REQUEST: //! Sent when an attempt to modify locking counter has been done
  6594. ProcessEventError("EVT_END_DETECTOR_LICENSE_SESSION_REQUEST", eventData->error, nDetectorID);
  6595. break;
  6596. case EVT_LICENSE_LOCKING_COUNTER_ABOUT_TO_EXPIRE:
  6597. //! sent when detector locking counter is about to expire
  6598. //(according to the parameterized threshold)
  6599. ProcessEventError("EVT_LICENSE_LOCKING_COUNTER_ABOUT_TO_EXPIRE", eventData->error, nDetectorID);
  6600. break;
  6601. case EVT_LICENSE_LOCKING_COUNTER_EXPIRED:
  6602. //! sent when detector locking counter has expired,
  6603. //detector is then locked and image acquisition features are disabled, unless unlock again
  6604. ProcessEventError("EVT_LICENSE_LOCKING_COUNTER_EXPIRED", eventData->error, nDetectorID);
  6605. break;
  6606. case EVT_ACQUISITION_SYNCHRO:
  6607. //! sent when digital tomography acquisition has been launched,
  6608. //to notify user of the synchronization status
  6609. {
  6610. AcquisitionSynchronization* acqSync = static_cast<AcquisitionSynchronization*>(eventData->data);
  6611. float fDelta = acqSync->delta_us; //computed delta duration in microseconds to use for pixrad timing synchronization with detector acquisition sequence
  6612. float fStdDev = acqSync->stdDev_us; //standard deviation of delta value, used to check the steadiness of the synchronization
  6613. float fDelta_med = acqSync->delta_med_us; //median of delta values
  6614. Info("EVT_ACQUISITION_SYNCHRO delta: %fms, standard: %fus, median: %fms", fDelta / 1000, fStdDev, fDelta_med / 1000);
  6615. }
  6616. break;
  6617. case EVT_ACQUISITION_TIME:
  6618. //! sent when digital tomography acquisition has been launched,
  6619. //to notify user of the core acquisition start time at host and detector level
  6620. {
  6621. AcquisitionTime* stAcqTime = static_cast<AcquisitionTime*>(eventData->data);
  6622. long long startDate = stAcqTime->detectorStartDate_us; //system date at which the detector started the acquisition
  6623. long long preambleTime = stAcqTime->detectorPreambleTime_us; //preamble time given by the detector
  6624. Info("EVT_ACQUISITION_TIME %lldus, %lldus", startDate, preambleTime);
  6625. }
  6626. break;
  6627. default:
  6628. break;
  6629. }
  6630. }
  6631. //设置保存过程图接口
  6632. bool TrixellCtrl::SetSaveRawDataMode(int nSaveRawDataMode)
  6633. {
  6634. Info(__FUNCTION__);
  6635. m_nSaveRaw = nSaveRawDataMode;
  6636. Info("Save Raw Mode: ({$})", m_nSaveRaw);
  6637. return true;
  6638. }
  6639. //离线采集断连设置离线模式接口
  6640. bool TrixellCtrl::OfflineFPD(int nDetectorID)
  6641. {
  6642. Info(__FUNCTION__);
  6643. m_nAutonumousID = nDetectorID;
  6644. int nIndex = nDetectorID;
  6645. if (m_pStPanelStatus[nIndex]->bHaveAutonumousMode == false)
  6646. {
  6647. Info("Current detector can not support antonumous mode");
  6648. return true;
  6649. }
  6650. Info("Current detector support antonumous mode");
  6651. if (m_pStPanelStatus[nIndex]->bAutonumousMode == true)
  6652. {
  6653. Info("Current detector already in offline mode");
  6654. StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_DISCONNECT_SUCCESS, "", nDetectorID);
  6655. return true;
  6656. }
  6657. Info("Current detector set to offline mode");
  6658. StartOfflineAutonumousThread();
  6659. return true;
  6660. }
  6661. //离线采集:设置到offline线程
  6662. bool TrixellCtrl::StartOfflineAutonumousThread()
  6663. {
  6664. HANDLE hAutonumousThread;
  6665. unsigned int unThreadID;
  6666. Info("Start Offline Autonumous Thread ");
  6667. hAutonumousThread = (HANDLE)_beginthreadex(NULL, 0, onOfflineAutonumousMode, (LPVOID)this, 0, &unThreadID);
  6668. if (hAutonumousThread == NULL)
  6669. {
  6670. Error("Start Autonumous Thread Error");
  6671. return false;
  6672. }
  6673. return true;
  6674. }
  6675. unsigned TrixellCtrl::onOfflineAutonumousMode(void* pParam)
  6676. {
  6677. TrixellCtrl* pInstance = (TrixellCtrl*)pParam;
  6678. Info("Offline Autonumous Mode");
  6679. if (!pInstance->OfflineAutonumousMode())
  6680. {
  6681. pInstance->StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_DISCONNECT_ERROR, "", pInstance->m_nAutonumousID);
  6682. }
  6683. else
  6684. {
  6685. pInstance->StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_DISCONNECT_SUCCESS, "", pInstance->m_nAutonumousID);
  6686. pInstance->m_pStPanelStatus[pInstance->m_nAutonumousID]->bAutonumousMode = true;
  6687. }
  6688. return 0;
  6689. }
  6690. bool TrixellCtrl::OfflineAutonumousMode()
  6691. {
  6692. // 1. 先切换到选中的探测器上
  6693. if (m_nDetectorID != m_nAutonumousID)
  6694. {
  6695. if (!SetActiveDetector(m_nAutonumousID))
  6696. {
  6697. Error("Change Detector Failed");
  6698. return false;
  6699. }
  6700. }
  6701. // 2. AED必须在QUIET状态
  6702. if (!SetSystemState(STATE_QUIET))
  6703. {
  6704. Error("Set Quiet State Failed");
  6705. return false;
  6706. }
  6707. // 3 将此探测器设置到AED模式
  6708. SetSyncMode(m_nDetectorID, SYNC_AED);
  6709. if (!m_pStPanelStatus[m_nAutonumousID]->bDC_AED == true) //如果没有切换到AED模式,也报错
  6710. {
  6711. Error("Set AED sync mode failed");
  6712. return false;
  6713. }
  6714. //4. 设置采集参数,主要是设置采集时图像自动OFFSET
  6715. //SetApplicationParam(2);
  6716. application_mode applicationMode = APPLICATION_MODE2;
  6717. Info("applicationMode: {$}, current detector ID: {$}", (int)applicationMode, m_nAutonumousID);
  6718. ApplicationParameter pAppParam[5] = { 0 };
  6719. char szTemp[5] = { 0 };
  6720. sprintf_s(szTemp, "%d", m_nTomoImgCount);
  6721. pAppParam[0].name = "acquisition.type"; pAppParam[0].value = "x";
  6722. pAppParam[1].name = "output.type"; pAppParam[1].value = "short";
  6723. pAppParam[2].name = "output.preview"; pAppParam[2].value = "false";
  6724. if (m_bPreviewEnable)
  6725. {
  6726. pAppParam[2].name = "output.preview"; pAppParam[2].value = "true";
  6727. }
  6728. if (CT_ALL == m_pStPanelStatus[m_nCurrentPanelID]->eCorrectType[0])
  6729. {
  6730. Info("All correction enable");
  6731. pAppParam[3].name = "all.enabled"; pAppParam[3].value = "true";
  6732. }
  6733. else if (CT_OFFSET == m_pStPanelStatus[m_nCurrentPanelID]->eCorrectType[0])
  6734. {
  6735. Info("Offset correction enable");
  6736. pAppParam[3].name = "offset.enabled"; pAppParam[3].value = "true";
  6737. }
  6738. else if (CT_GAIN == m_pStPanelStatus[m_nCurrentPanelID]->eCorrectType[0])
  6739. {
  6740. Info("Gain correction enable");
  6741. pAppParam[3].name = "gain.enabled"; pAppParam[3].value = "true";
  6742. }
  6743. else if (CT_DEFECT == m_pStPanelStatus[m_nCurrentPanelID]->eCorrectType[0])
  6744. {
  6745. Info("Defect correction enable");
  6746. pAppParam[3].name = "defect.enabled"; pAppParam[3].value = "true";
  6747. }
  6748. pAppParam[4].name = "image.number"; pAppParam[4].value = szTemp;
  6749. Info("Calling SetApplicationParameters");
  6750. error_status ErrorStatus = TED_PixRad_SetApplicationParameters(applicationMode, pAppParam, 5); //EVT_APPLICATION_PARAMETERS_STATUS
  6751. if (!TestError(ErrorStatus))
  6752. {
  6753. Error("Set application parameters command Failed");
  6754. return false;
  6755. }
  6756. Info("Set application parameters command OK");
  6757. //SetImageMetaData("0000");
  6758. //5. 设置到AC_AUTONOMOUS_NORMAL 离线模式
  6759. if (!SetSystemState(STATE_QUIET))
  6760. {
  6761. Error("Set Quiet State Failed");
  6762. return false;
  6763. }
  6764. Info("Call TED_PixRad_ApplicationControl in Autononous");
  6765. ErrorStatus = TED_PixRad_ApplicationControl(applicationMode, AC_AUTONOMOUS_NORMAL, true); // EVT_APPLICATION_CONTROL_CHANGED
  6766. if (!TestError(ErrorStatus))
  6767. {
  6768. Error("Set Application Control Failed");
  6769. return false;
  6770. }
  6771. if (!WaitRespond(g_nRespondTimeout, "AutonumousOffline"))
  6772. {
  6773. Error("Autonumous Offline failed");
  6774. return false;
  6775. }
  6776. Info("Set Application Control OK");
  6777. // 6 探测器会断开与SDK的连接
  6778. //SendDetectorInfo(m_nAutonumousID - 1, false);
  6779. // 7. 切换回到当前的探测器
  6780. if (m_nDetectorID != m_nAutonumousID)
  6781. {
  6782. if (!SetActiveDetector(m_nDetectorID))
  6783. {
  6784. Error("Change to Current Detector Failed");
  6785. return false;
  6786. }
  6787. if (!SetSystemState(STATE_PATIENT))
  6788. {
  6789. Error("Set Quiet State Failed");
  6790. //SendPanelStatus(PNL_DISCONNECT, RESULT_ERROR);
  6791. return false;
  6792. }
  6793. }
  6794. return true;
  6795. }
  6796. bool TrixellCtrl::SetSyncMode(int nDetectorID, SYNC_MODE nSyncMode)
  6797. {
  6798. Info(__FUNCTION__);
  6799. int nIndex = nDetectorID;
  6800. if (m_pStPanelStatus[nIndex]->bDC_AED == true)
  6801. {
  6802. Info("Already in AutoTrigger Mode, Return");
  6803. return true;
  6804. }
  6805. if (!SetSystemState(STATE_QUIET)) //设置到QUIET状态
  6806. {
  6807. Error("Set Quiet State Failed");
  6808. return false;
  6809. }
  6810. LockPixrad("DetectorControl");
  6811. Info("Call DetectorControl at DC_AUTOTRIGGER");
  6812. error_status ErrorStatus = TED_PixRad_DetectorControl(DC_AUTOTRIGGER_NORMAL, true); //EVT_DETECTOR_CONTROL_CHANGED
  6813. if (!TestError(ErrorStatus))
  6814. {
  6815. Info("Detector control command failed");
  6816. return false;
  6817. }
  6818. Info("Detector control command OK");
  6819. LockPixrad("DetectorControl");
  6820. UnlockPixrad("DetectorControl");
  6821. if (!SetSystemState(STATE_QUIET)) //恢复到QUIET状态
  6822. {
  6823. Error("Set Quiet State Failed");
  6824. }
  6825. Info("Set AutoTrigger Mode End");
  6826. return true;
  6827. }
  6828. bool TrixellCtrl::SetSyncMode(int nDetectorID, int nSyncMode)
  6829. {
  6830. Info("Set detector({$}) sync mode: {$}", nDetectorID, nSyncMode);
  6831. if (m_nCurrentOmMode != nSyncMode)
  6832. {
  6833. if (!SetSystemState(STATE_QUIET)) //需要在QUIET状态下设置
  6834. {
  6835. Info("Set quiet state failed");
  6836. return false;
  6837. }
  6838. Info("Calling DetectorControl, reset");
  6839. error_status ErrorCode = TED_PixRad_DetectorControl(DC_AUTOTRIGGER_NORMAL, false); //EVT_DETECTOR_CONTROL_CHANGED
  6840. if (!TestError(ErrorCode))
  6841. {
  6842. return false;
  6843. }
  6844. if (!WaitRespond(g_nRespondTimeoutLong, "Control"))
  6845. {
  6846. Error("Detector control timeout");
  6847. return false;
  6848. }
  6849. if (!SetSystemState(STATE_QUIET)) //恢复到QUIET状态
  6850. {
  6851. Error("Set quiet state failed");
  6852. }
  6853. m_nCurrentAppMode = 0;
  6854. }
  6855. m_nCurrentOmMode = nSyncMode;
  6856. return true;
  6857. }
  6858. //离线采集断连设置在线模式接口
  6859. bool TrixellCtrl::OnlineFPD(int nDetectorID)
  6860. {
  6861. Info(__FUNCTION__);
  6862. m_nAutonumousID = nDetectorID;
  6863. int nIndex = nDetectorID;
  6864. if (m_pStPanelStatus[nIndex]->bHaveAutonumousMode == false)
  6865. {
  6866. Info("Current detector can not support antonumous mode");
  6867. return true;
  6868. }
  6869. Info("Current detector support antonumous mode");
  6870. if (m_pStPanelStatus[nIndex]->bAutonumousMode == false)
  6871. {
  6872. Info("Current detector already in online mode");
  6873. StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_CONNECT_OK, "", nDetectorID);
  6874. return true;
  6875. }
  6876. Info("Current detector set to online mode");
  6877. StartOnlineAutonumousThread();
  6878. return true;
  6879. }
  6880. //离线采集:设置到online线程
  6881. bool TrixellCtrl::StartOnlineAutonumousThread()
  6882. {
  6883. HANDLE hAutonumousThread;
  6884. unsigned int unThreadID;
  6885. Info("Start Offline Autonumous Thread ");
  6886. hAutonumousThread = (HANDLE)_beginthreadex(NULL, 0, onOnlineAutonumousMode, (LPVOID)this, 0, &unThreadID);
  6887. if (hAutonumousThread == NULL)
  6888. {
  6889. Error("Start Autonumous Thread Error");
  6890. return false;
  6891. }
  6892. return true;
  6893. }
  6894. unsigned TrixellCtrl::onOnlineAutonumousMode(void* pParam)
  6895. {
  6896. TrixellCtrl* pInstance = (TrixellCtrl*)pParam;
  6897. Info("Online Autonumous Mode");
  6898. if (!pInstance->OnlineAutonumousMode())
  6899. {
  6900. pInstance->StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_CONNECT_ERROR, "", pInstance->m_nAutonumousID);
  6901. }
  6902. else
  6903. {
  6904. pInstance->StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_CONNECT_OK, "", pInstance->m_nAutonumousID);
  6905. pInstance->m_pStPanelStatus[pInstance->m_nAutonumousID]->bAutonumousMode = false;
  6906. }
  6907. return 0;
  6908. }
  6909. /***
  6910. * 离线采集重连接口。
  6911. ***/
  6912. bool TrixellCtrl::OnlineAutonumousMode()
  6913. {
  6914. Info(__FUNCTION__);
  6915. int nIndex = m_nAutonumousID;
  6916. //1. 先设置到QUIET模式
  6917. if (!SetSystemState(STATE_QUIET))
  6918. {
  6919. Error("Set Quiet State Failed");
  6920. return false;
  6921. }
  6922. Info("Call TED_PixRad_Connect %d", m_nAutonumousID);
  6923. //2. 重新连接探测器
  6924. error_status ErrorStatus = TED_PixRad_Connect(m_nAutonumousID, ""); //EVT_DETECTOR_INIT
  6925. if (!TestError(ErrorStatus))
  6926. {
  6927. Error("Connect Detector Failed");
  6928. return false;
  6929. }
  6930. if (!WaitRespond(g_nConnectTimeout, "Connect")) //设置一个10秒的连接超时
  6931. {
  6932. Error("Autonumous connect detector timeout");
  6933. return false;
  6934. }
  6935. if (m_pStPanelStatus[nIndex]->bConnectStatus == false)
  6936. {
  6937. Error("Connect Detector Failed");
  6938. ErrorFeedback(EVT_ERR_COMMUNICATE, "false", 0);
  6939. return false;
  6940. }
  6941. //3. 连接成功后,初始化探测器设置
  6942. Info("Connect Detector Success");
  6943. //4. 获取wifi battery
  6944. GetHardwareStatus(m_nAutonumousID);
  6945. //把探测器信息先发上去
  6946. //6.切换到正常拍片的同步模式
  6947. if (SYNC_AED == m_stDeviceIndex[m_nCurrentPanelID].nSyncMode)
  6948. {
  6949. SetSyncMode(m_nDetectorID, SYNC_AED);
  6950. }
  6951. else
  6952. {
  6953. SetFpdExamMode("", PIX_OM_AED, g_nAEDmode, false);
  6954. }
  6955. //7.刷新AED模式下的Offset
  6956. if (!m_pStPanelStatus[nIndex]->bAEDDarkCalibDone) //如果没有采集到dark calbration
  6957. {
  6958. Warn("Get dark calibration files failed");
  6959. }
  6960. else
  6961. {
  6962. Info("Refresh dark calibration files success");
  6963. }
  6964. //8. 加载矫正文件
  6965. /*application_mode applicationMode = APPLICATION_MODE2;
  6966. operating_mode operatingMode = OM_RAD_AUTOTRIGGER;
  6967. unsigned short detectorMode = defaultDetectorMode;
  6968. unsigned short gainReferenceId = defaultReferenceId;
  6969. unsigned short dmReferenceId = defaultReferenceId;
  6970. bool bResult = LoadReferenceEx(applicationMode, operatingMode, detectorMode, gainReferenceId, dmReferenceId);
  6971. if (!bResult)
  6972. {
  6973. Error("Load All Autonumous Reference File Failed");
  6974. }
  6975. else
  6976. {
  6977. Info("Load All Autonumous Reference File OK");
  6978. }*/
  6979. //9. 设置到PATIENT模式
  6980. if (!SetSystemState(STATE_PATIENT))
  6981. {
  6982. Error("Set Quiet State Failed");
  6983. }
  6984. return true;
  6985. }
  6986. /***
  6987. * 离线采集接口:获取采集的病人列表
  6988. ***/
  6989. bool TrixellCtrl::GetAutonumousImageList(int nDetectorID, vector<string>& AutonumousList)
  6990. {
  6991. Info("Get FPD({$}) Patient List", nDetectorID);
  6992. // 探测器不支持离线采集则直接返回
  6993. int nIndex = nDetectorID;
  6994. if (m_pStPanelStatus[nIndex]->bHaveAutonumousMode == false)
  6995. {
  6996. Info("Current detector can not support antonumous mode");
  6997. return true;
  6998. }
  6999. //1. 先切换到当前探测器
  7000. m_nAutonumousID = nDetectorID;
  7001. //2. 获取当前探测器中的列表
  7002. LockPixrad("GetStoredImageList");
  7003. m_vecStorageList.clear();
  7004. m_StoredImageMetaDataList.clear();
  7005. Info("Call TED_PixRad_GetStoredImageList");
  7006. error_status ErrorStatus = TED_PixRad_GetStoredImageList(); //EVT_END_STOREDIMAGE_LIST
  7007. if (!TestError(ErrorStatus))
  7008. {
  7009. Error("Get StoredImage List failed");
  7010. }
  7011. Info("Get StoredImage List command OK");
  7012. LockPixrad("GetStoredImageList"); //等待返回结果
  7013. UnlockPixrad("GetStoredImageList");
  7014. Info("Get Image List Over");
  7015. AutonumousList = m_vecStorageList;
  7016. return true;
  7017. }
  7018. string TrixellCtrl::RecognizeBarcode(string strData, int nLen)
  7019. {
  7020. if (strData == "") //图像头为空的不处理
  7021. {
  7022. Error("Illegal Image Header!");
  7023. return "";
  7024. }
  7025. size_t nDataMinPos = 0;
  7026. for (size_t i = 0; i < strData.length(); i++) //去掉条形码字符串两边的乱码
  7027. {
  7028. if ((strData[i] >= '!') && (strData[i] <= '~'))
  7029. {
  7030. nDataMinPos = i;
  7031. break;
  7032. }
  7033. }
  7034. string strBarcode = strData.substr(nDataMinPos, nLen);
  7035. Info("{$}", strBarcode);
  7036. return strBarcode;
  7037. }
  7038. /***
  7039. * 离线采集接口:删除采集的病人列表
  7040. ***/
  7041. bool TrixellCtrl::RemoveAutonumousImageList(string strMeta)
  7042. {
  7043. Info(__FUNCTION__);
  7044. size_t nImageNumber = m_vecStorageList.size();
  7045. int i = 0;
  7046. bool bFindImage = false;
  7047. while (i < nImageNumber)
  7048. {
  7049. if (m_vecStorageList[i] == "")
  7050. {
  7051. }
  7052. else
  7053. {
  7054. //CString strImageData = m_StoredImageList[i].imgParam.metadata->data; // , strMetaData, strMetaData.GetLength()) == 0)
  7055. string strImageData = m_vecStorageList[i];
  7056. if (strImageData == strMeta) //注意字串和主串,查找形如“abc”的条形码后会删掉“abcd”条形码的图像
  7057. {
  7058. bFindImage = true;
  7059. Info("Find Image with MetaData: {$}", strImageData);
  7060. Info("Call TED_PixRad_RemoveStoredImage");
  7061. error_status ErrorStatus = TED_PixRad_RemoveStoredImage(i);
  7062. if (TestError(ErrorStatus))
  7063. {
  7064. Info("Remove StoredImage command OK");
  7065. }
  7066. if (!WaitRespond(g_nRespondTimeout, "RemoveStoredImage"))
  7067. {
  7068. Error("Remove StoredImage timeout");
  7069. return false;
  7070. }
  7071. }
  7072. }
  7073. i++;
  7074. }
  7075. Info("Remove Denoted Images Over");
  7076. return true;
  7077. }
  7078. /***
  7079. * 离线采集接口:删除采集的所有病人列表
  7080. ***/
  7081. bool TrixellCtrl::RemoveAutonumousAll()
  7082. {
  7083. Info(__FUNCTION__);
  7084. error_status ErrorStatus;
  7085. Info("Call TED_PixRad_RemoveAllStoredImages");
  7086. ErrorStatus = TED_PixRad_RemoveAllStoredImages(); //EVT_START_REMOVE_ALL_STOREDIMAGES
  7087. if (!TestError(ErrorStatus))
  7088. {
  7089. Error("Remove All StoredImage failed");
  7090. return false;
  7091. }
  7092. Info("Remove All StoredImage command OK");
  7093. if (!WaitRespond(g_nRespondTimeout, "RemoveAutonumousAll"))
  7094. {
  7095. Error("Remove All StoredImage timeout");
  7096. return false;
  7097. }
  7098. Info("Remove All StoredImage success");
  7099. return true;
  7100. }
  7101. /***
  7102. * 离线采集接口:采集的病人Image
  7103. ***/
  7104. bool TrixellCtrl::GetImageMetaData(string strMetaData)
  7105. {
  7106. m_bWorkMode = true;
  7107. m_strGetMetaData = strMetaData;
  7108. Info("Get Meta Images: {$}", strMetaData);
  7109. HANDLE hGetStoredImageThread = nullptr;
  7110. DWORD dwThreadID = 0;
  7111. Info("Start Get Stored Image Thread ");
  7112. hGetStoredImageThread = CreateThread(NULL, 0, onGetStoredImageThread, this, 0, &dwThreadID);
  7113. if (hGetStoredImageThread == NULL)
  7114. {
  7115. Error("Get Stored Image Thread Error");
  7116. }
  7117. return true;
  7118. }
  7119. DWORD __stdcall TrixellCtrl::onGetStoredImageThread(PVOID pvoid)
  7120. {
  7121. TrixellCtrl* pInstance = (TrixellCtrl*)pvoid;
  7122. Info("Begin Get Stored Image Thread");
  7123. pInstance->GetStoredImage(pInstance->m_strGetMetaData);
  7124. Info("End Get Stored Image Thread");
  7125. return 0;
  7126. }
  7127. /***
  7128. * 图像获取:一个strMetaData可以对应多个图
  7129. ***/
  7130. bool TrixellCtrl::GetStoredImage(string strMetaData)
  7131. {
  7132. //设置为工作模式
  7133. StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_START_STOREDIMAGE, "", 0);
  7134. if (!SetSystemState(STATE_PATIENT))
  7135. {
  7136. Error("Set Patient State Failed");
  7137. }
  7138. size_t nImageNumber = m_StoredImageMetaDataList.size();
  7139. Info("Total Stored Images is {$}", nImageNumber);
  7140. int i = 0;
  7141. bool bFindImage = false;
  7142. m_strAutonumousMetaData = "";
  7143. m_nAutonumousImageIndex = 0;
  7144. m_bAutonumousMode = true;
  7145. while (i < nImageNumber)
  7146. {
  7147. if (m_StoredImageMetaDataList[i] == "")
  7148. {
  7149. Warn("Image Meta is NULL");
  7150. }
  7151. else
  7152. {
  7153. string strImageData = m_StoredImageMetaDataList[i];
  7154. if (strImageData == strMetaData)
  7155. {
  7156. bFindImage = true;
  7157. Info("Find Image with MetaData: {$}", strImageData);
  7158. m_strAutonumousMetaData = strImageData;
  7159. m_nAutonumousImageIndex = i;
  7160. Info("Call TED_PixRad_GetStoredImage");
  7161. error_status ErrorStatus = TED_PixRad_GetStoredImage(i, false, true, DT_USHORT_TYPE);
  7162. if (TestError(ErrorStatus))
  7163. {
  7164. Info("Get Stored Image command OK");
  7165. //break;
  7166. }
  7167. else
  7168. {
  7169. Error("Get Stored Image command failed");
  7170. //UnlockPixrad();
  7171. break;
  7172. }
  7173. if (!WaitRespond(g_nRespondTimeout, "GetStoredImage")) //5秒超时
  7174. {
  7175. Error("GetStoredImage detector timeout");
  7176. }
  7177. //调用一次该接口,下面Event会收到一遍
  7178. //- EVT_START_STOREDIMAGE
  7179. //- EVT_START_TRANSMIT
  7180. //- EVT_END_TRANSMIT
  7181. //- EVT_PREVIEW
  7182. //- EVT_START_TRANSMIT
  7183. //- EVT_END_TRANSMIT
  7184. //- EVT_IMAGE_AVAILABLE
  7185. //- EVT_END_STOREDIMAGE
  7186. }
  7187. }
  7188. i++;
  7189. }
  7190. if (!bFindImage) //没有找到该图像
  7191. {
  7192. Warn("Image with MetaData:%s Missed", strMetaData);
  7193. return false;
  7194. }
  7195. m_bAutonumousMode = false;
  7196. StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_END_STOREDIMAGE, "", 0);
  7197. Info("Get mapping image over.");
  7198. return true;
  7199. }
  7200. bool TrixellCtrl::ExportAutonumousAll()
  7201. {
  7202. HANDLE hExportAutonumousThread = nullptr;
  7203. DWORD dwThreadID = 0;
  7204. Info("Start Export Image to Local Thread ");
  7205. hExportAutonumousThread = CreateThread(NULL, 0, onExportAutonumousToLocal, this, 0, &dwThreadID);
  7206. if (hExportAutonumousThread == NULL)
  7207. {
  7208. Error("Get Stored Image Thread Error");
  7209. }
  7210. return true;
  7211. }
  7212. DWORD __stdcall TrixellCtrl::onExportAutonumousToLocal(PVOID pvoid)
  7213. {
  7214. TrixellCtrl* pInstance = (TrixellCtrl*)pvoid;
  7215. Info("Begin Export Stored Image Thread");
  7216. pInstance->ExportAutonumousToLocal();
  7217. Info("End Export Stored Image Thread");
  7218. return 0;
  7219. }
  7220. bool TrixellCtrl::ExportAutonumousToLocal()
  7221. {
  7222. Info(__FUNCTION__);
  7223. //1.设置探测器到QUIET
  7224. if (!SetSystemState(STATE_QUIET))
  7225. {
  7226. Error("Set Quiet State Failed");
  7227. return false;
  7228. }
  7229. //2.导出所有到本地.fxd文件
  7230. string strExportPath = m_strWorkPath + "\\rawdata\\Autonumous\\";
  7231. Info("Export all Image into local path: {$}", strExportPath);
  7232. LockPixrad("TransferStoredImages");
  7233. Info("Call TED_PixRad_TransferStoredImages");
  7234. error_status ErrorStatus = TED_PixRad_TransferStoredImages(strExportPath.c_str(),true, true, DT_USHORT_TYPE);
  7235. if (!TestError(ErrorStatus))
  7236. {
  7237. Error("Export Stored Image command failed");
  7238. }
  7239. else
  7240. {
  7241. Info("Export Stored Image command OK");
  7242. //UnlockPixrad("TransferStoredImages");
  7243. }
  7244. LockPixrad("TransferStoredImages");
  7245. UnlockPixrad("TransferStoredImages");
  7246. //3.恢复QUIET状态
  7247. if (!SetSystemState(STATE_QUIET))
  7248. {
  7249. Error("Set Quiet State Failed");
  7250. return false;
  7251. }
  7252. //4.将所有图保存为RAW图
  7253. for (int i = 0; i < m_vecStorageList.size(); ++i)
  7254. {
  7255. GetStoredImage(m_vecStorageList[i]);
  7256. }
  7257. //5.恢复QUIET状态
  7258. if (!SetSystemState(STATE_QUIET))
  7259. {
  7260. Error("Set Quiet State Failed");
  7261. return false;
  7262. }
  7263. StatusFeedback(EVT_AUTONUMOUS_STATUS, PANEL_EXPORT_AUTONUMOUS_FINISH, "", 0);
  7264. Info("Export Autonumous over");
  7265. return true;
  7266. }
  7267. /***
  7268. * 等待函数, 等待Event成功返回true,失败返回false
  7269. ***/
  7270. bool TrixellCtrl::WaitRespond(int nTimeOut, string strAction)
  7271. {
  7272. Info("---WaitRespond({$})--- {$}", nTimeOut, strAction);
  7273. DWORD dwResult = WaitForSingleObject(m_hRespondEvent, nTimeOut);
  7274. if (dwResult == WAIT_TIMEOUT) //等待超时
  7275. {
  7276. Error("Waited TimeOut");
  7277. ResetEvent(m_hRespondEvent);
  7278. return false;
  7279. }
  7280. else if (dwResult == WAIT_OBJECT_0)
  7281. {
  7282. Info("Waited got Signal");
  7283. ResetEvent(m_hRespondEvent);
  7284. }
  7285. else
  7286. {
  7287. DWORD dwErrorCode = GetLastError();
  7288. Error("Waited Failed: {$}", dwErrorCode);
  7289. ResetEvent(m_hRespondEvent);
  7290. return false;
  7291. }
  7292. return true;
  7293. }
  7294. /***
  7295. * 解锁等待函数
  7296. ***/
  7297. bool TrixellCtrl::SendRespond(string strAction)
  7298. {
  7299. SetEvent(m_hRespondEvent);
  7300. Info("---WaitRespond End--- {$}", strAction);
  7301. return true;
  7302. }
  7303. /***
  7304. * 触发采集序列
  7305. ***/
  7306. bool TrixellCtrl::ApplicationAcquireSequence()
  7307. {
  7308. Info("ApplicationAcquireSequence start");
  7309. application_mode applicationMode = application_mode(m_nCurrentMode - 1);
  7310. string strTemp = "unknown";
  7311. if (PIX_OM_AED == m_nCurrentOmMode)
  7312. {
  7313. strTemp = "aed";
  7314. }
  7315. else if (PIX_OM_RAD == m_nCurrentOmMode)
  7316. {
  7317. strTemp = "rad";
  7318. }
  7319. else if (PIX_OM_TOMO == m_nCurrentOmMode)
  7320. {
  7321. strTemp = "tomo";
  7322. }
  7323. //LockPixrad("ApplicationAcquisition");
  7324. Info("Call ApplicationAcquisition(appmode:{$}, {$})", (int)applicationMode, strTemp.c_str());
  7325. error_status ErrorStatus = TED_PixRad_ApplicationAcquisition(applicationMode); //EVT_START_ACQUISITION
  7326. if (!TestError(ErrorStatus))
  7327. {
  7328. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_ERROR);
  7329. }
  7330. //LockPixrad("ApplicationAcquisition");
  7331. //UnlockPixrad("ApplicationAcquisition");
  7332. Info("Application acquisition over");
  7333. m_nXwinOnIndex = 0; //开始采集,置为初值
  7334. m_nTomoImgIndex = 0; //开始采集,置为初值
  7335. m_nIgnoreImgNum = 0; //开始采集,置为初值
  7336. Info("ApplicationAcquireSequence over");
  7337. return true;
  7338. }