123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Timers;
- using Aitex.Core.Common;
- using Aitex.Core.RT.DataCenter;
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.OperationCenter;
- using Aitex.Core.RT.RecipeCenter;
- using Aitex.Core.RT.Routine;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using Aitex.Sorter.Common;
- using MECF.Framework.Common.DBCore;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.Jobs;
- using MECF.Framework.Common.Schedulers;
- using MECF.Framework.Common.SubstrateTrackings;
- using MECF.Framework.RT.ModuleLibrary.PMModules;
- using MECF.Framework.RT.ModuleLibrary.SystemModules;
- using MECF.Framework.RT.ModuleLibrary.SystemModules.Routines;
- using EfemDualSchedulerLib.Schedulers;
- using MECF.Framework.Common.DataCenter;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
- using JetVirgoPM.PMs.RecipeExecutors;
- namespace EfemDualSchedulerLib
- {
- /// <summary>
- /// 自动传输
- /// </summary>
- public partial class AutoTransfer : SchedulerModuleFactory, IAutoTransfer
- {
- //const Hand Hand_Dual = Hand.Blade1;
- //const Hand Hand_Single = Hand.Blade2;
- //用于避免两爪都有wafer,放了一片就又去LoadPort Pick
- private bool EfemRobotPickAllowable = true;
- private bool _isRunningInParallelMode;
- private List<ModuleName> _mapTarget = new List<ModuleName>();
- private List<ControlJobInfo> _lstControlJobs = new List<ControlJobInfo>();
- private List<ProcessJobInfo> _lstProcessJobs = new List<ProcessJobInfo>();
- //private Object _locker = new Object();
- private List<SchedulerPM> _lstPms = new List<SchedulerPM>();
- private List<SchedulerLoadPort> _lstLps = new List<SchedulerLoadPort>();
- private List<SchedulerLoadLock> _lstLls = new List<SchedulerLoadLock>();
- private List<SchedulerBuffer> _lstBuffers = new List<SchedulerBuffer>();
- private List<SchedulerPM> _lstPmsCurrentSequence = new List<SchedulerPM>();
- private R_TRIG _trigLp1JobComplete = new R_TRIG();
- private R_TRIG _trigLp2JobComplete = new R_TRIG();
- private R_TRIG _trigLp3JobComplete = new R_TRIG();
- private Dictionary<string, float> _temperatureSetpointDic = new Dictionary<string, float>();
- private Dictionary<string, R_TRIG> _temperatureTrigDic = new Dictionary<string, R_TRIG>();
- private Dictionary<string, List<string>> currentSlotSequenceList = new Dictionary<string, List<string>>()
- {
- {"LP1",Enumerable.Repeat("",25).ToList()},
- {"LP2",Enumerable.Repeat("",25).ToList()},
- {"LP3",Enumerable.Repeat("",25).ToList()}
- };
- private const string LogSource = "Scheduler";
- public string LPHadCreateJob { get; set; }
- //private bool _isCycleMode;
- //private int _cycleSetPoint = 0;
- //private int _cycledCount = 0;
- //private int _cycledWafer = 0;
- private SchedulerFACallback _faCallback;
- private SchedulerDBCallback _dbCallback;
- //private float _throughput;
- //private DeviceTimer _throughputTimer = new DeviceTimer();
- //private int _processedWaferCountInFinishedCJ;
- class CycleData
- {
- public DateTime StartTime { get; private set; }
- public TimeSpan EscapeTime => StartTime == DateTime.MinValue ? TimeSpan.Zero : DateTime.Now.Subtract(StartTime);
- public bool IsCycleMode => SC.GetValue<bool>("System.IsCycleMode");
- public string CycleBy => SC.GetStringValue("System.CycleBy");
- public int CycleCountSetPoint => SC.GetValue<int>("System.CycleCount");// 设置的循环次数
- public int CycledCount { get; private set; } // 已处理的循环次数
- public int CycleWaferCountSetPoint => SC.GetValue<int>("System.CycleWaferCount");// 设置的晶圆片数
- public int CycledWaferCount { get; private set; } // 已处理的晶圆片数
- public void Start()
- {
- LOG.Info("Cycle: Start cycle data");
- StartTime = DateTime.Now;
- }
- public void Reset()
- {
- LOG.Info("Cycle: Reset cycle data");
- CycledWaferCount = 0;
- CycledCount = 0;
- }
- //public void BeginOrAddCycle(int setpoint)
- //{
- // if (IsCycleMode) // add
- // {
- // CycleWaferCountSetPoint += setpoint;
- // LOG.Info($"Cycle: Add {setpoint} wafers, total cycle count = {CycleWaferCountSetPoint}");
- // }
- // else // begin
- // {
- // IsCycleMode = true;
- // StartTime = DateTime.Now;
- // CycleWaferCountSetPoint = setpoint;
- // CycledWaferCount = 0;
- // LOG.Info($"Cycle: Begin {setpoint} wafers");
- // }
- //}
- public bool IsCycleEnd()
- {
- if (!IsCycleMode)
- return true;
- if (CycleBy == "WaferCount" && CycledWaferCount >= CycleWaferCountSetPoint)
- {
- SC.SetItemValue("System.IsCycleMode", false);
- Reset();
- return true;
- }
- else if (CycleBy == "LotCount" && CycledCount >= CycleCountSetPoint)
- {
- SC.SetItemValue("System.IsCycleMode", false);
- Reset();
- return true;
- }
- return false;
- }
- public void Increase(int waferCount, int count = 1)
- {
- IncreaseWaferCount(waferCount);
- IncreaseCount(count);
- }
- public void IncreaseWaferCount(int waferCount)
- {
- CycledWaferCount += waferCount;
- LOG.Info($"Cycle: finished {CycledWaferCount} wafer(s)");
- }
- public void IncreaseCount(int count = 1)
- {
- CycledCount += count;
- LOG.Info($"Cycle: finished {CycledCount} Count(s)");
- }
- }
- class ThroughputData
- {
- public bool IsCalcing { get; private set; } = false;
- public DateTime CacledLastTime { get; private set; } = DateTime.MinValue; // 创建时间或者计算时间
- public double CalcedTotalTimeSeconds { get; private set; } = 0; // 总的计算时间
- public int CalcedProcessedCount { get; private set; } = 0; // 已计算完的总数(control job)
- public double TotalTimeSeconds { get; private set; }
- public DateTime CaclingLastTime { get; private set; } = DateTime.MinValue; // 创建时间或者计算时间
- public int CalcingProcessedCount { get; private set; } = 0;// 正在计算的总数(control job)
- public int ProcessedCount => CalcedProcessedCount + CalcingProcessedCount;
- public double Throughput { get; private set; }
- public double LiveThroughput { get; private set; }
- public void BeginCalc()
- {
- if (IsCalcing) return;
- IsCalcing = true;
- CalcedTotalTimeSeconds = 0;
- CacledLastTime = DateTime.Now;
- CaclingLastTime = DateTime.Now;
- LOG.Info("Throughput: Begin");
- }
- public void Pause()
- {
- if (!IsCalcing)
- {
- IsCalcing = false;
- LOG.Info("Throughput: Pause");
- }
- }
- public void Reset()
- {
- CacledLastTime = DateTime.Now;
- CalcedTotalTimeSeconds = 0;
- CalcedProcessedCount = 0;
- CaclingLastTime = DateTime.Now;
- CalcedProcessedCount = 0;
- CalcingProcessedCount = 0;
- Throughput = 0;
- LiveThroughput = 0;
- LOG.Info("Throughput: Reset");
- }
- public void UpdateCalced(int calcedCount)
- {
- CalcedProcessedCount += calcedCount;
- CalcingProcessedCount -= calcedCount;
- if (CalcingProcessedCount < 0) CalcingProcessedCount = 0;
- CalcedTotalTimeSeconds += DateTime.Now.Subtract(CacledLastTime).TotalSeconds;
- CacledLastTime = DateTime.Now;
- }
- public void UpdateCalcing(int calcingCount)
- {
- DateTime now = DateTime.Now;
- double seconds_this = now.Subtract(CaclingLastTime).TotalSeconds;
- int calcingCount_this = calcingCount - CalcingProcessedCount;
- double count_this = ProcessedCount + calcingCount;
- LiveThroughput = 3600 / (seconds_this / calcingCount_this);
- TotalTimeSeconds = CalcedTotalTimeSeconds + seconds_this;
- Throughput = 3600 * count_this / TotalTimeSeconds;
- LOG.Info($"Throughput: {Throughput}, Finished {count_this} wafer(s) in {(int)TotalTimeSeconds} seconds;" +
- $" {LiveThroughput} last wafer in {(int)seconds_this} seconds");
- CaclingLastTime = now;
- CalcingProcessedCount = calcingCount;
- }
- }
- private CycleData _CycleData = new CycleData();
- private ThroughputData _throughputData = new ThroughputData();
- private bool _isAutoUnloadFoup
- {
- get
- {
- return SC.GetValue<bool>("EFEM.LoadPort.EnableAutoUnloadFoup");
- }
- }
- private ModuleName _TMRobotBlade1Station = ModuleName.System;
- private Dictionary<ModuleName, bool> _loadlockCooling = new Dictionary<ModuleName, bool>();
- Queue<Action> tmRobotActions = new Queue<Action>() { };
- Queue<Action> efemRobotActions = new Queue<Action>() { };
- public AutoTransfer(EquipmentManager equipment)
- {
- _faCallback = new SchedulerFACallback();
- _dbCallback = new SchedulerDBCallback();
- if (SC.GetValueOrDefault<bool>("System.SetUp.PMA.IsInstalled"))
- _lstPms.Add(_pm1);
- if (SC.GetValueOrDefault<bool>("System.SetUp.PMB.IsInstalled"))
- _lstPms.Add(_pm2);
- //if (SC.GetValueOrDefault<bool>("System.SetUp.PMC.IsInstalled"))
- // _lstPms.Add(_pm3);
- if (SC.GetValueOrDefault<bool>("System.SetUp.LLA.IsInstalled"))
- _lstLls.Add(_loadlockA);
- if (SC.GetValueOrDefault<bool>("System.SetUp.LLB.IsInstalled"))
- _lstLls.Add(_loadlockB);
- if (SC.GetValueOrDefault<bool>("System.SetUp.LP1.IsInstalled"))
- _lstLps.Add(_lp1);
- if (SC.GetValueOrDefault<bool>("System.SetUp.LP2.IsInstalled"))
- _lstLps.Add(_lp2);
- if (SC.GetValueOrDefault<bool>("System.SetUp.LP3.IsInstalled"))
- _lstLps.Add(_lp3);
- //临时办法,设备异常后进行reset,重新home后reset机械手task
- OP.Subscribe($"{ModuleName.TM}.ResetTask", (string cmd, object[] args) =>
- {
- _tmRobot.ResetTask();
- return true;
- });
- OP.Subscribe($"{ModuleName.EFEM}.ResetTask", (string cmd, object[] args) =>
- {
- _efem.ResetTask();
- return true;
- });
- DATA.Subscribe("Scheduler.IsCycleMode", () => _CycleData.IsCycleMode);
- DATA.Subscribe("Scheduler.CycleBy", () => _CycleData.CycleBy);
- DATA.Subscribe("Scheduler.CycleCountSetPoint", () => _CycleData.CycleCountSetPoint);
- DATA.Subscribe("Scheduler.CycledCount", () => _CycleData.CycledCount);
- DATA.Subscribe("Scheduler.CycleWaferCountSetPoint", () => _CycleData.CycleWaferCountSetPoint);
- DATA.Subscribe("Scheduler.CycledWaferCount", () => _CycleData.CycledWaferCount);
- DATA.Subscribe("Scheduler.CycleEscapeTime", () => _CycleData.EscapeTime);
- DATA.Subscribe("Scheduler.Throughput", () => _throughputData.Throughput);
- DATA.Subscribe("Scheduler.LiveThroughput", () => _throughputData.LiveThroughput);
- DATA.Subscribe("System.Scheduler.RunningRecipeList", () => _GetRunningRecipeList());
- DATA.Subscribe("Scheduler.CjIdList", () => _GetRunningCjIdList());
- DATA.Subscribe("LP1.LocalJobName", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP1");
- if (jb != null)
- return jb.Name;
- return "";
- });
- DATA.Subscribe($"LP1.JobLotName", () =>
- {
- var cj = _lstControlJobs.FirstOrDefault(x => x.Module == "LP1");
- if (cj != null)
- return cj.LotName;
- return "";
- });
- DATA.Subscribe("LP1.LocalJobStatus", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP1");
- if (jb != null)
- return jb.State.ToString();
- return "";
- });
- DATA.Subscribe("LP1.CurrentRecipeList", () =>
- {
- List<string> result = Enumerable.Repeat("", 25).ToList();
- for (int i = 0; i < _lstProcessJobs.Count; i++)
- {
- foreach (var wafers in _lstProcessJobs[i].SlotWafers)
- {
- if (wafers.Item1 == ModuleName.LP1)
- {
- result[wafers.Item2] = _lstProcessJobs[i].Sequence.Name;
- }
- }
- }
- return result;
- });
- DATA.Subscribe("LP2.LocalJobName", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP2");
- if (jb != null)
- return jb.Name;
- return "";
- });
- DATA.Subscribe($"LP2.JobLotName", () =>
- {
- var cj = _lstControlJobs.FirstOrDefault(x => x.Module == "LP2");
- if (cj != null)
- return cj.LotName;
- return "";
- });
- DATA.Subscribe("LP2.LocalJobStatus", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP2");
- if (jb != null)
- return jb.State.ToString();
- return "";
- });
- DATA.Subscribe("LP2.CurrentRecipeList", () =>
- {
- List<string> result = Enumerable.Repeat("", 25).ToList();
- for (int i = 0; i < _lstProcessJobs.Count; i++)
- {
- foreach (var wafers in _lstProcessJobs[i].SlotWafers)
- {
- if (wafers.Item1 == ModuleName.LP2)
- {
- result[wafers.Item2] = _lstProcessJobs[i].Sequence.Name;
- }
- }
- }
- return result;
- });
- DATA.Subscribe("LP3.LocalJobName", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP3");
- if (jb != null)
- return jb.Name;
- return "";
- });
- DATA.Subscribe($"LP3.JobLotName", () =>
- {
- var cj = _lstControlJobs.FirstOrDefault(x => x.Module == "LP3");
- if (cj != null)
- return cj.LotName;
- return "";
- });
- DATA.Subscribe("LP3.LocalJobStatus", () =>
- {
- var jb = _lstControlJobs.Find(x => x.Module == "LP3");
- if (jb != null)
- return jb.State.ToString();
- return "";
- });
- DATA.Subscribe("LP3.CurrentRecipeList", () =>
- {
- List<string> result = Enumerable.Repeat("", 25).ToList();
- for (int i = 0; i < _lstProcessJobs.Count; i++)
- {
- foreach (var wafers in _lstProcessJobs[i].SlotWafers)
- {
- if (wafers.Item1 == ModuleName.LP3)
- {
- result[wafers.Item2] = _lstProcessJobs[i].Sequence.Name;
- }
- }
- }
- return result;
- });
- tmRobotActions.Enqueue(MonitorTmRobotLoadLockPickTask);
- tmRobotActions.Enqueue(MonitorTmRobotPMAPlaceTask);
- tmRobotActions.Enqueue(MonitorTmRobotPMBPlaceTask);
- tmRobotActions.Enqueue(MonitorTmRobotPMAPickTask);
- tmRobotActions.Enqueue(MonitorTmRobotPMBPickTask);
- tmRobotActions.Enqueue(MonitorTmRobotLoadLockPlaceTask);
- tmRobotActions.Enqueue(MonitorTmRobotGoToTask);
- efemRobotActions.Enqueue(MonitorEfemRobotAlignerPickTask);
- efemRobotActions.Enqueue(MonitorEfemRobotAlignerPlaceTask);
- efemRobotActions.Enqueue(MonitorEfemRobotLoadLockPlaceTask);
- efemRobotActions.Enqueue(MonitorEfemRobotLoadLockPickTask);
- efemRobotActions.Enqueue(MonitorEfemRobotLoadPortPickTask);
- efemRobotActions.Enqueue(MonitorEfemRobotLoadPortPlaceTask);
- }
- private List<string> _GetRunningCjIdList()
- {
- return _lstControlJobs/*.Where(o => o.State == EnumControlJobState.Executing
- || o.State == EnumControlJobState.Paused)*/.Select(o => o.InnerId.ToString()).ToList();
- }
- const string StrProcessRecipe = "ProcessRecipe";
- const string StrRecipe = "Recipe";
- private List<string> _GetRunningRecipeList()
- {
- var runningCjList = _lstControlJobs.Where(o => o.State == EnumControlJobState.Executing
- || o.State == EnumControlJobState.Paused).Select(o => o.Name).ToList();
- return _lstProcessJobs.Where(o => runningCjList.Contains(o.ControlJobName))
- .SelectMany(a => a.Sequence.Steps.SelectMany(b => b.StepParameter.Where(c => c.Key == StrProcessRecipe || c.Key == StrRecipe))).Select(d => d.Value as string)
- .Where(o => !string.IsNullOrWhiteSpace(o)).ToList();
- }
- public bool HasJobRunning
- {
- get { return _lstControlJobs.Count > 0; }
- }
- public void Clear()
- {
- _tmRobot.ResetTask();
- _efem.ResetTask();
- foreach (var pm in _lstPms)
- {
- pm.ResetTask();
- }
- //foreach (var lp in _lstLps)
- //{
- // lp.ResetTask();
- //}
- _lstControlJobs.Clear();
- _lstProcessJobs.Clear();
- _temperatureSetpointDic.Clear();
- _temperatureTrigDic.Clear();
- _CycleData.Reset();
- }
- #region Job Management
- public bool CreateJob(Dictionary<string, object> param)
- {
- string reason;
- string[] slotSequence = (string[])param["SlotSequence"];
- string jobId = (string)param["JobId"];
- string module = (string)param["Module"];
- LPHadCreateJob = (string)param["Module"];
- bool autoStart = (bool)param["AutoStart"];
- string lotId = jobId;
- if (param.ContainsKey("LotId"))
- lotId = (string)param["LotId"];
- if (!ValidateSequence(slotSequence, out reason))
- {
- EV.PostWarningLog(LogSource, $"{reason}");
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (slotSequence.Length != 25)
- {
- reason = $"slot sequence parameter not valid, length is {slotSequence.Length}, should be 25";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (!ModuleHelper.IsLoadPort(ModuleHelper.Converter(module)))
- {
- reason = $"{module} should be LP";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (string.IsNullOrEmpty(jobId))
- {
- jobId = "CJ_Local_" + module;
- }
- if (_lstControlJobs.Exists(x => x.Name == jobId))
- {
- reason = $"LotID : {jobId} already created";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- SchedulerLoadPort lp = GetModule(module) as SchedulerLoadPort;
- if (!lp.CheckReadyRunJob())
- {
- reason = $"{module} not ready";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- ControlJobInfo cj = new ControlJobInfo();
- cj.Name = jobId;
- cj.Module = module;
- cj.LotName = jobId;
- cj.LotInnerId = Guid.NewGuid();
- cj.LotWafers = new List<WaferInfo>();
- cj.SetState(EnumControlJobState.WaitingForStart);
- Dictionary<string, bool[]> seqSlot = new Dictionary<string, bool[]>();
- Dictionary<string, List<Tuple<ModuleName, int>>> seqSlotWafers = new Dictionary<string, List<Tuple<ModuleName, int>>>();
- Dictionary<string, string> indexSequence = new Dictionary<string, string>();
- bool enableGroupBySequence = SC.GetValue<bool>("System.Scheduler.GroupWaferBySequence");
- string WaferAssociationInfo = $"WaferAssociationInfo({module}):";
- for (int i = 0; i < 25; i++)
- {
- WaferAssociationInfo = WaferAssociationInfo + string.Format(" slot{0} -- {1};", i + 1, slotSequence[i]);
- if (string.IsNullOrEmpty(slotSequence[i]) || string.IsNullOrEmpty(slotSequence[i].Trim()))
- continue;
- string groupName = enableGroupBySequence ? slotSequence[i].Trim() : i.ToString();
- indexSequence[groupName] = slotSequence[i];
- if (!seqSlot.ContainsKey(groupName))
- {
- seqSlot[groupName] = new bool[25];
- }
- if (!seqSlotWafers.ContainsKey(groupName))
- {
- seqSlotWafers[groupName] = new List<Tuple<ModuleName, int>>();
- }
- seqSlot[groupName][i] = true;
- if (!WaferManager.Instance.CheckHasWafer(module, i))
- {
- reason = $"job wafer: {module} slot {i + 1} not in the carrier";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (!WaferManager.Instance.CheckWafer(ModuleHelper.Converter(module), i, WaferStatus.Normal))
- {
- reason = $"job wafer: {module} slot {i + 1} status is {WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), i).Status}";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- var wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), i);
- if (wafer == null || wafer.IsEmpty)
- {
- reason = $"specifies wafer: {module} slot {i + 1} not in the carrier";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (!ModuleHelper.IsLoadPort(ModuleHelper.Converter(wafer.WaferOrigin.Split('.')[0])))
- {
- reason = $"specifies wafer: {module} slot {i + 1} not origin LP";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (wafer.ProcessState != EnumWaferProcessStatus.Idle)
- {
- reason = $"specifies wafer: {module} slot {i + 1} process state is not idle";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- seqSlotWafers[groupName].Add(Tuple.Create(ModuleHelper.Converter(module), i));
- cj.LotWafers.Add(WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), i));
- WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), i).PPID = slotSequence[i];
- }
- currentSlotSequenceList[module] = slotSequence.Reverse().ToList();
- EV.PostInfoLog(LogSource, WaferAssociationInfo);
- if (seqSlotWafers.Count == 0)
- {
- reason = $"Can not create job, no wafer assigned";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- List<ProcessJobInfo> pjs = new List<ProcessJobInfo>();
- string[] seqs = seqSlot.Keys.ToArray();
- for (int i = 0; i < seqs.Length; i++)
- {
- ProcessJobInfo pj = new ProcessJobInfo();
- pj.Name = jobId + "_" + (i + 1);
- pj.Sequence = SequenceInfoHelper.GetInfo(indexSequence[seqs[i]]);
- pj.ControlJobName = cj.Name;
- pj.LotName = lotId;
- pj.SlotWafers = seqSlotWafers[seqs[i]];
- pj.SetState(EnumProcessJobState.Queued);
- if (!CheckSequencePmReady(pj.Sequence, null, out _, out string innerReason))
- {
- reason = $"no valid chamber for the {innerReason}";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (!CheckSequenceRecipeFileValid(pj.Sequence, out reason))
- {
- reason = $"recipe file not valid in the sequence, {reason}";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (!CheckSequenceOrderOk(pj.Sequence, out reason))
- {
- reason = $"sequence path not valid, {reason}";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- if (CheckSequenceNeedDummyWafer(pj.Sequence))
- {
- reason = $"create job failed, no valid dummy wafer exist";
- EV.PostWarningLog(LogSource, reason);
- _faCallback.JobCreateFailed(module, lotId, jobId, "");
- return false;
- }
- pjs.Add(pj);
- }
- foreach (var pj in pjs)
- {
- cj.ProcessJobNameList.Add(pj.Name);
- _lstProcessJobs.Add(pj);
- }
- _lstControlJobs.Add(cj);
- int totalWafer = 0;
- foreach (var pj in pjs)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- wafer.ProcessJob = pj;
- WaferDataRecorder.SetCjInfo(wafer.InnerId.ToString(), cj.InnerId.ToString());
- WaferDataRecorder.SetWaferSequence(wafer.InnerId.ToString(), pj.Sequence.Name);
- WaferDataRecorder.SetWaferLotId(wafer.InnerId.ToString(), jobId);
- WaferManager.Instance.UpdateWaferLotId(pjSlotWafer.Item1, pjSlotWafer.Item2, jobId);
- totalWafer++;
- }
- }
- _faCallback.JobCreated(cj, GetFirstProcessJob(cj));
- if (_CycleData.IsCycleMode)
- {
- _CycleData.Start();
- }
- CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
- JobDataRecorder.StartCJ(cj.InnerId.ToString(), carrier.InnerId.ToString(), cj.Name, cj.Module, cj.Module, totalWafer);
- return true;
- }
- public bool CreateControlJob(string jobId, string module, List<string> pjIDs, bool isAutoStart)
- {
- if (_lstControlJobs.Exists(x => x.Name == jobId))
- {
- EV.PostWarningLog(LogSource, $"{jobId} is already created");
- return false;
- }
- if (!ModuleHelper.IsLoadPort(ModuleHelper.Converter(module)))
- {
- EV.PostWarningLog(LogSource, $"{module} should be LoadPort");
- return false;
- }
- LoadPort lp = DEVICE.GetDevice<LoadPort>($"{module}");
- if (!lp.IsIdle)
- {
- EV.PostWarningLog(LogSource, $"{module} is not idle");
- return false;
- }
- if (!lp.IsMapped)
- {
- EV.PostWarningLog(LogSource, $"{module} is not mapped");
- return false;
- }
- if (!lp.IsPresent)
- {
- EV.PostWarningLog(LogSource, $"{module} is not present");
- return false;
- }
- foreach (var _lp in _lstLps)
- {
- if (_lp.Module.ToString() == module)
- {
- if (!_lp.IsOnline)
- {
- EV.PostWarningLog(LogSource, $"{module} is not online");
- return false;
- }
- if (_lp.IsError)
- {
- EV.PostWarningLog(LogSource, $"{module} is error");
- return false;
- }
- }
- }
- if (_lstProcessJobs.Count <= 0) //判断上一步ProcessJob是否创建成功
- {
- EV.PostWarningLog(LogSource, $"process job is not exist");
- return false;
- }
- ControlJobInfo cj = new ControlJobInfo();
- cj.Name = jobId;
- cj.Module = module;
- cj.SetState(EnumControlJobState.WaitingForStart);
- cj.LotName = jobId;
- cj.LotWafers = new List<WaferInfo>();
- int totalWafer = 0;
- foreach (var pjName in pjIDs)
- {
- var pj = _lstProcessJobs.FirstOrDefault(x => x.Name == pjName);
- if (pj == null)
- {
- LOG.Info($"not find {pjName} while create control job");
- continue;
- }
- var slotWafers = new List<Tuple<ModuleName, int>>();
- foreach (var slotWafer in pj.SlotWafers)
- {
- if (!WaferManager.Instance.CheckHasWafer(module, slotWafer.Item2))
- {
- EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} not in the carrier");
- return false;
- }
- if (!WaferManager.Instance.CheckWafer(ModuleHelper.Converter(module), slotWafer.Item2, WaferStatus.Normal))
- {
- EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} status is {WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).Status}");
- return false;
- }
- if (WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).ProcessState != EnumWaferProcessStatus.Idle)
- {
- EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} process status is {WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).ProcessState}");
- return false;
- }
- slotWafers.Add(Tuple.Create(ModuleHelper.Converter(module), slotWafer.Item2));
- totalWafer++;
- }
- pj.ControlJobName = jobId;
- cj.ProcessJobNameList.Add(pj.Name);
- pj.SlotWafers = slotWafers;
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- cj.LotWafers.Add(wafer);
- WaferDataRecorder.SetCjInfo(wafer.InnerId.ToString(), cj.InnerId.ToString());
- WaferDataRecorder.SetWaferSequence(wafer.InnerId.ToString(), pj.Sequence.Name);
- //WaferDataRecorder.SetWaferLotId(wafer.InnerId.ToString(), jobId);
- }
- }
- _lstControlJobs.Add(cj);
- CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
- JobDataRecorder.StartCJ(cj.InnerId.ToString(), carrier.InnerId.ToString(), cj.Name, cj.Module, cj.Module, totalWafer);
- return true;
- }
- public bool CreateProcessJob(string jobId, string sequenceName, List<int> slotNumbers, bool isAutoStart)
- {
- var sequenceInfo = SequenceInfoHelper.GetInfo(sequenceName);
- #region 模块检查
- if (!CheckSequenceAlignerReady(sequenceInfo, out string reason))
- {
- EV.PostWarningLog(LogSource, $"Aligner is not ready for the {reason}");
- return false;
- }
- if (!CheckSequencePMReady(sequenceInfo, out reason))
- {
- EV.PostWarningLog(LogSource, $"PM is not ready for the {reason}");
- return false;
- }
- #endregion
- #region Sequence检查
- if (!CheckSequenceAlignerOrder(sequenceInfo, out reason))
- {
- EV.PostWarningLog(LogSource, $"Aligner order is not valid for the {reason}");
- return false;
- }
- if (!CheckSequencePMOrder(sequenceInfo, out reason))
- {
- EV.PostWarningLog(LogSource, $"PM order is not valid, {reason}");
- return false;
- }
- #endregion
- var slotWafers = new List<Tuple<ModuleName, int>>();
- foreach (var slot in slotNumbers)
- {
- slotWafers.Add(Tuple.Create(ModuleName.System, slot));
- }
- ProcessJobInfo pj = new ProcessJobInfo();
- pj.Name = jobId;
- pj.Sequence = sequenceInfo;
- pj.SlotWafers = slotWafers;
- pj.SetState(EnumProcessJobState.Queued);
- _lstProcessJobs.Add(pj);
- return true;
- }
- private bool CheckSequenceAlignerReady(SequenceInfo seq, out string reason)
- {
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsAligner(module))
- {
- if (!_aligner.IsOnline)
- {
- reason = $"Step {i + 1}, {module} is not online";
- return false;
- }
- //if (!_aligner.IsIdle)
- //{
- // reason = $"Step {i + 1}, {module} is not idle";
- // return false;
- //}
- if (_aligner.IsError)
- {
- reason = $"Step {i + 1}, {module} is error";
- return false;
- }
- }
- }
- }
- reason = string.Empty;
- return true;
- }
- private bool CheckSequenceAlignerOrder(SequenceInfo seq, out string reason)
- {
- int alignerCount = 0;
- int alignerIndex = -1;
- int llIndex = -1;
- int pmIndex = -1;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsAligner(module))
- {
- alignerCount++;
- alignerIndex = i;
- if (i == seq.Steps.Count - 1)
- {
- reason = $"Step {i + 1}, {module} can not be the last step";
- return false;
- }
- }
- if (ModuleHelper.IsLoadLock(module))
- {
- if (llIndex == -1 || llIndex > i)
- llIndex = i;
- }
- if (ModuleHelper.IsPm(module))
- {
- pmIndex = i;
- }
- }
- }
- if (alignerCount >= 2)
- {
- reason = $"Step {alignerIndex + 1}, Aligner step can appear once at most in sequence";
- return false;
- }
- else if (alignerCount == 1)
- {
- if (llIndex != -1 && alignerIndex > llIndex)
- {
- reason = $"Step {alignerIndex + 1}, Aligner step should be in front of LoadLock step";
- return false;
- }
- if (pmIndex != -1 && alignerIndex > pmIndex)
- {
- reason = $"Step {alignerIndex + 1}, Aligner step should be in front of PM step";
- return false;
- }
- }
- reason = string.Empty;
- return true;
- }
- private bool CheckSequencePMReady(SequenceInfo seq, out string reason)
- {
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- if (stepInfo.StepModules.Count == 0)
- {
- reason = $"Step {i + 1}, no PM is selected";
- return false;
- }
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- foreach (var pm in _lstPms)
- {
- if (pm.Module == module)
- {
- if (!pm.IsOnline)
- {
- reason = $"Step {i + 1}, selected {module} is not online";
- return false;
- }
- //if (!pm.IsIdle)
- //{
- // reason = $"Step {i + 1}, selected {module} is not idle";
- // return false;
- //}
- if (pm.IsError)
- {
- reason = $"Step {i + 1}, selected {module} is error";
- return false;
- }
- #region Check Recipe File Valid
- var recipeContent = RecipeFileManager.Instance.LoadRecipe("", stepInfo.StepParameter[$"{module}Recipe"].ToString(), false);
- if (string.IsNullOrEmpty(recipeContent))
- {
- reason = $"Step {i + 1}, can not find recipe file {stepInfo.RecipeName}";
- return false;
- }
- #endregion
- }
- }
- }
- }
- }
- reason = "";
- return true;
- }
- private bool CheckSequencePMOrder(SequenceInfo seq, out string reason)
- {
- int pmCount = 0;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- pmCount++;
- break;
- }
- }
- }
- if (pmCount == 0)
- {
- reason = $"Sequence must contains PM step";
- return false;
- }
- if (pmCount >= 2)
- {
- reason = $"PM step only can appear once in sequence";
- return false;
- }
- reason = string.Empty;
- return true;
- }
- internal ProcessJobInfo GetFirstProcessJob(ControlJobInfo cj)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name)
- return pj;
- }
- return null;
- }
- public bool StopJob(string jobName)
- {
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
- if (cj == null)
- {
- EV.PostWarningLog(LogSource, $"stop job rejected, not found job with id {jobName}");
- return false;
- }
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name)
- {
- pj.SetState(EnumProcessJobState.Stopping);
- }
- }
- _faCallback.JobStopped(cj, GetFirstProcessJob(cj));
- _dbCallback.LotFinished(cj);
- return true;
- }
- public bool AbortJob(string jobName)
- {
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
- if (cj == null)
- {
- EV.PostWarningLog(LogSource, $"abort job rejected, not found job with id {jobName}");
- return false;
- }
- int unprocessed_cj = 0;
- int aborted_cj = 0;
- List<ProcessJobInfo> pjAbortList = new List<ProcessJobInfo>();
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name)
- {
- pj.SetState(EnumProcessJobState.Aborting);
- pjAbortList.Add(pj);
- int unprocessed = 0;
- int aborted = 0;
- WaferInfo[] wafers = WaferManager.Instance.GetWaferByProcessJob(pj.Name);
- foreach (var waferInfo in wafers)
- {
- waferInfo.ProcessJob = null;
- waferInfo.NextSequenceStep = 0;
- if (waferInfo.ProcessState != EnumWaferProcessStatus.Completed)
- {
- unprocessed++;
- unprocessed_cj++;
- }
- }
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
- }
- }
- foreach (var pj in pjAbortList)
- {
- _lstProcessJobs.Remove(pj);
- }
- _lstControlJobs.Remove(cj);
- JobDataRecorder.EndCJ(cj.InnerId.ToString(), aborted_cj, unprocessed_cj);
- _faCallback.JobAborted(cj, GetFirstProcessJob(cj));
- _dbCallback.LotFinished(cj);
- _temperatureSetpointDic.Clear();
- _temperatureTrigDic.Clear();
- return true;
- }
- public bool ResumeJob(string jobName)
- {
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
- if (cj == null)
- {
- EV.PostWarningLog(LogSource, $"resume job rejected, not found job with id {jobName}");
- return false;
- }
- if (cj.State == EnumControlJobState.Paused)
- {
- cj.SetState(EnumControlJobState.Executing);
- }
- _faCallback.JobResumed(cj, GetFirstProcessJob(cj));
- return true;
- }
- public bool StartJob(string jobName)
- {
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
- if (cj == null)
- {
- EV.PostWarningLog(LogSource, $"start job rejected, not found job with id {jobName}");
- return false;
- }
- if (cj.State == EnumControlJobState.WaitingForStart)
- {
- cj.SetState(EnumControlJobState.Executing);
- (GetModule(cj.Module) as SchedulerLoadPort).NoteJobStart();
- //if (cj.IsCycleMode)
- //{
- // _CycleData.BeginOrAddCycle(cj.CycleWaferCountSP);
- //}
- cj.BeginTime = DateTime.Now;
- cj.LotInnerId = Guid.NewGuid();
- _dbCallback.LotCreated(cj);
- _faCallback.JobStarted(cj, GetFirstProcessJob(cj));
- //foreach (var pj in _lstProcessJobs)
- //{
- // if (pj.ControlJobName == cj.Name)
- // {
- // pj.SetState(EnumProcessJobState.Processing);
- // }
- //}
- }
- return true;
- }
- public bool PauseJob(string jobName)
- {
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
- if (cj == null)
- {
- EV.PostWarningLog(LogSource, $"pause job rejected, not found job with id {jobName}");
- return false;
- }
- if (cj.State == EnumControlJobState.Executing)
- {
- cj.SetState(EnumControlJobState.Paused);
- }
- _faCallback.JobPaused(cj, GetFirstProcessJob(cj));
- return true;
- }
- public void Abort()
- {
- }
- public bool IsCJExisted(string CJID)
- {
- return _lstControlJobs.Exists(x => x.Name == CJID);
- }
- public void ModuleError(string moduleName)
- {
- GetModule(moduleName).ResetTask();
- PauseJob(string.Empty);
- }
- public void Map(string moduleName)
- {
- ModuleName target = ModuleHelper.Converter(moduleName);
- if (!ModuleHelper.IsLoadPort(target))
- {
- EV.PostWarningLog(LogSource, $"Invalid map target {target}");
- return;
- }
- if (!_mapTarget.Contains(target))
- {
- _mapTarget.Add(target);
- }
- }
- #endregion
- public Result Start(params object[] objs)
- {
- _ValueDict.Clear();
- _CycleData.Reset();
- var waferInfo = "";
- bool hasPmOnline = false;
- foreach (var schedulerPm in _lstPms)
- {
- if (schedulerPm.IsAvailable)
- {
- hasPmOnline = true;
- if (WaferManager.Instance.CheckHasWafer(schedulerPm.Module, 0))
- waferInfo += $"{(waferInfo == "" ? "" : ", ")}{schedulerPm.Module}";
- }
- }
- bool hasTMOnline = false;
- if (_tmRobot.IsAvailable)
- hasTMOnline = true;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0))
- waferInfo += $"{(waferInfo == "" ? "" : ", ")}{ModuleName.TMRobot} primary arm";
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1))
- waferInfo += $"{(waferInfo == "" ? "" : ", ")}{ModuleName.TMRobot} secondly arm";
- if (!hasPmOnline || !hasTMOnline)
- {
- var content = hasPmOnline ? "" : "both process chamber";
- content += hasTMOnline ? "" : $"{(content == "" ? "" : ", ")}TM";
- EV.PostWarningLog("Scheduler", $"can not change to auto mode, {content} is busy or offline");
- return Result.FAIL;
- }
- if (waferInfo != "")
- {
- EV.PostWarningLog("Scheduler", $"can not change to auto mode, {waferInfo} wafer presence.");
- return Result.FAIL;
- }
- if (!_efem.IsOnline)
- {
- EV.PostWarningLog("Scheduler", $"can not change to auto mode, EFEM is offline");
- return Result.FAIL;
- }
- return Result.RUN;
- }
- public Result Monitor()
- {
- for (int i = 0; i < 25; i++)
- {
- ProcessJobInfo pj = WaferManager.Instance.GetWafer(_lp1.Module, i).ProcessJob;
- if (pj == null)
- break;
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
- if (cj == null)
- break;
- if (_lp1.FirstDetectWaferArrive(i))
- {
- _faCallback.JobWaferEnd(cj, pj, _lp1.Module.ToString(), i);
- }
- }
- for (int i = 0; i < 25; i++)
- {
- ProcessJobInfo pj = WaferManager.Instance.GetWafer(_lp2.Module, i).ProcessJob;
- if (pj == null)
- break;
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
- if (cj == null)
- break;
- if (_lp2.FirstDetectWaferArrive(i))
- {
- _faCallback.JobWaferEnd(cj, pj, _lp2.Module.ToString(), i);
- }
- }
- MonitorJobTasks();
- MonitorCleanTasks();
- ControlJobInfo cjActive = _lstControlJobs.Find(x => x.State == EnumControlJobState.Executing);
- if (cjActive != null)
- {
- MonitorModuleTasks();
- }
- return Result.RUN;
- }
- #region Job task
- public Result MonitorJobTasks()
- {
- UpdateParallelMode();
- CalcingThroughput();
- UpdateProcessJobStatus();
- UpdateControlJobStatus();
- //if (GetUnprocessedWaferCount() < SC.GetValue<int>("System.Scheduler.WaferCountBelowWhichStartNewProcessJob"))
- {
- StartNewJob();
- }
- return Result.RUN;
- }
- //only for pj in process
- protected int GetUnprocessedWaferCount()
- {
- int count = 0;
- foreach (ProcessJobInfo pj in _lstProcessJobs)
- {
- if (pj.State == EnumProcessJobState.Processing || pj.State == EnumProcessJobState.Paused)
- count += GetUnprocessedWaferCount(pj);
- }
- if (CheckWaferNeedProcess(WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0)))
- count++;
- if (CheckWaferNeedProcess(WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1)))
- count++;
- if (CheckWaferNeedProcess(WaferManager.Instance.GetWafer(ModuleName.Aligner, 0)))
- count++;
- return count;
- }
- protected int GetUnprocessedWaferCount(ProcessJobInfo pj)
- {
- int count = 0;
- for (int i = 0; i < pj.SlotWafers.Count; ++i)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2);
- if (wafer.IsEmpty)
- continue;
- if (CheckWaferNeedProcess(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2))
- count++;
- }
- return count;
- }
- protected bool CheckAllWaferReturned(ProcessJobInfo pj, bool checkAllProcessed)
- {
- for (int i = 0; i < pj.SlotWafers.Count; ++i)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2);
- if (wafer.IsEmpty)
- return false;
- if (checkAllProcessed && CheckWaferNeedProcess(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2))
- return false;
- }
- return true;
- }
- protected bool CheckAllDummyWaferReturned()
- {
- foreach (var schedulerPm in _lstPms)
- {
- if (WaferManager.Instance.CheckWaferIsDummy(schedulerPm.Module, 0))
- return false;
- }
- if (WaferManager.Instance.CheckWaferIsDummy(_tmRobot.Module, 0))
- return false;
- if (WaferManager.Instance.CheckWaferIsDummy(_tmRobot.Module, 1))
- return false;
- return true;
- }
- protected bool CheckAllPmCleaned(ProcessJobInfo pj)
- {
- foreach (var schedulerPm in _lstPms)
- {
- if (CheckNeedRunClean(schedulerPm.Module, out _, out _))
- {
- foreach (var sequenceStepInfo in pj.Sequence.Steps)
- {
- if (sequenceStepInfo.StepModules.Contains(schedulerPm.Module))
- return false;
- }
- }
- }
- return true;
- }
- private void UpdateProcessJobStatus()
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.State == EnumProcessJobState.Processing)
- {
- if (CheckAllWaferReturned(pj, true) && CheckAllPmCleaned(pj) && CheckAllDummyWaferReturned())
- {
- pj.SetState(EnumProcessJobState.ProcessingComplete);
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
- }
- }
- else if (pj.State == EnumProcessJobState.Stopping)
- {
- if (CheckAllWaferReturned(pj, false) && CheckAllPmCleaned(pj) && CheckAllDummyWaferReturned())
- {
- pj.SetState(EnumProcessJobState.ProcessingComplete);
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
- }
- }
- }
- }
- private void UpdateParallelMode()
- {
- bool enableParallel = SC.GetValue<bool>("System.Scheduler.IsRunInParallelMode");
- int hasJobLpCount = 0;
- _isRunningInParallelMode = enableParallel;
- List<ModuleName> pmUsed = new List<ModuleName>();
- foreach (var lp in _lstLps)
- {
- var cj = _lstControlJobs.Find(x => x.Module == lp.Module.ToString());
- if (cj != null)
- {
- hasJobLpCount++;
- var pj = _lstProcessJobs.FirstOrDefault(x => x.ControlJobName == cj.Name);
- if (pj != null)
- {
- var seq = pj.Sequence;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module) && !pmUsed.Contains(module))
- pmUsed.Add(module);
- }
- }
- }
- }
- }
- _isRunningInParallelMode = enableParallel && hasJobLpCount > 1 && pmUsed.Count > 1;
- }
- private void UpdateControlJobStatus()
- {
- if (_lstControlJobs.Count == 0)
- return;
- List<ControlJobInfo> cjRemoveList = new List<ControlJobInfo>();
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- bool allPjCompleted = true;
- foreach (var pjName in cj.ProcessJobNameList)
- {
- var pj = _lstProcessJobs.FirstOrDefault(x => x.Name == pjName);
- if (pj == null) { LOG.Error($"Not find pj named {pjName} in {cj.Name}"); continue; }
- if (pj.State != EnumProcessJobState.Complete &&
- pj.State != EnumProcessJobState.ProcessingComplete)
- {
- allPjCompleted = false; break;
- }
- }
- if (allPjCompleted)
- {
- if (!_CycleData.IsCycleMode || (_CycleData.IsCycleMode && _CycleData.IsCycleEnd()))
- CompleteJobClean(cj);
- _FinishCJ(cj);
- cj.EndTime = DateTime.Now;
- string strInfo = $"{cj.Module} has finished: \r\n\r\nProcessed wafer number: {cj.LotWafers.Count} \r\nStart time: {cj.BeginTime} \r\nEnd time: {cj.EndTime} \r\nDuration: {(cj.EndTime - cj.BeginTime).TotalSeconds:F0} sec";
- EV.PostInfoLog("Scheduler", strInfo);
- if (SC.GetValue<bool>("System.Job.EnablePopDialogWhenJobDone"))
- {
- EV.PostPopDialogMessage(EventLevel.Information, "System Information", strInfo);
- }
- }
- }
- }
- if (_lstControlJobs.Any(cj => cj.State == EnumControlJobState.Completed) && _CycleData.IsCycleMode && !_CycleData.IsCycleEnd())
- {
- var completeCJs = from cj in _lstControlJobs
- where cj.State == EnumControlJobState.Completed
- select cj;
- var otherCJs = from cj in _lstControlJobs
- where cj.State != EnumControlJobState.Completed
- select cj;
- _lstControlJobs = otherCJs.Concat(completeCJs).ToList();
- _lstControlJobs.ForEach(cj =>
- {
- if (cj.State == EnumControlJobState.Completed)
- {
- _CycleData.IncreaseCount();
- if (_CycleData.IsCycleEnd())
- return;
- cj.SetState(EnumControlJobState.Executing);
- cj.BeginTime = DateTime.Now;
- cj.LotWafers.ForEach(x =>
- {
- x.NextSequenceStep = 0;
- x.ProcessState = EnumWaferProcessStatus.Idle;
- });
- foreach (var pjName in cj.ProcessJobNameList)
- {
- var pj = _lstProcessJobs.Find(x => x.Name == pjName);
- if (pj == null)
- {
- LOG.Error($"Not find pj named {pjName} in {cj.Name}");
- continue;
- }
- pj.SetState(EnumProcessJobState.Queued);
- }
- }
- });
- }
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Completed
- && (!_CycleData.IsCycleMode || _CycleData.IsCycleMode && _CycleData.IsCycleEnd())
- && (!_isAutoUnloadFoup || (_isAutoUnloadFoup && (GetModule(cj.Module.ToString()) as SchedulerLoadPort).IsUnloaded)))
- {
- (GetModule(cj.Module) as SchedulerLoadPort).NoteJobComplete();
- cjRemoveList.Add(cj);
- }
- }
- foreach (var cj in cjRemoveList)
- {
- List<ProcessJobInfo> pjRemoveList = _lstProcessJobs.Where(o => o.ControlJobName == cj.Name).ToList();
- pjRemoveList.ForEach(o => _lstProcessJobs.Remove(o));
- _lstControlJobs.Remove(cj);
- CalcedThroughput(pjRemoveList);
- }
- ControlJobInfo cjActived = null;
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- cjActived = cj;
- break;
- }
- }
- if (cjActived != null)
- {
- bool allPjResouceOk = true;
- string reason = string.Empty;
- foreach (var pjName in cjActived.ProcessJobNameList)
- {
- var pj = _lstProcessJobs.Find(x => x.Name == pjName);
- if (pj == null)
- {
- LOG.Error($"Not find pj named {pjName} in {cjActived.Name}");
- continue;
- }
- if (pj.State != EnumProcessJobState.Complete && pj.State != EnumProcessJobState.ProcessingComplete)
- {
- if (!CheckSequencePmReady(pj.Sequence, null, out _, out reason))
- {
- allPjResouceOk = false;
- break;
- }
- }
- }
- if (!allPjResouceOk)
- {
- cjActived.SetState(EnumControlJobState.Paused);
- EV.PostWarningLog(LogSource, $"{cjActived.Module} paused, {reason}");
- }
- }
- }
- private void _FinishCJ(ControlJobInfo cj)
- {
- cj.SetState(EnumControlJobState.Completed);
- int unprocessed_cj = 0;
- int aborted_cj = 0;
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name)
- {
- int unprocessed = 0;
- int aborted = 0;
- WaferInfo[] wafers = WaferManager.Instance.GetWaferByProcessJob(pj.Name);
- foreach (var waferInfo in wafers)
- {
- waferInfo.ProcessJob = null;
- waferInfo.NextSequenceStep = 0;
- if (waferInfo.ProcessState != EnumWaferProcessStatus.Completed)
- {
- unprocessed++;
- unprocessed_cj++;
- }
- }
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
- }
- }
- JobDataRecorder.EndCJ(cj.InnerId.ToString(), aborted_cj, unprocessed_cj);
- _faCallback.JobFinished(cj, GetFirstProcessJob(cj));
- _dbCallback.LotFinished(cj);
- }
- //private bool _HandleFinishedCycleCJ(ControlJobInfo cj)
- //{
- // //if (!cj.IsCycleMode) return false;
- // int countProcessed = 0;
- // foreach (var pjName in cj.ProcessJobNameList)
- // {
- // var pj = _lstProcessJobs.FirstOrDefault(x => x.Name == pjName);
- // if (pj == null) { LOG.Error($"Not find pj named {pjName} in {cj.Name}"); continue; }
- // if (pj.State == EnumProcessJobState.Complete || pj.State == EnumProcessJobState.ProcessingComplete)
- // {
- // foreach (var pjSlotWafer in pj.SlotWafers)
- // {
- // WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- // if (!wafer.IsEmpty && !CheckWaferNeedProcess(pjSlotWafer.Item1, pjSlotWafer.Item2))
- // countProcessed++;
- // }
- // }
- // }
- // _CycleData.Increase(countProcessed);
- // int leftCount = _CycleData.CycleWaferCountSetPoint - _CycleData.CycledWaferCount;
- // // finished cycle
- // if (leftCount <= 0) return false;
- // // 移除老的cj
- // var pjList = _lstProcessJobs.Where(o => o.ControlJobName == cj.Name).ToList();
- // CalcedThroughput(pjList);
- // pjList.ForEach(o => _lstProcessJobs.Remove(o));
- // _lstControlJobs.Remove(cj);
- // // 模拟 LP unload / load
- // {
- // ModuleName mName = ModuleHelper.Converter(cj.Module);
- // var wafers_old = WaferManager.Instance.GetWafers(mName).ToList();
- // WaferManager.Instance.DeleteWafer(mName, 0, SC.GetValue<int>($"EFEM.LoadPort.CassetteSlotNumber"));
- // CarrierManager.Instance.DeleteCarrier(cj.Module);
- // CarrierManager.Instance.CreateCarrier(cj.Module);
- // foreach (var wafer in wafers_old)
- // {
- // if (wafer.Status != WaferStatus.Normal) continue;
- // var newWafer = WaferManager.Instance.CreateWafer(mName, wafer.Slot, wafer.Status);
- // newWafer.PPID = wafer.PPID;
- // CarrierManager.Instance.RegisterCarrierWafer(cj.Module, wafer.Slot, newWafer);
- // }
- // }
- // // 产生新的cj
- // ControlJobInfo newCj = new ControlJobInfo();
- // newCj.Name = cj.Name;
- // newCj.Module = cj.Module;
- // newCj.LotName = cj.LotName;
- // //newCj.IsCycleMode = cj.IsCycleMode;
- // //newCj.CycleWaferCountSP = cj.CycleWaferCountSP;
- // //newCj.CycledWaferCount = _CycleData.CycledWaferCount;
- // newCj.LotInnerId = Guid.NewGuid();
- // newCj.LotWafers = cj.LotWafers.Take(leftCount).ToList();
- // int addedCount = 0;
- // List<ProcessJobInfo> newPjList = new List<ProcessJobInfo>();
- // //int toAddCount = Math.Min(leftCount, cj.LotWafers.Count);
- // for (int ii = 0; ii < cj.ProcessJobNameList.Count; ii++)
- // {
- // string pjName = cj.ProcessJobNameList[ii];
- // var pj = pjList.FirstOrDefault(o => o.ControlJobName == cj.Name && o.Name == pjName);
- // if (pj == null) continue;
- // int toAddCount = Math.Min(leftCount - addedCount, cj.LotWafers.Count);
- // if (toAddCount <= 0) break;
- // addedCount += toAddCount;
- // ProcessJobInfo newPj = new ProcessJobInfo();
- // newPj.Name = pj.Name;
- // newPj.Sequence = pj.Sequence;
- // newPj.ControlJobName = pj.ControlJobName;
- // newPj.SlotWafers = pj.SlotWafers.Take(toAddCount).ToList();
- // newPj.SetState(EnumProcessJobState.Queued);
- // _lstProcessJobs.Add(newPj);
- // newCj.ProcessJobNameList.Add(pj.Name);
- // newPjList.Add(newPj);
- // }
- // _lstControlJobs.Add(newCj);
- // // 开始新的cj
- // newCj.SetState(EnumControlJobState.Executing);
- // newCj.LotInnerId = Guid.NewGuid();
- // newCj.BeginTime = DateTime.Now;
- // _dbCallback.LotCreated(newCj);
- // newPjList.ForEach(o => ActiveProcessJob(o));
- // return true;
- //}
- public bool CheckAllJobDone()
- {
- if (_lp1.IsAvailable)
- {
- _trigLp1JobComplete.CLK = CheckJobComplete(ModuleName.LP1.ToString());
- if (_trigLp1JobComplete.Q)
- {
- if (_isAutoUnloadFoup)
- {
- _lp1.Unload();
- }
- EV.Notify("CARRIER_PROCESS_COMPLETE", new SerializableDictionary<string, object>()
- {
- { "PortID", 1},
- { "PORT_ID", 1},
- { "CarrierID", CarrierManager.Instance.GetCarrier(_lp1.Module.ToString()).CarrierId},
- { "CAR_ID", CarrierManager.Instance.GetCarrier(_lp1.Module.ToString()).CarrierId}
- });
- }
- }
- if (_lp2.IsAvailable)
- {
- _trigLp2JobComplete.CLK = CheckJobComplete(ModuleName.LP2.ToString());
- if (_trigLp2JobComplete.Q)
- {
- if (_isAutoUnloadFoup)
- {
- _lp2.Unload();
- }
- EV.Notify("CARRIER_PROCESS_COMPLETE", new SerializableDictionary<string, object>()
- {
- { "PortID", 2},
- { "PORT_ID", 2},
- { "CarrierID", CarrierManager.Instance.GetCarrier(_lp2.Module.ToString()).CarrierId},
- { "CAR_ID", CarrierManager.Instance.GetCarrier(_lp2.Module.ToString()).CarrierId}
- });
- }
- }
- if (_lp3.IsAvailable)
- {
- _trigLp3JobComplete.CLK = CheckJobComplete(ModuleName.LP3.ToString());
- if (_trigLp3JobComplete.Q)
- {
- if (_isAutoUnloadFoup)
- {
- _lp3.Unload();
- }
- EV.Notify("CARRIER_PROCESS_COMPLETE", new SerializableDictionary<string, object>()
- {
- { "PortID", 3 },
- { "PORT_ID", 3 },
- { "CarrierID", CarrierManager.Instance.GetCarrier(_lp3.Module.ToString()).CarrierId },
- { "CAR_ID", CarrierManager.Instance.GetCarrier(_lp3.Module.ToString()).CarrierId }
- });
- }
- }
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing || cj.State == EnumControlJobState.Paused)
- return false;
- }
- if (!_lp1.IsAvailable || !_lp2.IsAvailable || !_lp3.IsAvailable)
- return false;
- return true;
- }
- private bool CheckJobComplete(string lp = null)
- {
- if (_lstProcessJobs.Count == 0)
- return false;
- if (_lstControlJobs.Count == 0)
- return false;
- if (_CycleData.IsCycleMode && !_CycleData.IsCycleEnd())
- return false;
- if (lp != null)
- {
- var cj = _lstControlJobs.Find(x => x.Module == lp);
- if (cj == null)
- return false;
- }
- foreach (var pj in _lstProcessJobs)
- {
- if (lp == null)
- {
- if (pj.State != EnumProcessJobState.ProcessingComplete)
- {
- return false;
- }
- }
- }
- foreach (var cj in _lstControlJobs)
- {
- if (lp == null)
- {
- if (cj.State != EnumControlJobState.Completed)
- {
- return false;
- }
- }
- else
- {
- if (cj.Module == lp && cj.State != EnumControlJobState.Completed)
- {
- return false;
- }
- }
- }
- return true;
- }
- private void StartNewJob()
- {
- ControlJobInfo cjActived = null;
- bool enableParallel = SC.GetValue<bool>("System.Scheduler.IsRunInParallelMode");
- List<ModuleName> pmOccupied = GetPmUsedInRunningPj();
- var orderedLstCJs = _lstControlJobs.OrderBy(x => x.BeginTime);
- foreach (var cj in orderedLstCJs)
- {
- if (cj.State != EnumControlJobState.Executing)
- continue;
- cjActived = cj;
- foreach (var pjName in cjActived.ProcessJobNameList)
- {
- var pj = _lstProcessJobs.Find(x => x.Name == pjName);
- if (pj == null)
- {
- LOG.Error($"Not find pj named {pjName} in {cjActived.Name}");
- continue;
- }
- if (pj.State == EnumProcessJobState.Queued)
- {
- var pmIsReady = CheckSequencePmReady(pj.Sequence, pmOccupied, out var pmUsed, out string reason);
- if (pmUsed.Count > 0)
- {
- var needPreClean = pmUsed.Any(x =>
- {
- return SC.GetValue<bool>($"{x.ToString()}.JobClean.IsEnabled") && SC.GetValue<bool>($"{x.ToString()}.JobClean.EnablePreJobClean");
- });
- if (needPreClean && !pmIsReady)
- break;
- ActiveProcessJob(pj);
- foreach (var moduleName in pmUsed)
- {
- if (!pmOccupied.Contains(moduleName))
- pmOccupied.Add(moduleName);
- }
- break;
- }
- }
- }
- if (!_isRunningInParallelMode)
- break;
- }
- }
- private List<ModuleName> GetPmUsedInRunningPj()
- {
- var pmUsed = new List<ModuleName>();
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State != EnumControlJobState.Executing && cj.State != EnumControlJobState.Paused)
- continue;
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && (pj.State == EnumProcessJobState.Processing || pj.State == EnumProcessJobState.Paused))
- {
- for (int i = 0; i < pj.Sequence.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = pj.Sequence.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module) && !pmUsed.Contains(module))
- pmUsed.Add(module);
- }
- }
- }
- }
- }
- return pmUsed;
- }
- //private bool CheckSequencePmReady(SequenceInfo seq, out string reason)
- //{
- // for (int i = 0; i < seq.Steps.Count; i++)
- // {
- // SequenceStepInfo stepInfo = seq.Steps[i];
- // bool hasPm = false;
- // foreach (var module in stepInfo.StepModules)
- // {
- // if (ModuleHelper.IsPm(module))
- // {
- // PM pm = DEVICE.GetDevice<PM>(module.ToString());
- // if (pm.IsInstalled && !pm.IsError)
- // {
- // hasPm = true;
- // break;
- // }
- // }
- // else
- // {
- // hasPm = true; // other modules default ok
- // }
- // }
- // if (!hasPm)
- // {
- // reason = $"Step {i + 1} no valid PM, " + string.Join("|", stepInfo.StepModules);
- // return false;
- // }
- // }
- // reason = "";
- // return true;
- //}
- private bool CheckSequencePmReady(SequenceInfo seq, List<ModuleName> pmOccupied, out List<ModuleName> pmUsed, out string reason)
- {
- pmUsed = new List<ModuleName>();
- reason = "";
- bool pmIsReady = true;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- bool hasPm = false;
- foreach (var module in stepInfo.StepModules)
- {
- if (!ModuleHelper.IsPm(module))
- {
- hasPm = true;
- break;
- }
- PMModuleBase pm = EquipmentManager.Modules[module] as PMModuleBase;
- if (pm.IsInstalled && (pmOccupied == null || !pmOccupied.Contains(module)))
- {
- hasPm = true;
- }
- if (!pmUsed.Contains(module))
- pmUsed.Add(module);
- }
- if (pmIsReady && !hasPm)
- {
- reason = $"Step {i + 1} no valid PM, " + string.Join("|", stepInfo.StepModules);
- pmIsReady = false;
- }
- }
- return pmIsReady;
- }
- private bool CheckSequenceRecipeFileValidTobedone(SequenceInfo seq, out string reason)
- {
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- var recipeContent =
- RecipeFileManager.Instance.LoadRecipe($"{module}\\", stepInfo.RecipeName, false);
- if (string.IsNullOrEmpty(recipeContent))
- {
- reason = $"Can not find recipe file {module}\\{stepInfo.RecipeName}";
- return false;
- }
- string cleanRecipeName = "";
- if (stepInfo.CleanInterval > 0
- && stepInfo.StepParameter.ContainsKey("CleanRecipeNoWafer")
- && !string.IsNullOrEmpty((string)stepInfo.StepParameter["CleanRecipeNoWafer"]))
- {
- cleanRecipeName = (string)stepInfo.StepParameter["CleanRecipeNoWafer"];
- if (!string.IsNullOrEmpty(cleanRecipeName))
- {
- recipeContent =
- RecipeFileManager.Instance.LoadRecipe($"{module}\\", cleanRecipeName, false);
- if (string.IsNullOrEmpty(recipeContent))
- {
- reason = $"Can not find recipe file {module}\\{cleanRecipeName}";
- return false;
- }
- }
- }
- if (stepInfo.CleanInterval > 0
- && stepInfo.StepParameter.ContainsKey("CleanRecipeWafer")
- && !string.IsNullOrEmpty((string)stepInfo.StepParameter["CleanRecipeWafer"]))
- {
- cleanRecipeName = (string)stepInfo.StepParameter["CleanRecipeWafer"];
- if (!string.IsNullOrEmpty(cleanRecipeName))
- {
- recipeContent =
- RecipeFileManager.Instance.LoadRecipe($"{module}\\", cleanRecipeName, false);
- if (string.IsNullOrEmpty(recipeContent))
- {
- reason = $"Can not find recipe file {module}\\{cleanRecipeName}";
- return false;
- }
- }
- }
- }
- }
- }
- reason = "";
- return true;
- }
- private bool CheckSequenceRecipeFileValid(SequenceInfo seq, out string reason)
- {
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- var recipeContent =
- RecipeFileManager.Instance.LoadRecipe("", stepInfo.StepParameter[$"{module}Recipe"].ToString(), false);
- if (string.IsNullOrEmpty(recipeContent))
- {
- reason = $"Can not find recipe file {stepInfo.StepParameter[$"{module}Recipe"].ToString()}";
- return false;
- }
- }
- }
- }
- reason = "";
- return true;
- }
- private bool CheckSequenceOrderOk(SequenceInfo seq, out string reason)
- {
- reason = "";
- bool foundPm = false;
- bool isLLBeforePm = false;
- bool isLLAfterPm = false;
- bool isAlignerAfterLL = false;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- foundPm = true;
- }
- if (!foundPm && ModuleHelper.IsLoadLock(module))
- {
- isLLBeforePm = true;
- }
- if (foundPm && ModuleHelper.IsLoadLock(module))
- {
- isLLAfterPm = true;
- }
- if (ModuleHelper.IsAligner(module) && (isLLBeforePm || foundPm))
- {
- isAlignerAfterLL = true;
- }
- }
- }
- if (!isLLBeforePm)
- {
- reason = $"not found LL before PM;";
- return false;
- }
- if (!isLLAfterPm)
- {
- reason = $"not found LL after PM;";
- return false;
- }
- if (!foundPm)
- {
- reason = $"not found PM in the sequence file;";
- return false;
- }
- if (isAlignerAfterLL)
- {
- reason = "Aligner after LL not support";
- return false;
- }
- return true;
- }
- private bool CheckSequenceNeedDummyWafer(SequenceInfo seq)
- {
- bool needDummyWafer = false;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- if (stepInfo.CleanInterval > 0
- && stepInfo.StepParameter.ContainsKey("CleanRecipeWafer")
- && !string.IsNullOrEmpty((string)stepInfo.StepParameter["CleanRecipeWafer"]))
- {
- needDummyWafer = true;
- break;
- }
- }
- }
- if (needDummyWafer)
- break;
- }
- return needDummyWafer;
- }
- private bool ActiveProcessJob(ProcessJobInfo pj)
- {
- //pm is ok
- if (!CheckSequencePmReady(pj.Sequence, null, out _, out string reason))
- {
- EV.PostWarningLog(LogSource, $"can not active {pj.Name}, {reason}");
- return false;
- }
- _lstPmsCurrentSequence.Clear();
- for (int i = 0; i < pj.Sequence.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = pj.Sequence.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (ModuleHelper.IsPm(module))
- {
- var pm = _lstPms.Find(x => x.Module == module);
- if (pm != null)
- _lstPmsCurrentSequence.Add(pm);
- }
- }
- }
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- wafer.ProcessJob = pj;
- wafer.NextSequenceStep = 0;
- WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString());
- }
- ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
- CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
- JobDataRecorder.StartPJ(pj.InnerId.ToString(), carrier.InnerId.ToString(), cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count);
- pj.SetState(EnumProcessJobState.Processing);
- PreJobClean(cj);
- return true;
- }
- #endregion
- #region Module task
- public Result MonitorModuleTasks()
- {
- MonitorPMTask();
- MonitorEfemRobotTask();
- for (int i = 0; i < tmRobotActions.Count; i++)
- {
- MonitorTmRobotTask();
- }
- //MonitorLoadLockTask();
- MonitorInterlockTask();
- MonitorAlignerTask();
- return Result.RUN;
- }
- private void MonitorInterlockTask()
- {
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing || cj.State == EnumControlJobState.Paused ||
- cj.State == EnumControlJobState.WaitingForStart)
- {
- var lp = GetModule(cj.Module);
- if (CarrierManager.Instance.CheckNoCarrier(lp.Module, 0))
- {
- EV.PostAlarmLog("System", "Cassette removed while job not finished.");
- //Singleton<RouteManager>.Instance.PostMsg(RouteManager.MSG.ERROR);
- }
- }
- }
- }
- private void MonitorAlignerTask()
- {
- if (!_aligner.IsAvailable)
- return;
- if (CheckWaferNextStepIsAlign(_aligner.Module, 0))
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(_aligner.Module, 0);
- GetWaferSequenceAlignAngle(_aligner.Module, 0, out double angle);
- if (_aligner.Align(angle))
- {
- wafer.NextSequenceStep++;
- }
- WaferDataRecorder.SetWaferNotchAngle(wafer.InnerId.ToString(), (float)angle);
- }
- }
- //private void MonitorBufferTask()
- //{
- // foreach (var buffer in _lstBuffers)
- // {
- // if (!buffer.IsAvailable)
- // continue;
- // }
- //}
- private void MonitorLoadLockTask()
- {
- // bool isPrepareTransferForEfemobotPlace = GetWaferCountInJobQueue() > 0;
- // foreach (var ll in _lstLls)
- // {
- // if (ll.Entity.IsPrepareTransfer)
- // {
- // return;
- // }
- // var deviceLL = DEVICE.GetDevice<LoadLock>(ll.Module.ToString());
- // //if (ll.CheckAtAtm() && (ll.Entity.IsCooling || deviceLL.CheckDoorOpen()))
- // if (deviceLL.CheckDoorOpen())
- // {
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // int emptySlot = 0;
- // foreach (var wafer in wafers)
- // {
- // if (wafer.IsEmpty || wafer.ProcessState != EnumWaferProcessStatus.Idle)
- // emptySlot++;
- // }
- // if (emptySlot >= GetWaferCountInJobQueue())
- // {
- // isPrepareTransferForEfemobotPlace = false;
- // break;
- // }
- // }
- // }
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsAvailable)
- // continue;
- // var deviceLL = DEVICE.GetDevice<LoadLock>(ll.Module.ToString());
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // var isEmptyLL = true;
- // bool isPrepareTransferForEfemobotPick = true;
- // for (int i = 0; i <= 5;)
- // {
- // var wafer0 = WaferManager.Instance.GetWafer(ll.Module, i);
- // var wafer1 = WaferManager.Instance.GetWafer(ll.Module, i + 1);
- // if (!wafer0.IsEmpty || !wafer1.IsEmpty)
- // isEmptyLL = false;
- // if (wafer0.IsEmpty && wafer1.IsEmpty && GetVacuumWafer() > 0)
- // isPrepareTransferForEfemobotPick = false;
- // if ((!wafer0.IsEmpty && wafer0.ProcessState == EnumWaferProcessStatus.Idle) ||
- // (!wafer1.IsEmpty && wafer1.ProcessState == EnumWaferProcessStatus.Idle))
- // isPrepareTransferForEfemobotPick = false;
- // i += 2;
- // }
- // if (isEmptyLL)
- // isPrepareTransferForEfemobotPick = false;
- // if (isPrepareTransferForEfemobotPlace && isEmptyLL && (_tmDevice.CheckSlitValveClose(ll.Module) || GetVacuumWafer() == 0) &&
- // !ll.Entity.IsPrepareTransferReady(ModuleName.EfemRobot, EnumTransferType.Place))
- // {
- // ll.PrepareTransfer(ModuleName.EfemRobot, EnumTransferType.Place, 0);
- // return;
- // }
- // if (isPrepareTransferForEfemobotPick)
- // {
- // if (!ll.Entity.IsPrepareTransferReady(ModuleName.EfemRobot, EnumTransferType.Pick))
- // {
- // if (!_loadlockCooling.ContainsKey(ll.Module))
- // _loadlockCooling.Add(ll.Module, false);
- // _loadlockCooling[ll.Module] = false;
- // ll.PrepareTransfer(ModuleName.EfemRobot, EnumTransferType.Pick, 0);
- // return;
- // }
- // //TODO, cooling 要在 Open ATM door 之前做,PrepareTransfer 需要分开 [2021/7/3 TerryLu]
- // if (ll.Entity.IsPreCoolingDone())
- // {
- // foreach (var wafer in wafers)
- // {
- // if (wafer != null && !wafer.IsEmpty && GetWaferSequenceLoadLockCoolingTime(ll.Module, wafer.Slot, out int coolingTime))
- // {
- // _loadlockCooling[ll.Module] = true;
- // ll.Cooling(coolingTime);
- // break;
- // }
- // }
- // if (_loadlockCooling[ll.Module])
- // {
- // foreach (var wafer in wafers)
- // {
- // if (wafer != null && !wafer.IsEmpty)
- // {
- // wafer.NextSequenceStep++;
- // }
- // }
- // }
- // }
- // }
- // bool isPrepareTransferForTMRobot = true;
- // bool isAllEmpty = true;
- // foreach (var wafer in wafers)
- // {
- // if (!wafer.IsEmpty)
- // isAllEmpty = false;
- // if (wafer.IsEmpty && GetATMWafer() > 0)
- // {
- // isPrepareTransferForTMRobot = false;
- // break;
- // }
- // if (wafer.ProcessState != EnumWaferProcessStatus.Idle)
- // {
- // isPrepareTransferForTMRobot = false;
- // break;
- // }
- // }
- // if (isAllEmpty)
- // {
- // if (GetVacuumWafer() == 0)
- // {
- // isPrepareTransferForTMRobot = false;
- // }
- // else
- // {
- // foreach (var anotherLL in _lstLls)
- // {
- // if (!anotherLL.IsOnline || anotherLL == ll)
- // continue;
- // var anotherLLWafers = WaferManager.Instance.GetWafers(anotherLL.Module).ToList();
- // int count = 0;
- // for (int i = 0; i <= 5;)
- // {
- // if (WaferManager.Instance.CheckNoWafer(anotherLL.Module, i) && WaferManager.Instance.CheckNoWafer(anotherLL.Module, i + 1))
- // {
- // count++;
- // }
- // i += 2;
- // }
- // if (count >= GetVacuumWafer())
- // {
- // isPrepareTransferForTMRobot = false;
- // break;
- // }
- // }
- // }
- // }
- // if (isPrepareTransferForTMRobot && !ll.Entity.IsPrepareTransferReady(ModuleName.TMRobot, EnumTransferType.Pick))
- // {
- // ll.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
- // continue;
- // }
- // }
- }
- private void MonitorPMTask()
- {
- foreach (var pm in _lstPms)
- {
- if (!pm.IsAvailable)
- continue;
- if (WaferManager.Instance.CheckHasWafer(pm.Module, 0) || WaferManager.Instance.CheckHasWafer(pm.Module, 1))
- {
- if (CheckNeedRunClean(pm.Module, out bool withWafer, out string recipe) && withWafer
- && WaferManager.Instance.GetWafer(pm.Module, 0).Status == WaferStatus.Dummy
- && WaferManager.Instance.GetWafer(pm.Module, 0).ProcessState == EnumWaferProcessStatus.Wait
- && WaferManager.Instance.GetWafer(pm.Module, 1).Status == WaferStatus.Dummy
- && WaferManager.Instance.GetWafer(pm.Module, 1).ProcessState == EnumWaferProcessStatus.Wait)
- {
- pm.Process(recipe, true, withWafer);
- continue;
- }
- var wafer0 = WaferManager.Instance.GetWafer(pm.Module, 0);
- var wafer1 = WaferManager.Instance.GetWafer(pm.Module, 1);
- if (CheckCanProcess(pm.Module))
- {
- WaferInfo wafer = wafer0.Status != WaferStatus.Empty ? wafer0 : wafer1;
- if (pm.Process(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[$"{pm.Module}Recipe"].ToString(), false, true))
- {
- if (wafer0.Status != WaferStatus.Empty)
- wafer0.NextSequenceStep++;
- if (wafer1.Status != WaferStatus.Empty)
- wafer1.NextSequenceStep++;
- continue;
- }
- }
- }
- else
- {
- if (CheckNeedRunClean(pm.Module, out bool withWafer, out string recipe) && !withWafer)
- {
- pm.Process(recipe, true, withWafer);
- continue;
- }
- if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)
- && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)
- )
-
- {
- var _moduleName = ModuleName.LP1;
- if (LPHadCreateJob != "LP1")
- {
- _moduleName = ModuleName.LP2;
- }
- SlotItem item = GetNextWaferInJobQueue(_moduleName);
- if (item != null && CheckWaferNeedProcessPre(item.Module, item.Slot, pm.Module))
- {
- if (GetWaferTemperatureSetInRecipe(item.Module, item.Slot, pm.Module, out double temp1, out double temp2) && !pm.CheckTempReady(temp1, temp2))
- {
- if (temp1 != 0 && temp2 != 0)
- {
- pm.Preheating(temp1, temp2);
- continue;
- }
- }
- }
- }
- }
- //if (!pm.IsAvailable)
- // continue;
- //var wafers = FindAllLoadLockSlotForTMRobotPick();
- //if (wafers.Count > 0)
- //{
- // if (wafers.Any(x => CheckWaferNeedProcess(x.Item1.Module, x.Item2, pm.Module)))
- // {
- // for (int i = 0; i < WaferManager.Instance.GetWafers(pm.Module).Length; i++)
- // {
- // if (WaferManager.Instance.CheckNoWafer(pm.Module, i) && !pm.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, i))
- // {
- // pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, i);
- // return;
- // }
- // }
- // }
- //}
- //else
- //{
- // if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0)
- // && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)
- // && WaferManager.Instance.CheckNoWafer(pm.Module, 0)
- // && WaferManager.Instance.CheckNoWafer(pm.Module, 1)
- // && _tmRobot.IsAvailable
- // && !pm.CheckSlitValveClose())
- // {
- // pm.CloseSlitValve();
- // return;
- // }
- //}
- }
- }
- private void MonitorTmRobotTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- //TM robot is idle, release all the target
- foreach (var ll in _lstLls)
- {
- if (ll.IsWaitTransfer(ModuleName.TMRobot))
- ll.StopWaitTransfer(ModuleName.TMRobot);
- }
- foreach (var pm in _lstPms)
- {
- if (pm.IsWaitTransfer(ModuleName.TMRobot))
- pm.StopWaitTransfer(ModuleName.TMRobot);
- }
- //MonitorTmRobotDummyWaferBufferTask();
- //if (!_tmRobot.IsAvailable)
- // return;
- if (!_tmRobot.IsAvailable)
- return;
- var act = tmRobotActions.Peek();
- act.Invoke();
- if (!_tmRobot.IsAvailable)
- return;
- if (act == MonitorTmRobotLoadLockPickTask)
- {
- List<Tuple<SchedulerLoadLock, int>> availableLoadLockSlots = FindAllLoadLockSlotForTMRobotPick();
- if (availableLoadLockSlots.Count > 0)
- {
- Tuple<SchedulerLoadLock, int> firstSlot = GetWaferOrderInJobQueue(availableLoadLockSlots);
- if (firstSlot != null)
- {
- SchedulerLoadLock ll = firstSlot.Item1;
- int pickSlot = firstSlot.Item2;
- if (!ll.IsAvailable)
- return;
- }
- }
- }
- if (act == MonitorTmRobotLoadLockPlaceTask && _lstLls.All(x => !x.IsAvailable))
- return;
- tmRobotActions.Enqueue(tmRobotActions.Dequeue());
- //MonitorTmRobotLoadLockPickTask();
- //if (!_tmRobot.IsAvailable)
- // return;
- //MonitorTmRobotPMPickTask();
- //if (!_tmRobot.IsAvailable)
- // return;
- //MonitorTmRobotLoadLockPlaceTask();
- //if (!_tmRobot.IsAvailable)
- // return;
- //MonitorTmRobotPMPlaceTask();
- //if (!_tmRobot.IsAvailable)
- // return;
- //MonitorTmRobotGoToTask();
- }
- private void MonitorTmRobotLoadLockPlaceTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- //place to ll
- bool blade0HasWaferAndProcessed = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) && CheckWaferNextStepIsLoadLock(ModuleName.TMRobot, 0);
- bool blade1HasWaferAndProcessed = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) && CheckWaferNextStepIsLoadLock(ModuleName.TMRobot, 1);
- if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed)
- {
- Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2;
- foreach (var ll in _lstLls)
- {
- if (!ll.IsAvailable)
- continue;
- if (!CheckWaferNextStepIsLoadLock(ModuleName.TMRobot, (int)placeBlade, ll.Module))
- continue;
- int? placeSlot = GetAvilableLoadLockSlotForTMRobotPlace(ll);
- if (placeSlot != null)
- {
- if (_tmRobot.Place(ll.Module, (int)placeSlot, placeBlade, 0, 0, false))
- {
- WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade).NextSequenceStep++;
- ll.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- if (GetEmptySlotInPM() < 1)
- return;
- }
- private void MonitorTmRobotLoadLockPickTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- if (!CanTmRobotLoadLockPick())
- return;
- //pick from ll
- if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- Hand pickBlade;
- if (_tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
- {
- pickBlade = Hand.Blade1;
- }
- else if (_tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- pickBlade = Hand.Blade2;
- }
- else
- {
- return;
- }
- //if (_lstLls.All(x => !x.IsAvailable))
- // return;
- List<Tuple<SchedulerLoadLock, int>> availableLoadLockSlots = FindAllLoadLockSlotForTMRobotPick();
- if (availableLoadLockSlots.Count > 0)
- {
- Tuple<SchedulerLoadLock, int> firstSlot = GetWaferOrderInJobQueue(availableLoadLockSlots);
- if (firstSlot != null)
- {
- SchedulerLoadLock ll = firstSlot.Item1;
- int pickSlot = firstSlot.Item2;
- if (!ll.IsAvailable)
- return;
- if (_tmRobot.Pick(ll.Module, (int)pickSlot, pickBlade, 0, 0, false))
- {
- ll.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- }
- private R_TRIG tmRobotGotoLoadLockTrig = new R_TRIG();
- private R_TRIG tmRobotGotoPMTrig = new R_TRIG();
- SchedulerPM gotoPm = null;
- private void MonitorTmRobotGoToTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- //int gotoSlot = Int32.MaxValue;
- //int gotoModule = -1;
- //int waferOriginSlot = int.MaxValue;
- if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- //PMA、PMB都为空,ll中有需要跑的wafer时,准备tmRobot到ll
- var llWafers = FindAllLoadLockSlotForTMRobotPick();
- tmRobotGotoLoadLockTrig.CLK = llWafers.Count > 0 && !CanTmRobotLoadLockPick() && GetEmptySlotInPMA() == 2 && GetEmptySlotInPMB() == 2;
- if (tmRobotGotoLoadLockTrig.Q)
- {
- if (_tmRobot.Goto(llWafers[0].Item1.Module, llWafers[0].Item2, Hand.Blade1))
- {
- llWafers[0].Item1.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- //PMA、PMB都在工艺过程中,tmRobot移动到先开始工艺的腔体位置
- bool PMAInProcess = _pm1.CheckInProcess();
- bool PMBInProcess = _pm2.CheckInProcess();
- if (PMAInProcess ^ PMBInProcess)
- {
- gotoPm = PMAInProcess ? _pm1 : _pm2;
- }
- if (!PMAInProcess && !PMBInProcess)
- {
- gotoPm = null;
- }
- tmRobotGotoPMTrig.CLK = PMAInProcess && PMBInProcess && gotoPm != null;
- if (tmRobotGotoPMTrig.Q)
- {
- if (_tmRobot.Goto(gotoPm.Module, 0, Hand.Blade1))
- {
- gotoPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- private bool CanTmRobotLoadLockPick()
- {
- if (FindAllLoadLockSlotForTMRobotPick().Count <= 1
- && GetUnprocessedWaferCount() >= 1
- && WaferManager.Instance.GetWafers(ModuleName.TMRobot).All(x => x.IsEmpty))
- //&& (CheckWaferNeedProcess(ModuleName.EfemRobot, 0) || CheckWaferNeedProcess(ModuleName.EfemRobot, 1) || CheckWaferNeedProcess(ModuleName.Aligner, 0)))
- return false;
- var tmWafers = WaferManager.Instance.GetWafers(ModuleName.TMRobot);
- for (int i = 0; i < tmWafers.Length; i++)
- {
- if (!tmWafers[i].IsEmpty && !CheckWaferNeedProcess(tmWafers[i]))
- return false;
- }
- foreach (var pm in _lstPms)
- {
- var pmWafer0 = WaferManager.Instance.GetWafer(pm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(pm.Module, 1);
- //如果腔体中两片都满了,则跳过
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- continue;
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var wafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(wafer))
- continue;
- //判断TMRobot是否已经存在相同recipeName的wafer
- for (int i = 0; i < tmWafers.Length; i++)
- {
- if (CheckWaferNeedProcess(tmWafers[i])
- && tmWafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- return false;
- }
- }
- }
- return true;
- }
- //private void MonitorTmRobotDummyWaferBufferTask()
- //{
- // if (!_tmRobot.IsAvailable)
- // return;
- // //place to buffer
- // bool blade0HasWaferAndProcessedDummy = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
- // WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).Status == WaferStatus.Dummy &&
- // WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).ProcessState == EnumWaferProcessStatus.Completed;
- // bool blade1HasWaferAndProcessedDummy = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) &&
- // WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).Status == WaferStatus.Dummy &&
- // WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).ProcessState == EnumWaferProcessStatus.Completed;
- // if (blade0HasWaferAndProcessedDummy || blade1HasWaferAndProcessedDummy)
- // {
- // Hand placeBlade = blade0HasWaferAndProcessedDummy ? Hand.Blade1 : Hand.Blade2;
- // if (blade0HasWaferAndProcessedDummy && blade1HasWaferAndProcessedDummy)
- // {
- // if (WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).OriginSlot <
- // WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).OriginSlot)
- // {
- // placeBlade = Hand.Blade2;
- // }
- // }
- // int placeSlot = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade).OriginSlot;
- // if (WaferManager.Instance.CheckNoWafer(_pm1.Module, placeSlot) && _pm1.IsReadyForPlace(ModuleName.TMRobot, placeBlade, placeSlot))
- // {
- // if (_tmRobot.Place(_pm1.Module, placeSlot, placeBlade))
- // {
- // _pm1.WaitTransfer(ModuleName.TMRobot);
- // return;
- // }
- // }
- // }
- // if (!_tmRobot.IsAvailable)
- // return;
- // //pick from buffer
- // foreach (var schedulerPm in _lstPms)
- // {
- // if (!CheckNeedRunClean(schedulerPm.Module, out bool withWafer, out string _) || !withWafer)
- // continue;
- // if (WaferManager.Instance.CheckHasWafer(schedulerPm.Module, 0))
- // continue;
- // if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) ||
- // WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- // {
- // Hand pickBlade = WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0)
- // ? Hand.Blade1
- // : Hand.Blade2;
- // for (int i = 0; i < 2; i++)
- // {
- // if ((WaferManager.Instance.GetWafer(_pm1.Module, i).ProcessState == EnumWaferProcessStatus.Wait)
- // && _pm1.IsReadyForPick(ModuleName.TMRobot, pickBlade, i))
- // {
- // if (_tmRobot.Pick(_pm1.Module, i, pickBlade))
- // {
- // _pm1.WaitTransfer(ModuleName.TMRobot);
- // return;
- // }
- // }
- // }
- // }
- // }
- //}
- private void MonitorTmRobotPMAPlaceTask()
- {
- //if (!_pm1.IsAvailable)
- // return;
- //if (_tmRobot.HasWafer(0) && CheckWaferNeedProcess(ModuleName.TMRobot, 0, _pm1.Module))
- //{
- // if (WaferManager.Instance.CheckNoWafer(_pm1.Module, 0) && !_pm1.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 0))
- // {
- // _pm1.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
- // return;
- // }
- // if (WaferManager.Instance.CheckNoWafer(_pm1.Module, 1) && !_pm1.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 1))
- // {
- // _pm1.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 1);
- // return;
- // }
- //}
- //if (_tmRobot.HasWafer(1) && CheckWaferNeedProcess(ModuleName.TMRobot, 1, _pm1.Module))
- //{
- // if (WaferManager.Instance.CheckNoWafer(_pm1.Module, 0) && !_pm1.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 0))
- // {
- // _pm1.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
- // return;
- // }
- // if (WaferManager.Instance.CheckNoWafer(_pm1.Module, 1) && !_pm1.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 1))
- // {
- // _pm1.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 1);
- // return;
- // }
- //}
- if (!_tmRobot.IsAvailable)
- return;
- //place
- bool blade0HasWaferAndNeedProcesse = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) && CheckWaferNeedProcess(ModuleName.TMRobot, 0);
- bool blade1HasWaferAndNeedProcesse = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) && CheckWaferNeedProcess(ModuleName.TMRobot, 1);
- if (blade0HasWaferAndNeedProcesse || blade1HasWaferAndNeedProcesse)
- {
- Hand placeBlade = blade0HasWaferAndNeedProcesse ? Hand.Blade1 : Hand.Blade2;
- var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade);
- //foreach (var schedulerPm in _lstPms)
- {
- var schedulerPm = _pm1;
- if (!schedulerPm.IsAvailable)
- return;
- var pmWafer0 = WaferManager.Instance.GetWafer(schedulerPm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(schedulerPm.Module, 1);
- //如果腔体中两片都满了,则不允许放入
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- return;
- //如果腔体中两片都为空,则取一片放入
- if (pmWafer0.IsEmpty && pmWafer1.IsEmpty)
- {
- if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 0)
- && CheckCanPlaceWaferToPM(schedulerPm.Module, wafer))
- {
- if (GetWaferTemperatureSetInRecipe(ModuleName.TMRobot, (int)placeBlade, ModuleName.PMA, out double temp1, out double temp2))
- {
- if (_tmRobot.Place(schedulerPm.Module, 0, placeBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var pmWafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(pmWafer))
- return;
- int placeSlot = pmWafer0.IsEmpty ? 0 : 1;
- if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, placeSlot)
- && CheckCanPlaceWaferToPM(schedulerPm.Module, wafer))
- {
- if (GetWaferTemperatureSetInRecipe(ModuleName.TMRobot, (int)placeBlade, ModuleName.PMA, out double temp1, out double temp2))
- {
- if (_tmRobot.Place(schedulerPm.Module, placeSlot, placeBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- }
- }
- }
- private void MonitorTmRobotPMBPlaceTask()
- {
- //if (!_pm2.IsAvailable)
- // return;
- //if (_tmRobot.HasWafer(0) && CheckWaferNeedProcess(ModuleName.TMRobot, 0, _pm2.Module))
- //{
- // if (WaferManager.Instance.CheckNoWafer(_pm2.Module, 0) && !_pm2.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 0))
- // {
- // _pm2.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
- // return;
- // }
- // if (WaferManager.Instance.CheckNoWafer(_pm2.Module, 1) && !_pm2.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 1))
- // {
- // _pm2.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 1);
- // return;
- // }
- //}
- //if (_tmRobot.HasWafer(1) && CheckWaferNeedProcess(ModuleName.TMRobot, 1, _pm2.Module))
- //{
- // if (WaferManager.Instance.CheckNoWafer(_pm2.Module, 0) && !_pm2.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 0))
- // {
- // _pm2.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
- // return;
- // }
- // if (WaferManager.Instance.CheckNoWafer(_pm2.Module, 1) && !_pm2.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, 1))
- // {
- // _pm2.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 1);
- // return;
- // }
- //}
- if (!_tmRobot.IsAvailable)
- return;
- //place
- bool blade0HasWaferAndNeedProcesse = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) && CheckWaferNeedProcess(ModuleName.TMRobot, 0);
- bool blade1HasWaferAndNeedProcesse = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) && CheckWaferNeedProcess(ModuleName.TMRobot, 1);
- if (blade0HasWaferAndNeedProcesse || blade1HasWaferAndNeedProcesse)
- {
- Hand placeBlade = blade0HasWaferAndNeedProcesse ? Hand.Blade1 : Hand.Blade2;
- var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade);
- //foreach (var schedulerPm in _lstPms)
- {
- var schedulerPm = _pm2;
- if (!schedulerPm.IsAvailable)
- return;
- var pmWafer0 = WaferManager.Instance.GetWafer(schedulerPm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(schedulerPm.Module, 1);
- //如果腔体中两片都满了,则不允许放入
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- return;
- //如果腔体中两片都为空,则取一片放入
- if (pmWafer0.IsEmpty && pmWafer1.IsEmpty)
- {
- if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 0)
- && CheckCanPlaceWaferToPM(schedulerPm.Module, wafer))
- {
- if (GetWaferTemperatureSetInRecipe(ModuleName.TMRobot, (int)placeBlade, ModuleName.PMB, out double temp1, out double temp2))
- {
- if (_tmRobot.Place(schedulerPm.Module, 0, placeBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var pmWafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(pmWafer))
- return;
- int placeSlot = pmWafer0.IsEmpty ? 0 : 1;
- if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, placeSlot)
- && CheckCanPlaceWaferToPM(schedulerPm.Module, wafer))
- {
- if (GetWaferTemperatureSetInRecipe(ModuleName.TMRobot, (int)placeBlade, ModuleName.PMB, out double temp1, out double temp2))
- {
- if (_tmRobot.Place(schedulerPm.Module, placeSlot, placeBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- }
- }
- }
- private void MonitorTmRobotPMAPickTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- // pick
- if ((WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)))
- {
- Hand pickBlade;
- if (_tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
- {
- pickBlade = Hand.Blade1;
- }
- else if (_tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- pickBlade = Hand.Blade2;
- }
- else
- {
- return;
- }
- //foreach (var schedulerPm in _lstPms)
- {
- var schedulerPm = _pm1;
- if (!schedulerPm.IsAvailable)
- return;
- if (CheckCanPickWaferFromPM(schedulerPm.Module, 0))
- {
- if (GetWaferTemperatureSetInRecipe(schedulerPm.Module, 0, ModuleName.PMA, out double temp1, out double temp2))
- {
- if (_tmRobot.Pick(schedulerPm.Module, 0, pickBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- if (CheckCanPickWaferFromPM(schedulerPm.Module, 1))
- {
- if (GetWaferTemperatureSetInRecipe(schedulerPm.Module, 1, ModuleName.PMA, out double temp1, out double temp2))
- {
- if (_tmRobot.Pick(schedulerPm.Module, 1, pickBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- }
- }
- private void MonitorTmRobotPMBPickTask()
- {
- if (!_tmRobot.IsAvailable)
- return;
- // pick
- if ((WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)))
- {
- Hand pickBlade;
- if (_tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
- {
- pickBlade = Hand.Blade1;
- }
- else if (_tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- pickBlade = Hand.Blade2;
- }
- else
- {
- return;
- }
- //foreach (var schedulerPm in _lstPms)
- {
- var schedulerPm = _pm2;
- if (!schedulerPm.IsAvailable)
- return;
- if (CheckCanPickWaferFromPM(schedulerPm.Module, 0))
- {
- if (GetWaferTemperatureSetInRecipe(schedulerPm.Module, 0, ModuleName.PMB, out double temp1, out double temp2))
- {
- if (_tmRobot.Pick(schedulerPm.Module, 0, pickBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- if (CheckCanPickWaferFromPM(schedulerPm.Module, 1))
- {
- if (GetWaferTemperatureSetInRecipe(schedulerPm.Module, 1, ModuleName.PMB, out double temp1, out double temp2))
- {
- if (_tmRobot.Pick(schedulerPm.Module, 1, pickBlade, temp1, temp2, true))
- {
- schedulerPm.WaitTransfer(ModuleName.TMRobot);
- return;
- }
- }
- }
- }
- }
- }
- static readonly List<string> llNameList = new List<string>()
- { "IsAvailable", "Task", "IsOnline", "IsError" , "IsIdle", "IsBusy", "IsPrepareTransfer", "IsCooling", "IsAtm", "IsVacuum", "Cooling", "WaitTransfer"
- , "Wafer0", "Wafer1", "Wafer2", "Wafer3", "Wafer4", "Wafer5"
- , "NextStep0", "NextStep1", "NextStep2", "NextStep3", "NextStep4", "NextStep5"
- , "need0", "need1", "need2", "need3", "need4", "need5"};
- static readonly List<string> efemNameList = new List<string>()
- { "IsAvailable","IsOnline","IsReady","Task","IsError"," WaitTransfer"
- , "Wafer0", "Wafer1", "Wafer2"
- , "NextStep0", "NextStep1", "NextStep2"
- , "need0", "need1", "need2"};
- static readonly List<string> tmRobotNameList = new List<string>()
- { "IsAvailable","IsOnline","IsError","Task","IsError"," WaitTransfer"
- , "Wafer0", "Wafer1", "Wafer2", "Wafer3"
- , "NextStep0", "NextStep1", "NextStep2", "NextStep3"
- , "need0", "need1", "need2", "need3"};
- static readonly List<string> pmNameList = new List<string>()
- { "IsAvailable","IsOnline","IsError","TaskDone","IsError"," WaitTransfer"
- , "Wafer0", "Wafer1", "Wafer2", "Wafer3"
- , "NextStep0", "NextStep1", "NextStep2", "NextStep3"
- , "need0", "need1", "need2", "need3"};
- static readonly List<string> lpNameList = new List<string>()
- { "IsAvailable","Task","IsOnline","IsError","IsReady"};
- private int _GetWaferNextStepId(ModuleName module, int slotId)
- {
- if (!WaferManager.Instance.IsWaferSlotLocationValid(module, slotId)) return -1;
- var wafer = WaferManager.Instance.GetWafer(module, slotId);
- return wafer.NextSequenceStep;
- }
- private string _GetWaferOrigin(ModuleName module, int slotId)
- {
- if (!WaferManager.Instance.IsWaferSlotLocationValid(module, slotId)) return "";
- var wafer = WaferManager.Instance.GetWafer(module, slotId);
- return wafer.WaferOrigin;
- }
- private void MonitorEfemRobotTask()
- {
- if (!_efem.IsAvailable)
- return;
- ////efem robot is idle, release all the target
- foreach (var ll in _lstLls)
- {
- if (ll.IsWaitTransfer(ModuleName.EfemRobot))
- ll.StopWaitTransfer(ModuleName.EfemRobot);
- }
- if (_aligner.IsWaitTransfer(ModuleName.EfemRobot))
- _aligner.StopWaitTransfer(ModuleName.EfemRobot);
- foreach (var lp in _lstLps)
- {
- if (lp.IsWaitTransfer(ModuleName.EfemRobot))
- lp.StopWaitTransfer(ModuleName.EfemRobot);
- }
- if (!_efem.IsAvailable)
- return;
- var act = efemRobotActions.Peek();
- act.Invoke();
- if (!_efem.IsAvailable)
- return;
- efemRobotActions.Enqueue(efemRobotActions.Dequeue());
- //if (!_efem.IsAvailable)
- // return;
- //MonitorEfemRobotAlignerTask();
- //if (!_efem.IsAvailable)
- // return;
- //MonitorEfemRobotLoadLockTask();
- //if (_aligner.HasWafer(0) && (!_efem.Blade1Enable || !_efem.Blade2Enable))
- // return;
- //if (_aligner.HasWafer(0) && (_efem.HasWafer(0) || _efem.HasWafer(1)))
- // return;
- //if (!_efem.IsAvailable)
- // return;
- //MonitorEfemRobotLoadPortTask();
- //MonitorEfemRobotGoToTask();
- }
- private void MonitorEfemRobotLoadPortPlaceTask()
- {
- if (!_efem.IsAvailable)
- return;
- //place
- bool blade0HasWaferAndProcessed = _efem.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) &&
- !CheckWaferNeedProcess(ModuleName.EfemRobot, 0);
- bool blade1HasWaferAndProcessed = _efem.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) &&
- !CheckWaferNeedProcess(ModuleName.EfemRobot, 1);
- if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed)
- {
- Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2;
- if (blade0HasWaferAndProcessed && blade1HasWaferAndProcessed)
- {
- if (WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).OriginSlot <
- WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).OriginSlot)
- {
- placeBlade = Hand.Blade2;
- }
- }
- SlotItem destination = GetWaferReturnLoadPort(ModuleName.EfemRobot, (int)placeBlade);
- if (destination != null && ModuleHelper.IsLoadPort(destination.Module))
- {
- SchedulerLoadPort lp = (SchedulerLoadPort)GetModule(destination.Module.ToString());
- if (lp.IsReadyForPlace(ModuleName.EfemRobot, placeBlade, destination.Slot))
- {
- if (_efem.Place(destination.Module, destination.Slot, placeBlade))
- {
- lp.WaitTransfer(ModuleName.EfemRobot);
- if (_CycleData.IsCycleMode)
- _CycleData.IncreaseWaferCount(1);
- //_cycledTotalWafer++;
- //if (SC.ContainsItem("System.TotalCycledWafer"))
- // SC.SetItemValue("System.TotalCycledWafer", _cycledTotalWafer);
- return;
- }
- }
- }
- }
- }
- private void MonitorEfemRobotLoadPortPickTask()
- {
- if (!_efem.IsAvailable)
- return;
- if (_aligner.HasWafer(0) && (!_efem.Blade1Enable || !_efem.Blade2Enable))
- return;
- if (_aligner.HasWafer(0) && (_efem.HasWafer(0) || _efem.HasWafer(1)))
- return;
- if (_lstLls.Any(x => GetEmptySlotInLoadLock(x) < 4))
- return;
- //pick
- bool isBlade0Empty = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
- bool isBlade1Empty = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
- if (GetWaferCountInJobQueue() > 0 && (isBlade0Empty || isBlade1Empty) && EfemRobotPickAllowable)
- {
- Hand pickBlade = isBlade1Empty ? Hand.Blade2 : Hand.Blade1;
- SlotItem position = GetWaferInJobQueue();
- if (position != null)
- {
- SchedulerLoadPort lp = GetModule(position.Module.ToString()) as SchedulerLoadPort;
- if (lp != null && lp.IsReadyForPick(ModuleName.EfemRobot, pickBlade, position.Slot))
- {
- //WaferManager.Instance.GetWafer(position.Module, position.Slot).NextSequenceStep++;
- if (_efem.Pick(position.Module, position.Slot, pickBlade))
- {
- lp.WaitTransfer(ModuleName.EfemRobot);
- return;
- }
- }
- }
- }
- }
- private bool GetWaferProcessAccess(WaferInfo wafer)
- {
- if (wafer.ProcessJob == null || string.IsNullOrEmpty(wafer.ProcessJob.Name))
- return false;
- return GetPMOccupiedCount(wafer.ProcessJob.Name) > GetWaitingProcessWaferCount(wafer.ProcessJob.Name);
- }
- private int GetPMOccupiedCount(string pjName)
- {
- List<ModuleName> location = new List<ModuleName>();
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.Name != pjName)
- continue;
- if (pj.State != EnumProcessJobState.Processing)
- continue;
- foreach (var step in pj.Sequence.Steps)
- {
- foreach (var module in step.StepModules)
- {
- if (ModuleHelper.IsPm(module) && !location.Exists(x => x == module))
- location.Add(module);
- }
- }
- }
- return location.Count;
- }
- private int GetWaitingProcessWaferCount(string pjName)
- {
- List<Tuple<ModuleName, int>> location = new List<Tuple<ModuleName, int>>()
- {
- Tuple.Create(ModuleName.TMRobot, 0),
- Tuple.Create(ModuleName.TMRobot, 1),
- Tuple.Create(ModuleName.LLA, 0),
- Tuple.Create(ModuleName.LLB, 0),
- Tuple.Create(ModuleName.AlignerB, 0),
- Tuple.Create(ModuleName.PMA, 0),
- Tuple.Create(ModuleName.PMB, 0),
- Tuple.Create(ModuleName.PMC, 0),
- };
- int count = 0;
- foreach (var tuple in location)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(tuple.Item1, tuple.Item2);
- if (wafer.IsEmpty)
- continue;
- if (wafer.ProcessJob != null && wafer.ProcessJob.Name == pjName)
- count++;
- }
- return count;
- }
- Dictionary<string, Dictionary<string, List<object>>> _ValueDict = new Dictionary<string, Dictionary<string, List<object>>>();
- //private void PrintVariables(string key, List<string> names, params object[] values)
- //{
- // StackTrace trace = new StackTrace(true);
- // var frames = trace.GetFrames();//1代表上级,2代表上上级,以此类推
- // if (frames.Length < 2) return;
- // var frame1 = frames[1];
- // var method1 = frame1.GetMethod();
- // if (method1 == null) return;
- // string methodName = method1.Name;
- // var newList = values.ToList();
- // if (!_ValueDict.ContainsKey(methodName))
- // {
- // _ValueDict[methodName] = new Dictionary<string, List<object>>() { { key, newList } };
- // LOG.Debug($"{methodName} Key={key} Values({_ToString(names, newList)})");
- // }
- // else
- // {
- // var dict = _ValueDict[methodName];
- // if (dict.ContainsKey(key))
- // {
- // var list = dict[key];
- // StringBuilder builder = new StringBuilder();
- // for (int ii = 0; ii < names.Count; ii++)
- // {
- // if (list[ii].Equals(newList[ii])) continue;
- // builder.Append($",{names[ii]}({list[ii]} --> {newList[ii]})");
- // list[ii] = newList[ii];
- // }
- // if (builder.Length > 0)
- // {
- // LOG.Debug($"{methodName} Key={key} {builder.ToString()}");
- // }
- // }
- // else
- // {
- // _ValueDict[methodName].Add(key, newList);
- // LOG.Debug($"{methodName} Key={key} Values({_ToString(names, newList)})");
- // }
- // }
- //}
- private string _ToString(List<string> names, List<object> objList)
- {
- StringBuilder builder = new StringBuilder();
- for (int ii = 0; ii < names.Count; ii++)
- {
- builder.Append($",{names[ii]}={objList[ii]}");
- }
- return builder.ToString().Trim(',');
- }
- private void MonitorEfemRobotLoadLockPickTask()
- {
- if (!_efem.IsAvailable)
- return;
- foreach (var ll in _lstLls)
- {
- if (!ll.IsAvailable)
- continue;
- //pick
- bool blade1EmptyAndEnable = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
- bool blade2EmptyAndEnable = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
- if (blade1EmptyAndEnable || blade2EmptyAndEnable)
- {
- if (CheckWaferNeedProcess(ModuleName.EfemRobot, 0) || CheckWaferNeedProcess(ModuleName.EfemRobot, 1))
- continue;
- Hand pickBlade = blade2EmptyAndEnable ? Hand.Blade2 : Hand.Blade1;
- int pickSlot = Int32.MaxValue;
- for (int i = 0; i < 8; i++)
- {
- if (!CheckWaferNeedProcess(ll.Module, i) &&
- ll.IsReadyForPick(ModuleName.EfemRobot, pickBlade, i))
- {
- pickSlot = i;
- break;
- }
- }
- if (pickSlot != Int32.MaxValue)
- {
- //WaferManager.Instance.GetWafer(ll.Module, pickSlot).NextSequenceStep++;
- if (_efem.Pick(ll.Module, pickSlot, pickBlade))
- {
- ll.WaitTransfer(ModuleName.EfemRobot);
- return;
- }
- }
- }
- }
- if (!_efem.IsAvailable)
- return;
- }
- private void MonitorEfemRobotLoadLockPlaceTask()
- {
- if (!_efem.IsAvailable)
- return;
- //place
- foreach (var ll in _lstLls)
- {
- if (!ll.IsAvailable)
- continue;
- bool blade1NeedPlace = _efem.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) && CheckWaferNeedProcess(ModuleName.EfemRobot, 0) && !CheckWaferNextStepIsAlign(ModuleName.EfemRobot, 0);
- bool blade2NeedPlace = _efem.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) && CheckWaferNeedProcess(ModuleName.EfemRobot, 1) && !CheckWaferNextStepIsAlign(ModuleName.EfemRobot, 1);
- if (!blade1NeedPlace && !blade2NeedPlace)
- {
- EfemRobotPickAllowable = true;
- }
- else
- {
- EfemRobotPickAllowable = false;
- }
- if (blade1NeedPlace || blade2NeedPlace)
- {
- Hand placeBlade = blade1NeedPlace ? Hand.Blade1 : Hand.Blade2;
- if (!CheckWaferNextStepIsLoadLock(ModuleName.EfemRobot, (int)placeBlade, ll.Module))
- continue;
- int placeSlot = Int32.MaxValue;
- if (blade1NeedPlace || blade2NeedPlace)
- {
- for (int i = 0; i < 6; i++)
- {
- if (ll.IsReadyForPlace(ModuleName.EfemRobot, placeBlade, i))
- {
- placeSlot = i;
- break;
- }
- }
- }
- if (placeSlot != Int32.MaxValue)
- {
- if (_efem.Place(ll.Module, (int)placeSlot, placeBlade))
- {
- WaferManager.Instance.GetWafer(ModuleName.EfemRobot, (int)placeBlade).NextSequenceStep++;
- ll.WaitTransfer(ModuleName.EfemRobot);
- return;
- }
- }
- }
- }
- }
- private void MonitorEfemRobotAlignerPickTask()
- {
- if (!_efem.IsAvailable)
- return;
- if (!_aligner.IsAvailable)
- return;
- //pick from aligner
- if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner, 0) && !CheckWaferNextStepIsAlign(ModuleName.Aligner, 0))
- {
- bool blade1EmptyAndEnable = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
- bool blade2EmptyAndEnable = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
- if (blade1EmptyAndEnable || blade2EmptyAndEnable)
- {
- Hand pickBlade = blade1EmptyAndEnable ? Hand.Blade1 : Hand.Blade2;
- //if ((blade1Empty && blade2Empty))
- {
- if (_aligner.IsReadyForPick(ModuleName.EfemRobot, pickBlade, 0))
- {
- if (_efem.Pick(_aligner.Module, 0, pickBlade))
- {
- _aligner.WaitTransfer(ModuleName.EfemRobot);
- return;
- }
- }
- }
- }
- }
- if (!_efem.IsAvailable)
- return;
- }
- private void MonitorEfemRobotAlignerPlaceTask()
- {
- if (!_efem.IsAvailable)
- return;
- //place to aligner
- if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner, 0))
- {
- bool blade1NeedAlign = _efem.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) &&
- CheckWaferNextStepIsAlign(ModuleName.EfemRobot, 0);
- bool blade2NeedAlign = _efem.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) &&
- CheckWaferNextStepIsAlign(ModuleName.EfemRobot, 1);
- if (blade1NeedAlign || blade2NeedAlign)
- {
- Hand placeBlade = blade1NeedAlign ? Hand.Blade1 : Hand.Blade2;
- if (blade1NeedAlign && blade2NeedAlign &&
- WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).OriginSlot <
- WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).OriginSlot)
- placeBlade = Hand.Blade2;
- if (_aligner.IsReadyForPlace(ModuleName.EfemRobot, placeBlade, 0))
- {
- if (_efem.Place(_aligner.Module, 0, placeBlade))
- {
- _aligner.WaitTransfer(ModuleName.EfemRobot);
- return;
- }
- }
- }
- }
- }
- //private void MonitorEfemRobotGoToTask()
- //{
- // if (!_efem.IsAvailable)
- // return;
- // SchedulerLoadLock gotoLL = null;
- // Hand gotoBlade = Hand.Both;
- // int gotoSlot = int.MaxValue;
- // bool arm1Empty = WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
- // bool arm2Empty = WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 2);
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsOnline)
- // continue;
- // if (!ll.Entity.IsPrepareTransfer)
- // continue;
- // if (arm1Empty && arm2Empty)
- // {
- // for (int i = 0; i <= 5; i++)
- // {
- // var wafer = WaferManager.Instance.GetWafer(ll.Module, i);
- // if (wafer != null && !wafer.IsEmpty && wafer.ProcessState == EnumWaferProcessStatus.Completed)
- // {
- // gotoLL = ll;
- // gotoBlade = Hand.Both;
- // gotoSlot = 0;
- // break;
- // }
- // }
- // }
- // else
- // {
- // if (!arm1Empty && !arm2Empty)
- // {
- // for (int i = 0; i <= 1; i++)
- // {
- // if (WaferManager.Instance.CheckNoWafer(ll.Module, i) &&
- // WaferManager.Instance.CheckNoWafer(ll.Module, i + 2) &&
- // WaferManager.Instance.CheckNoWafer(ll.Module, i + 4))
- // {
- // gotoBlade = Hand.Both;
- // gotoSlot = i;
- // gotoLL = ll;
- // break;
- // }
- // else if (WaferManager.Instance.CheckNoWafer(ll.Module, i) &&
- // WaferManager.Instance.CheckNoWafer(ll.Module, i + 2))
- // {
- // gotoBlade = Hand.Blade1;
- // gotoSlot = i;
- // gotoLL = ll;
- // break;
- // }
- // if (ll.IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade2, i + 4))
- // {
- // gotoBlade = Hand.Blade2;
- // gotoSlot = i + 4;
- // gotoLL = ll;
- // break;
- // }
- // }
- // }
- // else if (!arm1Empty)
- // {
- // for (int i = 0; i <= 1; i++)
- // {
- // if (WaferManager.Instance.CheckNoWafer(ll.Module, i) &&
- // WaferManager.Instance.CheckNoWafer(ll.Module, i + 2) &&
- // WaferManager.Instance.CheckNoWafer(ll.Module, i + 4))
- // {
- // gotoBlade = Hand.Both;
- // gotoSlot = i;
- // gotoLL = ll;
- // break;
- // }
- // }
- // }
- // else
- // {
- // for (int i = 0; i <= 1; i++)
- // {
- // if (ll.IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade2, i + 4))
- // {
- // gotoBlade = Hand.Blade2;
- // gotoSlot = i + 4;
- // gotoLL = ll;
- // break;
- // }
- // }
- // if (gotoSlot == Int32.MaxValue)
- // {
- // for (int i = 0; i <= 5; i++)
- // {
- // if (ll.IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade2, i))
- // {
- // gotoBlade = Hand.Blade2;
- // gotoSlot = i + 4;
- // gotoLL = ll;
- // break;
- // }
- // }
- // }
- // }
- // }
- // if (gotoLL != null && gotoSlot != int.MaxValue)
- // break;
- // }
- // if (gotoLL != null && gotoSlot != int.MaxValue)
- // {
- // if (_efem.PreviousTarget == gotoLL.Module)
- // return;
- // if (_efem.Goto(gotoLL.Module, gotoSlot, gotoBlade))
- // {
- // gotoLL.WaitTransfer(ModuleName.EfemRobot);
- // return;
- // }
- // }
- //}
- private SlotItem GetNextWaferInJobQueue(ModuleName lpModule)
- {
- if (!_isRunningInParallelMode)
- {
- foreach (var cj in _lstControlJobs)
- {
- if (lpModule != ModuleName.System && (cj.Module != lpModule.ToString()))
- continue;
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (CheckWaferNeedProcessAndPMAvailable(pjSlotWafer.Item1, pjSlotWafer.Item2))
- return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
- }
- }
- }
- }
- }
- return null;
- }
- //parallel mode
- Dictionary<string, SlotItem> pjWafer = new Dictionary<string, SlotItem>();
- Dictionary<string, List<ModuleName>> pmUsed = new Dictionary<string, List<ModuleName>>();
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State != EnumControlJobState.Executing)
- continue;
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (CheckWaferNeedProcessAndPMAvailable(pjSlotWafer.Item1, pjSlotWafer.Item2))
- {
- pjWafer[pj.Name] = new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
- break;
- }
- }
- }
- }
- }
- if (pjWafer.Count == 0)
- return null;
- if (pjWafer.Count == 1)
- return pjWafer.Values.First();
- string preferPj = pjWafer.Keys.First();
- int runningWaferCount = GetWaitingProcessWaferCount(preferPj);
- foreach (var slotItem in pjWafer)
- {
- if (slotItem.Key == preferPj)
- continue;
- int count = GetWaitingProcessWaferCount(slotItem.Key);
- if (count < runningWaferCount)
- {
- preferPj = slotItem.Key;
- runningWaferCount = count;
- }
- }
- return pjWafer[preferPj];
- }
- public bool CheckWaferNeedProcessAndPMAvailable(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- if (wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(ModuleName.PMA) || wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(ModuleName.PMB))
- {
- var hasPmAvailable = false;
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
- {
- var pm = GetModule(stepModule.ToString()) as SchedulerPM;
- if (pm != null)
- {
- if (pm.IsAvailable || (pm.IsOnline && pm.Task != SchedulerModule.TaskType.PreJobProcess))
- {
- hasPmAvailable = true;
- break;
- }
- }
- }
- if (!hasPmAvailable)
- return false;
- if (processIn == ModuleName.System)
- return true;
- if (wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(processIn))
- return true;
- }
- }
- return false;
- }
- public bool LoadRecipe(string module, string CurrentRecipeBaseName, out double temp1, out double temp2)
- {
- var CurrentRecipeContent = RecipeFileManager.Instance.LoadRecipe("", CurrentRecipeBaseName, true);
- temp1 = 0;
- temp2 = 0;
- if (string.IsNullOrEmpty(CurrentRecipeContent))
- {
- EV.PostInfoLog(ModuleName.System.ToString(), $"error during read recipe file {CurrentRecipeBaseName}");
- return false;
- }
- if (!Recipe.Parse(module, CurrentRecipeContent, out RecipeHead recipeHead, out var recipeSteps))
- {
- return false;
- }
- temp1 = GetChamber1Temp(recipeHead);
- temp2 = GetChamber2Temp(recipeHead);
- return true;
- }
- public double GetChamber1Temp(RecipeHead CurrentRecipeHead)
- {
- if (CurrentRecipeHead != null)
- {
- if (!string.IsNullOrEmpty(CurrentRecipeHead.Chamber1Temperature))
- {
- double setpoint = Convert.ToDouble(CurrentRecipeHead.Chamber1Temperature);
- if (setpoint > 0 && setpoint < 600)
- return setpoint;
- }
- }
- return 0;
- }
- public double GetChamber2Temp(RecipeHead CurrentRecipeHead)
- {
- if (CurrentRecipeHead != null)
- {
- if (!string.IsNullOrEmpty(CurrentRecipeHead.Chamber2Temperature))
- {
- double setpoint = Convert.ToDouble(CurrentRecipeHead.Chamber2Temperature);
- if (setpoint > 0 && setpoint < 600)
- return setpoint;
- }
- }
- return 0;
- }
- private bool GetWaferTemperatureSetInRecipe(ModuleName waferModule, int waferSlot, ModuleName pmModule, out double temp1, out double temp2)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- var seq = wafer.ProcessJob.Sequence;
- for (int i = 0; i < seq.Steps.Count; i++)
- {
- SequenceStepInfo stepInfo = seq.Steps[i];
- foreach (var module in stepInfo.StepModules)
- {
- if (module == pmModule)
- {
- LoadRecipe(pmModule.ToString(), seq.Steps[i].StepParameter[module == ModuleName.PMA ? "PMARecipe" : "PMBRecipe"].ToString(), out double chambertemp1, out double chambertemp2);
- temp1 = (double)chambertemp1;
- temp2 = (double)chambertemp2;
- return true;
- }
- }
- }
- temp1 = 0;
- temp2 = 0;
- LOG.Error($"Can not find wafer {waferModule} {waferSlot + 1} temperature set in recipe");
- return false;
- }
- #endregion
- #region Logic Check
- private bool CheckLoadLockAvaiableForTMRobot()
- {
- bool isPrepareTransferForTMobot = GetVacuumWafer() == 0;
- foreach (var ll in _lstLls)
- {
- if (!ll.IsAvailable)
- continue;
- var deviceLL = DEVICE.GetDevice<LoadLock>(ll.Module.ToString());
- var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- for (int i = 0; i <= 5;)
- {
- var wafer0 = WaferManager.Instance.GetWafer(ll.Module, i);
- var wafer1 = WaferManager.Instance.GetWafer(ll.Module, i + 1);
- if ((!wafer0.IsEmpty && wafer0.ProcessState == EnumWaferProcessStatus.Idle) ||
- (!wafer1.IsEmpty && wafer1.ProcessState == EnumWaferProcessStatus.Idle))
- {
- isPrepareTransferForTMobot = true;
- break;
- }
- i += 2;
- }
- }
- return isPrepareTransferForTMobot;
- }
- //private bool CheckPMTemperature(string module)
- //{
- // var pmDevice = DEVICE.GetDevice<SpinelPM>(module);
- // if (pmDevice != null && _temperatureSetpointDic.ContainsKey(module) && _temperatureSetpointDic[module] > 0)
- // {
- // if (!pmDevice.CheckHeater1Temperature(_temperatureSetpointDic[module]) ||
- // !pmDevice.CheckHeater2Temperature(_temperatureSetpointDic[module]))
- // {
- // if (!_temperatureTrigDic.ContainsKey(module))
- // _temperatureTrigDic.Add(module, new R_TRIG());
- // _temperatureTrigDic[module].CLK = true;
- // if (_temperatureTrigDic[module].Q)
- // {
- // EV.PostWarningLog("Scheduler", $"{module} heater temperature is not in the scope");
- // }
- // pmDevice.SetHeater1(_temperatureSetpointDic[module]);
- // pmDevice.SetHeater2(_temperatureSetpointDic[module]);
- // }
- // if (pmDevice.CheckHeater1Temperature(_temperatureSetpointDic[module]) &&
- // pmDevice.CheckHeater2Temperature(_temperatureSetpointDic[module]))
- // {
- // return true;
- // }
- // }
- // else
- // return true;
- // return false;
- //}
- private bool CheckWaferNextProcessIsPM(ModuleName waferModule, int waferSlot)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.ProcessJob == null ||
- wafer.ProcessJob.Sequence == null ||
- wafer.ProcessJob.Sequence.Steps == null ||
- wafer.ProcessJob.Sequence.Steps.Count <= wafer.NextSequenceStep ||
- wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep] == null ||
- wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- {
- return false;
- }
- return wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Any(x => ModuleHelper.IsPm(x));
- }
- private bool CheckWaferNextProcessIsPMAvaiable(ModuleName waferModule, int waferSlot)
- {
- if (!CheckWaferNextProcessIsPM(waferModule, waferSlot))
- return false;
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
- {
- if (_lstPms.Any(pm => pm.Module == stepModule && pm.IsAvailable && WaferManager.Instance.CheckNoWafer(pm.Module, waferSlot)))
- {
- return true;
- }
- }
- return false;
- }
- private bool CheckNeedRunClean(ModuleName module, out bool withWafer, out string recipeName)
- {
- recipeName = string.Empty;
- withWafer = false;
- return false;
- SequenceInfo seq = GetCurrentSequenceInfo();
- int waferProcessed = StatsDataManager.Instance.GetValue($"{module}.WaferProcessedSincePreviousClean");
- if (seq == null)
- return false;
- foreach (var stepInfo in seq.Steps)
- {
- if (!stepInfo.StepModules.Contains(module))
- continue;
- if (stepInfo.StepParameter.ContainsKey("CleanRecipeNoWafer")
- && !string.IsNullOrEmpty((string)stepInfo.StepParameter["CleanRecipeNoWafer"]))
- {
- if (stepInfo.CleanInterval > 0 && waferProcessed >= stepInfo.CleanInterval)
- {
- recipeName = (string)stepInfo.StepParameter["CleanRecipeNoWafer"];
- withWafer = false;
- return true;
- }
- }
- if (stepInfo.StepParameter.ContainsKey("CleanRecipeWafer")
- && !string.IsNullOrEmpty((string)stepInfo.StepParameter["CleanRecipeWafer"]))
- {
- if (stepInfo.CleanInterval > 0 && waferProcessed >= stepInfo.CleanInterval)
- {
- recipeName = (string)stepInfo.StepParameter["CleanRecipeWafer"];
- withWafer = true;
- return true;
- }
- }
- }
- return false;
- }
- private bool CheckVacuumWaferHasAvailableTarget(ModuleName waferModule, int waferSlot, ModuleName chamberSwappable)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- //System.Diagnostics.Trace.Assert(!wafer.IsEmpty);
- if (CheckWaferNeedProcess(waferModule, waferSlot))
- {
- // Check for an empty PM
- foreach (var pm in _lstPms)
- {
- if (WaferManager.Instance.CheckNoWafer(pm.Module, 0) || pm.Module == chamberSwappable)
- {
- if (pm.IsAvailable == false)
- continue;
- if (!CheckWaferNextProcessIn(waferModule, waferSlot, pm.Module))
- continue;
- return true;
- }
- }
- }
- else
- {
- // No more processing needed, check for a outbound loadlock slot
- return true;
- }
- return false;
- }
- private bool CheckWaferNextProcessIn(ModuleName waferModule, int waferSlot, ModuleName chamber)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.ProcessJob == null ||
- wafer.ProcessJob.Sequence == null ||
- wafer.ProcessJob.Sequence.Steps == null ||
- wafer.ProcessJob.Sequence.Steps.Count <= wafer.NextSequenceStep ||
- wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep] == null ||
- wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- {
- return false;
- }
- return wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(chamber);
- }
- private SequenceInfo GetCurrentSequenceInfo()
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.State == EnumProcessJobState.Processing)
- {
- return pj.Sequence;
- }
- }
- return null;
- }
- private bool GetWaferSequenceAlignAngle(ModuleName module, int slot, out double angle)
- {
- angle = 0;
- if (!WaferManager.Instance.CheckHasWafer(module, slot))
- return false;
- WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.Aligner))
- return false;
- angle = wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].AlignAngle;
- return true;
- }
- private bool GetWaferSequenceLoadLockCoolingTime(ModuleName module, int slot, out int coolingTime)
- {
- coolingTime = 0;
- if (!WaferManager.Instance.CheckHasWafer(module, slot))
- return false;
- WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(module))
- return false;
- if (!int.TryParse(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["CoolingTime"].ToString(),
- out coolingTime))
- {
- coolingTime = SC.GetValue<int>("System.DefaultCoolingTime");
- EV.PostWarningLog("Scheduler", $"Sequence step LL cooling time is not valid, instead with the SC default value {coolingTime} seconds");
- return false;
- }
- return true;
- }
- private bool CheckWaferNextStepIsLoadLock(ModuleName module, int slot, ModuleName LL = ModuleName.System)
- {
- if (!WaferManager.Instance.CheckHasWafer(module, slot))
- return false;
- WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- if (LL != ModuleName.System && !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(LL))
- return false;
- if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.LLA) &&
- !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.LLB))
- return false;
- return true;
- }
- private bool CheckWaferNextStepIsAlign(ModuleName module, int slot)
- {
- if (!WaferManager.Instance.CheckHasWafer(module, slot))
- return false;
- WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.Aligner) &&
- !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.AlignerA) &&
- !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.AlignerB))
- return false;
- return true;
- }
- public bool CheckWaferNeedProcess(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.Status == WaferStatus.Dummy && wafer.ProcessState == EnumWaferProcessStatus.Wait)
- {
- if (ModuleHelper.IsPm(processIn))
- {
- return (CheckNeedRunClean(processIn, out bool withWafer, out _) && withWafer);
- }
- return true;
- }
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count || wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- return false;
- if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(processIn))
- return false;
- bool hasPm = false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
- {
- if (ModuleHelper.IsPm(stepModule))
- {
- hasPm = true;
- break;
- }
- }
- if (hasPm)
- break;
- }
- if (processIn == ModuleName.System && !hasPm)
- return false;
- return true;
- }
- public bool CheckWaferNeedProcess(WaferInfo wafer, ModuleName processIn = ModuleName.System)
- {
- if (wafer.IsEmpty)
- return false;
- if (wafer.Status == WaferStatus.Dummy && wafer.ProcessState == EnumWaferProcessStatus.Wait)
- {
- if (ModuleHelper.IsPm(processIn))
- {
- return (CheckNeedRunClean(processIn, out bool withWafer, out _) && withWafer);
- }
- return true;
- }
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count || wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- return false;
- if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(processIn))
- return false;
- bool hasPm = false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
- {
- if (ModuleHelper.IsPm(stepModule))
- {
- hasPm = true;
- break;
- }
- }
- if (hasPm)
- break;
- }
- if (processIn == ModuleName.System && !hasPm)
- return false;
- return true;
- }
- public bool CheckWaferNeedProcessPre(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- if (wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(ModuleName.PMA) || wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(ModuleName.PMB))
- {
- if (processIn == ModuleName.System)
- return true;
- if (wafer.ProcessJob.Sequence.Steps[i].StepModules
- .Contains(processIn))
- return true;
- }
- }
- return false;
- }
- public bool CheckWaferNeedGotoPM(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.Status == WaferStatus.Dummy && wafer.ProcessState == EnumWaferProcessStatus.Wait)
- {
- if (ModuleHelper.IsPm(processIn))
- {
- return (CheckNeedRunClean(processIn, out bool withWafer, out _) && withWafer);
- }
- return true;
- }
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count || wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- return false;
- if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps.Any(x => x.StepModules.Contains(processIn)))
- return false;
- bool hasPm = false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
- {
- if (ModuleHelper.IsPm(stepModule))
- {
- hasPm = true;
- break;
- }
- }
- if (hasPm)
- break;
- }
- if (processIn == ModuleName.System && !hasPm)
- return false;
- return true;
- }
- public bool CheckWaferNeedGotoPM(WaferInfo wafer, ModuleName processIn = ModuleName.System)
- {
- if (wafer.IsEmpty)
- return false;
- if (wafer.Status == WaferStatus.Dummy && wafer.ProcessState == EnumWaferProcessStatus.Wait)
- {
- if (ModuleHelper.IsPm(processIn))
- {
- return (CheckNeedRunClean(processIn, out bool withWafer, out _) && withWafer);
- }
- return true;
- }
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count || wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
- return false;
- if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps.Any(x => x.StepModules.Contains(processIn)))
- return false;
- bool hasPm = false;
- for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
- {
- foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
- {
- if (ModuleHelper.IsPm(stepModule))
- {
- hasPm = true;
- break;
- }
- }
- if (hasPm)
- break;
- }
- if (processIn == ModuleName.System && !hasPm)
- return false;
- return true;
- }
- public bool CheckWaferSequenceStepDone(ModuleName waferModule, int waferSlot)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep < wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- return true;
- }
- public bool CheckWaferProcessModuleIsAvailable(ModuleName waferModule, int waferSlot)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
- if (wafer.IsEmpty)
- return false;
- if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
- return false;
- if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
- return false;
- foreach (var step in wafer.ProcessJob.Sequence.Steps)
- {
- foreach (var module in step.StepModules)
- {
- if (WaferManager.Instance.CheckNoWafer(module, 0)
- && _lstPms.Find(x => x.Module == module).IsAvailable
- && !CheckNeedRunClean(module, out bool _, out string _))
- return true;
- }
- }
- return false;
- }
- private int GetATMWafer()
- {
- int count = GetWaferCountInJobQueue();
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0))
- count++;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1))
- count++;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 2))
- count++;
- return count;
- }
- private int GetVacuumWafer()
- {
- int count = 0;
- foreach (var schedulerPm in _lstPms)
- {
- if (schedulerPm == null ||
- (!schedulerPm.IsOnline))
- continue;
- if (WaferManager.Instance.CheckHasWafer(schedulerPm.Module, 0) || WaferManager.Instance.CheckHasWafer(schedulerPm.Module, 1))
- count++;
- }
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1))
- count++;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
- count++;
- return count;
- }
- private int GetVacuumProcessedWafer()
- {
- int count = 0;
- foreach (var schedulerPm in _lstPmsCurrentSequence)
- {
- if (schedulerPm == null)
- continue;
- if (WaferManager.Instance.CheckHasWafer(schedulerPm.Module, 0)
- && schedulerPm.IsAvailable
- && !CheckWaferNeedProcess(schedulerPm.Module, 0)
- && !WaferManager.Instance.CheckWaferIsDummy(schedulerPm.Module, 0))
- count++;
- }
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) && !CheckWaferNeedProcess(ModuleName.TMRobot, 0) && !WaferManager.Instance.CheckWaferIsDummy(ModuleName.TMRobot, 0))
- count++;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) && !CheckWaferNeedProcess(ModuleName.TMRobot, 1) && !WaferManager.Instance.CheckWaferIsDummy(ModuleName.TMRobot, 1))
- count++;
- return count;
- }
- private int GetUnprocessedWafer()
- {
- int count = 0;
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (CheckWaferNeedProcess(pjSlotWafer.Item1, pjSlotWafer.Item2))
- count++;
- }
- }
- }
- }
- }
- foreach (var ll in _lstLls)
- {
- if (CheckWaferNeedProcess(ll.Module, 0))
- count++;
- if (CheckWaferNeedProcess(ll.Module, 1))
- count++;
- if (CheckWaferNeedProcess(ll.Module, 2))
- count++;
- if (CheckWaferNeedProcess(ll.Module, 3))
- count++;
- if (CheckWaferNeedProcess(ll.Module, 4))
- count++;
- if (CheckWaferNeedProcess(ll.Module, 5))
- count++;
- }
- if (CheckWaferNeedProcess(ModuleName.TMRobot, 0))
- count++;
- if (CheckWaferNeedProcess(ModuleName.TMRobot, 1))
- count++;
- if (CheckWaferNeedProcess(ModuleName.TMRobot, 2))
- count++;
- if (CheckWaferNeedProcess(ModuleName.TMRobot, 3))
- count++;
- return count;
- }
- private int GetAvailablePmCount()
- {
- int count = 0;
- foreach (var pm in _lstPms)
- {
- if (!pm.IsAvailable)
- continue;
- if (WaferManager.Instance.CheckNoWafer(pm.Module, 0))
- count++;
- }
- return count;
- }
- private SlotItem GetWaferInJobQueue()
- {
- SlotItem slotItem = null;
- bool enableParallel = SC.GetValue<bool>("System.Scheduler.IsRunInParallelMode");
- var OrderedLstCJs = _lstControlJobs.OrderBy(x => x.BeginTime);
- if (enableParallel)
- {
- var priorityFindWaferGotoPMA = GetWaferCountLoadLockToPM(ModuleName.PMA) < 1;
- var priorityFindWaferGotoPMB = GetWaferCountLoadLockToPM(ModuleName.PMB) < 1;
- foreach (var cj in OrderedLstCJs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (priorityFindWaferGotoPMA)
- {
- if (CheckWaferNeedGotoPM(pjSlotWafer.Item1, pjSlotWafer.Item2, ModuleName.PMA))
- {
- return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
- }
- }
- if (priorityFindWaferGotoPMB)
- {
- if (CheckWaferNeedGotoPM(pjSlotWafer.Item1, pjSlotWafer.Item2, ModuleName.PMB))
- {
- return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
- }
- }
- }
- }
- }
- }
- }
- }
- if (slotItem == null)
- {
- foreach (var cj in OrderedLstCJs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (CheckWaferNeedProcess(pjSlotWafer.Item1, pjSlotWafer.Item2))
- {
- return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
- }
- }
- }
- }
- }
- }
- }
- return slotItem;
- }
- private Tuple<SchedulerLoadLock, int> GetWaferOrderInJobQueue(List<Tuple<SchedulerLoadLock, int>> llSlots)
- {
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- foreach (var slot in llSlots)
- {
- var wafer = WaferManager.Instance.GetWafer(slot.Item1.Module, slot.Item2);
- if (wafer.OriginStation == (int)pjSlotWafer.Item1 && wafer.OriginSlot == pjSlotWafer.Item2)
- return slot;
- }
- }
- }
- }
- }
- }
- return null;
- }
- private bool CheckWaferInJobQueue(ModuleName module, int slot)
- {
- foreach (var cj in _lstControlJobs)
- {
- if (cj.State == EnumControlJobState.Executing)
- {
- foreach (var pj in _lstProcessJobs)
- {
- if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- if (pjSlotWafer.Item1 == module && pjSlotWafer.Item2 == slot && CheckWaferNeedProcess(pjSlotWafer.Item1, pjSlotWafer.Item2))
- {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
- private int GetWaferCountInJobQueue()
- {
- int count = 0;
- foreach (var lp in _lstLps)
- {
- for (int i = 0; i < 25; i++)
- {
- if (CheckWaferNeedProcess(lp.Module, i))
- count++;
- }
- }
- return count;
- }
- //private SchedulerLoadLock GetCurrentLoadLockForTMPlace()
- //{
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsAvailable)
- // continue;
- // //if (!ll.CheckAtVacuum())
- // // continue;
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // if (wafers.Any(x => x.ProcessState == EnumWaferProcessStatus.Completed))
- // {
- // for (int i = 0; i < 5;)
- // {
- // if ((WaferManager.Instance.CheckNoWafer(ll.Module, i))
- // && (WaferManager.Instance.CheckNoWafer(ll.Module, i + 1)))
- // {
- // return ll;
- // }
- // i += 2;
- // }
- // }
- // }
- // SchedulerLoadLock currentLoadLock = null;
- // DateTime dtMin = DateTime.MaxValue;
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsAvailable || !ll.CheckAtVacuum())
- // continue;
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // DateTime dtCurrentLL = DateTime.MaxValue;
- // foreach (var wafer in wafers)
- // {
- // if (wafer != null && !wafer.IsEmpty && wafer.SubstHists.Length > 0)
- // {
- // var dt = wafer.SubstHists[wafer.SubstHists.Length - 1].AccessTime;
- // if (dt.CompareTo(dtMin) < 0)
- // dtCurrentLL = dt;
- // }
- // }
- // if (dtCurrentLL.CompareTo(dtMin) < 0)
- // {
- // dtMin = dtCurrentLL;
- // currentLoadLock = ll;
- // }
- // }
- // foreach (var ll in _lstLls)
- // {
- // if (currentLoadLock != null && currentLoadLock != ll)
- // continue;
- // for (int i = 0; i < 5;)
- // {
- // if ((WaferManager.Instance.CheckNoWafer(ll.Module, i))
- // && (WaferManager.Instance.CheckNoWafer(ll.Module, i + 1)))
- // {
- // return currentLoadLock;
- // }
- // i += 2;
- // }
- // currentLoadLock = null;//no empty slot
- // }
- // return currentLoadLock;
- //}
- //private SchedulerLoadLock GetCurrentLoadLockForTMPick()
- //{
- // SchedulerLoadLock currentLoadLock = null;
- // DateTime dtMin = DateTime.MaxValue;
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsAvailable || !ll.CheckAtVacuum())
- // continue;
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // DateTime dtCurrentLL = DateTime.MaxValue;
- // foreach (var wafer in wafers)
- // {
- // if (wafer != null && !wafer.IsEmpty && wafer.ProcessState == EnumWaferProcessStatus.Idle && wafer.SubstHists.Length > 0)
- // {
- // var dt = wafer.SubstHists[wafer.SubstHists.Length - 1].AccessTime;
- // if (dt.CompareTo(dtMin) < 0)
- // dtCurrentLL = dt;
- // }
- // }
- // if (dtCurrentLL.CompareTo(dtMin) < 0)
- // {
- // dtMin = dtCurrentLL;
- // currentLoadLock = ll;
- // }
- // }
- // return currentLoadLock;
- //}
- //private SchedulerLoadLock GetCurrentLoadLockForEfem()
- //{
- // SchedulerLoadLock currentLoadLock = null;
- // foreach (var ll in _lstLls)
- // {
- // if (!ll.IsOnline)
- // continue;
- // var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- // if (loadlockDevice.CheckDoorOpen())
- // {
- // foreach (var wafer in wafers)
- // {
- // if (wafer != null && !wafer.IsEmpty && wafer.ProcessState == EnumWaferProcessStatus.Idle)
- // {
- // currentLoadLock = ll;
- // break;
- // }
- // }
- // if (!wafers.Any(x => x.IsEmpty))
- // {
- // currentLoadLock = null;
- // }
- // }
- // }
- // return currentLoadLock;
- //}
- private int GetEmptySlotInCurrentLoadLock()
- {
- int count = 0;
- //SchedulerLoadLock currentLoadLock = GetCurrentLoadLockForEfem();
- foreach (var ll in _lstLls)
- {
- if (!ll.IsOnline)
- continue;
- //if (currentLoadLock != null && currentLoadLock != ll)
- // continue;
- //var loadlockDevice = DEVICE.GetDevice<SpinelLoadLock>(ll.Module.ToString());
- var wafers = WaferManager.Instance.GetWafers(ll.Module).ToList();
- //if (loadlockDevice.CheckDoorOpen())
- {
- for (int i = 0; i <= 1; i++)
- {
- var wafer0 = WaferManager.Instance.GetWafer(ll.Module, i);
- var wafer1 = WaferManager.Instance.GetWafer(ll.Module, i + 2);
- var wafer2 = WaferManager.Instance.GetWafer(ll.Module, i + 4);
- if (wafer0 != null && wafer0.IsEmpty)
- count++;
- if (wafer1 != null && wafer1.IsEmpty)
- count++;
- if (wafer2 != null && wafer2.IsEmpty)
- count++;
- if (count > 0)
- break;
- }
- }
- }
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) && CheckWaferNeedProcess(ModuleName.EfemRobot, 0))
- count--;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) && CheckWaferNeedProcess(ModuleName.EfemRobot, 1))
- count--;
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 2) && CheckWaferNeedProcess(ModuleName.EfemRobot, 2))
- count--;
- return count < 0 ? 0 : count;
- }
- private int GetEmptySlotInLoadLock(SchedulerLoadLock ll)
- {
- int count = 0;
- {
- if (!ll.IsOnline)
- return count;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty)
- count++;
- }
- }
- return count;
- }
- private int GetEmptySlotInLoadLock()
- {
- int count = 0;
- foreach (var ll in _lstLls)
- {
- if (!ll.IsOnline)
- continue;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty)
- count++;
- }
- }
- return count;
- }
- private int GetEmptySlotInPM()
- {
- int count = 0;
- foreach (var pm in _lstPms)
- {
- if (!pm.IsOnline)
- continue;
- var wafers = WaferManager.Instance.GetWafers(pm.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty)
- count++;
- }
- }
- return count;
- }
- private int GetEmptySlotInPMA()
- {
- int count = 0;
- if (!_pm1.IsOnline)
- return count;
- var wafers = WaferManager.Instance.GetWafers(_pm1.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty)
- count++;
- }
- return count;
- }
- private int GetEmptySlotInPMB()
- {
- int count = 0;
- if (!_pm2.IsOnline)
- return count;
- var wafers = WaferManager.Instance.GetWafers(_pm2.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty)
- count++;
- }
- return count;
- }
- private bool CheckAlignerWaferCanPick(WaferInfo wafer, ModuleName aligner)
- {
- if (wafer == null || wafer.IsEmpty || wafer.ProcessJob == null ||
- wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null || wafer.ProcessJob.Sequence.Steps.Count == 0)
- return false;
- var stepModules = wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules;
- int count = 0;
- int waferCount = 0;
- if (stepModules == null || stepModules.Count == 0)
- {
- return false;
- }
- foreach (var pm in _lstPms)
- {
- if (pm.IsOnline && stepModules.Contains(pm.Module))
- {
- count++;
- if (WaferManager.Instance.CheckHasWafer(pm.Module, 0))
- waferCount++;
- }
- }
- if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- count++;
- }
- else if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- var robotWafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) ? 0 : 1);
- if (robotWafer != null && !robotWafer.IsEmpty && robotWafer.ProcessJob != null &&
- robotWafer.ProcessJob.Sequence != null || robotWafer.ProcessJob.Sequence.Steps != null && robotWafer.ProcessJob.Sequence.Steps.Count > 0)
- {
- stepModules = robotWafer.ProcessJob.Sequence.Steps[robotWafer.NextSequenceStep].StepModules;
- if (stepModules != null && stepModules.Count > 0)
- {
- if (stepModules.Contains(aligner))
- {
- count++;
- }
- }
- }
- }
- return count - waferCount > 0;
- }
- private bool CheckWaferCanPick(WaferInfo wafer)
- {
- if (wafer == null || wafer.IsEmpty || wafer.ProcessJob == null ||
- wafer.ProcessJob.Sequence == null || wafer.ProcessJob.Sequence.Steps == null || wafer.ProcessJob.Sequence.Steps.Count == 0)
- return false;
- var stepModules = wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep + 1].StepModules;
- int count = 0;
- int waferCount = 0;
- if (stepModules == null || stepModules.Count == 0)
- {
- return false;
- }
- if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
- {
- count++;
- }
- return count - waferCount > 0;
- }
- private SlotItem GetWaferReturnLoadPort(ModuleName module, int slot)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
- if (!wafer.IsEmpty)
- {
- return new SlotItem((ModuleName)wafer.OriginStation, wafer.OriginSlot);
- }
- return null;
- }
- private bool ValidateSequence(string[] seqs, out string reason)
- {
- reason = string.Empty;
- bool isAllSequenceNull = true;
- for (int i = 0; i < seqs.Length; i++)
- {
- if (string.IsNullOrEmpty(seqs[i]))
- continue;
- var sequence = SequenceInfoHelper.GetInfo(seqs[i]);
- if ((sequence == null || sequence.Steps == null || sequence.Steps.Count == 0) && !string.IsNullOrEmpty(sequence.Name))
- {
- reason = $"Invalid sequence {seqs[i]}";
- return false;
- }
- isAllSequenceNull = false;
- foreach (var step in sequence.Steps)
- {
- foreach (var module in step.StepModules)
- {
- if (!SC.GetValueOrDefault<bool>($"System.SetUp.{module}.IsInstalled"))
- {
- reason = $"Invalid sequence {seqs[i]}, {module} is uninstalled";
- return false;
- }
- }
- if (step.StepModules.Any(x => x == ModuleName.Aligner))
- {
- if (!SC.GetValueOrDefault<bool>("System.SetUp.Aligner.IsInstalled"))
- {
- reason = $"Invalid sequence {seqs[i]}, Aligner is uninstalled";
- return false;
- }
- if (step.AlignAngle < 0 || step.AlignAngle > 360)
- {
- reason = $"Invalid sequence {seqs[i]}, Aligner angle parameter is not valid";
- return false;
- }
- }
- }
- }
- if (isAllSequenceNull)
- {
- reason = $"Invalid sequence, sequence are all null ";
- return false;
- }
- return true;
- }
- private void CalcedThroughput(List<ProcessJobInfo> pjRemoveList)
- {
- int count = 0;
- foreach (var pj in pjRemoveList)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- if (waferInfo.ProcessState == EnumWaferProcessStatus.Completed
- && waferInfo.SubstTransStatus == SubstrateTransportStatus.AtDestination)
- {
- count++;
- }
- }
- }
- _throughputData.UpdateCalced(count);
- }
- private void CalcingThroughput()
- {
- if (!_lstControlJobs.Any())
- {
- _throughputData.Pause();
- return;
- }
- if (!_lstControlJobs.Any(x => x.State == EnumControlJobState.Executing))
- {
- _throughputData.Pause();
- return;
- }
- _throughputData.BeginCalc();
- int count = 0;
- foreach (var pj in _lstProcessJobs)
- {
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- if (waferInfo.ProcessState == EnumWaferProcessStatus.Completed
- && waferInfo.SubstTransStatus == SubstrateTransportStatus.AtDestination)
- {
- count++;
- }
- }
- }
- if (count > _throughputData.CalcingProcessedCount)
- {
- _throughputData.UpdateCalcing(count);
- }
- }
- #endregion
- #region Checked
- public bool CheckCanProcess(ModuleName pmModule)
- {
- var wafer0 = WaferManager.Instance.GetWafer(pmModule, 0);
- var wafer1 = WaferManager.Instance.GetWafer(pmModule, 1);
- //如果PM腔体中有wafer,但不需要process,则不允许PM进行Process
- if (!wafer0.IsEmpty && !CheckWaferNeedProcess(pmModule, 0, pmModule))
- {
- return false;
- }
- if (!wafer1.IsEmpty && !CheckWaferNeedProcess(pmModule, 1, pmModule))
- {
- return false;
- }
- //如果PM腔体中两片wafer都需要Process,并且recipe名字相同,则允许process
- if (CheckWaferNeedProcess(pmModule, 0, pmModule)
- && CheckWaferNeedProcess(pmModule, 1, pmModule)
- && wafer0.ProcessJob.Sequence.Name == wafer1.ProcessJob.Sequence.Name)
- {
- return true;
- }
- //如果PM腔体中只有一片wafer需要Process,并且LLA/LLB/TMRobot中找不到相同SequenceName的wafer时,允许process
- if (CheckWaferNeedProcess(pmModule, 0, pmModule))
- {
- var pmWafer = WaferManager.Instance.GetWafer(pmModule, 0);
- if (pmWafer.ProcessJob != null)
- {
- if (GetSameSequenceUnprocessedWaferCount(new List<ModuleName>() { ModuleName.LLA, ModuleName.LLB, ModuleName.TMRobot }, pmWafer.ProcessJob.Sequence.Name) == 0)
- return true;
- }
- }
- if (CheckWaferNeedProcess(pmModule, 1, pmModule))
- {
- var pmWafer = WaferManager.Instance.GetWafer(pmModule, 1);
- if (pmWafer.ProcessJob != null)
- {
- if (GetSameSequenceUnprocessedWaferCount(new List<ModuleName>() { ModuleName.LLA, ModuleName.LLB, ModuleName.TMRobot }, pmWafer.ProcessJob.Sequence.Name) == 0)
- return true;
- }
- }
- return false;
- }
- public bool CheckCanPlaceWaferToPM(ModuleName pmModule, WaferInfo wafer)
- {
- if (!_tmRobot.IsAvailable)
- return false;
- if (!CheckWaferNeedProcess(wafer, pmModule))
- return false;
- var wafer0 = WaferManager.Instance.GetWafer(pmModule, 0);
- if (!wafer0.IsEmpty && !CheckWaferNeedProcess(pmModule, 0, pmModule))
- {
- return false;
- }
- var wafer1 = WaferManager.Instance.GetWafer(pmModule, 1);
- if (!wafer1.IsEmpty && !CheckWaferNeedProcess(pmModule, 1, pmModule))
- {
- return false;
- }
- if (CheckWaferNeedProcess(wafer0, pmModule)
- && CheckWaferNeedProcess(wafer, pmModule)
- && wafer0.ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- return true;
- if (CheckWaferNeedProcess(wafer1, pmModule)
- && CheckWaferNeedProcess(wafer, pmModule)
- && wafer1.ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- return true;
- if (wafer0.IsEmpty
- && wafer1.IsEmpty
- && CheckWaferNeedProcess(wafer, pmModule))
- return true;
- return false;
- }
- public bool CheckCanPickWaferFromPM(ModuleName pmModule, int slot)
- {
- if (!_tmRobot.IsAvailable)
- return false;
- var wafer = WaferManager.Instance.GetWafer(pmModule, slot);
- if (!wafer.IsEmpty
- && wafer.ProcessJob != null
- && wafer.ProcessJob.Sequence != null
- && wafer.ProcessJob.Sequence.Steps != null
- && wafer.ProcessState == EnumWaferProcessStatus.Completed)
- return true;
- return false;
- }
- public int GetSameSequenceUnprocessedWaferCount(List<ModuleName> modules, string sequenceName)
- {
- int count = 0;
- for (int i = 0; i < modules.Count; i++)
- {
- var wafers = WaferManager.Instance.GetWafers(modules[i]);
- for (int j = 0; j < wafers.Length; j++)
- {
- if (CheckWaferNeedProcess(wafers[j])
- && wafers[j].ProcessJob != null
- && wafers[j].ProcessJob.Sequence.Name == sequenceName)
- count++;
- }
- }
- return count;
- }
- public int? GetAvilableLoadLockSlotForEfemRobotPlace(SchedulerLoadLock ll)
- {
- if (!ll.IsAvailable)
- return null;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty && ll.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, i))
- return i;
- }
- return null;
- }
- public int? GetAvilableLoadLockSlotForTMRobotPlace(SchedulerLoadLock ll)
- {
- if (!ll.IsAvailable)
- return null;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- for (int i = 0; i < wafers.Length; i++)
- {
- if (wafers[i].IsEmpty && ll.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, i))
- return i;
- }
- return null;
- }
- public int? GetAvilableLoadLockSlotForTMRobotPick(SchedulerLoadLock ll)
- {
- if (!ll.IsAvailable)
- return null;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- foreach (var pm in _lstPms)
- {
- var pmWafer0 = WaferManager.Instance.GetWafer(pm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(pm.Module, 1);
- //如果腔体中两片都满了,则跳过
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- continue;
- //如果腔体中两片都为空,则取一片放入
- if (pmWafer0.IsEmpty && pmWafer1.IsEmpty)
- {
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i))
- return i;
- }
- }
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var wafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(wafer))
- return null;
- var tmWafers = WaferManager.Instance.GetWafers(ModuleName.TMRobot);
- //判断TMRobot是否已经存在相同recipeName的wafer
- for (int i = 0; i < tmWafers.Length; i++)
- {
- if (CheckWaferNeedProcess(tmWafers[i])
- && tmWafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- return null;
- }
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i)
- && wafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- return i;
- }
- }
- }
- return null;
- }
- public List<Tuple<SchedulerLoadLock, int>> GetAvilableLoadLockSlotForTMRobotPick()
- {
- List<Tuple<SchedulerLoadLock, int>> result = new List<Tuple<SchedulerLoadLock, int>>();
- foreach (var ll in _lstLls)
- {
- if (!ll.IsAvailable)
- continue;
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- foreach (var pm in _lstPms)
- {
- var pmWafer0 = WaferManager.Instance.GetWafer(pm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(pm.Module, 1);
- //如果腔体中两片都满了,则跳过
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- continue;
- //如果腔体中两片都为空,则取一片放入
- if (pmWafer0.IsEmpty && pmWafer1.IsEmpty)
- {
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i, pm.Module)
- && !result.Exists(x => x.Item1 == ll && x.Item2 == i))
- result.Add(new Tuple<SchedulerLoadLock, int>(ll, i));
- }
- }
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var wafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(wafer))
- continue;
- var tmWafers = WaferManager.Instance.GetWafers(ModuleName.TMRobot);
- //判断TMRobot是否已经存在相同recipeName的wafer
- for (int i = 0; i < tmWafers.Length; i++)
- {
- if (CheckWaferNeedProcess(tmWafers[i])
- && tmWafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- continue;
- }
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i, pm.Module)
- && wafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name
- && !result.Exists(x => x.Item1 == ll && x.Item2 == i))
- result.Add(new Tuple<SchedulerLoadLock, int>(ll, i));
- }
- }
- }
- }
- return result;
- }
- public List<Tuple<SchedulerLoadLock, int>> FindAllLoadLockSlotForTMRobotPick()
- {
- List<Tuple<SchedulerLoadLock, int>> result = new List<Tuple<SchedulerLoadLock, int>>();
- foreach (var ll in _lstLls)
- {
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- foreach (var pm in _lstPms)
- {
- var pmWafer0 = WaferManager.Instance.GetWafer(pm.Module, 0);
- var pmWafer1 = WaferManager.Instance.GetWafer(pm.Module, 1);
- //如果腔体中两片都满了,则跳过
- if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty)
- continue;
- //如果腔体中两片都为空,则取一片放入
- if (pmWafer0.IsEmpty && pmWafer1.IsEmpty)
- {
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i, pm.Module)
- && !result.Exists(x => x.Item1 == ll && x.Item2 == i))
- result.Add(new Tuple<SchedulerLoadLock, int>(ll, i));
- }
- }
- //如果腔体中一片为空,则取一片相同recipeName的放入
- if (!pmWafer0.IsEmpty || !pmWafer1.IsEmpty)
- {
- var wafer = !pmWafer0.IsEmpty ? pmWafer0 : pmWafer1;
- if (!CheckWaferNeedProcess(wafer))
- continue;
- var tmWafers = WaferManager.Instance.GetWafers(ModuleName.TMRobot);
- //判断TMRobot是否已经存在相同recipeName的wafer
- for (int i = 0; i < tmWafers.Length; i++)
- {
- if (CheckWaferNeedProcess(tmWafers[i])
- && tmWafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name)
- continue;
- }
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty
- && ll.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)
- && CheckWaferNeedProcess(ll.Module, i, pm.Module)
- && wafers[i].ProcessJob.Sequence.Name == wafer.ProcessJob.Sequence.Name
- && !result.Exists(x => x.Item1 == ll && x.Item2 == i))
- result.Add(new Tuple<SchedulerLoadLock, int>(ll, i));
- }
- }
- }
- }
- return result;
- }
- public int GetWaferCountLoadLockToPM(ModuleName pmModule)
- {
- int result = 0;
- foreach (var ll in _lstLls)
- {
- var wafers = WaferManager.Instance.GetWafers(ll.Module);
- foreach (var pm in _lstPms)
- {
- if (pm.Module != pmModule)
- continue;
- for (int i = 0; i < wafers.Length; i++)
- {
- if (!wafers[i].IsEmpty && CheckWaferNeedProcess(ll.Module, i, pm.Module))
- result++;
- }
- }
- }
- return result;
- }
- #endregion
- }
- }
|