diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20fa1f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/Tools +/Machinings +/SetUp +/Beam/CutData.lua +/Beam/DrillData.lua +/Beam/MillingData.lua +/Beam/PocketingData.lua +/Beam/SawingData.lua diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fc5c416 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,100 @@ +{ + "Lua.diagnostics.globals": [ + "EmtTcPos", + "EgtGetAllTcPosNames", + "EgtGetFirstNameInGroup", + "EgtSetStatus", + "EgtEmptyGroup", + "EgtGetFirstRawPart", + "EmtLinkRawPartToGroup", + "EgtVerifyRawPartPhase", + "EgtGetNextRawPart", + "EMT", + "EgtOutText", + "EgtGetFirstPartInRawPart", + "EmtSetLastError", + "EgtGetToolsInCurrSetupPos", + "EgtLoadTool", + "EgtSetName", + "EgtGroup", + "EgtSetLevel", + "EgtOutLog", + "EmtUnlinkAllRawPartsFromGroups", + "EgtSetAxisPos", + "EgtGetPhaseCount", + "EgtGetCurrMachGroup", + "EgtErase", + "EgtVolZmapBox", + "EgtSetColor", + "EgtGetFirstInGroup", + "EgtGetNext", + "EgtGetFirstOperation", + "EgtGetOperationType", + "EgtSetOperationStatus", + "EgtGetNextOperation", + "EgtGetDebugLevel", + "EgtGetAxisId", + "EgtGetBaseId", + "EgtMove", + "EgtTdbGetCurrToolParam", + "EmtAddCollisionObjEx", + "EgtGetNextActiveOperation", + "EgtGetFirstActiveOperation", + "EgtSetCurrMachining", + "EgtGetMachiningParam", + "EgtSetMode", + "EgtGetHeadId", + "EgtPause", + "EgtGetAxisPos", + "EgtGetOperationName", + "EgtGetMachiningGeometry", + "EgtVolZmapPartCount", + "EgtVolZmapPartVolume", + "EgtRemoveVolZmapPart", + "EgtDraw", + "EgtNumToString", + "EgtSplitString", + "EmtUnlinkRawPartFromGroup", + "EgtRelocate", + "EgtVolZmapGetEdges", + "EgtGetCurrMachineName", + "EgtGetCurrMachineDir", + "EgtGetStringFromIni", + "EgtGetCurrFilePath", + "EgtGetMachGroupName", + "EgtSaveObjToFile", + "EmtSetOutstrokeInfo", + "EgtTdbSetCurrTool", + "EgtUiUnitsAreMM", + "EgtGetAxisHomePos", + "EgtSetInfo", + "EgtGetTcPosId", + "EgtGetName", + "EgtGetCurrMachining", + "EgtOutBox", + "EgtResetCurrMachining", + "EgtGetPhaseDisposition", + "EgtExistsFile", + "EmtGeneral", + "EmtBase", + "EmtAxis", + "EmtHead", + "EmtTable", + "EmtModifyExitPosition", + "EmtModifyAxisHome", + "EgtRemoveInfo", + "EmtUnlinkAllFixturesFromGroups", + "EMC", + "EgtSetCurrPhase", + "EgtTdbGetToolFromUUID", + "EgtGetPrevActiveOperation", + "EgtExistsInfo", + "EgtGetLastInGroup", + "EmtGetAxesPos", + "EgtRemoveOperationHome", + "EgtGetPartInRawPartCount", + "EgtGetOperationPhase", + "EgtSetOperationMode", + "EgtSetCalcTool" + ] +} \ No newline at end of file diff --git a/Beam/BeamData.lua b/Beam/BeamData.lua new file mode 100644 index 0000000..843f738 --- /dev/null +++ b/Beam/BeamData.lua @@ -0,0 +1,113 @@ +-- BeamData.lua by Egaltech s.r.l. 2022/03/20 +-- Raccolta dati generali per Travi + +EgtOutLog( ' KAIROS-BeamData started', 1) + +-- Tabella per definizione modulo +local BeamData = { + ROT90 = false, -- flag abilitazione rotazione 90 gradi + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 450, -- larghezza massima del grezzo + MAX_HEIGHT = 250, -- altezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo corto + LEN_VERY_SHORT_PART = 400, -- lunghezza massima pezzo molto corto (molto probabile lo scarico a caduta) + MAX_RAW = 30000, -- massima lunghezza grezzo (deve essere minore di LenTable - RAW_OFFSET) + STD_RAW = 14000, -- lunghezza standard della barra di grezzo + OVM_HEAD = 10, -- sovramateriale testa + OVM_MID = 5.4, -- sovramateriale intermedio (spessore lama) + MINRAW_S = 750, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1070, -- minimo grezzo in coda scaricabile per sezioni grandi + MAX_LEN_SCRAP = 270, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 270, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 205, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = -195, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 190, -- altezza minima di trave alta + MAX_DIM_DICE = 155, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto + DECR_VERT_CUT = 12.5, -- riduzione profondità per affondamento verticale in taglio orizzontale + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 1, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-36.8deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.2, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = -0.51, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.867, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + MAX_DIST_HTFEA = 50.0, -- massima distanza di feature da testa o coda per essere considerata tale + MAX_LEN_HTFEA = 2000.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 600, -- lunghezza lavoro estremi iniziale e finale (std=600) + LONGCUT_MAXLEN = 1200, -- lunghezza massima sezione di taglio longitudinale (std=1200) + MAX_LEN_RIDGELAP_FROM_BOTTOM = 141, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 96, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 100, -- larghezza minima trave per inseriemento codolo nel centro del trave; 0 = automatico + DIM_STRIP = -1, -- dimensione codolo sostegno parti lasciate su contorno libero o archi (-1 = da Q...) + DIM_STRIP_SMALL = 1, -- dimensione codolo piccolo (quando le parti sostenute sono sicuramente sulla parte sopra del pezzo) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + RAW_OFFSET = 2000, -- spostamento grezzo rimanente dopo split + VICE_MINH = 110, -- altezza minima della morsa + OFFSET_DRILL_TENON = 0, -- offset fori su tenoni verso base degli stessi (0=non fare) + USER_HOLE_DIAM = 0, -- diametro foro per L20 + MAX_TOOL_LEN_FOR_HOR_MACH = 311, -- massima lunghezza utensile per poter fare forature (fresature) oltre i 10 gradi dalla verticale + DRILL_VZ_MIN_LONG_TOOL = 0.984, -- componente limite per lavorazioni con punta lunga + MAX_TOOL_LEN_BACK_HOR_MACH = 250, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + MAX_HEIGHT_ROT_B_ABOVE = 500, -- massima altezza della trave che permette di ruotare l'asse B sopra la stessa senza collisioni + KIOTP = 3, -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare + MAXDIAM_POCK_CORNER = 30, -- diametro massimo utensile ammesso per tasche con angoli interni + ADVANCE_TAIL_CUT = true, -- per spostare prima del taglio di separazione il taglio di coda su pezzi corti con robabile caduta + ADVANCE_TAIL_OFFS = 5, -- accorciamento taglio di coda avanzato (minimo 1) +} + +-- Aggiornamento con dati da B&W +local sData = EgtGetSourceDir().."EbwData.lua" +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.YMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.YMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + if Machine.User then + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F5 == 1 then + BeamData.MAX_LEN_SCRAP = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP + else + BeamData.MAX_LEN_SCRAP = 100000 + end + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F6 == 1 then + BeamData.MAX_LEN_SCRAP_START = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP_START + else + BeamData.MAX_LEN_SCRAP_START = 100000 + end + BeamData.USER_HOLE_DIAM = Machine.User.L020_DIAM_HOLE or BeamData.USER_HOLE_DIAM + BeamData.OFFSET_DRILL_TENON = Machine.User.L040_OFFSET_P1 or BeamData.OFFSET_DRILL_TENON + end + end +end + +--------------------------------------------------------------------- +local function GetChainSawBlockedAxis( nInd) + --if nInd == 1 then + -- return 'CS=-90' + --else + return 'CS=0' + --end +end +BeamData.GetChainSawBlockedAxis = GetChainSawBlockedAxis + +--------------------------------------------------------------------- +local function GetMaxLenRidgeLapFromBottom( dHRaw) + if dHRaw < BeamData.MIN_DIM_HBEAM then + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM + 0.01 + else + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM + 0.01 + end +end +BeamData.GetMaxLenRidgeLapFromBottom = GetMaxLenRidgeLapFromBottom + +--------------------------------------------------------------------- +return BeamData diff --git a/Beam/BeamTableTemplate.ini b/Beam/BeamTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/Beam/BeamTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/Beam/EbwData.lua b/Beam/EbwData.lua new file mode 100644 index 0000000..b9a6409 --- /dev/null +++ b/Beam/EbwData.lua @@ -0,0 +1,45 @@ +-- C:\EgtData\Machines\Saomad-KAIROS\Beam\EbwData.lua + +local Offsets = { + MIN_Y=-1225, + MAX_Y=540, + MIN_Z=-512, + MAX_Z=910, + MIN_A=-109.5, + MAX_A=109.5, + MIN_C=-240, + MAX_C=240, + MIN_X1=290, + MAX_X1=3735, + PARK_X1=600, + MIN_X2=-3735, + MAX_X2=-290, + PARK_X2=-600, + BEAM_LOAD=1800.0, + BEAM_UNLOAD=-1800, + TURN_OFFS=0, + MILL_PIVOT=-217.00, + TAB_OFFSET_Y=0, + TAB_OFFSET_Z=0, + TIPO_CN=0, + RIBCAR=0, + NOULOAD=0 +} + +local Trave = { + YMIN=30, + YMAX=451, + ZMIN=30, + ZMAX=251 +} + +local User = { + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L020_DIAM_HOLE=14, + L040_OFFSET_P1=0 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/Beam/MachData.ini b/Beam/MachData.ini new file mode 100644 index 0000000..dae59d4 --- /dev/null +++ b/Beam/MachData.ini @@ -0,0 +1,52 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,YCARICO,-1460.0,YCARICO +2=l,YSCARICO,1700.0,YSCARICO +3=l,OFFSETRIB,150.0,OFFSETRIB +4=l,PARKYY,480,PARKYY +5=l,PARKVV,-480,PARKVV +6=l,PIVOTFRESA,-177.0,PIVOTFRESA +7=l,PIVOTLAMA,242.0,PIVOTLAMA +8=l,OFFSETX,-900.0,OFFSETX +9=l,OFFSETZ,-1015.0,OFFSETZ +10=l,MIN_X,-1350,MIN_X +11=l,MAX_X,0,MAX_X +12=l,MIN_Y,110,MIN_Y +13=l,MAX_Y,3735,MAX_Y +14=l,MIN_Z,-1350,MIN_Z +15=l,MAX_Z,0,MAX_Z +16=d,MIN_B,-180,MIN_B +17=d,MAX_B,360,MAX_B +18=d,MIN_C,-360,MIN_C +19=d,MAX_C,360,MAX_C +20=l,MIN_V,-3735,MIN_V +21=l,MAX_V,-110,MAX_V +22=d,TIPO_CN,2,TIPO_CN +23=d,OFFSETCLAMA,0,OFFSETCLAMA +24=d,OFFSETBLAMA,0,OFFSETBLAMA +25=d,RIBCAR,0,RIBCAR +26=d,SECSUP,1,SECSUP +27=d,BLOCKHAUS,0,Blockhaus Configuration +28=l,NOULOAD,0,Max Unload Length (0=no limits) +29=l,OFFSETX_RINV_1,150,OFFSETX_RINV_1 +30=l,OFFSETZ_RINV_1,347,OFFSETZ_RINV_1 +31=l,OFFSETX_RINV_2,150,OFFSETX_RINV_2 +32=l,OFFSETZ_RINV_2,347,OFFSETZ_RINV_2 + +[2] +Name=Trave +1=l,XMIN,29,XMIN +2=l,XMAX,305,XMAX +3=l,ZMIN,20,ZMIN +4=l,ZMAX,625,ZMAX + +[3] +Name=User +1=d,OPTIMIZATIONS_ENABLE_SLICES_F5,1,ENABLE_SLICES_ON_END +2=d,OPTIMIZATIONS_ENABLE_SLICES_F6,1,ENABLE_SLICES_ON_START +3=d,OPTIMIZATIONS_LENGTH_SLICES,100,SLICES_LENGTH +4=l,L020_DIAM_HOLE,20,L020_HOLE_DIAM +5=l,L040_OFFSET_P1,0,L040_ON_TENON_OFFSET diff --git a/Beam/MachiningTypes.ini b/Beam/MachiningTypes.ini new file mode 100644 index 0000000..6cddc2c --- /dev/null +++ b/Beam/MachiningTypes.ini @@ -0,0 +1,43 @@ +[Cut] +1=HeadSide +2=TailSide + +[Drill] +1=Drill +2=Drill_AT +3=Pocket +4=AngleDrill + +[Milling] +1=Prof +2=FreeContour +3=Tenon +4=DtTenon +5=DtMortise +6=DtMortise_AT +7=BirdsMouth +8=Chamfer +9=Mark +10=Text +11=Text_AT +12=Decor01 +13=Long2Cut +14=Long2CutDown +15=LongSmallCut +16=BHSideMill +17=CleanCorner +18=ProfTCone +19=Long2CutSide +20=SmallToolContour +21=AntiSplintMillCut + +[Pocketing] +1=Pocket +2=Pocket_AT +3=OpenPocket +4=Mortise +5=Mortise_AT + +[Sawing] +1=Sawing +2=Mortising diff --git a/Messages/Eng.txt b/Messages/Eng.txt new file mode 100644 index 0000000..25af1c9 --- /dev/null +++ b/Messages/Eng.txt @@ -0,0 +1,4 @@ +// English machine message file 2023/12/06 + +[PLC] + diff --git a/Messages/Ita.txt b/Messages/Ita.txt new file mode 100644 index 0000000..f594dc9 --- /dev/null +++ b/Messages/Ita.txt @@ -0,0 +1,11 @@ +// File dei messaggi macchina Italiano 2023/12/06 +[MDI] + + +[PLC] + + +[CNC] + + +[INPUT] diff --git a/Messages/oem_alarms_plc_ita.xml b/Messages/oem_alarms_plc_ita.xml new file mode 100644 index 0000000..c602b12 --- /dev/null +++ b/Messages/oem_alarms_plc_ita.xml @@ -0,0 +1,262 @@ + + + + slaeconv + + 700000/PLC/PMC + MACCHINA IN EMERGENZA + + + 700001/PLC/PMC + FUNGO SU QUADRO PREMUTO + + + 700002/PLC/PMC + FUNGO SU CONSOLLE PREMUTO + + + 700003/PLC/PMC + PORTE APERTE + + + 700004/PLC/PMC + ANOMALIA PRESENZA ARIA + + + 700005/PLC/PMC + CAMBIO UTENSILE INTERROTTO! PREMERE RESET PER 5 SECONDI + + + 700006/PLC/PMC + ANOMALIA SBLOCCO UTENSILE + + + 700007/PLC/PMC + ANOMALIA BLOCCO UTENSILE + + + 700008/PLC/PMC + ANOMALIA APERTURA PRESSORE ORIZZONTALE X2 + + + 700009/PLC/PMC + ANOMALIA CHIUSURA PRESSORE ORIZZONTALE X2 + + + 700010/PLC/PMC + ANOMALIA AVANTI PISTONE SCARICO + + + 700011/PLC/PMC + ANOMALIA INDIETRO PISTONE SCARICO + + + 700012/PLC/PMC + ANOMALIA SALITA SOLLEVATORE X1 + + + 700013/PLC/PMC + ANOMALIA DISCESA SOLLEVATORE X1 + + + 700014/PLC/PMC + ANOMALIA SALITA SOLLEVATORE X2 + + + 700015/PLC/PMC + ANOMALIA DISCESA SOLLEVATORE X2 + + + 700016/PLC/PMC + ANOMALIA SEGA AVANTI + + + 700017/PLC/PMC + ANOMALIA SEGA INDIETRO + + + 700018/PLC/PMC + ANOMALIA SALITA BATTUTA INTERMEDIA INGRESSO + + + 700019/PLC/PMC + ANOMALIA DISCESA BATTUTA INTERMEDIA INGRESSO + + + 700020/PLC/PMC + ANOMALIA CATENE INGRESSO SU + + + 700021/PLC/PMC + ANOMALIA CATENE INGRESSO GIU + + + 700022/PLC/PMC + ANOMALIA PIATTO AVANTI X1 + + + 700023/PLC/PMC + ANOMALIA PIATTO INDIETRO X1 + + + 700024/PLC/PMC + ANOMALIA PIATTO AVANTI X2 + + + 700025/PLC/PMC + ANOMALIA PIATTO INDIETRO X2 + + + 700026/PLC/PMC + ANOMALIA SALITA PRESSORE VERTICALE X1 + + + 700027/PLC/PMC + ANOMALIA DISCESA PRESSORE VERTICALE X1 + + + 700028/PLC/PMC + ANOMALIA SALITA PRESSORE VERTICALE X2 + + + 700029/PLC/PMC + ANOMALIA DISCESA PRESSORE VERTICALE X2 + + + 700030/PLC/PMC + ANOMALIA APERTURA PRESSORE ORIZZONTALE X1 + + + 700031/PLC/PMC + ANOMALIA CHIUSURA PRESSORE ORIZZONTALE X1 + + + 700032/PLC/PMC + ANOMALIA CONDIZIONATORE QUADRO ELETTRICO + + + 700033/PLC/PMC + SBLOCCO UT NON POSSIBILE CON MANDRINO NON FERMO + + + 700034/PLC/PMC + ANOMALIA SBLOCCO UTENSILE 2 + + + 700035/PLC/PMC + INTERVENTO TERMICO POMPA DI LUBRIFICAZIONE + + + 700036/PLC/PMC + LIVELLO MINIMO OLIO LUBRIFICAZIONE + + + 700037/PLC/PMC + ANOMALIA APERTURA PROTEZIONE CONI SINISTRA + + + 700038/PLC/PMC + ANOMALIA CHIUSURA PROTEZIONE CONI SINISTRA + + + 700039/PLC/PMC + ANOMALIA APERTURA PROTEZIONE CONI DESTRA + + + 700040/PLC/PMC + ANOMALIA CHIUSURA PROTEZIONE CONI DESTRA + + + 700041/PLC/PMC + ANOMALIA AVANTI RULLIERA MODILE X1 + + + 700042/PLC/PMC + ANOMALIA INDIETRO RULLIERA MOBILE X1 + + + 700043/PLC/PMC + ANOMALIA AVANTI RULLIERA 100 MODILE X1 + + + 700044/PLC/PMC + ANOMALIA INDIETRO RULLIERA 100 MOBILE X1 + + + 700045/PLC/PMC + ANOMALIA AVANTI RULLIERA MODILE X2 + + + 700046/PLC/PMC + ANOMALIA INDIETRO RULLIERA MOBILE X2 + + + 700047/PLC/PMC + ANOMALIA AVANTI RULLIERA 100 MODILE X2 + + + 700048/PLC/PMC + ANOMALIA INDIETRO RULLIERA 100 MOBILE X2 + + + 700049/PLC/PMC + SCARICO PIENO + + + 700050/PLC/PMC + PASSO LEGNO IMPEGNATO + + + 700051/PLC/PMC + ASSE Z NON IN POSIZIONE PER START CICLO + + + 700052/PLC/PMC + ASSE Y NON IM POSIZIONE PER START CICLO + + + 700053/PLC/PMC + INCONGRUENZA DATI UTENSILE IN MANDRINO + + + 700054/PLC/PMC + STOP WORKING ATTIVO + + + 700055/PLC/PMC + AUTO OFF ATTIVO + + + 700056/PLC/PMC + LUNGHEZZA PEZZO ERRATA + + + 700057/PLC/PMC + LARGHEZZA PEZZO ERRATA + + + 700058/PLC/PMC + SPESSORE PEZZO ERRATO + + + 700059/PLC/PMC + FEED HOLD - SPINDLE HOLD + + + 700060/PLC/PMC + PRERISCALDO MANDRINO + + + 700061/PLC/PMC + PRERISCALDO MANDRINO IN CORSO + + + 700062/PLC/PMC + SELETTORE BYPASS PULSANTIERA WIRELESS ATTIVO + + + 700063/PLC/PMC + VALVOLA PROPORZIONALE SMC PROFIBUS CHIUSURA PINZE FAULT + + + diff --git a/README.md b/README.md deleted file mode 100644 index 79a1535..0000000 --- a/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# Saomad-Kairos - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.steamware.net/egalware-machines/saomad/saomad-kairos.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.steamware.net/egalware-machines/saomad/saomad-kairos/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/Saomad-KAIROS.SIEMENS.mlpe b/Saomad-KAIROS.SIEMENS.mlpe new file mode 100644 index 0000000..49070de --- /dev/null +++ b/Saomad-KAIROS.SIEMENS.mlpe @@ -0,0 +1,1780 @@ +-- Processore macchina Saomad-KAIROS by EgalTech s.r.l. 2023/12/06 +-- Con controllo numerico Siemens + +-- Variabili di modulo +local MLE_INFO = 'Saomad-KAIROS.SIEMENS.mlpe ver.'..PP_VER..' by EgalWare s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.C1t = 'I=AC(' -- X centro arco, dopo valore chiudere la tonda + EMT.C2t = 'J=AC(' -- Y centro arco, dopo valore chiudere la tonda + EMT.C3t = 'K=AC(' -- Z centro arco, dopo valore chiudere la tonda + EMT.RRt = 'CR=' -- raggio per arco + EMT.FMAXPINZE = 45000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + EmtOutput( ';'..EMT.INFO) + else + EmtOutput( ';Program Start') + end + EmtOutput( ';'.. MLE_INFO..'\n') + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') + -- Dichiaro inizio + EMT.FIRST = true + EMT.TLAST = nil + EMT.NSTEP = 0 +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' or EMT.AUXTYPE == 'R' then + ; + elseif EMT.AUXTYPE == 'U' then + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sOut = ';Part End' + EmtOutput( sOut) + sOut= 'PRODUCTION('..tostring( EMT.PRODID)..','..tostring( EMT.PATTID)..','..tostring( EMT.CUTID)..',2)' + EmtOutput( sOut) + end + end + end + EmtOutput( 'STOPRE') + EmtOutput( '_STEP=0') + EmtOutput( 'M30') + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil +end + +--------------------------------------------------------------------- +function OnToolData() + -- tabella codice -> nome tipo utensile + local tToolType = { [256] = 'DRILL', [257] = 'DRILL_L', [512] = 'SAW', [513] = 'SAW_F', [1024] = 'MILL', [1025] = 'MILL_NT', + [1026] = 'POLISHING', [2048] = 'CHAINSAW', [4096] = 'CHISEL'} + -- emissione dati utensile + --local sOut = ';'..EMT.TCPOS..' L='..EmtLenToString( EMT.TLEN, 3)..' D='..EmtLenToString( EMT.TDIAM, 3)..' A='..EgtIf( EMT.TUSED, '1', '0')..' '..( tToolType[EMT.TTYPE] or 'NONE') + local sOut = ';'..EMT.TCPOS..' L='..EmtLenToString( EMT.TLEN, 3)..' D='..EmtLenToString( EMT.TDIAM, 3)..' A='..EgtIf( EMT.TUSED, '1', '0')..' '..EMT.TOOL + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.X1POS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- inizio programma + EmtOutput( '\nRESTART') + EmtOutput( 'STOPRE') + EmtOutput( '_STEP=0') + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + elseif IsStartPhase( EMT.PHASE) then + EMT.X1DELTA = EMT.X1POS - LoadT + EMT.X2DELTA = nil + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- dati della barra + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- se carico barra + if EMT.LOAD then + -- assegnazione dati barra + local sOut = ';Bar Dimensions' + EmtOutput( sOut) + sOut = 'C_WIDTH='..EmtLenToString( HTrave, 3) + EmtOutput( sOut) + sOut = 'C_HEIGHT='..EmtLenToString( STrave, 3) + EmtOutput( sOut) + sOut = 'C_LENGTH='..EmtLenToString( LBarra, 3) + EmtOutput( sOut) + -- se altrimenti ricarico barra dopo rotazione speciale + elseif EMT.RELOAD then + local sOut = ';Bar Dimensions' + EmtOutput( sOut) + sOut = 'C_WIDTH='..EmtLenToString( HTrave, 3) + EmtOutput( sOut) + sOut = 'C_HEIGHT='..EmtLenToString( STrave, 3) + EmtOutput( sOut) + sOut = 'C_LENGTH='..EmtLenToString( LBarra, 3) + EmtOutput( sOut) + -- altrimenti recupero rimanenza + else + -- aggiorno dati aggancio carrelli alla trave + EMT.X1DELTA = EMT.X1POS - LoadT + EMT.X2DELTA = nil + end + -- Inizio produzione trave + if IdTrave >= 0 then + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sOut = ';Part Start' + EmtOutput( sOut) + sOut= 'PRODUCTION('..tostring( EMT.PRODID)..','..tostring( EMT.PATTID)..','..tostring( EMT.CUTID)..',1)' + EmtOutput( sOut) + else + EmtOutput( '') + EmtOutput( ';REMAIN UNLOAD') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- eventuale preparazione per rotazione immediata + if IsStartPhase( EMT.PHASE) and EMT.AUXSTR then + -- emissione movimento carrelli per rotazione + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( ';ROTATION') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then EMT.CHAN2 = true end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- emissione movimento carrelli + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( ';ROTATION') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then EMT.CHAN2 = true end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmitSpeedOff() + EmtOutput( '') + EmtOutput( ';PART UNLOAD') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EMT.CHAN2 = true + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sOut = ';Part End' + EmtOutput( sOut) + sOut= 'PRODUCTION('..tostring( EMT.PRODID)..','..tostring( EMT.PATTID)..','..tostring( EMT.CUTID)..',2)' + EmtOutput( sOut) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + if MCH_TP.DIST then EMT.TDIST = EgtTdbGetCurrToolParam( MCH_TP.DIST) end + if EMT.TDIST and abs( EMT.TDIST) < 0.1 then EMT.TDIST = nil end + -- dichiaro utensile appena selezionato + EMT.TSELECT = true + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() + EmitSpeedOff() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.FEEDFIRST = true + -- determino subito se taglio di separazione di pezzo a caduta + EMT.PREFALLCUT = nil + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Split') then + local ClId = EgtGetFirstNameInGroup( EMT.MCHID, 'CL') + local P1Id = EgtGetFirstNameInGroup( ClId or GDB_ID.NULL, 'P1') + local sAE1 = EgtGetInfo( P1Id or GDB_ID.NULL, 'AE1') or '' + if sAE1 == '0,Fall' then + EMT.PREFALLCUT = true + end + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmitSpeedOff() + EmtOutput( ';PART SPLIT') + elseif EMT.AUXTYPE == 'U' then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + if IsLastMachining( EMT.MCHID) then + EmitSpeedOff() + end + EmtOutput( ';PART UNLOAD') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + EmtOutput( ';PART ROTATION') + elseif EMT.FALL then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + EmtOutput( ';FALL') + else + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + EmtOutput( ';SPLIT 2') + end + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EMT.CHAN2 = true + if EMT.AUXTYPE == 'S' then + ; + elseif EMT.AUXTYPE == 'U' then + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sOut = ';Part End' + EmtOutput( sOut) + sOut= 'PRODUCTION('..tostring( EMT.PRODID)..','..tostring( EMT.PATTID)..','..tostring( EMT.CUTID)..',2)' + EmtOutput( sOut) + end + elseif EMT.AUXTYPE == 'P' then + if EMT.FALL then + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sOut = ';Part End' + EmtOutput( sOut) + sOut= 'PRODUCTION('..tostring( EMT.PRODID)..','..tostring( EMT.PATTID)..','..tostring( EMT.CUTID)..',2)' + EmtOutput( sOut) + end + elseif not EMT.PREROT then + ; + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.PREVTOOL = EMT.TOOL + EMT.PREVR3 = EMT.R3 +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EMT.L1opp = EMT.L1op + EMT.L2opp = EgtIf( EMT.TSELECT, ParkY, EMT.L2op) + EMT.L3opp = EgtIf( EMT.TSELECT, ParkZ, EMT.L3op) + EMT.R1pp = EgtIf( EMT.TSELECT, ParkC, EMT.R1p) + EMT.R2pp = EgtIf( EMT.TSELECT, ParkA, EMT.R2p) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( EMT.AUX, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif EgtGetInfo( EMT.DISPID, 'TYPE') == 'REST' then + EMT.AUXTYPE = 'R' + else + EMT.AUXTYPE = 'P' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + MyBackupAxes() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + -- decido se muovere prima testa o carrelli (standard prima testa) + local bHeadFirst = true + local sLateG101 + if not ( EMT.LOAD or EMT.RELOAD) and not EMT.ZMAX then + local DeltaT = EMT.L1 - EMT.TLAST + if ( DeltaT < -GEO.EPS_SMALL and EMT.X2DELTA) or ( DeltaT > GEO.EPS_SMALL and EMT.X1DELTA) then bHeadFirst = false end + end + -- sistemo movimenti + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- verifico presenza movimento carrelli + local bMoveChar = ( #EMT.AUXSTR > 0) + -- carico + if EMT.LOAD then + EmtOutput( 'STOPRE') + EMT.NSTEP = EMT.NSTEP + 10 + local sStep = EgtNumToString( EMT.NSTEP, 0) + EmtOutput( '_STEP='..sStep) + -- eseguo carico + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EMT.AUXSTR = {} + -- supporti in posizione intermedia + sOut = 'SUPPORT(1,1)' + EmtOutput( sOut) + -- prima lavorazione + sOut = EMT.MCHNAME..'/'..EMT.TOOL + EmtOutput( '; *** ' .. sOut .. ' ***') + EMT.LOAD = false + -- altri casi + else + if not EMT.RELOAD and not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + EMT.ZMAX = true + EMT.PREVTOOL = EMT.TOOL + end + if bMoveChar then + local bStoPre + if EMT.CHAN2 then + EmtOutput( 'WAIT_CHAN(2)') + EmtOutput( 'STOPRE') + bStoPre = true + EMT.CHAN2 = nil + end + if EMT.TRAILON then + EmtOutput( 'TRAILOF(X2,X1)') + EmtOutput( 'TRANS') + EmtOutput( 'STOPRE') + bStoPre = true + EMT.TRAILON = nil + end + if not bStoPre then EmtOutput( 'STOPRE') end + EmtOutput( '') + EMT.NSTEP = EMT.NSTEP + 10 + local sStep = EgtNumToString( EMT.NSTEP, 0) + EmtOutput( '_STEP='..sStep) + end + local sOut = EMT.MCHNAME..'/'..EMT.TOOL + EmtOutput( '; *** ' .. sOut .. ' ***') + -- movimento carrelli + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EMT.AUXSTR = {} + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + EMT.CHAN2 = bMoveChar + end + -- se utensile appena selezionato, lo devo dichiarare + if EMT.TSELECT then + EMT.TSELECT = nil + if bMoveChar then + local sStep = EgtNumToString( EMT.NSTEP, 0) + EmtOutput( '_N'..sStep..':STOPRE') + end + local nTool = 100 + tonumber( string.sub( EMT.TCPOS, 2)) + local sOut = 'PRE_WORK(1,1,' .. EgtNumToString( nTool, 0) .. ','..EgtNumToString( EMT.S, 0) ..',,,,)' + EmtOutput( sOut) + EMT.SPEED_ON = true + -- eventuali emissioni per ripartenza successiva al carico + elseif bMoveChar then + local sStep1 = EgtNumToString( EMT.NSTEP + 1, 0) + EmtOutput( 'GOTOF '..'_N'..sStep1) + local sStep = EgtNumToString( EMT.NSTEP, 0) + EmtOutput( '_N'..sStep..':STOPRE') + local nTool = 100 + tonumber( string.sub( EMT.TCPOS, 2)) + local sOut = 'PRE_WORK(1,1,' .. EgtNumToString( nTool, 0) .. ','..EgtNumToString( EMT.S, 0) ..',,,,)' + EmtOutput( sOut) + EMT.SPEED_ON = true + EmtOutput( '_N'..sStep1..':STOPRE') + end + -- eventuale avvio mandrino (se non già avviato) + EmitSpeedOn( EMT.S) + -- primo posizionamento testa rispetto a 0M + EmtResetPrev() + if EMT.ZMAX then + sOut = 'SUPA G0 D0 Z'..EgtNumToString( ParkZ, 3) + else + sOut = 'SUPA G0 D0' .. EmtGetAxis( 'L3') + end + EmtOutput( sOut) + -- movimento YAC con interpolazione approssimata tramite F opportune per ogni asse + --EmtOutput( string.format( '; Y:%.3f->%.3f A:%.3f->%.3f C::%.3f->%.3f', EMT.L2opp, EMT.L2, EMT.R2pp, EMT.R2, EMT.R1pp, EMT.R1)) + local dFeedY, dFeedA, dFeedC = CalcFeedYAC( EMT.L2opp - EMT.L2, EMT.R2pp - EMT.R2, EMT.R1pp - EMT.R1) + sOut = '_POSIZ_YAC('..EgtNumToString( EMT.L2, 3)..','..EgtNumToString( EMT.R2, 3)..','..EgtNumToString( EMT.R1, 3)..','.. + EgtNumToString( dFeedY, 0)..','..EgtNumToString( dFeedA, 0)..','..EgtNumToString( dFeedC, 0)..')' + EmtOutput( sOut) + -- se necessario, attesa fine movimenti carrelli e presa assi relativi + if bMoveChar then + sOut = 'WAIT_CHAN(2)' + EmtOutput( sOut) + EMT.CHAN2 = nil + if EMT.X1DELTA and EMT.X2DELTA then + EmtOutput( 'GET(X1,X2)') + EmtOutput( 'STOPRE') + EmtOutput( 'TRAILON(X2,X1)') + EMT.TRAILON = true + elseif EMT.X1DELTA then + EmtOutput( 'GET(X1)') + elseif EMT.X2DELTA then + EmtOutput( 'GET(X2)') + end + end + if EMT.ZMAX and EMT.L3 < ParkZ - 10 then + sOut = 'SUPA G0 D0' .. EmtGetAxis( 'L3') + EmtOutput( sOut) + end + -- assegnazione assi geometrici (GEOMAX) + EmtOutput( 'TRANS') + if EMT.X1DELTA then + sOut = 'GEOAX(1,X1,2,Y1,3,Z1)' + else + sOut = 'GEOAX(1,X2,2,Y1,3,Z1)' + end + EmtOutput( sOut) + EmtOutput( 'G90 G17') + -- primo posizionamento carrello rispetto a 0M + if EMT.X1DELTA then + local dPosX1 = EMT.L1 + EMT.X1DELTA + sOut = 'G1 X' .. EmtLenToString( dPosX1, 3) .. ' F' .. GetClampFeed( EMT.LB) + EmtOutput( sOut) + elseif EMT.X2DELTA then + local dPosX2 = EMT.L1 + EMT.X2DELTA + sOut = 'G1 X' .. EmtLenToString( dPosX2, 3) .. ' F' .. GetClampFeed( EMT.LB) + EmtOutput( sOut) + else + EmtSetLastError( 1213, "Part to machine without charriots") + end + -- se taglio di separazione prima di scarico a caduta, emissione stop tappeto scarico trucioli + if EMT.PREFALLCUT then + EmtOutput( ';M29') + EMT.PREFALLCUT = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se alto in Z (non serve l'avvicinamento finale) + if EMT.FLAG == 2 then + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() + return + -- altrimenti ripristino i valori originali degli assi + else + MyRestoreAxes() + end + end + -- se standard + if EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo del piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- emissione del piano generico + EmtOutput( EMT.IPLGLSTR) + end + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax() + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- se altrimenti rotazione a Z max + elseif EMT.FLAG == 5 then + -- viene gestito all'inizio della lavorazione successiva + -- altrimenti errore + else + EmtSetLastError( 1212, "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo del piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- emissione del piano generico + EmtOutput( EMT.IPLGLSTR) + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (non contiene l'offset in X per sovramateriale di testa EMT.X_OFF) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + if EMT.FEEDFIRST then + local sOut = 'M_OK(1,'..EgtNumToString( EMT.S, 0)..')' + EmtOutput( sOut) + EMT.FEEDFIRST = false + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + -- se nulla da emettere, esco + if #sAxes == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + MyBackupAxes() + EMT.TLAST = EMT.L1 + + if EMT.FEEDFIRST then + local sOut = 'M_OK(1,'..EgtNumToString( EMT.S, 0)..')' + EmtOutput( sOut) + EMT.FEEDFIRST = false + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if #sAxes == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString( EMT.MOVE, 0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcDinamicaPinze( dH, dS, dL) + local MinTempoAcc = 0.3 -- [s] + local MaxTempoAcc = 4.0 -- [s] + local KgMtCubo= 550 -- densità legno [Kg / metro cubo] + local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg] + local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min] + local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N] + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito) / 1000) + if ( TempoAcc < MinTempoAcc) then TempoAcc = MinTempoAcc end + if ( TempoAcc > MaxTempoAcc) then TempoAcc = MaxTempoAcc end + local AccMaxPinze = FMaxPinze / ( 60 * MinTempoAcc) + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if RidFeed > 100 then + RidFeed = 100 + elseif RidFeed < 10 then + RidFeed = 10 + end + return AccPinze, AccMaxPinze, RidFeed, TempoAcc +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function CalcFeedYAC( dDeltaY, dDeltaA, dDeltaC) + local dTY = abs( dDeltaY) / FmaxY + local dTA = abs( dDeltaA) / FmaxA + local dTC = abs( dDeltaC) / FmaxC + local dT = max( dTY, dTA, dTC) + local dFeedY = FmaxY + if dTY > 0.001 then dFeedY = FmaxY * dTY / dT end + local dFeedA = FmaxA + if dTA > 0.001 then dFeedA = FmaxA * dTA / dT end + local dFeedC = FmaxC + if dTC > 0.001 then dFeedC = FmaxC * dTC / dT end + return dFeedY, dFeedA, dFeedC +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- reset stato pinze + EMT.X1STAT = 0 + EMT.X2STAT = 0 + end + elseif Cmd[1] == '1' then + elseif Cmd[1] == '2' then + elseif Cmd[1] == '3' then + elseif Cmd[1] == '11' then + EMT.X1STAT = tonumber( Cmd[2]) + elseif Cmd[1] == '12' then + EMT.X2STAT = tonumber( Cmd[2]) + elseif Cmd[1] == '21' then + local dX1Delta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1Delta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = dX2Delta + elseif dX1Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + if EMT.X1DELTA and not EMT.X2DELTA then + local sInfo = string.format( ';LOAD D1=%.1f', EMT.X1DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 1 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 0 + local sRef1 = EmtLenToString( EMT.X1DELTA, 3) + local sRef2 = EmtLenToString( ParkX1 + EMT.X1DELTA, 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- reset stato + EMT.MCIND = 0 + EMT.X1DLTP = EMT.X1DELTA + EMT.X2DLTP = EMT.X2DELTA + EMT.X1STAP = EgtIf( EMT.X1DELTA, 1, 0) + EMT.X2STAP = EgtIf( EMT.X2DELTA, 1, 0) + EMT.X1STAI = EMT.X1STAP + EMT.X2STAI = EMT.X2STAP + EMT.X1STAT = 0 + EMT.X2STAT = 0 + EMT.MCX1 = {} + EMT.MCX2 = {} + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + EMT.MCIND = EMT.MCIND + 1 + if Cmd[2] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[3]) + EMT.MCX2[EMT.MCIND] = 0 + elseif Cmd[2] == 'X2' then + EMT.MCX1[EMT.MCIND] = 0 + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[3]) + end + end + elseif Cmd[1] == '2' then + EMT.MCIND = EMT.MCIND + 1 + for i = 2, 4, 2 do + if Cmd[i] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[i+1]) + elseif Cmd[i] == 'X2' then + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[i+1]) + end + end + if not EMT.MCX1[EMT.MCIND] then EMT.MCX1[EMT.MCIND] = 0 end + if not EMT.MCX2[EMT.MCIND] then EMT.MCX2[EMT.MCIND] = 0 end + elseif Cmd[1] == '3' then + EMT.MCIND = EMT.MCIND + 1 + for i = 2, 6, 2 do + if Cmd[i] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[i+1]) + elseif Cmd[i] == 'X2' then + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[i+1]) + end + end + elseif Cmd[1] == '11' then + EMT.X1STAT = tonumber( Cmd[2]) + if EMT.MCIND == 0 then EMT.X1STAI = EMT.X1STAT end + elseif Cmd[1] == '12' then + EMT.X2STAT = tonumber( Cmd[2]) + if EMT.MCIND == 0 then EMT.X2STAI = EMT.X2STAT end + elseif Cmd[1] == '21' then + local dX1Delta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1Delta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = dX2Delta + elseif dX1Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + if EMT.X1STAP ~= 0 and EMT.X2STAP ~= 0 and EMT.X1STAI == 0 and EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 1 then + local sInfo = string.format( ';X1+X2->X1+X2 D12=%.1f', EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 11 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 0 + local sRef1 = EmtLenToString( EMT.MCX1[1], 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X2STAP ~= 0 and EMT.X2STAI == 0 and EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 1 then + local sInfo = string.format( ';X1+X2->X1+X2 D12=%.1f', EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 12 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 0 + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X2STAP ~= 0 and EMT.X1DELTA and not EMT.X2DELTA and EMT.MCIND == 1 then + local sInfo = string.format( ';X1+X2->X1 D1=%.1f', EMT.X1DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 12 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X2STAP ~= 0 and EMT.X1DELTA and not EMT.X2DELTA and EMT.MCIND == 2 then + local sInfo = string.format( ';%sX2->X1 D1=%.1f', EgtIf( EMT.X1STAP > 0, 'X1+', ''), EMT.X1DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 32 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EgtIf( EMT.MCX2[1] == 0, EMT.L1opp + EMT.X2DLTP, EMT.MCX2[1]), 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sRef3 = EmtLenToString( EMT.MCX2[2], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX1[2] == 0, EMT.MCX1[1], EMT.MCX1[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X2STAP ~= 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 1 then + local sInfo = string.format( ';X1+X2->X2 D2=%.1f', EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 21 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 0 + local sRef1 = EmtLenToString( EMT.L1opp + EMT.X1DLTP, 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X2STAP ~= 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND >= 3 then + local sInfo = string.format( ';X1+X2->X2 D2=%.1f', EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 34 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = EgtIf( EMT.MCIND >= 4, 2, 1) + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sRef3 = EmtLenToString( EMT.MCX2[2], 3) + local sRef4 = EmtLenToString( EMT.MCX1[2], 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX2[3] == 0, EMT.MCX2[2], EMT.MCX2[3]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX1[3] == 0, EMT.MCX1[2], EMT.MCX1[3]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X2STAP == 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 1 then + local sInfo = string.format( ';X1->X2 D2=%.1f', EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 31 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.L1opp + EMT.X1DLTP, 3) + local sRef2 = EmtLenToString( ParkX2, 3) + local sRef3 = EmtLenToString( EMT.MCX1[1], 3) + local sRef4 = EmtLenToString( ParkX2, 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 2 then + local sInfo = string.format( ';X1%s->X2 D2=%.1f', EgtIf( EMT.X2STAP > 0, '+X2', ''), EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 31 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EgtIf( EMT.MCX1[1] == 0, EMT.L1opp + EMT.X1DLTP, EMT.MCX1[1]), 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sRef3 = EmtLenToString( EMT.MCX1[2], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND >= 3 then + local sInfo = string.format( ';X1%s->X2 D2=%.1f', EgtIf( EMT.X2STAP > 0, '+X2', ''), EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local sGet = 'GET(X1,X2)' + table.insert( EMT.AUXSTR, sGet) + local sReset = 'TRANS' + table.insert( EMT.AUXSTR, sReset) + local sFeed = 'FA[X1]='..GetFmaxClamp()..' FA[X2]='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sFeed) + local sMove = 'POS[X1]='..EmtLenToString( EMT.MCX1[1], 3)..' POS[X2]='..EmtLenToString( EMT.MCX2[1], 3) + table.insert( EMT.AUXSTR, sMove) + local nFunz = 34 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = EgtIf( EMT.MCIND >= 5, 2, 1) + local sRef1 = EmtLenToString( EMT.MCX2[2], 3) + local sRef2 = EmtLenToString( EMT.MCX1[2], 3) + local sRef3 = EmtLenToString( EMT.MCX2[3], 3) + local sRef4 = EmtLenToString( EMT.MCX1[3], 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX2[4] == 0, EMT.MCX2[3], EMT.MCX2[4]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX1[4] == 0, EMT.MCX1[3], EMT.MCX1[4]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X1STAI ~= 0 and EMT.X1DELTA and EMT.X2DELTA and ( EMT.MCIND == 1 or EMT.MCIND == 2) then + local sInfo = string.format( ';X1%s->X1+X2 D12=%.1f', EgtIf( EMT.X2STAP > 0, '+X2', ''), EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 41 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EgtIf( EMT.MCX1[1] == 0, EMT.L1opp + EMT.X1DLTP, EMT.MCX1[1]), 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sRef3 = EmtLenToString( EgtIf( not EMT.MCX1[2] or EMT.MCX1[2] == 0, EMT.MCX1[1], EMT.MCX1[2]), 3) + local sRef4 = EmtLenToString( EgtIf( not EMT.MCX2[2] or EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X1STAI == 0 and EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 2 then + local sInfo = string.format( ';X1%s->X1+X2 D12=%.1f', EgtIf( EMT.X2STAP > 0, '+X2', ''), EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 42 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sRef3 = EmtLenToString( EgtIf( EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX1[2] == 0, EMT.MCX1[1], EMT.MCX1[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND >= 3 then + local sInfo = string.format( ';X1%s->X1+X2 D12=%.1f', EgtIf( EMT.X2STAP > 0, '+X2', ''), EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 43 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = EgtIf( EMT.MCIND >= 4, 2, 1) + local sRef1 = EmtLenToString( EMT.MCX1[1], 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sRef3 = EmtLenToString( EMT.MCX1[2], 3) + local sRef4 = EmtLenToString( EMT.MCX2[2], 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX1[3] == 0, EMT.MCX1[2], EMT.MCX1[3]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX2[3] == 0, EMT.MCX2[2], EMT.MCX2[3]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP ~= 0 and EMT.X1DELTA and not EMT.X2DELTA and EMT.MCIND >= 3 then + local sInfo = string.format( ';X1->X1 D1=%.1f', EMT.X1DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 33 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = EgtIf( EMT.MCIND >= 4, 2, 1) + local sRef1 = EmtLenToString( EMT.MCX1[1], 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sRef3 = EmtLenToString( EMT.MCX1[2], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX1[3] == 0, EMT.MCX1[2], EMT.MCX1[3]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX2[3] == 0, EgtIf( EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), EMT.MCX2[3]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP == 0 and EMT.X1DELTA and EMT.X2DELTA and ( EMT.MCIND == 1 or EMT.MCIND == 2) then + local sInfo = string.format( ';X2->X1+X2 D12=%.1f', EMT.X1DELTA - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 42 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sRef3 = EmtLenToString( EgtIf( not EMT.MCX2[2] or EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sRef4 = EmtLenToString( EgtIf( not EMT.MCX1[2] or EMT.MCX1[2] == 0, EMT.MCX1[1], EMT.MCX1[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP == 0 and EMT.X1STAI == 0 and EMT.X2STAP ~= 0 and EMT.X2STAI ~= 0 and EMT.X1DELTA and not EMT.X2DELTA and EMT.MCIND == 4 then + local sInfo = string.format( ';X2->X1 D1=%.1f', EMT.X1DELTA) + table.insert( EMT.AUXSTR, sInfo) + local sGet = 'GET(X1,X2)' + table.insert( EMT.AUXSTR, sGet) + local sReset = 'TRANS' + table.insert( EMT.AUXSTR, sReset) + local sFeed = 'FA[X1]='..GetFmaxClamp()..' FA[X2]='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sFeed) + local sMove = 'POS[X1]='..EmtLenToString( EMT.MCX1[1], 3)..' POS[X2]='..EmtLenToString( EMT.MCX2[1], 3) + table.insert( EMT.AUXSTR, sMove) + local nFunz = 33 + local nVertClamp = EgtIf( EMT.X1STAT == 2, 1, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.MCX1[2], 3) + local sRef2 = EmtLenToString( EMT.MCX2[2], 3) + local sRef3 = EmtLenToString( EMT.MCX1[3], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX2[3] == 0, EMT.MCX2[2], EMT.MCX2[3]), 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX1[4] == 0, EMT.MCX1[3], EMT.MCX1[4]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX2[4] == 0, EMT.MCX2[3], EMT.MCX2[4]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.X1STAP == 0 and EMT.X1STAI == 0 and EMT.X2STAP ~= 0 and EMT.X2STAI ~= 0 and not EMT.X1DELTA and EMT.X2DELTA and EMT.MCIND == 3 then + local sInfo = string.format( ';X2->X2 D2=%.1f', EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local nFunz = 34 + local nVertClamp = EgtIf( EMT.X2STAT == 2, 2, 0) + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = 1 + local sRef1 = EmtLenToString( EMT.MCX2[1], 3) + local sRef2 = EmtLenToString( EMT.MCX1[1], 3) + local sRef3 = EmtLenToString( EMT.MCX2[2], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX1[2] == 0, EMT.MCX1[1], EMT.MCX1[2]), 3) + local sRef5 = EmtLenToString( EgtIf( EMT.MCX2[3] == 0, EMT.MCX2[2], EMT.MCX2[3]), 3) + local sRef6 = EmtLenToString( EgtIf( EMT.MCX1[3] == 0, EMT.MCX1[2], EMT.MCX1[3]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4, sRef5, sRef6) + table.insert( EMT.AUXSTR, sOut) + elseif EMT.MCIND > 0 then + EmtSetLastError( 1215, "Charriot move : unmanaged case ("..EMT.MCHNAME..')') + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio + if EMT.AUXIND <= 2 then + -- reset stato + EMT.MCIND = 0 + EMT.X1STAT = 0 + EMT.X2STAT = 0 + EMT.MCX1 = {} + EMT.MCX2 = {} + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + EMT.MCIND = EMT.MCIND + 1 + if Cmd[2] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[3]) + EMT.MCX2[EMT.MCIND] = 0 + elseif Cmd[2] == 'X2' then + EMT.MCX1[EMT.MCIND] = 0 + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[3]) + end + end + elseif Cmd[1] == '2' then + EMT.MCIND = EMT.MCIND + 1 + for i = 2, 4, 2 do + if Cmd[i] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[i+1]) + elseif Cmd[i] == 'X2' then + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[i+1]) + end + end + if not EMT.MCX1[EMT.MCIND] then EMT.MCX1[EMT.MCIND] = 0 end + if not EMT.MCX2[EMT.MCIND] then EMT.MCX2[EMT.MCIND] = 0 end + elseif Cmd[1] == '3' then + EMT.MCIND = EMT.MCIND + 1 + for i = 2, 6, 2 do + if Cmd[i] == 'X1' then + EMT.MCX1[EMT.MCIND] = tonumber( Cmd[i+1]) + elseif Cmd[i] == 'X2' then + EMT.MCX2[EMT.MCIND] = tonumber( Cmd[i+1]) + end + end + elseif Cmd[1] == '11' then + EMT.X1STAT = tonumber( Cmd[2]) + elseif Cmd[1] == '12' then + EMT.X2STAT = tonumber( Cmd[2]) + if EMT.UNL and EMT.X2STAT == 0 then + local sWait = 'WAIT_CHAN(2)' + table.insert( EMT.AUXSTR, sWait) + local sSync = 'STOPRE' + table.insert( EMT.AUXSTR, sSync) + local nFunz = 6 + local nVertClamp = 0 + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LT) + local dAcc = 4 + local nOpt = 0 + local sRef1 = EMT.MCX2[#EMT.MCX2] + local sRef2 = EmtLenToString( ParkX2 - ( EMT.LB - EMT.X2DELTA), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '21' then + local dX1Delta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1Delta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = dX2Delta + elseif dX1Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + if EMT.AUXIND > 1 then + local sInfo = string.format( ';X1->X2 D2=%.1f', EMT.LB - EMT.X2DELTA) + table.insert( EMT.AUXSTR, sInfo) + local sWait = 'WAIT_CHAN(2)' + table.insert( EMT.AUXSTR, sWait) + local sSync = 'STOPRE' + table.insert( EMT.AUXSTR, sSync) + local nFunz = 31 + local nVertClamp = 0 + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LB) + local dAcc = 4 + local nOpt = EgtIf( EMT.MCIND >= 3, 2, 1) + local sRef1 = EmtLenToString( EMT.MCX1[1], 3) + local sRef2 = EmtLenToString( EMT.MCX2[1], 3) + local sRef3 = EmtLenToString( EMT.MCX1[2], 3) + local sRef4 = EmtLenToString( EgtIf( EMT.MCX2[2] == 0, EMT.MCX2[1], EMT.MCX2[2]), 3) + local sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,%s,%s)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2, sRef3, sRef4) + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'X1' then + local sOut = 'STOPRE' + table.insert( EMT.AUXSTR, sOut) + EMT.NSTEP = EMT.NSTEP + 10 + local sStep = EgtNumToString( EMT.NSTEP, 0) + sOut = '_STEP='..sStep + table.insert( EMT.AUXSTR, sOut) + sOut = 'TRAILOF(X2,X1)' + table.insert( EMT.AUXSTR, sOut) + sOut = '_N'..sStep..':STOPRE' + table.insert( EMT.AUXSTR, sOut) + sOut = 'TRANS' + table.insert( EMT.AUXSTR, sOut) + sOut = 'STOPRE' + table.insert( EMT.AUXSTR, sOut) + EMT.TRAILON = nil + sOut = 'POS[X1]='..Cmd[3]..' FA[X1]='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.X1POS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local dX1Delta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1Delta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = dX2Delta + elseif dX1Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + ; + elseif Cmd[1] == '2' then + local sOut = 'STOPRE' + table.insert( EMT.AUXSTR, sOut) + EMT.NSTEP = EMT.NSTEP + 10 + local sStep = EgtNumToString( EMT.NSTEP, 0) + sOut = '_STEP='..sStep + table.insert( EMT.AUXSTR, sOut) + local nFunz = 6 + local nVertClamp = 0 + local dPress = 2.5 + local dFeed = GetClampFeed( EMT.LT) + local dAcc = 4 + local nOpt = 0 + local sRef1 = Cmd[5] + local sRef2 = EmtLenToString( ParkX2 - ( EMT.LT - EMT.X2DELTA), 3) + sOut = string.format( '_POSIZ_T(%d,%d,%.1f,%.1f,%.1f,%d,%s,%s,,)', nFunz, nVertClamp, dPress, dFeed, dAcc, nOpt, sRef1, sRef2) + table.insert( EMT.AUXSTR, sOut) + sOut = '_N'..sStep..':STOPRE' + table.insert( EMT.AUXSTR, sOut) + EMT.U_STD = true + elseif Cmd[1] == '3' then + ; + elseif Cmd[1] == '11' then + ; + elseif Cmd[1] == '12' then + ; + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.X1DELTA, ' EA112', ' EA111') + EMT.SB = EgtIf( EMT.X1DELTA, ' EB112', ' EB111') + EMT.SC = EgtIf( EMT.X2DELTA, ' EC142', ' EC141') + EMT.SD = EgtIf( EMT.X2DELTA, ' ED142', ' ED141') + EMT.SE = EgtIf( EMT.X1DELTA, ' EE1', ' EE2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.PREROT then + sOut = 'G111 '..Cmd[2]..'='..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + else + sOut = 'G111 '..Cmd[2]..'='..Cmd[3]..' EA86 EB87 EC141 EE0 EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] ..'=' .. Cmd[3] ..' '.. Cmd[4] ..'=' .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..'='..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..'='..Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] ..'=' .. Cmd[3] ..' '.. Cmd[4] ..'=' .. Cmd[5] ..' '.. Cmd[6] ..'=' .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..'='..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..'='..Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', ' '..Cmd[6]..'='..Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PX1=' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if EMT.SPLITROT then + EMT.SA = EgtIf( Cmd[2] ~= '0', ' EA11' .. CalcCharStatus( Cmd[2], true), ' EA86') + EMT.SB = EgtIf( Cmd[2] ~= '0', ' EB11' .. CalcCharStatus( Cmd[2], true), ' EB87') + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + else + EMT.SA = ' EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + end + elseif Cmd[1] == '12' then + local sMsg = 'PX2=' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE2', ' EE1') + elseif Cmd[1] == '21' then + local dX1Delta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1Delta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = dX2Delta + elseif dX1Delta > 0 then + EMT.X1DELTA = dX1Delta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = ' EB112' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'ET1', '') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. '=' .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. '=' .. Cmd[3] ..' '.. Cmd[4] .. '=' .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'X1' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local sX1Taking = ' X1='..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'G111'..sX1Taking..' EA75 EB110 EE0 EF'..EmtLenToString( EMT.FMAXPINZE,0)..' ET1 E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. '=' .. Cmd[3] ..' '.. Cmd[4] .. '=' .. Cmd[5] ..' '.. Cmd[6] .. '=' .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PX1=' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PX2=' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local dX1YDelta = tonumber( Cmd[2]) + local dX2Delta = tonumber( Cmd[3]) + if dX1YDelta > 0 and dX2Delta > 0 then + EMT.X1DELTA = dX1YDelta + EMT.X2DELTA = dX2Delta + elseif dX1YDelta > 0 then + EMT.X1DELTA = dX1YDelta + EMT.X2DELTA = nil + elseif dX2Delta > 0 then + EMT.X1DELTA = nil + EMT.X2DELTA = dX2Delta + end + local sX1Load = ' X1='..EmtLenToString( LoadT) + local sOut = 'G111'..sX1Load..' EA76'..EMT.SB..' EE0 EF'..EmtLenToString( EMT.FMAXPINZE,0)..' ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyBackupAxes() + EMT.L1b = EMT.L1 + EMT.L2b = EMT.L2 + EMT.L3b = EMT.L3 + EMT.R1b = EMT.R1 + EMT.R2b = EMT.R2 + EMT.R3b = EMT.R3 + EMT.R4b = EMT.R4 + EMT.RRb = EMT.RR + EMT.C1b = EMT.C1 + EMT.C2b = EMT.C2 + EMT.C3b = EMT.C3 +end + +--------------------------------------------------------------------- +function MyRestoreAxes() + EMT.L1 = EMT.L1b + EMT.L2 = EMT.L2b + EMT.L3 = EMT.L3b + EMT.R1 = EMT.R1b + EMT.R2 = EMT.R2b + EMT.R3 = EMT.R3b + EMT.R4 = EMT.R4b + EMT.RR = EMT.RRb + EMT.C1 = EMT.C1b + EMT.C2 = EMT.C2b + EMT.C3 = EMT.C3b +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + local MyL1o = EMT.L1 + local MyL2o = EMT.L2 + local MyL3o = EMT.L3 + + --if EMT.REFLOC then + -- local vtE + -- if EMT.HEAD ~= 'H3' then + -- local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( 0)) + -- local LenRef = MillOffs + -- vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + -- else + -- local LenAux = ( EMT.TDIST or ChSawLen) + MillOffs + -- local LenRef = MillOffs + -- local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + -- vtE = vtAux * LenAux - Z_AX() * LenRef + -- end + -- EMT.L1 = EMT.L1 - vtE:getX() + -- EMT.L2 = EMT.L2 - vtE:getY() + -- EMT.L3 = EMT.L3 - vtE:getZ() + --end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + EMT.L1o = MyL1o + EMT.L2o = MyL2o + EMT.L3o = MyL3o + + -- Assi geometrici sempre XYZ (indipendentemente dal nome assi fisici) + EMT.L1t = 'X' + EMT.L2t = 'Y' + EMT.L3t = 'Z' +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, DeltaTabY, DeltaTabZ) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + local sXout, sYout, sZout + if EMT.X1DELTA then + sXout = ' X='..EmtLenToString( xS + EMT.X1DELTA)..'+OFS_T5_X1[0]' + sYout = ' Y=OFS_T5_X1[1]' + sZout = ' Z=OFS_T5_X1[2]' + elseif EMT.X2DELTA then + sXout = ' X='..EmtLenToString( xS + EMT.X2DELTA)..'+OFS_T5_X2[0]' + sYout = ' Y=OFS_T5_X2[1]' + sZout = ' Z=OFS_T5_X2[2]' + else + EmtSetLastError( 1214, "Part to machine without charriots") + end + EMT.IPLGLSTR = 'TRANS'..sXout..sYout..sZout.. + '\nAROT Z'..EgtNumToString( dAngO)..'\nAROT Y'..EgtNumToString( dAngV)..'\nAROT Z'..EgtNumToString( dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function VerifyEmitRotation() + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- se sono uguali non devo fare alcunchè + if nRot == nPrevRot then + return false + end + -- determino quanto ruotare + local nDeltaRot = nRot - nPrevRot + -- se rotazione automatica richiesta e possibile + if AutomaticRotation and EMT.LB >= AutoRotMinLen then + local sOut = 'M180 L0=' .. tostring( nDeltaRot) + EmtOutput( sOut) + else + local sOut + if nDeltaRot == 1 then + sOut = 'M151' + elseif nDeltaRot == 2 then + sOut = 'M152' + elseif nDeltaRot == 3 then + sOut = 'M153' + end + EmtOutput( sOut) + EmtOutput( 'M86') + EmtOutput( 'G4F.5') + end + return true +end + +--------------------------------------------------------------------- +function EmitZmax() + local sOut = 'SUPA G0 D0 Z'..EgtNumToString( ParkZ, 3) + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitSpeedOn( nSpeed) + if not EMT.SPEED_ON then + EmtOutput( 'M_ON(1,'..EgtNumToString( nSpeed, 0) ..')') + EMT.SPEED_ON = true + end +end + +--------------------------------------------------------------------- +function EmitSpeedOff() + if EMT.SPEED_ON then + EmtOutput( 'M_OFF(1)') + EMT.SPEED_ON = nil + end +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +function GetClampFeed( dLen) + local KgMtCubo= 550 -- densità legno [Kg / metro cubo] + local Massa = ( EMT.HT * EMT.ST * dLen * KgMtCubo ) / 1e9 -- massa [Kg] + local RefMassa = 100 -- massa di riferimento con massima feed + local dCoeff = EgtClamp( RefMassa / Massa, 0.1, 1) + return EmtLenToString( dCoeff * EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/Saomad-KAIROS.ini b/Saomad-KAIROS.ini new file mode 100644 index 0000000..b20647e --- /dev/null +++ b/Saomad-KAIROS.ini @@ -0,0 +1,112 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam +NCType=5 ; 1=Tpa, 2=Num Flexium, 3=Num Axium APServer, 4=Num Axium PCToolkit, 5=Siemens_Sharp7 +Flow=2 +IsoFileDir=\\192.168.214.253\iso +Ip=192.168.214.1 +Rack=0 +Slot=1 +Debug=2 + +[MainVariables] +; 1 = Name, Variable Path, ReadType, Type +; ReadType => o=one time;c=continuous +; Type => plc;cn +1=Data_ToRead,302:0.0:1,c,plc +2=Reset_State,302:0.1:1,c,plc +3=Running,302:2.0:2,c,plc +;1=Data_ToRead,302:0.0:3,c,plc +;2=Reset_State,302:1.0:2,c,plc +;3=Running,302:2.0:2,c,plc +4=P_Prod,302:4.0:2,c,plc +5=P_Machgroup,302:6.0:2,c,plc +6=P_Part,302:8.0:2,c,plc +7=P_State,302:10.0:2,c,plc +8=Laser_X,302:12.0:2,c,plc +9=Laser_Y,302:14.0:2,c,plc +10=Laser_Z,302:16.0:2,c,plc +11=Alarms1,302:18.0:2,c,plc +12=Alarms2,302:20.0:2,c,plc +13=Alarms3,302:22.0:2,c,plc +14=Alarms4,302:24.0:2,c,plc +15=Alarms5,302:26.0:2,c,plc +16=Alarms6,302:28.0:2,c,plc +17=Data_Readed,301:0.0:1,c,plc +18=Reset_Readed,301:0.1:1,c,plc +19=ISO_Num,301:2.0:2,c,plc +20=Reset_Step,301:1.4:1,c,plc +21=Reset_Step_Ok,302:0.2:1,c,plc +22=NC_Status,302:30.0:2,c,plc +23=NC_Mode,302:32.0:2,c,plc +24=Open_Clamp,302:0.4:1,c,plc +25=PLC_Messages1,302:18.0:2,c,plc +26=PLC_Messages2,302:20.0:2,c,plc +27=PLC_Messages3,302:22.0:2,c,plc +28=PLC_Messages4,302:24.0:2,c,plc +29=PLC_Messages5,302:26.0:2,c,plc +30=PLC_Messages6,302:28.0:2,c,plc + +[Languages] +Enable=0 +Language1=Italiano,Ita.txt +Language2=English,Eng.txt + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=0 + +[ToolHolder] +H1.1=Standard.nge +H1.1:MILL_NOTIP=MillNoTip.nge +H1.1:SAW_FLAT=TcSaw2.nge +H3.1=ChainSaw.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 +GenMachining=0 +SurfFinishing=1 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H1=6608 +; 5 axis saw +H2=6615 +; Chainsaw +H3=6616 +; Angular transmission +H5=6603 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,458,74,669,933 + +[VMill] +Enable=1 +Save=0 diff --git a/Saomad-KAIROS.mlde b/Saomad-KAIROS.mlde new file mode 100644 index 0000000..c35a52a --- /dev/null +++ b/Saomad-KAIROS.mlde @@ -0,0 +1,493 @@ +-- Descrizione macchina Saomad-KAIROS by EgalWare s.r.l. 2024/06/27 +-- 2024/06/27 ver 2.6f1 Prima versione (derivata da Kairos023) + +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.6f1' +MIN_MACH_VER = '2.5j1' + +EgtOutLog ( '** Saomad-KAIROS '..PP_VER..' (MinMach '.. MIN_MACH_VER ..') **', 1) + +-- Parametri macchina +NumericalControl = 'SIEMENS' +ChainSaw = false +MinY = -1225 +MaxY = 690 +ParkY = 400 +FmaxY = 45000 +MinZ = -512 +MaxZ = 910 +ParkZ = 900 +FmaxZ = 45000 +MinA = -109.5 +MaxA = 109.5 +ParkA = 0 +FmaxA = 10440 +MinC = -240 +MaxC = 240 +ParkC = 90 +FmaxC = 18000 +MillOffs = 217.0 +ChSawLen = 141.5 +MinX1 = 290.0 +MaxX1 = 3760.0 +ParkX1 = 480.0 +FmaxX1 = 45000 +MinX2 = -3760.0 +MaxX2 = -290.0 +ParkX2 = -480.0 +FmaxX2 = 45000 +LoadT = 1800.0 +UnloadT = -1800 +TurnerOffs = 0 +MaxHOpen = 301 +MaxVOpen = 621 +LenToPress = 500 +MinRX = -10 +MidRX = 130 +MaxRX = 430 +DeltaTabY = 0 +DeltaTabZ = 0 +DimTabY = 500 +DimTabX = 34000 +DistBack = 880 +StartRotation = true +AutomaticRotation = true +AutoRotMinLen = 2600 +MaxUnloadLen = 0 +DefTcPos = 'T1' +CoeffVM = 0.5 + +-- Aggiornamento con dati da B&W +local sData = EgtGetSourceDir().."Beam\\EbwData.lua" +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + if Machine.Offsets.TIPO_CN == 0 then + NumericalControl = 'SIEMENS' + end + if Machine.Offsets.MIN_Y then MinY = Machine.Offsets.MIN_Y end + if Machine.Offsets.MAX_Y then MaxY = Machine.Offsets.MAX_Y end + if Machine.Offsets.MIN_Z then MinZ = Machine.Offsets.MIN_Z end + if Machine.Offsets.MAX_Z then MaxZ = Machine.Offsets.MAX_Z end + if Machine.Offsets.MIN_A then MinA = Machine.Offsets.MIN_A end + if Machine.Offsets.MAX_A then MaxA = Machine.Offsets.MAX_A end + if Machine.Offsets.MIN_C then MinC = Machine.Offsets.MIN_C end + if Machine.Offsets.MAX_C then MaxC = Machine.Offsets.MAX_C end + if Machine.Offsets.MILL_PIVOT then MillOffs = - Machine.Offsets.MILL_PIVOT end + if Machine.Offsets.MIN_X1 then MinX1 = Machine.Offsets.MIN_X1 end + if Machine.Offsets.MAX_X1 then MaxX1 = Machine.Offsets.MAX_X1 end + if Machine.Offsets.MIN_X2 then MinX2 = Machine.Offsets.MIN_X2 end + if Machine.Offsets.MAX_X2 then MaxX2 = Machine.Offsets.MAX_X2 end + ParkX1 = Machine.Offsets.PARK_X1 or ParkX1 + ParkX2 = Machine.Offsets.PARK_X2 or ParkX2 + if Machine.Offsets.BEAM_LOAD then LoadT = Machine.Offsets.BEAM_LOAD end + if Machine.Offsets.BEAM_UNLOAD then UnloadT = Machine.Offsets.BEAM_UNLOAD end + TurnerOffs = Machine.Offsets.TURN_OFFS or TurnerOffs + if Machine.Offsets.TAB_OFFSET_Y then DeltaTabY = Machine.Offsets.TAB_OFFSET_Y end + if Machine.Offsets.TAB_OFFSET_Z then DeltaTabZ = Machine.Offsets.TAB_OFFSET_Z end + if Machine.Offsets.NOULOAD then MaxUnloadLen = Machine.Offsets.NOULOAD end + end + ParkY = EgtClamp( ParkY, MinY, MaxY) + ParkZ = EgtClamp( ParkZ, MinZ, MaxZ) + ParkA = EgtClamp( ParkA, MinA, MaxA) + ParkC = EgtClamp( ParkC, MinC, MaxC) + end +end + +EmtGeneral { + File='Saomad-KAIROS.nge', + Offset = Vector3d( 0.0, -835, -779.06), + AxisMaxAdjust = 30, + AxisMaxRotAdj = 0.5, + ExitMaxAdjust = 30, + ExitMaxRotAdj = 0.5, + AngDeltaMinForHome = 165, + Special = 'Saomad-KAIROS.mlse', + Processor = 'Saomad-KAIROS.mlpe'} +local BaseId = EmtBase { + Name = 'Base', + Geo='BASE/GEO', + Aux={'BASE/SOLID', 'BASE/LOAD', 'BASE/UNLOAD', 'BASE/TC', 'BASE/TC2', 'BASE/SIGN', 'BASE/COLLISION'}} +local YId = EmtAxis { + Name = 'Y', + Parent = 'Base', + Token = 'Y1', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( -278.7237, 322.3254, 2068.04), + Stroke = {MinY, MaxY}, + Home = ParkY, + Geo = 'Y_AXIS/GEO', + Aux = 'Y_AXIS/SOLID'} +EmtAxis { + Name = 'Z', + Parent = 'Y', + Token = 'Z1', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0.0257, -151.1589, 627.0044), + Stroke = {MinZ, MaxZ}, + Home = ParkZ, + Geo = 'Z_AXIS/GEO', + Aux = {'Z_AXIS/SOLID', 'Z_AXIS/COLLISION'}} +local CId = EmtAxis { + Name = 'C', + Parent = 'Z', + Token = 'C1', + Type = MCH_AT.ROTARY, + Dir = -Z_AX(), + Pos = Point3d( 0, 0, 600.0), + Stroke = {MinC, MaxC}, + Home = ParkC, + Geo = 'C_AXIS/GEO', + Aux = {'C_AXIS/SOLID', 'C_AXIS/COLLISION'}} +EmtAxis { + Name = 'A', + Parent = 'C', + Token = 'A1', + Type = MCH_AT.ROTARY, + Dir = Y_AX(), + Pos = Point3d( 0, 0, MillOffs), + Stroke = {MinA, MaxA}, + Home = ParkA, + Geo = 'A_AXIS/GEO', + Aux = {'A_AXIS/SOLID', 'A_AXIS/COLLISION'}} +-- Frese +local H1Id = EmtHead { + Name = 'H1', + Parent = 'A', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 2, + OthColl = {'A/SOLID', 'C/SOLID'}, + Geo = 'H1_HEAD/GEO'} +EgtSetInfo( H1Id, 'ZMAXONROT', '1,60') +-- Sega a catena +EmtAxis { + Name = 'CS', + Parent = 'A', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { -90, 90}, + Home = 0, + Geo = 'CS_AXIS/GEO'} +local H3Id = EmtHead { + Name = 'H3', + Parent = 'CS', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, -ChSawLen), + TDir = -X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'A/SOLID', 'C/SOLID'}, + Geo = 'H3_HEAD/GEO'} +EgtSetInfo( H3Id, 'ZMAXONROT', '1,5') +-- Morse +local X1Id = EmtAxis { + Name = 'X1', + Token = 'X1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( -1253.5, 245.0, 918.94), + Stroke = { MinX1, MaxX1}, + Home = ParkX1, + Geo = 'X1_AXIS/GEO', + Aux = {'X1_AXIS/SOLID', 'X1_AXIS/COLLISION'}} +local PX1Id = EmtAxis { + Name = 'PX1', + Parent = 'X1', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d( -1253.5, 95.0, 918.94), + Stroke = { 0, MaxHOpen}, + Home = MaxHOpen, + Geo = 'PX1_AXIS/GEO', + Aux = {'PX1_AXIS/SOLID', 'PX1_AXIS/COLLISION'}} +local QX1Id = EmtAxis { + Name = 'QX1', + Parent = 'X1', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( -874.2, -22.5, 668.9787), + Stroke = { 0, MaxVOpen}, + Home = MaxVOpen, + Geo = 'QX1_AXIS/GEO', + Aux = 'QX1_AXIS/SOLID'} +local X2Id = EmtAxis { + Name = 'X2', + Token = 'X2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( 1253.5001, 245.0, 918.94), + Stroke = { MinX2, MaxX2}, + Home = ParkX2, + Geo = 'X2_AXIS/GEO', + Aux = {'X2_AXIS/SOLID', 'X2_AXIS/COLLISION'}} +local PX2Id = EmtAxis { + Name = 'PX2', + Parent = 'X2', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d( 1253.5001, 95.0, 918.94), + Stroke = { 0, MaxHOpen}, + Home = MaxHOpen, + Geo = 'PX2_AXIS/GEO', + Aux = {'PX2_AXIS/SOLID', 'PX2_AXIS/COLLISION'}} +local QX2Id = EmtAxis { + Name = 'QX2', + Parent = 'X2', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 874.2001, 640.4727, -1591.561), + Stroke = { 0, MaxVOpen}, + Home = MaxVOpen, + Geo = 'QX2_AXIS/GEO', + Aux = 'QX2_AXIS/SOLID'} +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { -30000, 30000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( -DimTabX, DeltaTabY - DimTabY, DeltaTabZ), + Scale = { DimTabX / 20000, DimTabY / 500, 1}, + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- ToolChanger 10 posizioni verticale +local ptTcCen = Point3d( -520.9759, -817, 1056.0424) +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = ptTcCen, + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T2', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T2'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*2), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*3), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*4), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*6), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*7), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*8), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*9), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T10'} +EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = ptTcCen - Vector3d( 0, 0, 110*10), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T11'} +-- ToolChanger lama +EmtTcPos { + Name = 'T21', + Parent = 'Base', + Pos = Point3d( 518.0241, -748.997, 271.8273), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T21'} +-- ToolChanger motosega +EmtTcPos { + Name = 'T22', + Parent = 'Base', + Pos = Point3d( 656.5865, -768.913, 715.2899), + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T22'} + +-- Aggiusto posizioni geometriche +local vtMove = Vector3d( 0, ( DeltaTabY - 0), ( DeltaTabZ - 0)) +local vtMoveY = Vector3d( 0, 0, ( DeltaTabZ - 0)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'LOAD'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'UNLOAD'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC2'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X1Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PX1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PX1Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QX1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PX2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PX2Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QX2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'SOLID'), vtMoveY, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PX1LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PX1Id, 'SOLID') or GDB_ID.NULL, 'Light') +PX2LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PX2Id, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- Se testa con sega a catena + if EMC.HEAD == 'H3' then + -- aggiustamenti per distanza + local dDist = EgtIf( EMC.DIST and abs( EMC.DIST) > 1, EMC.DIST, ChSawLen) + EmtModifyExitPosition( EMC.HEAD, EMC.EXIT, Point3d( 0, 0, -dDist)) + if not EMC.VER or EMC.VER < '2.5h2' then + local vtMove = Point3d( 0, 0, -dDist) - Point3d( EMC.EXITPOS) + local ExitId = EgtGetFirstNameInGroup( EgtGetHeadId( EMC.HEAD), 'T'..tostring( EMC.EXIT)) + EgtMove( ExitId, vtMove) + end + -- recupero valore asse CS bloccato + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosCS = tonumber( sVal:sub( 4) or '') + EmtModifyAxisHome( 'C', GetChainSawCHomeFromVirtualAxis( dPosCS)) + else + EmtModifyAxisHome( 'C', ParkC) + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la sega a catena dal valore dell'asse virtuale +function GetChainSawCHomeFromVirtualAxis( dPosCS) + -- se CS=0 -> HomeC = -90 + if abs( dPosCS) < 0.1 then + return 90 + -- altrimenti CS=90 -> HomeC = -180 + else + return 0 + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello X1 +function SetPX1Light( bClosed) + if not PX1LightId then return end + EgtSetColor( PX1LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PX1LightId, 'On', '1') + else + EgtRemoveInfo( PX1LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello X1 +function GetPX1Light() + if not PX1LightId then return false end + return ( EgtGetInfo( PX1LightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello X2 +function SetPX2Light( bClosed) + if not PX2LightId then return end + EgtSetColor( PX2LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PX2LightId, 'On', '1') + else + EgtRemoveInfo( PX2LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello X2 +function GetPX2Light() + if not PX2LightId then return false end + return ( EgtGetInfo( PX2LightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPX1Light( false) + SetPX2Light( false) + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/Saomad-KAIROS.mlpe b/Saomad-KAIROS.mlpe new file mode 100644 index 0000000..579290f --- /dev/null +++ b/Saomad-KAIROS.mlpe @@ -0,0 +1,1430 @@ +-- Processore macchina Saomad-KAIROS by EgalWare s.r.l. 2023/12/03 +-- Funzioni generiche indipendenti dal controllo + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +LONG_TOOL_MINLEN = 221 +BIG_TOOL_DIAM = 300 + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'SIEMENS' then + dofile( sBaseDir .. 'Saomad-KAIROS.SIEMENS.mlpe') +else + EmtSetLastError( 1201, 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 4 + +--------------------------------------------------------------------- +function OnSimulStart() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Muovo i supporti nella posizione intermedia + SimulMoveAxes( 'RX1', MidRX, MCH_SIM_STEP.RAPID, 'RX2',MidRX, MCH_SIM_STEP.RAPID) + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'Z', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'A', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM3') or GDB_ID.NULL + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX1'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX1'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[10] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM3') or GDB_ID.NULL + EMT.MCODET[11] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[12] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX2'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[13] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[14] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX2'), 'COLLISION'), 'STM2') or GDB_ID.NULL + EMT.MCODET[15] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE1') or GDB_ID.NULL + EMT.MCODET[16] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE2') or GDB_ID.NULL + EMT.MCODET[17] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'BACK') or GDB_ID.NULL + EMT.MCODET[18] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'BELT') or GDB_ID.NULL + EMT.MCODET[19] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'RX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL + EMT.MCODET[20] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'RX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL + for i = #EMT.MCODET, 1, -1 do + if not EMT.MCODET[i] or EMT.MCODET[i] == GDB_ID.NULL then + table.remove( EMT.MCODET, i) + EgtOutLog( ' Warning : MCODET element (' .. tostring( i) .. ') is null') + elseif EgtGetDebugLevel() >= 4 then + EgtOutLog( ' MCODET element (' .. tostring( i) .. ') is ok') + end + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +function OnSimulEnd() + -- Muovo i supporti nella posizione home + SimulMoveAxes( 'RX1', MinRX, MCH_SIM_STEP.RAPID, 'RX2',MinRX, MCH_SIM_STEP.RAPID) +end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + EgtSetAxisPos( 'T', LoadT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino dimensioni del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.LB = 0 + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.LB = b3Sol:getDimX() + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico primo utensile sulla testa 1 + local sTool, nTlen = FindFirstToolOnHead( 'H1') + if sTool then + EMT.TOOL_1 = sTool + else + EMT.TOOL_1 = GetDefaultToolName() + end + EgtLoadTool( 'H1', 1, EMT.TOOL_1) + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + ShowToolInTcPos( EMT.TCPOS_1, false) + EMT.LOAD = true + -- Se vero inizio e abilitato creo gli Zmap + EMT.VMILL = {} + if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then + local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) + local nPartRawId = EgtGetFirstRawPart() + while nPartRawId do + -- se è lo scarto finale tagliato a pezzi, esco + local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') + if nRawOrd == nLastOrd + 1 then break end + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') + local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + -- aggiungo eventuale scrap successivo + if nRawOrd == nLastOrd then + local nScrapId = EgtGetNextRawPart( nPartRawId) + if nScrapId then + local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') + local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) + if b3ScrapRaw then + b3Raw:Add( b3ScrapRaw) + end + end + end + -- determino la risoluzione dello Zmap + local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() + local dTol = 4.71 + if dArea < CoeffVM * 0.15e6 then + dTol = 0.71 + elseif dArea < CoeffVM * 0.3e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 0.6e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 2.4e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 4.8e6 then + dTol = 3.77 + end + -- creo lo Zmap + local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if VMillId then + EgtSetName( VMillId, 'VMill') + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetColor( VMillId, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nPartRawId) + while nId do + if nId ~= VMillId then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + table.insert( EMT.VMILL, VMillId) + end + nPartRawId = EgtGetNextRawPart( nPartRawId) + end + end + -- fasi successive + else + EMT.LOAD = false + end + -- recupero sovramateriale di testa del pezzo corrente + local nCurrRawId = EgtGetFirstRawPart() + while nCurrRawId do + if EgtVerifyRawPartPhase( nCurrRawId, EMT.PHASE) then + break + end + nCurrRawId = EgtGetNextRawPart( nCurrRawId) + end + EMT.HOVM = EgtGetInfo( nCurrRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola + if IsStartOrRestPhase( EMT.PHASE) then + -- se fase inizio, segnalo giacitura del grezzo + if IsStartPhase( EMT.PHASE) then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + EgtOutText( tostring( -90 * nRot) .. '° rotated bar') + else + EgtOutText( 'Not rotated bar') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw = EgtGetRawPartBBox( nRawId) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + local b3Tmp = EgtGetRawPartBBox( nRawId) or BBox3d() + b3Raw:Add( b3Tmp) + nScrapRawId = nRawId + end + end + nRawId = nNextRawId + end + -- gestione eventuale scarto affettato successivo + if EMT.VMILL and #EMT.VMILL > 0 then + EMT.SCRAP = nScrapRawId + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + else + EMT.SCRAP = nil + end + -- recupero CutId del pezzo in lavorazione + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.X1SPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #( EMT.MCODET or {}) do + EMT.CODET[i] = EMT.MCODET[i] + end + for i = 1, #( EMT.VMILL or {}) do + table.insert( EMT.CODET, EMT.VMILL[i]) + end + end + -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola + elseif IsMidPhase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- eseguo aggancio + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + end + nRawId = nNextRawId + end + -- se Vmill, nascondo eventuale scrap + if EMT.VMILL then + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + end + -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico + elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'X1') + end + end + nRawId = nNextRawId + end + end + -- Indicazione angolo rotazione pezzo + EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0 + local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN') + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + -- se disposizione intermedia + if IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se le rotazioni delle fasi corrente e precedente sono diverse + if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- se le rotazioni delle fasi corrente e precedente sono diverse + if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + end + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosCS) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + EMT.TOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + -- se non è chiamato da altro script (non c'è parametro) + if not dPosCS then + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + for i, Coll in ipairs( EMT.COLLOBJ) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002) + end + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 2 + EMT.A1n = 'X1' + EMT.A2n = 'X2' + end + -- se sega a catena, imposto subito angolo scelto per asse virtuale CS + if EMT.HEAD == 'H3' then + if not dPosCS then + -- recupero la lavorazione successiva + local NextMchId + if EMT.MCHID then + NextMchId = EgtGetNextActiveOperation( EMT.MCHID) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato CS + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + dPosCS = tonumber( sVal:sub( 4)) + else + -- imposto visualizzazione + EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) + end + -- imposto il valore di CS + EgtSetAxisPos( 'CS', dPosCS) + EgtSetAxisPos( 'C', GetChainSawCHomeFromVirtualAxis( dPosCS)) + EgtSetAxisPos( 'A', 0) + end + -- breve pausa + EgtPause( 100) + EgtOutText( '') + EMT.TOOL_1 = EMT.TOOL + EMT.TCPOS_1 = EMT.TCPOS + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect() + -- se prossimo utensile non definito, è disposizione ed esco + if EMT.NEXTTOOL == '' then return end + -- se sega a catena o punta lunga o utensile di grosso diametro, devo cambiare + if EMT.HEAD == 'H3' or ( EMT.HEAD == 'H1' and ( EMT.TOTLEN > LONG_TOOL_MINLEN or EMT.TOTDIAM > BIG_TOOL_DIAM)) then + EgtOutText( 'Tool change in progress...') + -- movimento scarico sega a catena + if EMT.HEAD == 'H3' then + local dPosCS = EgtGetAxisPos( 'CS') + SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.COLLROT, 'C', GetChainSawCHomeFromVirtualAxis( dPosCS), MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'Y', ParkY, MCH_SIM_STEP.RAPID) + end + -- breve pausa + EgtPause( 100) + -- nascondo utensile su testa e lo visualizzo su TcPos + EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- movimento per carico utensile + SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.RAPROT, 'C', ParkC, MCH_SIM_STEP.RAPROT) + EgtOutText( '') + -- deposito utensile + else + if EMT.NEXTTOOL ~= EMT.TOOL_1 then + EgtOutText( 'Tool change in progress...') + -- simulo movimento + SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.COLLROT, 'C', ParkC, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'Y', ParkY, MCH_SIM_STEP.RAPID) + -- breve pausa + EgtPause( 100) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- nascondo l'utensile corrente + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + -- eseguo movimento opportuno + SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.RAPROT, 'C', ParkC, MCH_SIM_STEP.RAPROT) + else + EMT.TOOL_1 = nil + EMT.TCPOS_1 = nil + end + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo CS diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then + local dPrevCS = EgtGetAxisPos( 'CS') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosCS = tonumber( sVal:sub( 3)) + if abs( dPosCS - dPrevCS) > 1 then + OnSimulToolDeselect() + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosCS) + end + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) + -- recupero TASKID della feature lavorata + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.TASKID = 0 + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.LOAD then + EMT.LOAD = false + elseif EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.PREVHEAD = EMT.HEAD + EMT.PREVEXIT = EMT.EXIT +end + +--------------------------------------------------------------------- +--function OnSimulPathStart() +--end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then + EgtOutLog( 'OnSimulPathEnd', 5) + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + local b3Vmill = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD) + if b3Vmill:getDimX() < 1200 then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + end + -- aggiorno visualizzazione + EgtDraw() + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + --EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathStartAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + --EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathEndAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + -- Recupero la posizione corrente dei carrelli + local X1p = EgtGetAxisPos( 'X1') + local X2p = EgtGetAxisPos( 'X2') + -- Imposto movimento carrelli insieme con la tavola : + -- entrambe le pinze + if EMT.X1DELTA and EMT.X2DELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'X1' + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.X1DELTA + EMT.A2n = 'X2' + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.X2DELTA + -- solo pinza Y + elseif EMT.X1DELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'X1' + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.X1DELTA + EMT.A2n = 'X2' + EMT.A2m = nil + EMT.A2 = ParkX2 + -- solo pinza V + elseif EMT.X2DELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'X1' + EMT.A1m = nil + EMT.A1 = EgtIf( EMT.X1SPEC, X1p, ParkX1) + EMT.A2n = 'X2' + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.X2DELTA + end + -- Controllo scorrimento pinze chiuse X1 e X2 + if EMT.X1DELTA then + local dX1DeltaP = X1p - EMT.L1p + if abs( EMT.X1DELTA - dX1DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'X1 slide : ' .. EmtLenToString( dX1DeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.X1DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + if EMT.X2DELTA then + local dX2DeltaP = X2p - EMT.L1p + if abs( EMT.X2DELTA - dX2DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'X2 slide : ' .. EgtNumToString( dX2DeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.X2DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Controllo corse assi X1 e X2 + VerifyX1Stroke( EMT.A1) + VerifyX2Stroke( EMT.A2) + -- se inizio lavorazione + if EMT.MCHFIRST then + EgtOutText( '') + EMT.MCHFIRST = false + EMT.POSTROT = nil + end +end + +--------------------------------------------------------------------- +--function OnSimulMoveEnd() +--end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 then + Class = 'T_H1' + elseif EMT.SIMCOBIND == 1002 then + Class = 'TH_H1' + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 1 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ExecAuxCmd( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( EgtIf( Cmd[3], Cmd[3], Cmd[2])) + elseif Cmd[1] == '1' then + if not SimulMoveAxis( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID) then + if VerifyX12Stroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '2' then + if Cmd[2] == 'X1' and EMT.POSTROT then + local dPosY = tonumber( Cmd[3]) - EMT.HOVM + Cmd[3] = EgtNumToString( dPosY, 3) + EMT.HOVM = 0 + end + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo il movimento + local _, bOk, bOk2 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, + Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID) + if not ( bOk and bOk2) then + local nI = EgtIf( not bOk, 2, 4) + if VerifyX12Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '3' then + -- Verifico movimento carrelli con trave agganciata + VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) + -- Eseguo il movimento + local _, bOk, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, + Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID, + Cmd[6], tonumber( Cmd[7]), MCH_SIM_STEP.RAPID) + if not ( bOk and bOk2 and bOk3) then + local nI = EgtIf( not bOk, 2, EgtIf( not bOk2, 4, 6)) + if VerifyX12Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '11' then + local dPX1 = MaxHOpen + if Cmd[2] ~= '0' then + dPX1 = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PX1', dPX1, MCH_SIM_STEP.RAPID) + local dQX1 = MaxVOpen + if Cmd[2] == '2' then + dQX1 = EgtIf( EMT.ROT == -1, EMT.SB, EMT.HB) + end + SimulMoveAxis( 'QX1', dQX1, MCH_SIM_STEP.RAPID) + SetPX1Light( Cmd[2] ~= '0') + elseif Cmd[1] == '12' then + local dPX2 = MaxHOpen + if Cmd[2] ~= '0' then + dPX2 = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PX2', dPX2, MCH_SIM_STEP.RAPID) + local dQX2 = MaxVOpen + if Cmd[2] == '2' then + dQX2 = EgtIf( EMT.ROT == -1, EMT.SB, EMT.HB) + end + SimulMoveAxis( 'QX2', dQX2, MCH_SIM_STEP.RAPID) + SetPX2Light( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nX1Delta = tonumber( Cmd[2]) + local nX2Delta = tonumber( Cmd[3]) + if nX1Delta > 0.01 and nX2Delta > 0.01 then + EMT.X1DELTA = nX1Delta + EMT.X2DELTA = nX2Delta + elseif nX1Delta > 0.01 then + EMT.X1DELTA = nX1Delta + EMT.X2DELTA = nil + elseif nX2Delta > 0.01 then + EMT.X1DELTA = nil + EMT.X2DELTA = nX2Delta + end + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.X1SPEC = true + end +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL and #EMT.VMILL > 0 then + local vMillId = EMT.VMILL[1] + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- li sposto per lasciare spazio al nuovo pezzo + local nId = EgtGetFirstInGroup( nVmGrpId) + while nId do + EgtMove( nId, Vector3d( 0, -( EMT.SB + 50.0), 0), GDB_RT.GLOB) + nId = EgtGetNext( nId) + end + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) + EgtRelocate( vMillId, nLayId) + local vtMove = Vector3d( 0, -800, 0) + if EMT.FALL then vtMove = Vector3d( -300, -800, -600) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + table.remove( EMT.VMILL, 1) + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + if sExt and sExt:lower() == ".nge" then + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end + end +end + +--------------------------------------------------------------------- +function VerifyYSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y + if sName1 == 'T' and sName2 == 'X1' and GetPX1Light() then + local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'X1') + local dYDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'YDeltaP=%.3f YDeltaA=%.3f', dYDeltaP, dYDeltaA), 5) + if abs( dYDeltaA - dYDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( dYDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyVSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello V + if sName1 == 'T' and sName2 == 'X2' and GetPX2Light() then + local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'X2') + local dVDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'VDeltaP=%.3f VDeltaA=%.3f', dVDeltaP, dVDeltaA), 5) + if abs( dVDeltaA - dVDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'V slide : ' .. EmtLenToString( dVDeltaP, 3) .. ' -> ' .. EmtLenToString( dVDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + return true +end + +--------------------------------------------------------------------- +function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + end + -- Eseguo verifica + if sName2 == 'X1' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'X2' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) + end + return true +end + +--------------------------------------------------------------------- +function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + elseif sName3 == 'T' then + sName1, sName3 = sName3, sName1 + dVal1, dVal3 = dVal3, dVal1 + end + -- Eseguo verifica + if sName2 == 'X1' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'X2' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyX1Stroke( dX1) + if dX1 < MinX1 then + EmtSetOutstrokeInfo( 'X1', 'X1', true, dX1 - MinX1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'X1 axis outstroke ' .. EgtNumToString( dX1 - MinX1, 3) + EgtOutLog( sErr) + return false + elseif dX1 > MaxX1 then + EmtSetOutstrokeInfo( 'X1', 'X1', true, dX1 - MaxX1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'X1 axis outstroke ' .. EgtNumToString( dX1 - MaxX1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyX2Stroke( dX2) + if dX2 > MaxX2 then + EmtSetOutstrokeInfo( 'X2', 'X2', true, dX2 - MaxX2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'X2 axis outstroke ' .. EgtNumToString( dX2 - MaxX2, 3) + EgtOutLog( sErr) + return false + elseif dX2 < MinX2 then + EmtSetOutstrokeInfo( 'X2', 'X2', true, dX2 - MinX2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'X2 axis outstroke ' .. EgtNumToString( dX2 - MinX2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyX12Stroke( sName, dVal) + if sName == 'X1' then + return VerifyX1Stroke( dVal) + elseif sName == 'X2' then + return VerifyX2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTcPos +end + + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 75000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 50000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 6 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 6 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'T') + EMT.L2 = EgtGetAxisHomePos( 'Y') + EMT.L3 = EgtGetAxisHomePos( 'Z') + EMT.R1 = EgtGetAxisHomePos( 'C') + EMT.R2 = EgtGetAxisHomePos( 'A') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + ; + -- se altrimenti disposizione intermedia o finale dopo separazione e rotazione, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + ; + end + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true + EMT.CHARMOVE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + local Cmd = EgtSplitString( EMT.AUX) + if ( Cmd[1] == '1' and Cmd[2] ~= 'Z') or Cmd[1] == '2' or Cmd[1] == '3' then + EMT.CHARMOVE = true + end + if EMT.AUXIND == EMT.AUXTOT and EMT.CHARMOVE then + local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function FindFirstToolOnHead( sH1) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su testa indicata + local sTool, nTlen + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if sHead and ( sHead == sH1) then + sTool = sTest + nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + if CurrMachId then + EgtSetCurrMachining( CurrMachId) + else + EgtResetCurrMachining() + end + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTool, nTlen +end + +--------------------------------------------------------------------- +function GetDefaultToolName() + local vTools = EgtGetToolsInCurrSetupPos( DefTcPos) + if vTools and vTools[1] and #vTools[1] > 0 then + return vTools[1] + else + local sErr = 'Missing tool in Default Position ' .. DefTcPos + EgtOutLog( 'Error : ' .. sErr) + if EMT.VER and EMT.VER >= '2.3a2' and EMT.SIM1ST then + EgtOutBox( sErr, 'ERROR', 'ERROR') + end + return '' + end +end + +--------------------------------------------------------------------- +function IsStartPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START') +end + +--------------------------------------------------------------------- +function IsRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsStartOrRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +function IsMid2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +function IsEnd2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +function GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +--------------------------------------------------------------------- +function GetPhaseOrd( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +function IsLastMachining( nMchId) + local nOpeId = EgtGetNextActiveOperation( nMchId) + while nOpeId do + local nType = EgtGetOperationType( nOpeId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + return false + end + nOpeId = EgtGetNextActiveOperation( nOpeId) + end + return true +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** +--------------------------------------------------------------------- diff --git a/Saomad-KAIROS.mlse b/Saomad-KAIROS.mlse new file mode 100644 index 0000000..5bda9bc --- /dev/null +++ b/Saomad-KAIROS.mlse @@ -0,0 +1,3847 @@ +-- Special Operations macchina Saomad-KAIROS by EgalWare s.r.l. 2023/12/01 + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico i dati globali +local sBaseDir = EgtGetSourceDir() +local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua') + +---------------------- OnSpecialMoveZup ----------------------------- +--------------------------------------------------------------------- +function OnSpecialMoveZup() + --EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT)) + + -- Inizializzazioni + EMC.ERR = 0 + EMC.MODIF = false + + -- se sega a catena + if EMC.HEAD == 'H3' then + + + end + +end + +---------- OnSpecialApplyDisposition & OnPostApplyMachining --------- +----------------------- Costanti ------------------------------------ +local DELTA_TOL_V = 110 +local DELTA_TOL_S = 160 +local DELTA_TOL_L = 310 +local DELTA_TOL_FIXED = 50 +local DeltaTol = DELTA_TOL_S +local DELTA_SIC = 1 +local AGG_LOAD = 0 +local MIN_JOIN_VV = 75 +local MIN_JOIN_SS = 100 +local MIN_JOIN_LS = 100 +local MIN_JOIN_SL = 290 +local MIN_JOIN_LL = 400 +local MinJoin = MIN_JOIN_SS +local MinOther = abs( MinX1) + abs( MaxX2) + MinJoin + +----------------------- Variabili ----------------------------------- +local Test = false + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiunge + if not nClId then + nClId = EgtGroup( EMC.DISPID) + if not nClId then + return nil + end + EgtSetName( nClId, 'CL') + -- altrimenti lo svuoto + else + EgtEmptyGroup( nClId) + end + + return nClId +end + +--------------------------------------------------------------------- +local function IsStartOrRestPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +local function IsMidPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +local function IsEndPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END') +end + +--------------------------------------------------------------------- +local function IsMid2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +local function IsEnd2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +local function GetNextStartOrRestPhase( nPhase) + local nNextPhase = nPhase + 1 + while nNextPhase <= EgtGetPhaseCount() do + if IsStartOrRestPhase( nNextPhase) then + break ; + end + nNextPhase = nNextPhase + 1 + end + return nNextPhase +end + +--------------------------------------------------------------------- +local function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +local function IsLastOperationBeforeRotation( nOperId) + -- se ultima fase o ultima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == EgtGetPhaseCount() or IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + return false + end + -- recupero la successiva operazione attiva + local nNextOperId = EgtGetNextActiveOperation( nOperId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della prossima fase + local nRot = GetPhaseRot( EMC.PHASE) + local nNextRot = GetPhaseRot( EMC.PHASE + 1) + -- ritorno se sono diverse + return ( nRot ~= nNextRot) +end + +--------------------------------------------------------------------- +local function IsFirstMachiningAfterRotation( nMchId) + -- se prima fase o prima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == 1 or IsStartOrRestPhase( EMC.PHASE) then + return false + end + -- recupero la precedente operazione attiva + local nPrevOperId = EgtGetPrevActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della fase precedente + local nRot = GetPhaseRot( EMC.PHASE) + local nPrevRot = GetPhaseRot( EMC.PHASE - 1) + -- ritorno se sono diverse + return ( nRot ~= nPrevRot) +end + +--------------------------------------------------------------------- +local function UpdateMinJoinDeltaTol() + local L_SMALL = 800 + local H_V = 90 + local H_S = 150 + local H_L = 250 + local W_V = 90 + local W_S = 150 + local W_L = 450 + if EMC.SB <= W_V and EMC.HB <= H_V then + MinJoin = MIN_JOIN_VV + DeltaTol = DELTA_TOL_V + elseif EMC.LB <= L_SMALL then + MinJoin = MIN_JOIN_SS + DeltaTol = DELTA_TOL_S + else + local dMinJoinS + local dMinJoinL + if EMC.SB <= W_S then + dMinJoinS = MIN_JOIN_SS + dMinJoinL = MIN_JOIN_LS + elseif EMC.SB <= W_L then + local Coeff = ( EMC.SB - W_S) / ( W_L - W_S) + dMinJoinS = ( 1 - Coeff) * MIN_JOIN_SS + Coeff * MIN_JOIN_SL + dMinJoinL = ( 1 - Coeff) * MIN_JOIN_LS + Coeff * MIN_JOIN_LL + else + dMinJoinS = MIN_JOIN_SL + dMinJoinL = MIN_JOIN_LL + end + if EMC.HB <= H_S then + MinJoin = dMinJoinS + DeltaTol = DELTA_TOL_S + elseif EMC.HB <= H_L then + local Coeff = ( EMC.HB - H_S) / ( H_L - H_S) + MinJoin = ( 1 - Coeff) * dMinJoinS + Coeff * dMinJoinL + DeltaTol = ( 1 - Coeff) * DELTA_TOL_S + Coeff * DELTA_TOL_L + else + MinJoin = dMinJoinL + DeltaTol = DELTA_TOL_L + end + if EMC.SB < W_V then + DeltaTol = DELTA_TOL_V + end + end + MinOther = abs( MinX1) + abs( MaxX2) + MinJoin +end + +--------------------------------------------------------------------- +local function GetCUTID() + -- recupero CUTID del pezzo in lavoro + local nOrd = GetPhaseOrd( EMC.PHASE) + local nPartRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + nPartRawId = nRawId + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + return CutID +end + +--------------------------------------------------------------------- +local function EnsureZmax( bZmaxOk, vCmd) + if not bZmaxOk then table.insert( vCmd, { 1, 'Z', EgtGetAxisHomePos( 'Z')}) end + return true +end + +--------------------------------------------------------------------- +local function EmitComment( vCmd, sOut) + EgtOutLog( ' ' .. sOut, 1) + if Test then + table.insert( vCmd, { 0, sOut}) + end +end + +--------------------------------------------------------------------- +function OnSpecialApplyDisposition() + + EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***', 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Campi obbligatori ma non usati + EMC.HEAD = "" + EMC.EXIT = 1 + EMC.TCPOS = "" + EMC.SHIFTS = 0 + EMC.SBH = false + + -- Se disposizione da saltare non devo fare alcunché + if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Recupero il tipo dell'operazione successiva + local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) + + -- Se ci sono lavorazioni successive non devo fare alcunché + if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end + + -- Imposto gruppo e path di movimento + local nClId = PrepareClGroup( EMC.DISPID) + if not nClId then + EMC.ERR = 3 + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se l'operazione successiva è una disposizione con rotazione, devo preparare il pezzo alla rotazione + if IsLastOperationBeforeRotation( EMC.DISPID) then + -- aggiornamento posizioni + if IsStartPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + EMC.CNT = 1 + else + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + EMC.HCING = 0 + EMC.TCING = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + -- Eseguo preparazione alla rotazione + local vCmd = SpecCalcPreRot() + SpecOutputCmds( vCmd, true) + return + end + + -- Se l'operazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and bSplit and not IsEnd2Phase( EMC.PHASE) then + -- aggiornamento posizioni + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.HOVM = EgtGetInfo( nRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 + -- Eseguo scarico + local vCmd = SpecCalcUnload() + SpecOutputCmds( vCmd, true) + return + end + + -- Verifico ci sia un solo grezzo nella fase corrente + local nRawCount = 0 + local nCurrRawId = GDB_ID.NULL + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + nRawCount = nRawCount + 1 + nCurrRawId = nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if not b3Raw or b3Raw:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = 0 + EMC.HCING = 0 + EMC.TCING = 0 + + -- Devo scaricare il grezzo rimasto (deve essere unico) + -- Posizione trave + local dPosT + + -- Se fase 1 o dopo rotazione eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 or IsEnd2Phase( EMC.PHASE) then + dPosT = LoadT + if IsEnd2Phase( EMC.PHASE) then dPosT = dPosT + TurnerOffs end + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxX1 - dPosT)) + -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza + elseif IsStartOrRestPhase( EMC.PHASE) then + -- recupero posizione trave e quota di aggancio carrello + dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY - dPosT, 0}) + -- recupero CNT + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + if EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP and EgtExistsInfo( nPrevOpeId, 'SKIP') then + nPrevOpeId = EgtGetPrevActiveOperation( nPrevOpeId) + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxX1 - dPosT)) + end + -- altrimenti fase successiva pari + else + local dPosV = EgtGetInfo( EMC.DISPID, 'VPOS', 'd') + EMC.VDELTA = dPosV + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EgtIf( EMC.LB < abs( MinX2 - UnloadT), MinJoin, EMC.LB - abs( MinX2 - UnloadT) + MinJoin + DeltaTol) + vCmd2 = SpecCalcCarriages( dDistFront, 0) + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + end + -- eseguo scarico + SpecSetCarrPosFromCmds( vCmd2) + local vCmd3 = SpecCalcUnload() + -- unisco ed emetto i comandi + vCmd = EgtJoinTables( vCmd, vCmd2) + vCmd = EgtJoinTables( vCmd, vCmd3) + SpecOutputCmds( vCmd, true) +end + +--------------------------------------------------------------------- +function OnPostApplyMachining() + + EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + -- se precedente operazione non esiste, errore + if not nPrevOpeId then + EMC.ERR = 1 + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 or IsFirstMachiningAfterRotation( EMC.MCHID) then + -- posizioni home + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + EMC.HCING_IGNORE = true + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + end + EMC.HCING_IGNORE = true + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 2 + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId or GDB_ID.NULL) + if not vAxes then + EMC.ERR = 3 + return + end + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + end + EMC.CNT = nil + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId or GDB_ID.NULL) + if not vAxes then + EMC.ERR = 4 + return + end + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico se ultima lavorazione prima di una rotazione + local bPreRotMch = IsLastOperationBeforeRotation( EMC.MCHID) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + local bPreSplit = ( sNotes:find( 'Presplit') ~= nil) + local bSplitting = ( sNotes:find( 'Split') ~= nil) + local bPreCut = ( sNotes:find( 'Precut') ~= nil) + local bCutting = ( sNotes:find( 'Cut') ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + if bPreSplit or bPreCut then + EgtSetInfo( EMC.MCHID, 'IS_PRE', '1') + else + EgtRemoveInfo( EMC.MCHID, 'IS_PRE') + end + + -- Agisco sui diversi percorsi della lavorazione + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) + while nPathId do + -- assegno id percorso da elaborare + EMC.PATHID = nPathId + -- recupero id del successivo + nPathId = EgtGetNext( nPathId) + -- verifico se ultimo percorso di ultima lavorazione della fase + local bLast = ( bMchLast and ( not nPathId)) + -- se ultimo, elimino ritorno in home + if bLast then EgtRemoveOperationHome( EMC.MCHID) end + -- salvo lo stato di trave e carrelli + local OriTPos = EMC.TPOS + local OriYDelta = EMC.YDELTA + local OriVDelta = EMC.VDELTA + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- se separazione, verifico il risultato + if bSplitting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -101 + EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' + -- ripristino lo stato originale di trave e carrelli + EMC.TPOS = OriTPos + EMC.YDELTA = OriYDelta + EMC.VDELTA = OriVDelta + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- pinzaggio ancora impossibile, pezzo a caduta + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -102 + EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' + end + -- scarico standard + elseif EMC.ERR == 0 then + -- segnalazione warning + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + -- se taglio del residuo finale, scarico standard + elseif bCutting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- se non ci sono errori, segnalazione warning + if EMC.ERR == 0 then + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + end + if EMC.ERR > 0 then return end + -- determino la posizione finale della trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + end + +end + +--------------------------------------------------------------------- +function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Assegno flag di pezzo in separazione + local bFixedDelta = ( bPreSplit or bSplitting or bPreCut or bCutting) + + -- Se separazione o taglio del grezzo finale, verifico se precedente era una preparazione + local bFixedPos = false + if bPreSplit or bSplitting or bPreCut or bCutting then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + bFixedPos = EgtExistsInfo( nPrevOpeId or GDB_ID.NULL, 'IS_PRE') + end + + -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro + local b3Tot = BBox3d() + local b3Raw = BBox3d() + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + local nCurrRawId = GDB_ID.NULL + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Tot:Add( b3Tmp) + if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + b3Raw = b3Tmp + nCurrRawId = nRawId + end + end + nRawId = EgtGetNextRawPart( nRawId) + end + if b3Tot:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = EgtIf( bSplit, b3Raw:getDimX(), b3Tot:getDimX()) + 10 * GEO.EPS_SMALL + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LR = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.YMIN = b3Raw:getMin():getY() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 + EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 + EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 + EMC.XMAX = b3Raw:getMax():getX() - EMC.HOVM + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront or not dDistBack then return end + if bPreSplit or bSplitting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + local dNextHOVM = EgtGetInfo( EgtGetNextRawPart( nCurrRawId) or GDB_ID.NULL, 'HOVM', 'd') or 0 + local dBackOther = b3Tot:getDimX() - b3Raw:getDimX() - MinOther - dNextHOVM + EgtOutLog( 'DistBack='..EgtNumToString( dDistBack)..' OtherBack='..EgtNumToString( dBackOther), 3) + dDistBack = min( dDistBack, dBackOther) + elseif bPreCut or bCutting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = 0.0 + end + + -- Verifico lunghezza pezzo + if not bSplit and not VerifyPartLength() then + return + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin)) + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + if vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli + elseif not IsEndPhase( EMC.PHASE) then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + -- Se non ci sono spostamenti, confermo i parametri di aggancio + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.YDELTA, EMC.YDELTA, 0), EgtIf( EMC.VDELTA, EMC.VDELTA, 0)}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave + else + local vCmd = {} + SpecOutputCmds( vCmd) + end + EMC.HCING_IGNORE = nil + + -- Se taglio di separazione + local vCmd = {} + if bSplitting then + -- rimuovo eventuale vecchia info di Skip + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL + EgtRemoveInfo( NextDispId, 'SKIP') + -- verifico se separazione con caduta + if not EMC.VDELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + if IsEndPhase( EMC.PHASE + 1) then + EgtSetInfo( NextDispId, 'SKIP', '1') + local NextOpeId = EgtGetNextOperation( NextDispId) + while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do + EgtSetOperationMode( NextOpeId, false) + NextOpeId = EgtGetNextOperation( NextOpeId) + end + end + EMC.ERR = 18 + -- verifico che la barra sia agganciata ad entrambi i carrelli + elseif not EMC.YDELTA or not EMC.VDELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y or V not clamped' + return false + end + -- eseguo la separazione ( standard o di pezzo ruotato) + if not IsMid2Phase( EMC.PHASE + 1) then + vCmd = SpecCalcSplit( b3Raw:getDimX()) + else + vCmd = SpecCalcSplitRot( b3Raw:getDimX()) + end + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello V da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'VPOS', EMC.VDELTA) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + local vCmdTmp = SpecCalcUnload() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Se ritorno al carico per rotazione + if bPreRotMch then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- eseguo movimento prima di rotazione + local vCmdTmp = SpecCalcPreRot() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Emetto eventuali comandi di separazione e/o scarico + if #vCmd > 0 then + SpecOutputCmds( vCmd, true) + end + +end --SpecApplyPath( bLast) + +--------------------------------------------------------------------- +function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) + -- gruppi della lavorazione + local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + if not nPathId then + EMC.ERR = 12 + return + end + -- recupero ptMin ptMax della lavorazione + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + if not ptMin or not ptMax then + EMC.ERR = 13 + return + end + -- se pre-taglio, aggiorno ptMax con quello del taglio finale + if bPreCut then + local ptFinMax = GetFinalCutPmax( nMchId) + if ptFinMax then + ptMax = ptFinMax + end + end + -- Recupero del vettore estrusione (coincide con il vettore utensile) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + if not vtTool then + EMC.ERR = 14 + return + end + -- Recupero testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Calcolo del vettore ausiliario + local vAxes = EmtGetAxesPos( EgtGetFirstInGroup( nPathId)) + if not vAxes or #vAxes < 5 or ( sHead == 'H3' and #vAxes < 6) then + EMC.ERR = 15 + return + end + local vtAux = EgtGetCalcAuxDirFromAngles( vAxes[4], vAxes[5], vAxes[6]) + if not vtAux then + EMC.ERR = 16 + return + end + local vtArm = vtAux + -- Recupero dei dati dell'utensile + local nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local bSaw = ( nToolType == MCH_TY.SAW_STD or nToolType == MCH_TY.SAW_FLAT) + local bChain = ( nToolType == MCH_TY.MORTISE_STD) + local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTDist = EgtIf( EgtTdbGetCurrToolParam( MCH_TP.DIST) > 1, EgtTdbGetCurrToolParam( MCH_TP.DIST), ChSawLen) + -- Se sega a catena, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C + if bChain then + if abs( vAxes[6] or 0) < 1 then + vtArm = vtTool + else + vtArm = vtTool ^ vtAux + end + end + -- Calcolo limiti derivanti dalla lavorazione + local dDistFront, dDistBack = SpecCalcEncumbrance( vtTool, vtArm, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dTDist) + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function SpecialCalcPhaseEncumbrance( nPhase) + -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) + local dDistFront = EMC.LB + local dDistBack = EMC.LB + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nOrigExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- Ciclo sulle lavorazioni + local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) + while nMchId and EgtGetOperationPhase( nMchId) == nPhase do + -- imposto lavorazione e utensile correnti + EgtSetCurrMachining( nMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + if not EgtTdbSetCurrTool( sTool) then + local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + sTool = EgtTdbGetToolFromUUID( sTuuid) + EgtTdbSetCurrTool( sTool) + end + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + if sTool and sHead and nExit then EgtSetCalcTool( sTool, sHead, nExit) end + -- calcolo ingombri + local dDistF, dDistB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + nMchId = EgtGetNextActiveOperation( nMchId) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + if sOrigTool and sOrigHead and nOrigExit then EgtSetCalcTool( sOrigTool, sOrigHead, nOrigExit) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function GetFinalCutPmax( nMchId) + local nFinalCutId + local nId = EgtGetNextActiveOperation( nMchId) + while nId and EgtGetOperationPhase( nId) == EMC.PHASE do + nFinalCutId = nId + nId = EgtGetNextActiveOperation( nId) + end + if not nFinalCutId then return end + local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') + if not nCLId then return end + return EgtGetInfo( nCLId, 'MMAX', 'p') +end + +--------------------------------------------------------------------- +function SpecCalcEncumbrance( vtTool, vtArm, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dTDist) + -- Quota in Z dal punto di inclinazione dei carrelli + local dCompZ = sqrt( 1 - vtTool:getZ() * vtTool:getZ()) + local dZup = ptMin:getZ() - 0.5 * dCompZ * dTDiam - ( EMC.ZMIN + 130) + -- Posizione min e max del naso mandrino (rispetto a testa pezzo in X e riferimento pezzo in Y e Z) + local ptHeadMin = ptMin + vtTool * dTLen - Vector3d( EMC.XMAX, EMC.YMIN + EMC.SB, EMC.ZMIN) + local ptHeadMax = ptMax + vtTool * dTLen - Vector3d( EMC.XMAX, EMC.YMIN + EMC.SB, EMC.ZMIN) + -- Ingombro a sinistra + local dDistBack = EMC.LB + ptMin:getX() + LoadT + local dHeadBack = 350 + if bSaw then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadBack = EgtIf( vtArm:getX() < 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() < 0 then + dHeadBack = 450 + else + dHeadBack = EgtIf( vtTool:getX() > 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() > 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadBack = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadBack = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadBack = dHeadBack + BD.VICE_MINH + end + elseif ( vtTool:getX() > 0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadBack = max( 90, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadBack = 180 + elseif vtTool:getX() > -0.05 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() > -0.3 then + dHeadBack = 250 + elseif vtTool:getX() > -0.707 then + dHeadBack = 350 + elseif vtTool:getX() > -0.8667 then + dHeadBack = 450 + else + dHeadBack = 650 + end + else + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + -- per limiti corsa asse X1 + dHeadBack = max( dHeadBack, MinX1 + 1 - vtTool:getX() * ( MillOffs + dTLen)) + else + if ( vtTool:getX() > -0.1 and vtArm:getX() > -0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadBack = EgtIf( EMC.CNT == 1, 180, 130) + elseif ( vtTool:getX() > -0.1 and vtArm:getX() > -0.95) then + dHeadBack = 180 + elseif ( vtTool:getX() < -0.8) then + dHeadBack = 675 + elseif ( vtTool:getX() < -0.75) then + dHeadBack = 650 + elseif ( vtTool:getX() < -0.5) then + dHeadBack = 450 + end + if vtTool:getX() < -0.25 then + dHeadBack = dHeadBack + max( dTLen - 130, 0) * abs( vtTool:getX()) + elseif vtTool:getX() < 0 then + dHeadBack = dHeadBack + ( dTLen + 180) * abs( vtTool:getX()) + end + if vtTool:getX() > 0.866 then + dHeadBack = 50 + elseif vtTool:getX() >= 0 and dZup > 0 then + dHeadBack = max( EgtIf( EMC.CNT == 1, 180, 130), dHeadBack - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() < -0.259 then + dHeadBack = 510 + else + dHeadBack = EgtIf( vtTool:getZ() > 0.966, 160, 280) + end + end + -- per fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() < -0.5 then + dHeadBack = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() < 0.5 and vtTool:getZ() < 0.5 and vtArm:getX() < -0.5 then + dHeadBack = max( dHeadBack, 510) + end + -- per fresa diretta quasi esattamente come Y+/- e con la testa non troppo nel pezzo + if not bChain and abs( vtTool:getX()) < 0.017 and abs( vtTool:getZ()) < 0.017 and + (( vtTool:getY() > 0 and ptHeadMin:getY() > 80) or ( vtTool:getY() < 0 and ptHeadMax:getY() < -EMC.SB - 80)) then + dHeadBack = EgtIf( EMC.CNT == 1, 180, 130) + end + -- per limiti corsa asse X1 + if not bChain then + dHeadBack = max( dHeadBack, MinX1 + 1 - vtTool:getX() * ( MillOffs + dTLen)) + else + dHeadBack = max( dHeadBack, MinX1 + 1 - vtAux:getX() * ( MillOffs + dTDist) - vtTool:getX() * dTLen) + end + end + -- Ingombro a destra + local dDistFront = - ptMax:getX() - LoadT + local dHeadFront = 350 + if bSaw then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadFront = EgtIf( vtArm:getX() > 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() > 0 then + dHeadFront = 450 + else + dHeadFront = EgtIf( vtTool:getX() < 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() < - 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadFront = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadFront = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadFront = dHeadFront + BD.VICE_MINH + end + elseif ( vtTool:getX() < -0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadFront = max( 90, 40 + 0.5 * dTDiam * sqrt( vtTool:getY() * vtTool:getY() + vtTool:getZ() * vtTool:getZ())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadFront = 180 + elseif vtTool:getX() < 0.05 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() < 0.3 then + dHeadFront = 250 + elseif vtTool:getX() < 0.707 then + dHeadFront = 350 + elseif vtTool:getX() < 0.8667 then + dHeadFront = 450 + else + dHeadFront = 650 + end + else + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + -- per limiti corsa asse X2 + dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtTool:getX() * ( MillOffs + dTLen)) + else + if ( vtTool:getX() < -0.5 and vtArm:getX() < 0.1) then + dHeadFront = max( 50, dTDiam / 2 * abs( vtTool:getZ()) + 20) + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadFront = 130 + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.95) then + dHeadFront = 180 + elseif ( vtTool:getX() > 0.8) then + dHeadFront = 675 + elseif ( vtTool:getX() > 0.75) then + dHeadFront = 650 + elseif ( vtTool:getX() > 0.5) then + dHeadFront = 450 + end + if vtTool:getX() > 0.25 then + dHeadFront = dHeadFront + max( dTLen - 130, 0) * vtTool:getX() + elseif vtTool:getX() > 0 then + dHeadFront = dHeadFront + ( dTLen + 180) * vtTool:getX() + end + if vtTool:getX() < -0.866 then + dHeadFront = 50 + elseif vtTool:getX() <= 0 and dZup > 0 then + dHeadFront = max( 130, dHeadFront - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() > 0.259 then + dHeadFront = 510 + else + dHeadFront = EgtIf( vtTool:getZ() > 0.966, 160, 280) + end + end + -- per fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() > 0.5 then + dHeadFront = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() > -0.5 and vtTool:getZ() < 0.5 and vtArm:getX() > 0.5 then + dHeadFront = max( dHeadFront, 510) + end + -- per fresa diretta quasi esattamente come Y+/- e con la testa non troppo nel pezzo + if not bChain and abs( vtTool:getX()) < 0.017 and abs( vtTool:getZ()) < 0.017 and + (( vtTool:getY() > 0 and ptHeadMin:getY() > 80) or ( vtTool:getY() < 0 and ptHeadMax:getY() < -EMC.SB - 80)) then + dHeadFront = 130 + end + -- per limiti corsa asse X2 + if not bChain then + dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtTool:getX() * ( MillOffs + dTLen)) + else + dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtAux:getX() * ( MillOffs + dTDist) + vtTool:getX() * dTLen) + end + end + -- Stampe debug + EgtOutLog( ' Tdir=' .. tostring( vtTool) .. ' Adir=' .. tostring( vtArm) .. ' Zup=' .. EgtNumToString( dZup), 3) + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. + ' HeadFront=' .. EgtNumToString( dHeadFront) .. ' HeadBack=' .. EgtNumToString( dHeadBack), 3) + -- Restituisco ingombri effettivi + return ( dDistFront - dHeadFront), ( dDistBack - dHeadBack) +end + +--------------------------------------------------------------------- +function VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM then + EgtOutLog( ' Error CLAMP -> pezzo troppo corto') + EMC.ERR = 17 + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dMinDistBack= max( dDistBack, MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0)) + local dNewYDelta = max( EMC.LB - dMinDistBack, MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM) + local dNewVDelta = nil + local dNewY = dPosT + TurnerOffs + dNewYDelta + local vCmd = {} + EgtOutLog( ' *[L]', 1) + -- [L-1] + if dNewY - MaxX1 > 0 then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxX1 - dPosT - TurnerOffs) + EgtOutLog( ' *[L1]', 1) + end --[L-2] + if EMC.LB - dNewYDelta < MinJoin then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxX1 - dPosT - TurnerOffs) + EgtOutLog( ' *[L2]', 1) + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'X1', dPosT + dNewYDelta, 'X2', ParkX2}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, EgtIf( EMC.LB - dNewYDelta < LenToPress, 1, 2)}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewYDelta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = dPosT + EMC.YDELTA = dNewYDelta + EMC.VDELTA = nil + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MinBackJoin = MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0) + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AGG_LOAD, 0) + + local dDistFrontEff = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + if bFixedDelta and IsMid2Phase( EMC.PHASE + 1) then + dDistFrontEff = min( dDistFrontEff, EMC.LR - MinOther - EMC.TCING) + end + local dDistBackEff = min( dDistBack, EMC.LB - MyMinOther - EMC.HCING - EMC.HOVM) + + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. + ' Fixed : Delta=' .. EgtIf( bFixedDelta, 'T', 'F') .. ' Pos=' .. EgtIf( bFixedPos, 'T', 'F'), 3) + + -- [A] se posso mettere solo carrello Y + if dDistFrontEff < MinFrontJoin and dDistBackEff > MinBackJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = nil + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [B] se altrimenti posso mettere entrambi i carrelli Y e V + elseif dDistBackEff > MinBackJoin - GEO.EPS_SMALL and + dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [C] se altrimenti posso mettere solo carrello V + elseif dDistBackEff < MinBackJoin and dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = nil + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1)) + end + EgtOutLog( ' Error CLAMP impossible') + EMC.ERR = 18 + return {} + end + +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[S]', 1) + table.insert( vCmd, { 0, EgtIf( EMC.VDELTA, 'Split', 'Fall')}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vCmd, { 31, nRawId, 'X1'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'X1', LoadT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA or 0}) + -- imposto subito Y non più attaccato al trave in lavoro + EMC.YDELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + EgtSetInfo( PostDispId, 'YPOS', LoadT + dLDelta) + end + -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + EgtSetInfo( NextDispId, 'YPOS', LoadT + dLDelta) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcSplitRot( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[SR]', 1) + table.insert( vCmd, { 0, 'SplitRot'}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local vRaw = {} + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vRaw, nRawId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, 'X1'}) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'X1', LoadT + TurnerOffs + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.YDELTA = nil + -- apro il carrello Y + table.insert( vCmd, { 11, 0}) + -- sgancio i grezzi dal carrello Y + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, ''}) + end + -- lo porto in parcheggio + table.insert( vCmd, { 1, 'X1', ParkX1}) + -- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]', 1) + -- Se pinza Y chiusa , devo effettuare uno scambio + if EMC.YDELTA then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza V + local dDistFront = EMC.LB - MinOther - EMC.TCING - 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + if EMC.ERR ~= 0 then + return {} + end + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]', 1) + end + local vCmd = {} + -- Tipo di scarico + local bStdUl = ( MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1) + -- Commento + table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual Unloading')}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza Y chiusa, la apro + if EMC.YDELTA then + table.insert( vCmd, { 11, 0}) + end + -- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico + if bStdUl then + local dFinT = UnloadT - EMC.LB + local dFinV = dFinT + EMC.VDELTA + table.insert( vCmd, { 2, 'T', dFinT, 'X2', dFinV}) + else + table.insert( vCmd, { 1, 'X2', MaxX2}) + end + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'X2', ParkX2}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcPreRot() + local vCmdPre = {} + EgtOutLog( ' *[PR]', 1) + -- Se pinza V chiusa , devo effettuare uno scambio + if EMC.VDELTA then + -- imposto quote aggancio per avere solo pinza Y + local dDistFront = 0 + local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[PR1]', 1) + end + -- porto il pezzo alla zona di rotazione con il carro Y + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Pre-Rotation'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza V chiusa, la apro + if EMC.VDELTA then + table.insert( vCmd, { 12, 0}) + end + -- riporto la trave al carico + local RotT = LoadT + TurnerOffs - EMC.HOVM + table.insert( vCmd, { 2, 'X1', RotT + EMC.YDELTA, 'T', RotT}) + -- apro la morsa + table.insert( vCmd, { 11, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'X1', ParkX1}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecAdjustCarriages( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + + -- [A] richiesto solo carrello Y + if dYDeltaF and ( not dVDeltaF) then + -- [A1] rimango sul carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A2] torno da entrambi + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A3] torno da carrello V + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + else + EgtOutLog( ' Error CLAMP NULL-> Y impossibile') + error( 'Error CLAMP NULL-> Y impossibile') + end + + -- (B) richiesti entrambi i carrelli + elseif dYDeltaF and dVDeltaF then + -- [B1] passo da carrello Y a entrambi + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B2] continuo con entrambi i carrelli + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B3] passo da carrello V a entrambi + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + else + EgtOutLog( ' Error CLAMP NULL-> Y+V impossibile') + error( 'Error CLAMP NULL-> Y+V impossibile') + end + + -- [C] richiesto solo carrello V + elseif ( not dYDeltaF) and dVDeltaF then + -- [C1] provengo da solo carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C2] provengo da carrelli Y e V + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C3] rimango sul carrello V + elseif ( not dYDeltaI) and dVDeltaI then + return SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + else + EgtOutLog( ' Error CLAMP NULL-> V impossibile') + error( 'Error CLAMP NULL-> V impossibile') + end + + end + +end + +--------------------------------------------------------------------- +local function CalcCharStatus( sType, dDelta) + -- se per carrello Y + if sType == 'X1' then + return EgtIf( EMC.LB - dDelta < LenToPress, 1, 2) + -- altrimenti per carrello V + else + return EgtIf( dDelta < LenToPress, 1, 2) + end +end + +--------------------------------------------------------------------- +local function GetDeltaTol( dLenPresa, TCING, HCING, HOVM, Carr, bFixedDelta) + local dDeltaTolEff = DELTA_SIC + if Carr == 'X1' then + local dLenPreEff = dLenPresa - TCING + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + dDeltaTolEff = DeltaTol + end + elseif Carr == 'X2' then + local dLenPreEff = dLenPresa - HCING - HOVM + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + dDeltaTolEff = DeltaTol + end + end + return EgtIf( bFixedDelta, min( dDeltaTolEff, DELTA_TOL_FIXED), dDeltaTolEff) +end + +--------------------------------------------------------------------- +local function GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistN, sSide) + local dRecTotn = min( dDistN, dCorsaYfc+ dCorsaVfc) -- recupero possibile al netto di dCorsa..TrA) + local dCorsaYd, dCorsaYTd, dCorsaVd, dCorsaVTd + if sSide == 'Fr' then + if dRecTotn / 2 <= dCorsaYfc then + if dRecTotn / 2 <= dCorsaVfc then + dCorsaYTd = dRecTotn / 2 + dCorsaVd = dRecTotn / 2 + else + dCorsaVd = dCorsaVfc + dCorsaYTd = min( dCorsaYfc, dRecTotn - dCorsaVd) + end + else + dCorsaYTd = dCorsaYfc + dCorsaVd = min( dCorsaVfc, dRecTotn - dCorsaYTd) + end + dCorsaY = dCorsaYTd + dCorsaV = dCorsaVd + else + if dRecTotn / 2 <= dCorsaVfc then + if dRecTotn / 2 <= dCorsaYfc then + dCorsaVTd = dRecTotn / 2 + dCorsaYd = dRecTotn / 2 + else + dCorsaYd = dCorsaYfc + dCorsaVTd = min( dCorsaVfc, dRecTotn - dCorsaYd) + end + else + dCorsaVTd = dCorsaVfc + dCorsaYd = min( dCorsaYfc, dRecTotn - dCorsaVTd) + end + dCorsaY = dCorsaYd + dCorsaV = dCorsaVTd + end + return dCorsaY, dCorsaV +end + +--------------------------------------------------------------------- +local function PosxExtraYV( dX1PosA, dX2PosA, dTPosA, dMinX1, dMaxX2, sYV) + -- svolge la predisposizione iniziale di trave e carrelli in caso di situazione iniziale con un solo carrello chiuso + -- con un solo carrello chiuso per l'aggancio del carrello aperto + local dX1Pos, dX2Pos, dTPos + -- per aggancio del carrello X2 + if sYV == 'X2' then + dTPos = min( dTPosA, dX2PosA - MinJoin - EgtIf( EMC.HCING_IGNORE, 0, EMC.HCING) - EMC.HOVM) + dX1Pos = dX1PosA + ( dTPos - dTPosA) + if dX1Pos < dMinX1 then + dX2Pos = dX2PosA + ( dMinX1 - dX1Pos) + if dX2Pos > dMaxX2 + GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP X2') + error( 'Error CLAMP X2') + return + elseif dX2Pos > dMaxX2 - GEO.EPS_SMALL then + dX2Pos = dMaxX2 + end + dX1Pos = dMinX1 + dTPos = dTPosA + ( dX1Pos - dX1PosA) + else + --dX1Pos = dMinX1 + --dX1Pos = dX1Pos! + --dTPos = dTPosA + ( dX1Pos - dX1PosA) + --dTPos = dTPos! + dX2Pos = dX2PosA + end + end + -- per aggancio del carrello X1 + if sYV == 'X1' then + dTPos = max( dTPosA, dX1PosA + MinJoin + EMC.TCING - EMC.LB) + dX2Pos = dX2PosA + ( dTPos - dTPosA) + if dX2Pos > dMaxX2 then + dX1Pos = dX1PosA - ( dX2Pos - dMaxX2) + if dX1Pos < dMinX1 - GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP X1') + error( 'Error CLAMP X1') + return + elseif dX1Pos < dMinX1 + GEO.EPS_SMALL then + dX1Pos = dMinX1 + end + dX2Pos = dMaxX2 + dTPos = dTPosA + ( dX2Pos - dX2PosA) + else + -- ++++++++++++++++++++++++++++++++ + --dX2Pos = dMaxX2 + --dX2Pos = dX2Pos! + --dTPos = dTPosA + ( dX2Pos - dX2PosA) + --dTpos = dTPos!! + dX1Pos = dX1PosA + end + end + return dX1Pos, dX2Pos, dTPos +end + +--------------------------------------------------------------------- +local function PosXs2Enl (dYa, dVa, dTa, dExtraC, dCorsaTra, dCorsaYd, dCorsaVd, sYV) + -- svolge la fase di allontanamento dei carrelli per il recupero di 'ExtraX2'/'ExtraX1' + -- richiesto alle posizioni [--.xs2] delle funzioni SpecAdjustCarr.. + if sYV == 'X2' then -- caso di ExtraX2 (ed eventuale ulteriore allontanamento di X1) + local dCorsaYTrA = dCorsaTra + local dExtraX2n = dExtraC - dCorsaYTrA + -- eseguo allontanamento di Y e (V+T) + if dExtraX2n / 2 <= dCorsaYd then + if dExtraX2n / 2 <= dCorsaVd then + dYa = dYa + dExtraX2n / 2 + dVa = dVa - dExtraX2n / 2 + dTa = dTa - dExtraX2n / 2 + else + dVa = dVa - dCorsaVd + dTa = dTa - dCorsaVd + dYa = dYa + min( dExtraX2n - dCorsaVd, dCorsaYd) + end + else + dYa = dYa + dCorsaYd + dVa = dVa - min( dExtraX2n - dCorsaYd, dCorsaVd) + dTa = dTa - min( dExtraX2n - dCorsaYd, dCorsaVd) + end + end + + if sYV == 'X1' then -- caso di ExtraX1 (ed eventuale ulteriore allontanamento di X2) + local dCorsaVTrA = dCorsaTra + local dExtraX1n = -dExtraC - dCorsaVTrA + -- eseguo allontanamento di (Y+T) e V + if dExtraX1n / 2 <= dCorsaVd then + if dExtraX1n / 2 <= dCorsaYd then + dVa = dVa - dExtraX1n / 2 + dYa = dYa + dExtraX1n / 2 + dTa = dTa + dExtraX1n / 2 + else + dYa = dYa + dCorsaYd + dTa = dTa + dCorsaYd + dVa = dVa - min( dExtraX1n - dCorsaYd, dCorsaVd) + end + else + dVa = dVa - dCorsaVd + dYa = dYa + min( dExtraX1n - dCorsaVd, dCorsaYd) + dTa = dTa + min( dExtraX1n - dCorsaVd, dCorsaYd) + end + end + return dYa, dVa, dTa +end + +--------------------------------------------------------------------- +-- *** [A1] da carrello X1 a X1 : X1 -> X1 *** +--------------------------------------------------------------------- +function +SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A1] = X1 -> X1', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1 -> X1'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + -- recupero le posizioni correnti dei carrelli + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = ParkX2 + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dX2PosA - dTPosA + local dNewYDelta -- = dYDeltaF + local dCorsaYfc = MaxX1 - dX1PosA + local dCorsaYd = min( dCorsaYfc, EMC.LB - dYDeltaI - MinJoin) + + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 4 + else + dNewYDelta = dYDeltaA + end + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + + -- **[A1Ys]** |pos. di Y cambia in modo significativo| + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraX1' con (Y+T) e V accentrati q.b. per la presa con V + local dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2') + local dNewY = dTPos + dNewYDelta + local dExtraX1 = dNewY - MyMinX1 + -- effettuo spostamenti di (Y+T) e V per predisporre all'aggancio di T con V + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dVDeltaA = dX2PosA - dTPosA + + -- **[A1Ys-x]** posizione di |Y non raggiungibile| (oltre MyMinX1) + if dExtraX1 < 0 then + -- **[A1Ys-xs]** posizione di Y non raggiungibile, |con ExtraX1 'significativo'| + if -dExtraX1 > dYDeltaTol /2 then + --EmitComment( vCmd, '[A1Ys-xs]') + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + local dCorsaYfc = MaxX1 - dX1Pos + local dCorsaVfc = dX2Pos - MinX2 + local dDistFrN = (dX2Pos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + local dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + local dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos) + local dCorsaYr = dCorsaYTd + -- **[A1Ys-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr| + if -dExtraX1 > ( dCorsaVTr + dCorsaYr) and bYDeltaS then + EmitComment( vCmd, '[A1Ys-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaVTrA = MaxX2 - dX2Pos -- !! att.ne: non dX2PosA !! + -- **[A1Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T) + -- (dalle posizione impostate sopra per l'aggancio di V) + if dCorsaVTrA >= -dExtraX1 then + EmitComment( vCmd, '[A1Ys-xs1]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = dX2PosA + (-dExtraX1) + dTPosA = dTPosA + (-dExtraX1) + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dYDeltaA = dX1PosA - dTPosA + + else -- **[A1Ys-xs2]** + -- ci sarebbe un doppio movimento di Y ? => caso impossibile ? + EmitComment( vCmd, '[A1Ys-xs2]') + -- **1:** posiziono (ulteriormente!) (Y+T) e V + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1') + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dVDeltaA = dX2PosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: accentro** Y e (V+T) + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = MaxX2 + dTPosA = dX2PosA - dVDeltaA + --dVDeltaA = dX2PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [A1Ys-xs1/-xs2] + + -- **[A1Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')| + else --if -dExtraX1 < DeltaToll/2 + EmitComment( vCmd, '[A1Ys-xn]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y + dExtraX1 = 0 + dX1PosA = MyMinX1 -- (pos. finale) + table.insert( vCmd, { 1, 'X1', dX1PosA}) + -- dYDeltaA = dX1PosA - dTPosA + end --[A1Ys-xs/xn] + + -- **[A1Ys-r]** |posizione di Y raggiungibile| (ExtraX1 >=0) + -- (si esclude la possibilità di extra corsa oltre maxX1) + else + EmitComment( vCmd, '[A1Ys-r]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** posiziono Y alla posizione richiesta + dX1PosA = dNewY + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end -- [A1Ys] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dX1PosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'X2', ParkX2}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + -- reset contatore + EMC.CNT = nil + + else -- **[A1Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A1Yns]') + end --[A1Ys/ns] + + EgtOutLog(' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA1 + +--------------------------------------------------------------------- +-- *** [A2] da entrambi a carrello X1 : X1+X2 -> X1 *** +--------------------------------------------------------------------- +function SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A2] = X1+X2 -> X1 ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1+X2 -> X1'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + local dCorsaY = MaxX1 - MyMinX1 + local dCorsaV = MaxX2 - MinX2 + -- recupero le posizioni correnti dei carrelli + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dYDeltaF + -- tolleranze + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 4 + else + dNewYDelta = dYDeltaA + end + -- definisco 'ExtraX1' + local dNewY = dTPosA + dNewYDelta + local dExtraX1 = dNewY - MyMinX1 -- < 0 = nuova pos. di Y 'non raggiungibile' (= oltre MyMinX1) + -- definisco 'ExtraX1 significativo' + local bYxs = -dExtraX1 > dYDeltaTol / 2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI) .. + ' VDeltaI=' .. EgtNumToString( dVDeltaI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di V) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + if bYxs then + -- calcolo le **corse disponibili** dei carrelli **a partire dalle posizioni attuali** (=iniziali) + -- per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxX2 - dX2PosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaYr + dCorsaVTr + end + end + + -- **[A2Ys-xsw]** posizione NewY non raggiungibile (oltre MyMinX1), con ||dExtraX1 | > CorsaYr + CorsaVTr| + while bXsw do + EmitComment( vCmd, '[A2Ys-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- chiudo eventualmente il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano q.p. (Y+T) e V + dX1PosA = dX1PosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dX2PosA = dX2PosA - dCorsaVd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) + dX1PosA = MyMinX1 + dX2PosA = dX2PosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + -- valuto Delta attuali + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno l'extra corsa residua per Y + dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr + bYxs = -dExtraX1 > dYDeltaTol/2 + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end -- [A2Ys-xw] + + -- **[A2Ys]** se lo |spostamento| richiesto (ev' residuo) per |Y| è |'significativo'| + if bYDeltaS then + -- **[A2Ys-x]** se la |posizione per Y non è 'raggiungibile'| + if dExtraX1 < 0 then + -- **[A2Ys-xs]** se |ExtraX1 'significativo'| + if bYxs then + local dCorsaVTrA = MaxX2 - dX2PosA + -- **[A2Ys-xs1]** se posso recuperare ExtraX1 solo accentrando (V+T) e Y + if dCorsaVTrA >= -dExtraX1 then + EmitComment( vCmd, '[A2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro (V+T) q.b. e Y + dX2PosA = dX2PosA + (-dExtraX1) + dTPosA = dTPosA + (-dExtraX1) + dX1PosA = MyMinX1 -- (pos. finale) + --dYDeltaA = dX1PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[A2Ys-xs2]** + EmitComment( vCmd, '[A2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano (Y+T) e V + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1') + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dVDeltaA = dX2PosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) q.b. per recupero di dExtraX1 + dX1PosA = MyMinX1 + dX2PosA = MaxX2 + dTPosA = dX2PosA - dVDeltaA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end --[A2Ys-xs1/-xs2] + + -- [A2Ys-xn] |ExtraX1 ancora <= 0, ma 'non significativo'| + else --if dExtraX1 <= 0 then + EmitComment( vCmd, '[A2Ys-xn]') + dExtraX1 = 0 + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y + dX1PosA = MyMinX1 -- (pos. finale) + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end -- [A2Ys-xs/xn] + + --[A2Ys-r] dExtraX2 > 0 ( |pos. Y'raggiungibile|) + else + EmitComment( vCmd, '[A2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y + dX1PosA = dTPosA + dNewYDelta -- (pos. finale) + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end -- [A2Ys-x/r] + + else -- [A2Yns] |spostamento Y| (ev' residuo) |non significativo| + EmitComment( vCmd, '[A2Yns]') + end -- [A2Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dX1PosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'X2', ParkX2}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA2 + +--------------------------------------------------------------------- +-- *** [A3] da carrello X2 a X1 : X2 -> X1 *** +--------------------------------------------------------------------- +function SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A3] = X2 -> X1', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X2 -> X1'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + -- recupero le posizioni correnti + local dX1PosA = ParkX1 + local dTPosA = dTPosI + local dX2PosA = dTPosI + dVDeltaI + local dYDeltaA = dX1PosA - dTPosA + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dVDeltaF + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 4 + else + dNewYDelta = dYDeltaA + end + -- + EgtOutLog(' VDeltaI=' .. EgtNumToString( dVDeltaA) .. ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta) , 1) + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dX1Pos, dX2Pos, dTPos + local dNewY, dExtraX1, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraX1' con Y e (V+T) accentrati q.b. per la presa con Y + dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1') + dNewY = dTPos + dNewYDelta + dExtraX1 = dNewY - MyMinX1 --( <0 <=> pos. 'non raggiungibile') + bYxs = -dExtraX1 > dYDeltaTol/2 + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1Pos + dCorsaVfc = dX2Pos - MinX2 + --local dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dDistFrN = (dX2Pos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end + -- inizializzo + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + end + + -- **[A3Ys-xsw]** posizione finale dNewY non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[A3Ys-xsw]') + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo ev' il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dX1PosA = dX1PosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dX2PosA = dX2PosA - dCorsaVd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dX2PosA = dX2PosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dX1PosA = MyMinX1 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno ExtraX1 + dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end --[A3Ys-xw] + + -- **[A3Ys]** |spostamento| richiesto (ev' residuo) |di Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[A3Ys]') + -- **[A3Ys-x]** posizione di |Y non raggiungibile| + if dExtraX1 < 0 then + + -- **[A3Ys-xs]** |pos. NewY non raggiungibile, con ExtraX1 'significativo'| + -- ( -dExtraX1 <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bYxs then + local dCorsaVTrA = MaxX2 - dX2PosA + -- **[A3Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraX1 then + EmitComment( vCmd, '[A3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = dX2PosA - dExtraX1 + dTPosA = dTPosA - dExtraX1 + dYDeltaA = dX1PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[A3Ys-xs2]** + EmitComment( vCmd, '[A3Ys-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dYDeltaA = dX1PosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1') + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dVDeltaA = dX2PosA - dTPosA + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = MaxX2 + dTPosA = dX2PosA - dVDeltaA + --dYDeltaA = dX1PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [A3Ys-xs1/-xs2] + + -- **[A3Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')| + else --if -dExtraX1 < DeltaToll/2 + EmitComment( vCmd, '[A3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y e porto (V+T) alla posizione impostata + dExtraX1 = 0 + dX1PosA = MyMinX1 -- (pos. finale) + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end --[A3Ys-xs/xn] + + -- **[A3Ys-r]** |posizione di Y raggiungibile (ExtraX1 >=0)| + else + EmitComment( vCmd, '[A3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y in posizione finale ed ev' (V+T) come impostato sopra + dX1PosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [A3Ys] + + else -- **[A3Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A3Yns]') + end --[A3Ys/ns] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dX1PosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'X2', ParkX2}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA3 + +--------------------------------------------------------------------- +local function AdjustPositionsForB( dNewYDelta, dNewVDelta, TCING, HCING, HOVM, bFixedDelta) + local REF_DIST = 1400 + local dYDelta = 0 + local dVDelta = 0 + -- incremento se possibile la distanza tra le due posizioni + if not bFixedDelta and ( dNewYDelta - dNewVDelta) < REF_DIST then + local dEffAddDist = ( REF_DIST - ( dNewYDelta - dNewVDelta)) / 2 + dYDelta = max( min( dEffAddDist, EMC.LB - dNewYDelta - MinJoin - TCING), 0) + dVDelta = max( min( dEffAddDist, dNewVDelta - MinJoin - HOVM - HCING), 0) + end + return dYDelta, dVDelta +end + +--------------------------------------------------------------------- +-- *** [B1] da carrello X1 a entrambi : X1 -> X1+X2 *** +--------------------------------------------------------------------- +function SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B1] = X1 -> X1+X2', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1 -> X1+X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + local dCorsaY = MaxX1 - MyMinX1 + local dCorsaV = MaxX2 - MinX2 + -- recupero le posizioni correnti + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = ParkX2 + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dX2PosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog(' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dX1Pos, dX2Pos, dTPos + local dNewV, dExtraX2, bVxs + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- definisco 'ExtraX2' con (Y+T) e V accentrati q.b. per la presa di V + dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2') + dNewV = dTPos + dNewVDelta + dExtraX2 = dNewV - MaxX2 -- se > 0 pos. V non direttamente 'raggiungibile' + bVxs = dExtraX2 > dVDeltaTol/2 -- ExtraX2 'significativo' + if bVxs then + -- calcolo le **corse disponibili** dei carrelli a partire da Y e V c.s.| + -- per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxX1 - dX1Pos + dCorsaVfc = dX2Pos - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le **corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dX1Pos - MyMinX1) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr + end + -- inizializzo + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + end + + -- **[B1Vs-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B1Vs-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| imposto (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| allontano Y e (V+T) quanto possibile + dX1PosA = dX1PosA + dCorsaYd + dX2PosA = dX2PosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dX1PosA = dX1PosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dX2PosA = MaxX2 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno l'extra corsa residuo per V + dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr + end --[B1Vs-xw] + + -- **[B1Vs]** se lo |spostamento| finale richiesto (ev' residuo) di |V| è |'significativo'| + if bVDeltaS then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- **[B1Vs-x]** posizione di |V non raggiungibile| + if dExtraX2 > 0 then + -- **[B1Vs-xs]** |ExtraX2 'signfificativo'| + -- (ExtraX2 <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bVxs then + local dCorsaYTrA = dX1PosA - MyMinX1 + local dCorsaVra = MaxX2 - dX2PosA + -- **[B1Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando V e (Y+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaYTrA >= dExtraX2 then + EmitComment( vCmd, '[B1Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dX1PosA = dX1PosA - dExtraX2 + dTPosA = dTPosA - dExtraX2 + dX2PosA = MaxX2 -- (pos. finale) + dVDeltaA = dX2PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[B1Vs-xs2]** + EmitComment( vCmd, '[B1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dVDeltaA = dX2PosA - dTPosA + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraX2.... + local dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2') + local dYDispl1 = dX1Pos1 - dX1PosA + local dVDispl1 = dX2Pos1 - dX2PosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dX1Pos1 - dTPos1) + -- ...e anche di posizionare possibilmente Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxX1 - dX1Pos1 + dCorsaVfc = dX2Pos1 - MinX2 + dDistBkN = EMC.LB - (dX1Pos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'X2') + else + dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1 + end + + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro** (Y+T) e V + dX1PosA = dX1PosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dX2PosA = dX2PosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B1Vs-xs1/-xs2] + + -- **[B1Vs-xn]** |dExtraX2 ancora > 0 ma non 'significativo')| + else --if dExtraX2 < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: accentro (Y+T) alla posizione impostate e V al max + dExtraX2 = 0 + dX2PosA = MaxX2 -- (pos. finale) + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B1s-xs/xn] + + -- **[B1Vs-r]** |dExtraX2 < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[B1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posiziono ev' (Y+T) come impostato sopra e V in posizione finale + dX2PosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B1Vs] + + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + + else -- **[B1Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[B1Vns]') + if SpecTestOnlyRemarkInCmds( vCmd) then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- emetto posizione di V + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end + end -- [B1-s/ns] + + -- aggiorno la verifica di movimento 'significativo' per Y + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- **[B1Ys]** Se vi è uno |spostamento residuo di Y significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B1Ys]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraX1 = dNewY - MyMinX1 + -- **[B1Ys-r]** se pos. NewY è raggiungibile direttamente + if dExtraX1 >= 0 then --dNewY > MyMinX1 then + EmitComment( vCmd, '[B1Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dX1PosA = dTPosA + dNewYDelta + table.insert( vCmd, { 1, 'X1', dX1PosA}) + + -- **[B1Ys-xn]** se pos. NewY non è raggiungibile direttamente, ma ExtraX1 non è 'significativo' + elseif -dExtraX1 <= dYDeltaTol / 2 then + EmitComment( vCmd, '[B1Ys-xn]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y + dX1PosA = MyMinX1 + table.insert( vCmd, { 1, 'X1', dX1PosA}) + -- [B1sY-nr.xs] ma ExtraX1 'significativo' + + else -- **[B1Ys-xs]** + EmitComment( vCmd, '[B1Ys-xs]') + EgtOutLog( ' CLAMP : caso [B1Ys-xs] non gestito') + error( ' CLAMP : caso [B1Ys-xs] non gestito') + + end --[B1Ys-r/-nr] + else -- [B1Yns] spostamento residuo di Y non significativo + EmitComment( vCmd, '[B1Yns]') + end -- [B1Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- se non emessi movimenti, imposto posizione V + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre eseguita risalita Z) + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- *** [B2] da entrambi a entrambi i carrelli : X1+X2 -> X1+X2 *** +--------------------------------------------------------------------- +function SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B2] = X1+X2 -> X1+X2', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1+X2 -> X1+X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + -- recupero le posizioni correnti + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraX1' e ExtraX2' + local dNewY = dTPosA + dNewYDelta + local dNewV = dTPosA + dNewVDelta + local dExtraX1 = dNewY - MyMinX1 -- < 0 => nuova pos. di Y 'non raggiungibile' + local dExtraX2 = dNewV - MaxX2 -- > 0 => nuova pos. di V 'non raggiungibile' + local bYxs = -dExtraX1 > dYDeltaTol/2 + local bVxs = dExtraX2 > dVDeltaTol/2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag risalita a Zmax + local bZmaxOk = false + + -- **[B2V]** |accentramento di V| + if dVDeltaF > dVDeltaI then + EmitComment( vCmd, '[B2V]') + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bVxs then + -- calcolo le corse disponibili dei carrelli **dalle posizioni iniziali** + -- per allontanare Y e (V+T) + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- calcolo le corse di 'recupero' accentrando (Y+T) e V dopo l'allontanamento + dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1) + dCorsaVr = dCorsaVTd -- ((MaxX2-dNewV) non fa parte del recupero in quanto già disponibile!) + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr + end + end + + -- **[B2V-xsw]** posizione NewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYTr| + -- e spostamento richiesto di V significativo; + while bXsw do + EmitComment( vCmd, '[B2V-xsw]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1**: allontano Y e V(+T) quanto possibile + dX1PosA = dX1PosA + dCorsaYd + dX2PosA = dX2PosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** accentro (Y+T) e V + dX1PosA = dX1PosA - dCorsaYTr -- = MyMinX1 + dTPosA = dTPosA - dCorsaYTr + dX2PosA = MaxX2 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraX2 residuo + dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr + -- **aggiorno i recuperi disponibili** riallontanando Y e (V+T) e riaccentrando (Y+T) e V + dCorsaYfc = dCorsaY -- MaxX1 - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr + end -- [B2V-xsw] + + + --[B2Vs] |accentramento| (ev' residuo) |di V 'significativo'| + if bVDeltaS then + --[B2Vs-x] accentramento di V 'significativo' |con pos. NewV 'non raggiungibile'|(= oltre MaxX2) + if dExtraX2 > 0 then + -- (ExtraX2 <= (CorsaYTr+CorsaVr) da ciclo precedente) + --[B2Vs-xs] accentramento di V con |ExtraX2 'significativo'| + if bVxs then + local dCorsaYTrA = dX1PosA - MyMinX1 + local dCorsaVra = MaxX2 - dX2PosA + -- **[B2Vs-xs1]** se posso recuperare ExtraX2 solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraX2 then + EmitComment( vCmd, '[B2Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dX1PosA = dX1PosA - dExtraX2 + dTPosA = dTPosA - dExtraX2 + dX2PosA = MaxX2 -- (pos. finale) + dExtraX2 = 0 + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[B2Vs-xs2]** + EmitComment( vCmd, '[B2Vs-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraX2... + local dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2') + local dYDispl1 = dX1Pos1 - dX1PosA + local dVDispl1 = dX2Pos1 - dX2PosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dX1Pos1 - dTPos1) + -- ...e anche possibilmente di posizionare Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxX1 - dX1Pos1 + dCorsaVfc = dX2Pos1 - MinX2 + dDistBkN = EMC.LB - (dX1Pos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + --dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd-dYDispl1, dCorsaVTd+dVDispl1, 'X2') + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'X2') + else + dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dX1PosA = dX1PosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dX2PosA = dX2PosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B2Vs-xs1/xs2] + + -- **[B2Vs-xn]** |dExtraX2 non 'significativo'| + else + EmitComment( vCmd, '[B2Vs-xn]') + dExtraX2 = 0 + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V assumendo maxX2 come pos. finale + dX2PosA = MaxX2 -- (pos finale) + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end -- [B2Vs-xs/xn] + + -- **[B2Vs-r]** accentramento di |V| 'significativo' con pos.|'raggiungibile'| (= non oltre MaxX2) + else + EmitComment( vCmd, '[B2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V -- (pos finale) + dX2PosA = dTPosA + dNewVDelta + dExtraX2 = 0 + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end --[B2Vs] + + -- **[B2Vns]** accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Vns]') + dExtraX2 = 0 + end --[B2Vs/ns] + end --[B2V] ( accentramento di V) + + -- --------------------------------------------------------------------------- + -- **[B2Y]** |accentramento di Y| + if dYDeltaF < dYDeltaI then + EmitComment( vCmd, '[B2Y]') + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bYxs then + -- calcolo le **corse disponibili** dei carrelli dalle posizioni iniziali + -- per allontanare (Y+T) e V + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxX2 - dX2PosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end + end + + -- **[B2Ys-xsw]** |-dExtraX1 > dCorsaYr + dCorsaVTr| + while bXsw do + EmitComment( vCmd, '[B2Y-xsw]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |1:| allontano (Y+T) e V quanto possibile + dX1PosA = dX1PosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dX2PosA = dX2PosA - dCorsaVd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + + -- |2:| accentro Y e (V+T) + dX1PosA = MyMinX1 -- = dX1PosA - dCorsaYr + dX2PosA = dX2PosA + dCorsaVTr -- = MaxX2 + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto Delta 'attuali' + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraX1 residuo + dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr + -- aggiorno i recuperi disponibili riallontanando (Y+T) V e riaccentrando succ' Y e (V+T) + dCorsaYfc = dCorsaY -- MaxX1 - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end -- [B2Ys-xsw] + + -- **[B2Ys]** |accentramento di Y 'significativo'| + if bYDeltaS then + -- **[B2Ys-x]** accentramento di Y 'significativo' |con pos. NewY 'non raggiungibile'|(= oltre MyMinX1) + if dExtraX1 < 0 then + -- (-ExtraX1 <= (dCorsaYr + dCorsaVTr ) a ciclo precedente + -- **[B2Ys-xs]** accentramento di Y con |'ExtraX1 'significativo'| + if bYxs then + local dCorsaVTrA = MaxX2 - dX2PosA + local dCorsaYra = dX1PosA - MyMinX1 + -- **[B2Ys-xs1]** se posso recuperare ExtraX1 solo accentrando Y e (V+T) + if dCorsaVTrA >= -dExtraX1 then + EmitComment( vCmd, '[B2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y e (V+T) q.b. + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = dX2PosA - dExtraX1 -- = +(-dExtraX1) + dTPosA = dTPosA - dExtraX1 -- = +(-dExtraX1) + dExtraX1 = 0 + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[B2Ys-xs2]** + EmitComment( vCmd, '[B2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraX1... + dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1') + local dYDispl1 = dX1Pos1 - dX1PosA + local dVDispl1 = dX2Pos1 - dX2PosA + local dVDeltaDiff = dNewVDelta - (dX2Pos1 - dTPos1) + -- ...e anche possibilmente di posizionare V alla posizione finale + if dVDeltaDiff < 0 then + dCorsaYfc = MaxX1 - dX1Pos1 + dCorsaVfc = dX2Pos1 - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'X1') + else + dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + --dVDeltaA = dX2PosA - dTPosA + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| accentro Y e (V+T) + dX1PosA = dX1PosA - dYDispl1 - dCorsaYra -- POS. FINALE + dX2PosA = dX2PosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B2Ys-xs1/xs2] + + -- **[B2Ys-xn]** |dExtraX1 non 'significativo'| + else + EmitComment( vCmd, '[B2Ys-xn]') + dExtraX1 = 0 + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: posiziono Y assumendo MyMinX1 come pos. finale + dX1PosA = MyMinX1 -- (pos finale) + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end -- [B2Ys-xs/xn] + + --[B2Ys-r] accentramento di |Y| 'significativo' con pos.|'raggiungibile'| (non oltre MyMinX1) + else + EmitComment( vCmd, '[B2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| posiziono Y -- (pos finale) + dX1PosA = dTPosA + dNewYDelta + dExtraX2 = 0 + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end --[B2Ys] + + -- [B2Yns] accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Yns]') + dExtraX2 = 0 + end --[B2Ys/ns] + end --[B2Y] ( accentramento di V) + + -- ricalcolo gli 'spostamenti significativi' + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + + -- ------------------------------------------------------------------------------------------ + -- **[B2C]** |Spostamenti| di Y e/o V (ev' |residui| da cicli precedenti) + -- ++ possono essere solo allontanamenti ? +++++++++++++++++++++ + EmitComment( vCmd, '[B2C]') + -- **[B2Cs]** se c'è uno |spostamento (ev' residuo) significativo| + if bYDeltaS or bVDeltaS then + -- **[B2CYs]** se lo |spostamento (ev' residuo) di Y è 'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B2CYs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraX1 = dNewY - MyMinX1 + + -- **[B2CYs-r]** se posizione di |Y raggiungibile| + if dExtraX1 >= 0 and dNewY <= MaxX1 then + EmitComment( vCmd, '[B2CYs-r]') + -- chiudo eventualmente V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dX1PosA = dNewY + table.insert( vCmd, { 1, 'X1', dX1PosA}) + -- **[B2CYs-nr]** + else + EmitComment( vCmd, '[B2CYs-nr]') + EgtOutLog( ' CLAMP : posizione Y non raggiungibile' .. '- caso [B2Ys-nr] non gestito') + error( 'CLAMP : posizione Y non raggiungibile') + end + end -- [B2CYs] + + -- **[B2CVs]** se lo |spostamento (ev' residuo) di V è 'significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B2CVs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraX2 = dNewV - MaxX2 + + -- **[B2CVs-r]** se posizione NewV raggiungibile + if dExtraX2 <= 0 and dNewV >= MinX2 then + EmitComment( vCmd, '[B2CVs-r]') + -- chiudo eventualmente Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dX2PosA = dNewV + table.insert( vCmd, { 1, 'X2', dX2PosA}) + -- **[B2CVs-nr]** + else -- se ExtraX2 > 0 anche se non significativo + EmitComment( vCmd, '[B2CVs-nr]') + EgtOutLog( ' CLAMP : posizione V non raggiungibile' .. '- caso [B2cVs-nr] non gestito') + error( 'CLAMP : posizione V non raggiungibile') + end + end --[B2CsV] + + -- **[B2Cn]** |nessuno spostamento (ev' residuo significativo)| + else + EmitComment( vCmd, '[B2Cn]') + end -- [B2C] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- imposto stato carrelli, per eventuale uso pressori + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrB2 + +--------------------------------------------------------------------------------------------------------- +-- *** [B3] da carrello X2 a entrambi i carrelli : X2 -> X1+X2 *** +--------------------------------------------------------------------------------------------------------- +function SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B3] = X2 -> X1+X2', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X2 -> X1+X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + local dCorsaY = MaxX1 - MyMinX1 + local dCorsaV = MaxX2 - MinX2 + -- recupero le posizioni correnti + local dX2PosA = dTPosI + dVDeltaI + local dX1PosA = ParkX1 + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dX1PosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog( ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA)..' VDeltaI=' .. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dX1Pos, dX2Pos, dTPos + local dNewY, dExtraX1, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraX1' con (V+T) e Y accentrati q.b. per la presa di Y + dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1') + dNewY = dTPos + dNewYDelta + dExtraX1 = dNewY - MyMinX1 -- se < 0 pos. Y non direttamente 'raggiungibile' + bYxs = -dExtraX1 > dYDeltaTol/2 -- ExtraX1 'significativo' + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1Pos + dCorsaVfc = dX2Pos - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end + -- inizializzo + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + end + + -- **[B3Ys-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B3Ys-xsw]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dX1PosA = dX1PosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dX2PosA = dX2PosA - dCorsaVd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dX2PosA = dX2PosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dX1PosA = MyMinX1 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraX1 + dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr + end --[B3Ys-xsw] + + -- **[B3Ys]** |spostamento| finale richiesto (ev' residuo) di |Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B3Ys]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- **[B3Ys-x]** posizione di |Y non raggiungibile| + -- ( -dExtraX1 <= (CorsaYr+CorsaVr) da ciclo precedente ) + if dExtraX1 < 0 then + --EmitComment( vCmd, '[B3Ys-x]') + + -- **[B3Ys-xs]** |ExtraX1 'significativo'| + if bYxs then + --EmitComment( vCmd, '[B3Ys-xs]') + + local dCorsaVTrA = MaxX2 - dX2PosA + local dCorsaYra = dX1PosA - MyMinX1 + -- **[B3Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraX1 then + EmitComment( vCmd, '[B3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dX1PosA = MyMinX1 -- (pos. finale) + dX2PosA = dX2PosA - dExtraX1 + dTPosA = dTPosA - dExtraX1 + dYDeltaA = dX1PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[B3Ys-xs2]** + EmitComment( vCmd, '[B3Ys-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dYDeltaA = dX1PosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraX1... + dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1') + local dYDispl1 = dX1Pos1 - dX1PosA + local dVDispl1 = dX2Pos1 - dX2PosA + local dVDeltaDiff = dNewVDelta - (dX2Pos1 - dTPos1) + -- ...e anche di posizionare possibilmente V alla posizione finale + if dVDeltaDiff < 0 then + CorsaYfc = MaxX1 - dX1Pos1 + dCorsaVfc = dX2Pos1 - MinX2 + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'X1') + else + dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dX1PosA = dX1PosA - dYDispl1 - dCorsaYra -- POS. FINALE + dX2PosA = dX2PosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B3Ys-xs1/-xs2] + + -- **[B3Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')| + else --if -dExtraX1 < DeltaToll/2 + EmitComment( vCmd, '[B3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y e porto (V+T) alla posizione impostata + dExtraX1 = 0 + dX1PosA = MyMinX1 -- (pos. finale) + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end --[B3Ys-xs/xn] + + -- **[B3Ys-r]** |dExtraX1 > 0 (pos. Y raggiungibile)| + else + EmitComment( vCmd, '[B3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione ev' (V+T) come impostato sopra e Y in posizione finale + dX1PosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [B3Ys] + -- + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + + else -- [B3Yns] |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[B3Yns]') + end --[B3Ys/ns] + + -- aggiorno la verifica di movimento 'significativo' per V + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **[B3Vs]** Se vi è uno |spostamento residuo di V significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B3Vs]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraX2 = dNewV - MaxX2 + + -- **[B3Vs-x]** se pos. |NewV non è raggiungibile direttamente| (oltre MaxX2) + if dExtraX2 > 0 then --dNewV <= MaxX2 then + -- **[B3Vs-xs]** |ExtraX2 'significativo'| + if dExtraX2 > dVDeltaTol /2 then + EmitComment( vCmd, '[B3Vs-xs]') + EgtOutLog( ' CLAMP : caso [B3Vs-xs] non gestito') + error( ' CLAMP : caso [B3Vs-xs] non gestito') + + -- **[B3Vs-xn]** |ExtraX2 non 'significativo'| + else + EmitComment( vCmd, '[B3Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro V q.p. + dX2PosA = MaxX2 + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end -- [B3Vs-xs/xn] + + else -- **[B3Vs-r]** pos. |NewV raggiungibile direttamente| (non oltre MaxX2) + EmitComment( vCmd, '[B3Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dX2PosA = dNewV + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end --[B3Vs-x/-r] + + else -- [B3Vns] spostamento residuo di V non significativo + EmitComment( vCmd, '[B3Vns]') + end -- [B3Vs/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- se non emessi movimenti, imposto posizione Y + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'X1', dX1PosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre effettuato movimento) + table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB3 + +--------------------------------------------------------------------- +-- *** [C1] da carrello X1 a X2 : X1 -> X2 *** +--------------------------------------------------------------------- +function SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C1] = X1 -> X2 ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1 -> X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + -- recupero le posizioni correnti + --local dCorsaY = MaxX1 - MyMinX1 + --local dCorsaV = MaxX2 - MinX2 + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = ParkX2 + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dX2PosA - dTPosA + local dNewVDelta -- = dVDeltaF + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 4 + else + dNewVDelta = dVDeltaA + end + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta) , 1) + + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dX1Pos, dX2Pos, dTPos + local dNewV, dExtraX2, bVxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bVDeltaS then + -- definisco 'ExtraX2' con (Y+T) e V accentrati q.b. per la presa di V + dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2') + dNewV = dTPos + dNewVDelta + dExtraX2 = dNewV - MaxX2 + bVxs = dExtraX2 > dVDeltaTol/2 -- ExtraX2 'significativo' + if bVxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxX1 - dX1Pos + dCorsaVfc = dX2Pos - MinX2 + --local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dDistBkN = EMC.LB - (dX1Pos-dTPos) - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dX1Pos -MyMinX1) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr + end + -- inizializzo + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + end + + -- **[C1Vs-xsw]** posizione finale di V non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr| + -- con spostamento richiesto significativo e ExtraX2 significativo + while bXsw do + EmitComment( vCmd, '[C1Vs-xsw]') + -- **1:** posiziono (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** allontano Y e (V+T) quanto possibile + dX1PosA = dX1PosA + dCorsaYd + dX2PosA = dX2PosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3:** accentro (Y+T) e V + dX1PosA = dX1PosA - dCorsaYTr -- = MyMinX1 + dTPosA = dTPosA - dCorsaYTr + dX2PosA = MaxX2 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraX2** + dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr + end --[C1Vs-xw] + + -- **[C1Vs]** |spostamento| richiesto (ev' residuo) |di V| |'significativo'| + if bVDeltaS then + -- **[C1Vs-x]** posizione di |V non raggiungibile| + if dExtraX2 > 0 then + -- (dExtraX2 <= (CorsaYr+CorsaVr) da ciclo precedente) + -- **[C1Vs-xs]** posizione di V non raggiungibile, |con ExtraX2 'significativo'| + if bVxs then + local dCorsaYTrA = dX1PosA - MyMinX1 + -- **[C1Vs-xs1]** se posso recuperare dExtraX2 solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraX2 then + EmitComment( vCmd, '[C1Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dX1PosA = dX1PosA - dExtraX2 + dTPosA = dTPosA - dExtraX2 + dX2PosA = MaxX2 -- (pos. finale) + dVDeltaA = dX2PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + -- **[C1Vs-xs2]** dCorsaYTrA < dExtraX2 + else + EmitComment( vCmd, '[C1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + dVDeltaA = dX2PosA - dTPosA + -- chiudo (ev') il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:allontano** (V+T) q.b./q.p. e Y per preparare il recupero di ExtraX2 + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2') + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dYDeltaA = dX1PosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro**(Y+T) e V (pos. finale) + dX1PosA = MyMinX1 + dTPosA = dX1PosA - dYDeltaA + dX2PosA = MaxX2 + dVDeltaA = dX2PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + end -- [C1Vs-xs1/xs2] + + -- **[C1Vs-xn]** |ExtraX2 ancora > 0 , ma non 'significativo'| (<= DeltaTol/2) + else + EmitComment( vCmd, '[C1Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: porto ev' (Y+T) alla posizione impostata sopra e accentro V + dExtraX2 = 0 + dX2PosA = MaxX2 -- pos. finale + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + -- chiudo V (?) + table.insert( vCmd, { 12, 1}) + end -- [C1Vs-xs/xn] + + -- **[C1Vs-r]** posizione di V 'raggiungibile' (ExtraX2 <= 0) + else + EmitComment( vCmd, '[C1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posizione ev' (Y+T) come impostato sopra e V in posizione finale + dX2PosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [C1V-s] + + -- **[C1Vns]** |spostamento| richIesto per V |non 'significativo'| + else + EmitComment( vCmd, '[C1Vns]') + end + + -- calcolo i nuovi parametri di aggancio + dVDeltaA = dX2PosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'X1', ParkX1}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC1 + +--------------------------------------------------------------------- +-- *** [C2] da entrambi i carrelli a X2 : X1+X2 -> X2 *** +--------------------------------------------------------------------- +function SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C2] = X1+X2 -> X2', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X1+X2 -> X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + local dCorsaY = MaxX1 - MyMinX1 + local dCorsaV = MaxX2 - MinX2 + -- recupero le posizioni correnti dei carrelli + local dX1PosA = dTPosI + dYDeltaI + local dX2PosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewVDelta -- = dVDeltaF + -- tolleranze + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + -- definisco spostamento 'significativo' in base alle tolleranze + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto ev' il delta finale + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 4 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraX2' + local dNewV = dTPosI + dNewVDelta + local dExtraX2 = dNewV - MaxX2 -- > 0 se nuova pos. di X2 'non raggiungibile' (= oltre MaxX2) + local bVxs = dExtraX2 > dVDeltaTol/2 -- 'ExtraX2 significativo' + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' VDeltaF=' .. EgtNumToString( dVDeltaF) ,1) + EgtOutLog( ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di Y) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per YV significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + if bVxs then + -- calcolo le corse disponibili dei carrelli dalle posizioni attuali (=iniziali) + -- per allontanare Y e (V+T) q.p. + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr + end + end + + -- **[C2Vs-xsw]** posizione finale di V non raggiungibile, |con dExtraX2 > CorsaYTr + CorsaVr| + while bXsw do + EmitComment( vCmd, '[C2Vs-xsw]') + + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| allontano Y e (V+T) quanto possibile + dX1PosA = dX1PosA + dCorsaYd + dX2PosA = dX2PosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dX1PosA = dX1PosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dX2PosA = MaxX2 + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dX1PosA - dTPosA + dVDeltaA = dX2PosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraX2** + dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + dCorsaYfc = MaxX1 - dX1PosA + dCorsaVfc = dX2PosA - MinX2 + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1) + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr + end -- [C2V-xsw] + + -- **[C2Vs]** se lo |spostamento richiesto per V è significativo| + if bVDeltaS then + -- **[C2Vs-x]** posizione di |V non raggiungibile| (oltre MaxX2) + if dExtraX2 > 0 then + -- **[C2Vs-xs]** |ExtraX2 'significativo'| + if bVxs then + local dCorsaYTrA = dX1PosA - MyMinX1 + -- **[C2Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando V e (Y+T) + if dCorsaYTrA >= dExtraX2 then + EmitComment( vCmd, '[C2Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dX1PosA = dX1PosA - dExtraX2 + dTPosA = dTPosA - dExtraX2 + dX2PosA = MaxX2 -- (pos. finale) + dVDeltaA = dX2PosA - dTPosA + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + + else -- **[C2Vs-xs2]** + EmitComment( vCmd, '[C2Vs-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2') + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dYDeltaA = dX1PosA - dTPosA + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dX1PosA = MyMinX1 + dTPosA = dX1PosA - dYDeltaA + dX2PosA = MaxX2 -- (pos. finale) + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [C2Vs-xs1/-xs2] + + -- **[C2Vs-xn]** |dExtraX2 ancora > 0 ma non 'significativo')| + else --if dExtraX2 < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraX2 = 0 + dX2PosA = MaxX2 -- (pos. finale) + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end -- [C2s-xs/xn] + + -- **[C2Vs-r]** |dExtraX2 < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[C2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- porto V in posizione finale + dX2PosA = dTPosA + dNewVDelta + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end --[C2Vs] + + -- **[C2Vns]** = |spostamento di V non significativo| + else + EmitComment( vCmd, '[C2Vns]') + end --[C2Vs/n] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dX2PosA - dTPosA + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'X1', ParkX1}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC2 + +--------------------------------------------------------------------- +-- *** [C3] da carrello X2 a X2 : X2 -> X2 *** +--------------------------------------------------------------------- +function SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + EgtOutLog( ' *[C3] = X2 -> X2', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'X2 -> X2'}) + -- se primo scambio + local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1) + -- recupero le posizioni correnti dei carrelli + local dX2PosA = dTPosI + dVDeltaI + local dX1PosA = ParkX1 + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dX1PosA - dTPosA + local dNewVDelta + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta) + local bVDeltaS = (( dVDeltaF > dVDeltaA + dVDeltaTol and not bFixedPos) or dVDeltaF < dVDeltaA - DELTA_SIC) + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 4 + else + dNewVDelta = dVDeltaA + end + EgtOutLog( ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag per risalita testa a Zmax + local bZmaxOk = false + + -- **[C3Vs]** |pos. di V cambia in modo significativo| + if bVDeltaS then + EmitComment( vCmd, '[C3Vs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraX2' con (V+T) e Y accentrati q.b. per la presa con Y + local dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1') + local dNewV = dTPos + dNewVDelta + local dExtraX2 = dNewV - MaxX2 + -- effettuo spostamenti per predisporre all'aggancio di T con Y + dX1PosA = dX1Pos + dX2PosA = dX2Pos + dTPosA = dTPos + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dYDeltaA = dX1PosA - dTPosA + + -- **[C3Vs-x]** posizione di |V non raggiungibile| (oltre MaxX2) + if dExtraX2 > 0 then + -- **[C3Vs-xs]** posizione di V non raggiungibile, |con ExtraX2 'significativo'| + if dExtraX2 > dVDeltaTol /2 then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (V+T) e Y + local dCorsaYfc = MaxX1 - dX1Pos + local dCorsaVfc = dX2Pos - MinX2 + local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + local dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + local dCorsaYTr = dCorsaYd + (dX1Pos - MyMinX1) + local dCorsaVr = dCorsaVTd + + -- **[C3Vs-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr| + if dExtraX2 > ( dCorsaYTr + dCorsaVr) and bVDeltaS then + EmitComment( vCmd, '[C3Vs-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaYTrA = dX1Pos - MyMinX1 -- !! att.ne: non dX1PosA !! + -- **[C3Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando (Y+T) e V + -- (dalle posizione impostate sopra per l'aggancio di Y) + if dCorsaYTrA >= dExtraX2 then + EmitComment( vCmd, '[C3Vs-xs1]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dX1PosA = dX1PosA - dExtraX2 + dTPosA = dTPosA - dExtraX2 + dX2PosA = MaxX2 -- (pos. finale) + table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA}) + dVDeltaA = dX2PosA - dTPosA + + else -- **[C3Vs-xs2]** + -- ci sarebbe un doppio movimento di V ? => caso impossibile ? + EmitComment( vCmd, '[C3Vs-xs2]') + -- **1:** posiziono (ulteriormente!) Y e (V+T) + dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2') + table.remove( vCmd) + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA }) + dYDeltaA = dX1PosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dX1PosA = MyMinX1 + dX2PosA = MaxX2 -- (pos. finale) + dTPosA = dX1PosA - dYDeltaA + table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA}) + end -- [C3Vs-xs1/-xs2] + + -- **[C3Vs-xn]** |dExtraX2 > 0 ma 'non significativo')| + else --if dExtraX2 < DeltaToll/2 + EmitComment( vCmd, '[C3Vs-xn]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraX2 = 0 + dX2PosA = MaxX2 -- (pos. finale) + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end --[C3Vs-xs/xn] + + -- **[C3Vs-r]** |posizione di Y raggiungibile| (ExtraX1 >=0) + -- (si esclude la possibilità di extra corsa oltre maxX1) + else + EmitComment( vCmd, '[C3Vs-r]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** posiziono V alla posizione richiesta + dX2PosA = dNewV + table.insert( vCmd, { 1, 'X2', dX2PosA}) + end -- [C3Vs] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dX2PosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'X1', ParkX1}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + -- reset contatore + EMC.CNT = nil + + else -- **[C3Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[C3Vns]') + end --[C3Vs/ns] + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC3 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + + -- Registro il numero di comandi + if #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #vCmd do + local Cmd = vCmd[i] + local sKey = sRoot..tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + if Cmd[3] then sInfo = sInfo..','..Cmd[3] end + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 2 assi + elseif Cmd[1] == 2 then + local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 3 assi + elseif Cmd[1] == 3 then + local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. + Cmd[6]..','..EgtNumToString( Cmd[7],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa Y + elseif Cmd[1] == 11 then + local sInfo = '11,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.YDELTA = nil end + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.VDELTA = nil end + -- impostazione nuovo stato dei carrelli + elseif Cmd[1] == 21 then + local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.YDELTA then + EgtSetInfo( EMC.PATHID, 'YDELTA', EMC.YDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'YDELTA') + end + if EMC.VDELTA then + EgtSetInfo( EMC.PATHID, 'VDELTA', EMC.VDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'VDELTA') + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #vCmd do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + end + end +end + +--------------------------------------------------------------------- +function SpecTestOnlyRemarkInCmds( vCmd) + if not vCmd then return true end + -- verifico se nella lista dei comandi ci sono solo commenti + for i = 1, #vCmd do + if vCmd[i][1] ~= 0 then + return false + end + end + return true +end diff --git a/Saomad-KAIROS.nge b/Saomad-KAIROS.nge new file mode 100644 index 0000000..2c59a0a Binary files /dev/null and b/Saomad-KAIROS.nge differ diff --git a/Saomad-KAIROS_GLOBAL.txt b/Saomad-KAIROS_GLOBAL.txt new file mode 100644 index 0000000..c5e13be --- /dev/null +++ b/Saomad-KAIROS_GLOBAL.txt @@ -0,0 +1,46 @@ +Origins are defined in respect to GLOBAL + + ♫ Y_AXIS +X:-278.7237, Y:1157.3264, Z:2847.1 + + ♫ Z_AXIS +X:0.0257, Y:683.8421, Z:1431.0044 + + ♫ C_AXIS +X:0, Y:835.001, Z:1404.0 + + ♫ A_AXIS +X:0, Y:835.001, Z:1021.0 + + ♫ H1_HEAD_T1 +X:0, Y:835.001, Z:804.0 + + ♫ CS_AXIS +X:0, Y:835.001, Z:804.0 + + ♫ H3_HEAD_T1 +X:145.0, Y:835.001, Z:662.5 + + ♫ X1_AXIS +X:-1253.5, Y:1080.001, Z:1698.0 + + ♫ PX1_AXIS +X:-1253.5, Y:930.001, Z:1698.0 + + ♫ QX1_AXIS +X:-874.2, Y:812.501, Z:1475.4737 + + ♫ X2_AXIS +X:1253.5001, Y:1080.001, Z:1698.0 + + ♫ PX2_AXIS +X:1253.5001, Y:930.001, Z:1698.0 + + ♫ QX2_AXIS +X:874.2001, Y:1475.4737, Z:-812.501 + + ♫ T_AXIS +X:0, Y:835.001, Z:804.0 + + ♫ TABLE_R1 +X:-20000.0, Y:335.001, Z:804.0 diff --git a/Saomad-KAIROS_H1_HEAD_T1.txt b/Saomad-KAIROS_H1_HEAD_T1.txt new file mode 100644 index 0000000..1cfe46c --- /dev/null +++ b/Saomad-KAIROS_H1_HEAD_T1.txt @@ -0,0 +1,46 @@ +Origins are defined in respect to H1_HEAD_T1 + + ♫ Y_AXIS +X:-278.7237, Y:322.3254, Z:2068.04 + + ♫ Z_AXIS +X:0.0257, Y:-151.1589, Z:627.0044 + + ♫ C_AXIS +X:0, Y:0, Z:600.0 + + ♫ A_AXIS +X:0, Y:0, Z:217.0 + + ♫ H1_HEAD_T1 (ORIGIN) +X:0, Y:0, Z:0 + + ♫ CS_AXIS +X:0, Y:0, Z:0 + + ♫ H3_HEAD_T1 +X:0, Y:0, Z:-141.5 + + ♫ X1_AXIS +X:-1253.5, Y:245.0, Z:918.94 + + ♫ PX1_AXIS +X:-1253.5, Y:95.0, Z:918.94 + + ♫ QX1_AXIS +X:-874.2, Y:-22.5, Z:668.9787 + + ♫ X2_AXIS +X:1253.5001, Y:245.0, Z:918.94 + + ♫ PX2_AXIS +X:1253.5001, Y:95.0, Z:918.94 + + ♫ QX2_AXIS +X:874.2001, Y:613.0377, Z:-1591.561 + + ♫ T_AXIS +X:0, Y:0, Z:0 + + ♫ TABLE_R1 +X:-20000.0, Y:-500.0, Z:0 diff --git a/Scripts/ExitMach.lua b/Scripts/ExitMach.lua new file mode 100644 index 0000000..3288b17 --- /dev/null +++ b/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2023/09/22 13:00:00 +-- Machining Exit for Saomad-KAIROS machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/Scripts/InitMach.lua b/Scripts/InitMach.lua new file mode 100644 index 0000000..eb0b47a --- /dev/null +++ b/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2023/09/22 13:00:00 +-- Machining Init for Saomad-KAIROS machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/Scripts/SetUp.lua b/Scripts/SetUp.lua new file mode 100644 index 0000000..de04f2b --- /dev/null +++ b/Scripts/SetUp.lua @@ -0,0 +1,203 @@ +-- Gestione attrezzaggio per Saomad-KAIROS - 2023/10/16 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni +local PositionTable={{Pos = "Pos1", TcPos = "T1", Head = "H1", Group = "G1"}, + {Pos = "Pos2", TcPos = "T2", Head = "H1", Group = "G1"}, + {Pos = "Pos3", TcPos = "T3", Head = "H1", Group = "G1"}, + {Pos = "Pos4", TcPos = "T4", Head = "H1", Group = "G1"}, + {Pos = "Pos5", TcPos = "T5", Head = "H1", Group = "G1"}, + {Pos = "Pos6", TcPos = "T6", Head = "H1", Group = "G1"}, + {Pos = "Pos7", TcPos = "T7", Head = "H1", Group = "G1"}, + {Pos = "Pos8", TcPos = "T8", Head = "H1", Group = "G1"}, + {Pos = "Pos9", TcPos = "T9", Head = "H1", Group = "G1"}, + {Pos = "Pos10", TcPos = "T10", Head = "H1", Group = "G1"}, + {Pos = "Pos11", TcPos = "T11", Head = "H1", Group = "G1"}, + {Pos = "Pos12", TcPos = "T21", Head = "H1", Group = "G2"}, + {Pos = "Pos13", TcPos = "T22", Head = "H3", Group = "G3"}} +if EgtGetHeadId( 'H3') then + PositionTable[13].Head = 'H3' +end + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/THolders/ChainSaw.nge b/THolders/ChainSaw.nge new file mode 100644 index 0000000..189b266 Binary files /dev/null and b/THolders/ChainSaw.nge differ diff --git a/THolders/MillNoTip.nge b/THolders/MillNoTip.nge new file mode 100644 index 0000000..414ea8e Binary files /dev/null and b/THolders/MillNoTip.nge differ diff --git a/THolders/Standard.nge b/THolders/Standard.nge new file mode 100644 index 0000000..23ee6c6 Binary files /dev/null and b/THolders/Standard.nge differ diff --git a/THolders/Standard97.nge b/THolders/Standard97.nge new file mode 100644 index 0000000..2ab70eb Binary files /dev/null and b/THolders/Standard97.nge differ diff --git a/THolders/Standard_78.nge b/THolders/Standard_78.nge new file mode 100644 index 0000000..bb1e695 Binary files /dev/null and b/THolders/Standard_78.nge differ diff --git a/THolders/Standard_LC.nge b/THolders/Standard_LC.nge new file mode 100644 index 0000000..7d2b4c3 Binary files /dev/null and b/THolders/Standard_LC.nge differ diff --git a/THolders/TcSaw.nge b/THolders/TcSaw.nge new file mode 100644 index 0000000..99d4f05 Binary files /dev/null and b/THolders/TcSaw.nge differ diff --git a/THolders/TcSaw2.nge b/THolders/TcSaw2.nge new file mode 100644 index 0000000..39fd5a8 Binary files /dev/null and b/THolders/TcSaw2.nge differ