diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..450874d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,318 @@ +variables: + VERS_MAIN: '1.0' + MACH_NAME: '' + MACH_NAME_TEST: '' + MANUFACTURER: '' + NEW_REL: '' + NET_SHARE_X: '\\10.74.82.201\EgwTech' + NET_SHARE_Z: '\\10.74.82.201\Artifacts' + NET_SHARE_S: '\\10.74.82.201\Scambio' + NET_SHARE_R: '\\10.74.82.201\EgwTech' + NET_SHARE_H: '\\10.74.82.252\team drives' + NET_USERQ: 'steamw\egalware' + NET_USER_SERVICES: 'steamw\services' + MACH_VERS: '0.0.0.0' + TEMP_PATH: 'C:\MachinesDeploy' + MACHINES_PATH_R: 'R:\EgtData\Machines_GIT' + DEST_MACHINES_PATH_H: 'H:' + SRC_PATH: '' + BASE_PATH: '' + TEST_PATH: '' + URL_VERSIONS_LOG: "https://liman.egalware.com/ELM.API/api/release/save" + MACH_VERS_NUM: '0.0.0.0' + CRITICAL_STRING: "#critical#" + TOOLS_MACHINE_PATH: "" + + +#Note compilazione LUA: +# lua54 -o bin\$FileName -s $FileName: -o = output, -s = NON include i debug symbols + +# helper copia script verso cartella di rete S:\ delle cartelle bin +.ReplicaS: &ReplicaS + - | + net use S: /delete + SLEEP 2 + net use S: $env:NET_SHARE_S /u:$env:NET_USERQ $SDRIVE_PASSWD + ROBOCOPY /MIR $env:BASE_PATH S:\LucaM\MachinesDeploy\$env:MACH_NAME\$env:MACH_VERS\ /XD "bin" /XD "$env:MACH_NAME_TEST" + SLEEP 2 + net use S: /delete + +# helper copia script verso cartella di rete R:\ +.ReplicaR: &ReplicaR + - | + net use R: /delete + SLEEP 2 + net use R: $env:NET_SHARE_R /u:$env:NET_USERQ $ZDRIVE_PASSWD + echo "-----------------------" + echo " Copia macchina su R" + echo "-----------------------" + $customerPathR = $env:MACHINES_PATH_R + "\" + $env:MANUFACTURER + ROBOCOPY /MIR "$env:SRC_PATH" "$customerPathR\$env:MACH_NAME\" /XD "bin" + ROBOCOPY "$env:TEST_PATH" "$customerPathR\_TestMachines\$env:MACH_NAME_TEST\" /E /XD "bin" + ROBOCOPY /MIR "$env:BASE_PATH" "$customerPathR\_Deploy\$env:MACH_NAME\$env:MACH_VERS\" /XD "bin" /XD "$env:MACH_NAME_TEST" + SLEEP 2 + net use R: /delete + +# helper copia script verso drive condiviso +.ReplicaStor01: &ReplicaStor01 + - | + net use H: /delete + SLEEP 2 + net use H: $env:NET_SHARE_H /u:$env:NET_USER_SERVICES $SRVCS_PASSWD + echo "-----------------------" + echo " Copia macchina su stor01" + echo "-----------------------" + SLEEP 2 + $customerPathH = $env:DEST_MACHINES_PATH_H + "\" + $env:MANUFACTURER + "\test" + $destinationPath = "$customerPathH\$env:MACH_NAME" + "\" + ROBOCOPY "$env:BASE_PATH" "$destinationPath\" *.zip + SLEEP 2 + net use H: /delete + +# helper copia script verso cartella di rete R:\ per develop +.ReplicaR_DEV: &ReplicaR_DEV + - | + net use R: /delete + SLEEP 2 + net use R: $env:NET_SHARE_R /u:$env:NET_USERQ $ZDRIVE_PASSWD + echo "-----------------------" + echo " Copia macchina su R - DEV" + echo "-----------------------" + $customerPathR = $env:MACHINES_PATH_R + "\" + $env:MANUFACTURER + ROBOCOPY /MIR "$env:BASE_PATH" "$customerPathR\_Deploy\$env:MACH_NAME\_DEV\$env:MACH_VERS\" /XD "bin" /XD "$env:MACH_NAME_TEST" + SLEEP 2 + net use R: /delete + +#helper copia sorgenti da R a percorso temporaneo +.CreateBaseFolder: &CreateBaseFolder + - | + net use R: /delete + SLEEP 2 + net use R: $env:NET_SHARE_R /u:$env:NET_USERQ $ZDRIVE_PASSWD + echo "-----------------------" + echo " Recupero file non git da R e copia su macchina virtuale" + echo "-----------------------" + # test se la cartella con gli utensili esiste per questa macchina + if (!(Test-Path -Path $env:TOOLS_MACHINE_PATH)) { + echo "-----------------------" + echo "CANNOT FIND TOOLS FOR THIS MACHINE!!" + echo "-----------------------" + Exit 1} + ROBOCOPY "$env:TOOLS_MACHINE_PATH" "$env:SRC_PATH" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + ROBOCOPY "$env:TOOLS_MACHINE_PATH" "$env:TEST_PATH" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + ROBOCOPY "$env:TOOLS_MACHINE_PATH" "$env:SRC_PATH\bin\$env:MACH_NAME\" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + SLEEP 2 + net use R: /delete + +# helper compilazione LUA a 32 e 64 bit +.LuaCompile: &LuaCompile + - | + Set-Alias lua54 C:\Tools\Lua32\luac54 + echo "-----------------------" + echo " Copia file su macchina virtuale" + echo "-----------------------" + ROBOCOPY . "$env:SRC_PATH" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + ROBOCOPY . "$env:TEST_PATH" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + Rename-Item -Path "$env:TEST_PATH\$env:MACH_NAME.mlde" -NewName "$env:MACH_NAME_TEST.mlde" + Rename-Item -Path "$env:TEST_PATH\$env:MACH_NAME.ini" -NewName "$env:MACH_NAME_TEST.ini" + ROBOCOPY . "$env:SRC_PATH\bin\$env:MACH_NAME\" /E /XF "*.bat" /XF "*.yml" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" /XD ".vscode" + echo "-----------------------" + echo " Compilazione file *.lua 32/64bit" + echo "-----------------------" + $FileList = Get-ChildItem * -Include( "*.mlpe", "*.mlse") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + lua54 -o $env:SRC_PATH\bin\$env:MACH_NAME\$FileName -s $FileName + echo "lua54 -o bin\$FileName -s $FileName" + } + +# helper recupero nome macchina e costruttore +.machName-fix: &machName-fix + - | + echo "-----------------------" + echo " Recupero nome macchina e costruttore" + echo "-----------------------" + $fileName = dir *.mlde + $env:MACH_NAME = $fileName.BaseName + $env:MACH_NAME_TEST = $env:MACH_NAME + ".TEST" + $comp = $fileName.BaseName -split "-" + $env:MANUFACTURER = $comp[0] + Write-Output $env:MANUFACTURER + +# helper calcolo versione +.version-fix: &version-fix + - | + echo "-----------------------" + echo " Calcolo versione" + echo "-----------------------" + + # calcolo versione formato stringa + $fPath = "$env:MACH_NAME.mlde"; + $vLine = Select-String -path $fPath -Pattern '^PP_VER'; + $comp = $vLine -split "="; + $env:MACH_VERS = $comp[1].Replace("'","").Trim() + # display versione formato stringa + Write-Output $env:MACH_VERS + + # calcolo versione formato numerico + $fPath = "$env:MACH_NAME.mlde"; + $vLine = Select-String -path $fPath -Pattern '^PP_NVER'; + $comp = $vLine -split "="; + $env:MACH_VERS_NUM = $comp[1].Replace("'","").Trim() + # display versione formato numerico + Write-Output $env:MACH_VERS_NUM + +# helper calcolo versione se develop +.version-fix_DEV: &version-fix_DEV + - | + echo "-----------------------" + echo " Calcolo versione - DEV" + echo "-----------------------" + $commitAuthor = $CI_COMMIT_AUTHOR -split " " + $commitAuthor = $commitAuthor[0].Trim() + $env:MACH_VERS = $commitAuthor + # display versione + Write-Output $env:MACH_VERS + +# helper creazione folders +.folder-fix: &folder-fix + - | + echo "-----------------------" + echo " Creazione cartelle su macchina virtuale" + echo "-----------------------" + $env:TOOLS_MACHINE_PATH = "$env:MACHINES_PATH_R\$env:MANUFACTURER\_DefaultMachineSetup\$env:MACH_NAME" + Write-Output $env:TOOLS_MACHINE_PATH + $env:SRC_PATH = "$env:TEMP_PATH\$env:MACH_NAME\$env:MACH_VERS\$env:MACH_NAME"; + $env:BASE_PATH = "$env:TEMP_PATH\$env:MACH_NAME\$env:MACH_VERS"; + $env:TEST_PATH = "$env:TEMP_PATH\$env:MACH_NAME\$env:MACH_VERS\$env:MACH_NAME_TEST"; + Write-Output $env:BASE_PATH; + if (Test-Path $env:BASE_PATH) { Remove-Item -Path "$env:BASE_PATH\*" -R -Force }; + Write-Output $env:TEST_PATH; + +# helper compressione e pulizia folders +.ZipClean: &ZipClean + - | + " Compressione file su macchina virtuale" + $7zipPath = $env:ProgramFiles+"\7-Zip\7z.exe"; + if (-not (Test-Path -Path $7zipPath -PathType Leaf)) { + throw "7 zip file '$7zipPath' not found" + } + Set-Alias 7zip $7zipPath + $Target = "$env:BASE_PATH\$env:MACH_NAME.zip" + cd "$env:SRC_PATH\bin\" + $Source = "*" + 7zip a -tzip $Target $Source + Write-Output "called ZIP $Source --> $Target" + +# helper invio notifica a log versioni online (LiMan) +.SendToVersionsLog: &SendToVersionsLog + - | + echo "-----------------------" + echo " Invio versione a log online" + echo "-----------------------" + $tags = "" + $date = "" + # se critico scrive tag + if ( $CI_COMMIT_MESSAGE | Select-String -Pattern $env:CRITICAL_STRING) { + $tags = "CRITICAL" + $date = (Get-Date).AddDays(1).toString("yyyy-MM-ddTHH:mm:ss.fffZ") + } + else + { + $date = (Get-Date).AddDays(3).toString("yyyy-MM-ddTHH:mm:ss.fffZ") + } + $body = + @{ + codInst = "EgalWare" + codApp = $env:MACH_NAME + uplAppId = "UpdateManager" + masterKey = $LiMan_Key + tipo = "Machine" + versNum = $env:MACH_VERS_NUM + versText = $env:MACH_VERS + releaseDate = $date + relTags = $tags + } + $jsonBody = ConvertTo-Json -InputObject $body + echo $jsonBody + Invoke-WebRequest -Method Post -URI $env:URL_VERSIONS_LOG -ContentType "application/json" -Body $jsonBody -UseBasicParsing + + +# helper esecuzione test +.RunTest: &RunTest + - | + Write-Output "Test done!" + + +stages: + - build +# - test +# - deploy + +LuaCompile:build: + stage: build + only: + - main + - master + tags: + - win + before_script: + - *machName-fix + - *version-fix + - *folder-fix + script: + - *CreateBaseFolder + - *LuaCompile + - *ZipClean + - *ReplicaR + - *ReplicaStor01 + - *SendToVersionsLog + +LuaCompileDev:build: + stage: build + only: + - develop + tags: + - win + before_script: + - *machName-fix + - *version-fix_DEV + - *folder-fix + script: + - *CreateBaseFolder + - *LuaCompile + - *ZipClean + - *ReplicaR_DEV + +# LuaCompile:test: +# stage: test +# needs: ["LuaCompile:build"] +# only: +# - main +# - master +# - develop +# tags: +# - win +# before_script: +# - *version-fix +# - *folder-fix +# script: +# - *LuaCompile +# - *RunTest + +# LuaCompile:deploy: +# stage: deploy +# needs: ["LuaCompile:test"] +# only: +# - main +# - master +# tags: +# - win +# before_script: +# - *version-fix +# - *folder-fix +# script: +# - *LuaCompile +# - *ZipClean +# - *ReplicaR + diff --git a/Beam/BeamData.lua b/Beam/BeamData.lua new file mode 100644 index 0000000..75cd18c --- /dev/null +++ b/Beam/BeamData.lua @@ -0,0 +1,248 @@ +-- BeamData.lua by Egaltech s.r.l. 2023/05/12 +-- Raccolta dati generali per Travi + +EgtOutLog( ' PF1500rl-BeamData started') + +-- Tabella per definizione modulo +local BeamData = { + RIGHT_LOAD = true, -- flag carico da destra + SIMUL_VIEW_DIR = 1, -- direzione di vista predefinita per la simulazione (1=NW, 2=SW, 3=NE, 4=SE) + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 1500, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo piccolo + MAX_RAW = 20000, -- 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) + MIN_JOIN_S = 100, -- minima presa pinza per pezzo piccolo + MIN_JOIN_L = 450, -- minima presa pinza per pezzo grande + MINRAW_S = 980, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1680, -- minimo grezzo in coda scaricabile per sezioni grandi + CHAR_EXTRA_DIST = 400, -- distanza aggiuntiva per minimizzare scambi di carrelli + CHAR_LOAD_DIST = 3000, -- distanza suggerita di presa della pinza dalla testa trave al carico + MAX_LEN_SCRAP = 150, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 150, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 185, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = 185, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 610, -- altezza minima di trave alta + OVM_CHAIN_HBEAM = 8, -- sovramateriale per split con sega a catena + MAX_DIM_DICE = 155, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto + DECR_VERT_CUT = 25, -- riduzione profondità per affondamento verticale in taglio orizzontale + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 28, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 2, -- affondamento extra ridotto per tagli di lama e fresature + CUT_VZ_MIN = -0.484, -- componente limite in Z del versore di un taglio (-61deg) + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-30deg) + 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 = 2550.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 1500, -- lunghezza lavoro estremi iniziale e finale + LONGCUT_MAXLEN = 3000, -- lunghezza massima sezione di taglio longitudinale + MAX_LEN_RIDGELAP_FROM_BOTTOM = 0, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 0, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 0, -- larghezza minima trave per inserimento codolo nel centro della trave; 0 = automatico + DIM_STRIP = -1, -- dimensione codolo sostegno parti lasciate su contorno libero o archi + DIM_STRIP_SMALL = 2, -- 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 = 600, -- massima lunghezza ingombro 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 = 600, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + MIN_LEN_LAMELLO = 1000, -- lunghezza minima di fessura longitudinale per lavorazione tipo lamello (SideMillAsBlade) + PRESS_ROLLER = true, -- dichiarazione presenza rulli pressori + C_SIMM = true, -- dichiarazione simmetria mensola asse C + C_SIMM_ENC = 180, -- ingombro semi-forcella in X da naso mandrino (compresa sicurezza) + DOWN_HEAD = true, -- dichiarazione presenza seconda testa dal basso + DH_MAX_TOP = 370, -- quota massima raggiungibile dalla testa da sotto dal sotto del pezzo + KIOTP = 2, -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare + MAXDIAM_POCK_CORNER = 30, -- diametro massimo utensile ammesso per tasche con angoli interni + USE_LONGCUT = true, -- per i tagli longitudinali usare solo la lavorazione di lama LongCut + 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) + DOUBLE_HEAD_DOVETAIL = true, -- flag abilitazione lavorazione mortase a coda di rondine in doppio + DOUBLE_HEAD_MORTISE = true, -- flag abilitazione lavorazione mortase in doppio + DOUBLE_HEAD_DRILLING = true -- flag abilitazione forature in doppio +} + +--------------------------------------------------------------------- +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1500rl.data" +local sDataBeam = EgtGetCurrMachineDir().."\\Beam\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sDataBeam) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sDataBeam) then + local Machine = dofile( sDataBeam) + if Machine then + if Machine.Offsets then + if Machine.Offsets.DOUBLE_HEAD_DOVETAIL then BeamData.DOUBLE_HEAD_DOVETAIL = ( Machine.Offsets.DOUBLE_HEAD_DOVETAIL == 1) end + if Machine.Offsets.DOUBLE_HEAD_MORTISE then BeamData.DOUBLE_HEAD_MORTISE = ( Machine.Offsets.DOUBLE_HEAD_MORTISE == 1) end + if Machine.Offsets.DOUBLE_HEAD_DRILLING then BeamData.DOUBLE_HEAD_DRILLING = ( Machine.Offsets.DOUBLE_HEAD_DRILLING == 1) end + BeamData.MINRAW_S = max( BeamData.MINRAW_S, Machine.Offsets.MINRAW_S or BeamData.MINRAW_S) + BeamData.MINRAW_L = max( BeamData.MINRAW_L, Machine.Offsets.MINRAW_L or BeamData.MINRAW_L) + BeamData.CUT_EXTRA = Machine.Offsets.CUT_EXTRA or BeamData.CUT_EXTRA + BeamData.CUT_EXTRA_MIN = Machine.Offsets.CUT_EXTRA_MIN or BeamData.CUT_EXTRA_MIN + BeamData.DIM_STRIP_SMALL = Machine.Offsets.DIM_STRIP_SMALL or BeamData.DIM_STRIP_SMALL + BeamData.DIM_TO_CENTER_STRIP = Machine.Offsets.DIM_TO_CENTER_STRIP or BeamData.DIM_TO_CENTER_STRIP + BeamData.MAXDIAM_POCK_CORNER = Machine.Offsets.MAXDIAM_POCK_CORNER or BeamData.MAXDIAM_POCK_CORNER + end + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.XMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.XMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + if Machine.User then + BeamData.OFFSET_DRILL_TENON = Machine.User.L040_OFFSET_P1 or BeamData.OFFSET_DRILL_TENON + 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 + end + end +end + +--------------------------------------------------------------------- +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 + +--------------------------------------------------------------------- +local function GetBottomToolMaxTotLen( vtDir) + return 310 +end +BeamData.GetBottomToolMaxTotLen = GetBottomToolMaxTotLen + +--------------------------------------------------------------------- +local function GetSectionCoeff( dW, dH, dL) + local SEZ_L = 80000 + local SEZ_S = 20000 + local LEN_SMALL = 2000 + local dSez = dW * dH + if dSez <= SEZ_S then + return 0.0 + elseif dSez < SEZ_L then + if dL and dL < LEN_SMALL then dSez = max( 0.6 * dSez, SEZ_S) end + local dCoeff = ( dSez - SEZ_S) / ( SEZ_L - SEZ_S) + return dCoeff + else + return 1.0 + end +end + +--------------------------------------------------------------------- +local function GetMinJoin( dW, dH, dL) + local dCoeff = GetSectionCoeff( dW, dH, dL) + return ( 1 - dCoeff) * BeamData.MIN_JOIN_S + dCoeff * BeamData.MIN_JOIN_L +end +BeamData.GetMinJoin = GetMinJoin + +--------------------------------------------------------------------- +local function GetMinUnloadableRaw( dW, dH) + local dCoeff = GetSectionCoeff( dW, dH) + return ( 1 - dCoeff) * BeamData.MINRAW_S + dCoeff * BeamData.MINRAW_L +end +BeamData.GetMinUnloadableRaw = GetMinUnloadableRaw + +--------------------------------------------------------------------- +local function GetBlockedAxis( sHead, nToolType, sBlockedAxis) + -- lama + if nToolType == MCH_TY.SAW_STD or nToolType == MCH_TY.SAW_FLAT then + return '' + -- sega a catena + elseif nToolType == MCH_TY.MORTISE_STD then + if sHead == 'H13' then + if sBlockedAxis == 'parallel' then + return 'A1=0' + elseif sBlockedAxis == 'perpendicular' then + return 'A1=90' + end + else + return '' + end + -- fresa + elseif nToolType == MCH_TY.MILL_STD or nToolType == MCH_TY.MILL_NOTIP then + return '' + -- punta + elseif nToolType == MCH_TY.DRILL_STD or nToolType == MCH_TY.DRILL_LONG then + return '' + else + return '' + end +end +BeamData.GetBlockedAxis = GetBlockedAxis + +--------------------------------------------------------------------- +local function GetSetupInfo( sHead) + local SetupInfo = {} + + -- dati comuni + SetupInfo.bIsCSymmetric = true + SetupInfo.dCAxisEncumbrance = 180 + SetupInfo.bToolOnAggregate = false + + -- testa 5 assi da sopra + if sHead == 'H11' then + SetupInfo.bIsTopHead = true + SetupInfo.bIsBottomHead = not SetupInfo.bIsTopHead + SetupInfo.dMaxNegativeAngle = sin( -35) + -- lama su aggregato testa 5 assi da sopra + elseif sHead == 'H12' then + SetupInfo.bIsTopHead = true + SetupInfo.bIsBottomHead = not SetupInfo.bIsTopHead + SetupInfo.dMaxNegativeAngle = sin( -35) + -- seconda lama su aggregato testa 5 assi da sopra + elseif sHead == 'H16' then + SetupInfo.bIsTopHead = true + SetupInfo.bIsBottomHead = not SetupInfo.bIsTopHead + SetupInfo.dMaxNegativeAngle = sin( -35) + -- motosega + elseif sHead == 'H13' then + SetupInfo.bIsTopHead = true + SetupInfo.bIsBottomHead = not SetupInfo.bIsTopHead + SetupInfo.dMaxNegativeAngle = 0 + -- testa 5 assi da sotto + elseif sHead == 'H21' then + SetupInfo.bIsBottomHead = true + SetupInfo.bIsTopHead = not SetupInfo.bIsBottomHead + SetupInfo.dMaxPositiveAngle = sin( 25) + -- lama su aggregato testa 5 assi da sotto + elseif sHead == 'H22' then + SetupInfo.bIsBottomHead = true + SetupInfo.bIsTopHead = not SetupInfo.bIsBottomHead + SetupInfo.dMaxPositiveAngle = sin( 25) + end + + return SetupInfo +end +BeamData.GetSetupInfo = GetSetupInfo + +--------------------------------------------------------------------- +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/GetTs3Data.lua b/Beam/GetTs3Data.lua new file mode 100644 index 0000000..b43225d --- /dev/null +++ b/Beam/GetTs3Data.lua @@ -0,0 +1,30 @@ +-- GetTs3Data.lua by Egaltech s.r.l. 2022/04/07 +-- Recupero dati da file Ts3Data.lua di macchina + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--GTSD = {} +--GTSD.TS3PATH = 'Essetre-FAST\\Ts3Data.lua' + +local sLog = 'GetTs3Data : ' .. GTSD.TS3PATH +EgtOutLog( sLog) + +if EgtExistsFile( GTSD.TS3PATH) then + local Machine = dofile( GTSD.TS3PATH) + -- Assegno valori di interesse + Offsets = Machine.Offsets + _G.Offsets = Offsets + Trave = Machine.Trave + _G.Trave = Trave + User = Machine.User + _G.User = User +end + +-- Tutto ok +GTSD.ERR = 0 + +EgtOutLog( ' +++ GetTs3Data completed') diff --git a/Beam/MachData.ini b/Beam/MachData.ini new file mode 100644 index 0000000..04a78ac --- /dev/null +++ b/Beam/MachData.ini @@ -0,0 +1,80 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,X1_NEG,-3450,MIN_X1 +2=l,X1_POS,0,MAX_X1 +3=l,PARK_X1,-250,--- +4=l,Z1_NEG,-1565,MIN_Z1 +5=l,Z1_POS,0,MAX_Z1 +6=l,PARK_Z1,-545,PARK_Z1 +7=l,PARK_SAWZ1,-150,--- +8=d,B1_NEG,-127.0,MIN_B1 +9=d,B1_NEG1,-119.0,MIN_B1_SAW +10=d,B1_POS,127.0,MAX_B1 +11=d,B1_POS1,119.0,MAX_B1_SAW +12=d,PARK_B1,-90.0,--- +13=d,PARK_SAWB1,0.0,--- +14=d,C1_NEG,-275.0,MIN_C1 +15=d,C1_POS,275.0,MAX_C1 +16=d,PARK_C1,-90.0,--- +17=d,PARK_SAWC1,-90.0,--- +18=l,PIVOT_T1,170.02,PIVOT_HEAD1 +19=l,X2_NEG,-2950,MIN_X2 +20=l,X2_POS,0,MAX_X2 +21=l,PARK_X2,-70,--- +22=l,Z2_NEG,-880,MIN_Z2 +23=l,Z2_POS,0,MAX_Z2 +24=l,PARK_Z2,0,PARK_Z2 +25=d,B2_NEG,-127.0,MIN_B2 +26=d,B2_NEG1,-119.0,--- +27=d,B2_POS,127.0,MAX_B2 +28=d,B2_POS1,119.0,--- +29=d,PARK_B2,-90.0,--- +30=d,C2_NEG,-275.0,MIN_C2 +31=d,C2_POS,275.0,MAX_C2 +32=d,PARK_C2,-90.0,--- +33=l,PIVOT_T2,169.93,PIVOT_HEAD2 +34=l,MIN_Y1,378,MIN_Y1 +35=l,MAX_Y1,5771,MAX_Y1 +36=l,PARK_Y1,1036,PARK_Y1 +37=l,MIN_V1,10,MIN_V1 +38=l,MAX_V1,670,MAX_V1 +39=l,MIN_Y2,-5773,MIN_Y2 +40=l,MAX_Y2,-378,MAX_Y2 +41=l,PARK_Y2,-1036,PARK_Y2 +42=l,MIN_V2,-670,MIN_V2 +43=l,MAX_V2,-10,MAX_V2 +44=l,MIN_DELTAVY,391,MIN_DELTAVY +45=l,DIST_FTZERO,2206.1,CARICO_Y +46=l,DELTA_CARICZERO,45,OFFSET_RIB +47=l,DIST_UNLOAD,-2250,UNLOAD_Y +48=d,OFFSETBLAMAT1,0,OFFSET B SAW1 +49=d,OFFSETCLAMAT1,0,OFFSET C SAW1 +50=d,OFFSETBLAMAT2,0,OFFSET B SAW2 +51=d,OFFSETCLAMAT2,0,OFFSET C SAW2 +52=l,OFFSETXT1,-1178.6,OFFSET_X_HEAD1 +53=l,OFFSETZT1,-1243.7,OFFSET_Z_HEAD1 +54=l,OFFSETXT2,-2460.3,OFFSET_X_HEAD2 +55=l,OFFSETZT2,-444.0,OFFSET_Z_HEAD2 +56=l,OFFSETZSOTTOTRAVE,1005,OFFSET_Z_SOTTOTRAVE +57=d,SECONDSAW,1,SECOND_SAW +58=d,DOUBLE_HEAD_DOVETAIL,1,DT_MORTISE_IN_DOUBLE +59=d,DOUBLE_HEAD_POCKET,1,POCKET_IN_DOUBLE +60=d,DOUBLE_HEAD_DRILLING,1,DRILLING_IN_DOUBLE + +[2] +Name=Trave +1=l,XMIN,30,XMIN +2=l,XMAX,1250,XMAX +3=l,ZMIN,30,ZMIN +4=l,ZMAX,400,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..5267cc1 --- /dev/null +++ b/Beam/MachiningTypes.ini @@ -0,0 +1,62 @@ +[Cut] +1=HeadSide +2=HeadSide_H2 +3=TailSide +4=TailSide_H2 +5=LongCut + +[Drill] +1=Drill +2=Drill_H2 +3=Pocket +4=Pocket_H2 +5=Predrill +6=Predrill_H2 + +[Milling] +1=Prof +2=Prof_H2 +3=FreeContour +4=FreeContour_H2 +5=Tenon +6=Tenon_H2 +7=DtTenon +8=DtTenon_H2 +9=DtMortise +10=DtMortise_H2 +11=BirdsMouth +12=BirdsMouth_H2 +13=Chamfer +14=Mark +15=Mark_H2 +16=Text +17=Text_H2 +18=Decor01 +19=Long2Cut +20=Long2Cut_H2 +21=Long2CutDown +22=Long2CutDown_H2 +23=LongSmallCut +24=LongSmallCut_H2 +25=BHSideMill +26=CleanCorner +27=ProfTCone +28=Long2CutSide +29=Long2CutSide_H2 +30=SmallToolContour +31=SmallToolContour_H2 +32=AntiSplintMillCut +33=AntiSplintMillCut_H2 +34=SideMillAsBlade +35=SideMillAsBlade_H2 + +[Pocketing] +1=Pocket +2=Pocket_H2 +3=OpenPocket +4=OpenPocket_H2 +5=Mortise +6=Mortise_H2 + +[Sawing] +1=Sawing diff --git a/Beam/NestingData.ini b/Beam/NestingData.ini new file mode 100644 index 0000000..7b69376 --- /dev/null +++ b/Beam/NestingData.ini @@ -0,0 +1,3 @@ +[BEAM] +StartOffset=0 +Offset=0 diff --git a/Beam/Ts3Data_KO.lua b/Beam/Ts3Data_KO.lua new file mode 100644 index 0000000..7322182 --- /dev/null +++ b/Beam/Ts3Data_KO.lua @@ -0,0 +1,80 @@ +local Offsets = { + X1_NEG=-3675, + X1_POS=0, + PARK_X1=-250, + Z1_NEG=-1565, + Z1_POS=0, + PARK_Z1=-535, + PARK_SAWZ1=-150, + B1_NEG=-127, + B1_NEG1=-119, + B1_POS=127, + B1_POS1=119, + PARK_B1=-90, + PARK_SAWB1=0, + C1_NEG=-275, + C1_POS=275, + PARK_C1=-90, + PARK_SAWC1=-90, + PIVOT_T1=170.02, + X2_NEG=-3195, + X2_POS=0, + PARK_X2=-70, + Z2_NEG=-975, + Z2_POS=0, + PARK_Z2=-10, + B2_NEG=-127, + B2_NEG1=-119, + B2_POS=127, + B2_POS1=119, + PARK_B2=-90, + C2_NEG=-275, + C2_POS=275, + PARK_C2=-90, + PIVOT_T2=169.93, + MIN_Y1=378, + MAX_Y1=5771, + PARK_Y1=1036, + MIN_V1=10, + MAX_V1=670, + MIN_Y2=-5773, + MAX_Y2=-378, + PARK_Y2=-1036, + MIN_V2=-670, + MAX_V2=-10, + MIN_DELTAVY=375, + DIST_FTZERO=2224.25, + DELTA_CARICZERO=45, + DIST_UNLOAD=-2250, + OFFSETBLAMAT1=0, + OFFSETCLAMAT1=0, + OFFSETBLAMAT2=0, + OFFSETCLAMAT2=0, + OFFSETXT1=-1174.22, + OFFSETZT1=-1248.99, + OFFSETXT2=-2713.59, + OFFSETZT2=-528.29, + OFFSETZSOTTOTRAVE=1005, + SECONDSAW=1, + DOUBLE_HEAD_DOVETAIL=1, + DOUBLE_HEAD_MORTISE=1, + DOUBLE_HEAD_DRILLING=1, +} + +local Trave = { + XMIN=30, + XMAX=1500, + ZMIN=30, + ZMAX=400, +} + +local User = { + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L020_DIAM_HOLE=12, + L040_OFFSET_P1=0, +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/Common_PF1250.TPA.mlpe b/Common_PF1250.TPA.mlpe new file mode 100644 index 0000000..bf1a1e6 --- /dev/null +++ b/Common_PF1250.TPA.mlpe @@ -0,0 +1,2974 @@ +-- Processore macchina Essetre-PF1250 by Egalware s.r.l. 2024/01/22 +-- Con controllo numerico TPA + +-- Carico libreria +local BD = require( 'BeamData') + +-- Variabili di modulo +local CSP_INFO = INFO_STD_PP.NAME..' ver.'..INFO_STD_PP.VERSION..' by EgalWare s.r.l.' +local MACHINE_INFO = MACH_NAME..' ver.'..PP_VER + +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < MIN_MACH_VER then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum EgtMachKernel '..MIN_MACH_VER..')') + end + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + 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.FMAXPINZE = 116000 -- feed massima pinze + SetToParkLine() -- si inizia con linee da parcheggiare su stack +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- aggiungo prefisso per commentae commenti iniziali se la macchina è utilizzata per fare i test + local sPrefixCommentLine = '' ; if IS_TEST_MACHINE or EgtEndsWith( EgtGetCurrMachineDir(), '.TEST') then sPrefixCommentLine = '//' end + + -- Intestazioni + if EMT.INFO then + MyOutput( sPrefixCommentLine..'('..EMT.INFO..')') + else + MyOutput( '(Program Start)') + end + MyOutput( sPrefixCommentLine..'('.. CSP_INFO..')') + MyOutput( sPrefixCommentLine..'('.. MACHINE_INFO..')') + + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + MyOutput( 'M199') + end + -- Dichiaro inizio + EMT.FIRST = true + -- Inizializzazioni varie + MyOutput( 'G49') + -- Inizio lista utensili + MyOutput( 'M993 (Tool List Start)') + -- Dichiaro cabine con rulli in posizione di parcheggio + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + MyOutput( 'M05') + -- Emissione scarico + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'R' then + EmitMoveDataChars( { Y1=ParkY1, Y2=ParkY2, V1=ParkV1, V2=ParkV2, BeamVise=0, MoveType=3}) + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'U' then + EmitMoveStartChars( EgtIf( EMT.CHY_ON, 3, 2)) + EmitMoveWaitChars( EgtIf( EMT.CHY_ON, 3, 2), true) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + MyOutput( 'M202') + MyOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile + -- lama su aggregato da sotto + if EMT.HEAD == 'H22' then + -- recupero posizione lama + local dPosBase = tonumber( AdjustTcPos( false, EMT.TCPOS, 0)) + dAddLen = SawUnderOffsZ + local sData = ' P2=' .. EmtLenToString( dAddLen + EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( dAddLen + EMT.TTOTLEN, 3) + MyOutput( 'M992 P1='..tostring( dPosBase).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+1).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+2).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+3).. sData) + -- altri utensili tranne sega a catena + elseif EMT.HEAD ~= 'H13' then + local dAddLen = 0 + if EMT.HEAD == 'H12' then + dAddLen = -SawOffsZ + elseif EMT.HEAD == 'H16' then + dAddLen = -Saw2OffsZ + end + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( dAddLen + EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( dAddLen + EMT.TTOTLEN, 3) + MyOutput( sOut) + -- emissione dati sega a catena + else + -- recupero posizione motosega + local dPosBase = tonumber( AdjustTcPos( false, EMT.TCPOS, 0)) + if EMT.TDIST and abs( EMT.TDIST) < 0.1 then EMT.TDIST = nil end + local sData = ' P2=' .. EmtLenToString( ( EMT.TDIST or ChSawLen), 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ( EMT.TDIST or ChSawLen), 3) + MyOutput( 'M992 P1='..tostring( dPosBase).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+1).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+2).. sData) + MyOutput( 'M992 P1='..tostring( dPosBase+3).. sData) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione, se impostati + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EMT.TPOS + EMT.Y1POS = EgtGetInfo( EMT.DISPID, 'Y1POS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + MyOutput( 'G990 (Tool List End)') + MyOutput( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinMchY1, 2)..' P3='..EmtLenToString( MaxY1, 2).. + ' P4='..EmtLenToString( MinY2, 2)..' P5='..EmtLenToString( MaxMchY2, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( Mill2Offs, 2)..' P8='..EmtLenToString( ParkMchY1, 2)..' P9='..EmtLenToString( ParkMchY2, 2).. + ' P10='..EmtLenToString( -TurnerOffs, 2)..' P11='..EmtLenToString( MinV1, 2)..' P12='..EmtLenToString( MaxV1, 2).. + ' P13='..EmtLenToString( MinV2, 2)..' P14='..EmtLenToString( MaxV2, 2).. + ' P15='..EmtLenToString( -DeltaTabY, 2)..' P16='..EmtLenToString( DeltaTabZ - MillOffs, 2).. + ' P17='..EmtLenToString( Delta2TabY, 2)..' P18='..EmtLenToString( -Delta2TabZ - Mill2Offs, 2) + -- se è in configurazione a 3 teste + if EgtGetHeadId( 'H31') then + sOut = sOut .. ' P19='..EmtLenToString( -Delta3TabY, 2)..' P20='..EmtLenToString( Delta3TabZ - Mill3Offs, 2).. + ' P21='..EmtLenToString( Mill3Offs, 2).. ' P22='.. EmtLenToString( -ParkInLavZ2, 2) + else + sOut = sOut .. ' P22='..EmtLenToString( -MinZ2, 2) + end + + MyOutput( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + 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 + -- gruppo con info da BTL + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + local HBarra = EMT.HB + local SBarra = EMT.SB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local TempAccPinze, TempMinAccPinze, RidFeed = CalcDinamicaPinze( HTrave, STrave, LBarra) + local TempAccPinz1, TempMinAccPinz1, RidFeed1 = CalcDinamicaPinze( HTrave, STrave, LBarra - LTrave) + local TempAccPinz2, TempMinAccPinz2, RidFeed2 = CalcDinamicaPinze( HTrave, STrave, LTrave) + local ForzaPinze = CalcForzaPinze( HTrave, STrave, LBarra, LTrave) + if IdTrave >= 0 then + local sRem = ' SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' ' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + if EMT.PARTTYPE ~= 1 then + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + else + EMT.CUTID = -1 + end + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + EmitRemark( sRem) + if not TEST_USE then MyOutput( sStart) end + else + EmitRemark( 'REMAIN UNLOAD') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( max( HTrave, HBarra), 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) .. + ' P7=' .. EgtNumToString( TempAccPinze, 2) .. ' P8=' .. EgtNumToString( TempAccPinz2, 2) .. ' P9=' .. EgtNumToString( TempAccPinz1, 2) .. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + -- su macchine vecchie non si poteva settare forza pinzaggio. Parametro da attivare in MLDE + if EmitAccClamps then + sOut = sOut .. ' P11=' .. EgtNumToString( ForzaPinze, 2) .. ' P12=' .. EgtNumToString( ForzaPinze, 2) + end + MyOutput( sOut) + if EMT.LOAD then + SetStartValue( 1, LBarra) + SetStartValue( 2, max( HTrave, HBarra)) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( 0) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) .. + ' P7=' .. EgtNumToString( TempAccPinze, 2) .. ' P8=' .. EgtNumToString( TempAccPinz2, 2) .. ' P9=' .. EgtNumToString( TempAccPinz1, 2).. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + -- su macchine vecchie non si poteva settare forza pinzaggio. Parametro da attivare in MLDE + if EmitAccClamps then + sOut = sOut .. ' P11=' .. EgtNumToString( ForzaPinze, 2) .. ' P12=' .. EgtNumToString( ForzaPinze, 2) + end + MyOutput( sOut) + -- determino la quota di parcheggio della trave + local ParkT = GetParkT() + -- aggiorno dati aggancio carrelli alla trave + EMT.Y1DELTA = EMT.Y1POS - ParkT + EMT.Y2DELTA = nil + EmitBeamHeadData( { T=ParkT, Y1=EMT.Y1POS, SetHead=1, F=0}) + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( 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 + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- rotazione automatica o manuale (sempre con il medesimo comando) + local sOut = 'M180 P1=' .. tostring( -nDeltaRot) + MyOutput( sOut) + -- 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 + if #EMT.MDCHAR > 0 then + EmitRemark( 'PART UNLOAD') + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + if EMT.MDCHAR[i].Y1 then EMT.CHY_ON = true end + end + if #EMT.MDCHAR > 0 then + local nMoveType = EgtIf( EMT.CHY_ON, 3, 2) + EmitMoveStartChars( nMoveType) + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( nMoveType) + else + EmitMoveWaitChars( nMoveType, true) + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = 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 + EMT.HB = 0 + EMT.SB = 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 + local HBarra = b3Raw:getDimY() + EMT.HB = max( EMT.HB, HBarra) + local SBarra = b3Raw:getDimZ() + EMT.SB = max( EMT.SB, SBarra) + 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 + EMT.PARTTYPE = 0 + local sMaterial = EgtGetInfo( PartId, 'MATERIAL') + if sMaterial and sMaterial:find( 'CLT-', 1, true) == 1 then + EMT.PARTTYPE = 1 + elseif sMaterial and sMaterial:find( 'UT-', 1, true) == 1 then + EMT.PARTTYPE = 2 + end + 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.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 + EMT.TUSERNOTES = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.MCHCUT = ( EMT.MCHUSERNOTES:find( 'Cut;', 1, true) ~= nil) + + -- se sega a catena, aggiusto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = GetCurrChainSawingVirtualAxis() + -- imposto home dell'asse C1 (A=0 -> T101, A=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA, EMT.TTOTLEN) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + -- se lama su aggregato testa sotto, aggiusto subito angolo scelto per asse virtuale A + elseif EMT.HEAD == 'H22' then + -- valore dell'asse virtuale + local dPrevA = dPosA + dPosA = GetCurrSawingVirtualAxis() + -- imposto home dell'asse C2 (A=0 -> T201, A=90 -> T204) + local MyParkCSawC2 = GetSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C2', MyParkCSawC2) + -- se lavorazione attuale e precedente con lama su aggregato da sotto con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == EMT.PREVHEAD_H2 then + if abs( dPosA - dPrevA) > 1 then + EMT.TO_ZMAX = true + EMT.R3_CHANGED = true + end + end + end + + -- gestione eventuale lavorazione in doppio + local nDouType = EgtGetValInNotes( EMT.MCHUSERNOTES, 'DOUBLE', 'i') + if nDouType == 2 or nDouType == 3 then + local sDouTool = EgtGetValInNotes( EMT.MCHUSERNOTES, 'TOOLDOUBLE', 's') or EgtGetValInNotes( EMT.TUSERNOTES, 'DOUBLE', 's') or '' + local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if EgtTdbSetCurrTool( sDouTool) and EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) then + -- salvo dati + EMT.DOU_TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.DOU_TYPE = nDouType + EMT.DOU_TOOL = sDouTool + EMT.DOU_HEAD = 'H21' + EMT.DOU_EXIT = 1 + EMT.DOU_TPOS = AdjustTcPos( false, EgtTdbGetCurrToolParam( MCH_TP.TCPOS)) + EMT.DOU_SPEED = EgtTdbGetCurrToolParam( MCH_TP.SPEED) + -- non va in sicurezza testa in doppio + EMT.DOU_TO_ZMAX = nil + else + EmtSetLastError( 1211, 'Missing or not active double tool of '..sOldTool) + end + EgtTdbSetCurrTool( sOldTool) + end + -- se testa in doppio ancora da rimettere in sicurezza + if EMT.DOU_TO_ZMAX then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, false) + EmitDouZMax( EMT.DOU_TO_ZMAX) + end + -- controllo seguente trovato nella 3T. Da verificare + -- 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() + --MyOutput( ';Mach End') + -- Emissione split + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitRemark( 'PART SPLIT') + EMT.LB = EMT.LT + elseif EMT.AUXTYPE == 'U' then + EmitRemark( 'PART UNLOAD') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART ROTATION') + elseif EMT.FALL then + if EMT.TO_ZMAX and not EMT.ZMAX then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EMT.TO_ZMAX = nil + end + EmitRemark( 'PART FALL') + else + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART SPLIT 2') + end + end + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 1) + EmitMoveWaitChars( 1) + elseif EMT.AUXTYPE == 'U' then + local nMoveType = EgtIf( EMT.CHY_ON, 3, 2) + EmitMoveStartChars( nMoveType) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( nMoveType) + else + EmitMoveWaitChars( nMoveType, true) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + if EMT.FALL then + MyOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif not EMT.PREROT then + MyOutput( 'M77') + end + end + end + -- Reset + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.TO_ZMAX = nil + EMT.PREVTOOL = EMT.TOOL + if EMT.DOU_TYPE and not EMT.ZMAX then EMT.DOU_TO_ZMAX = EMT.DOU_TYPE end + EMT.DOU_TYPE = nil + -- se taglio finale, aggiorno lunghezza barra + if EMT.MCHCUT then + EMT.LB = EMT.LT + ( EMT.X_OFF or 0) + end + -- salvo dati utensile + local nSetHead = GetHeadSet( EMT.HEAD) + -- per gruppo testa 1 + if nSetHead == 1 then + EMT.PREVTOOL_H1 = EMT.TOOL + EMT.PREVHEAD_H1 = EMT.HEAD + EMT.PREVTCPOS_H1 = EMT.TCPOS + --EMT.PREVTCPOSREAL_H1 = EMT.TCPOSREAL + -- per gruppo testa 2 + elseif nSetHead == 2 then + EMT.PREVTOOL_H2 = EMT.TOOL + EMT.PREVHEAD_H2 = EMT.HEAD + EMT.PREVTCPOS_H2 = EMT.TCPOS + --EMT.PREVTCPOSREAL_H2 = EMT.TCPOSREAL + end +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- leggo se ancora presa iniziale carrello + --EMT.CNT = EgtGetInfo( EMT.PATHID, 'CNT', 'i') + --MyOutput( 'CNT='.. tostring( EMT.CNT or 0)) + -- se utensile non cambiato, salvo eventuali precedenti rotanti + if EMT.TOOL == EMT.PREVTOOL and not EMT.ZMAX then + EMT.L2pp = EMT.L2op + EMT.L3pp = EMT.L3op + EMT.R1pp = EMT.R1p + EMT.R2pp = EMT.R2p + else + EMT.L2pp = nil + EMT.L3pp = nil + EMT.R1pp = nil + EMT.R2pp = nil + end + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.MDCHAR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + EmitResetMachining() + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.MDCHAR = {} + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- salvo il comando per processarlo successivamente + table.insert( EMT.AUXCMD, EMT.AUX) + -- gestione speciale per richiesta di movimento a ZMAX + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '4' then + EMT.TO_ZMAX = true + end +end + +--------------------------------------------------------------------- +function ProcessPathStartAux( sCmd, nInd) + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( sCmd, nInd, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( sCmd, nInd) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( sCmd, nInd) + 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' + 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' + 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, EMT.AUXIND, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX, EMT.AUXIND) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX, EMT.AUXIND) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- gruppo della testa + local nHSet = GetHeadSet( EMT.HEAD) + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + local HomeZ1 = EgtGetAxisHomePos( 'Z1') + local HomeR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + local HomeR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + local PrevR1 = EMT.R1p or EMT.R1pp or HomeR1 + local PrevR2 = EMT.R2p or EMT.R2pp or HomeR2 + EmtResetPrev() + -- se prima lavorazione + if EMT.LOAD then + EMT.V2POS = ParkV2 + -- primo posizionamento + local Speed = EMT.S + if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' or EMT.HEAD == 'H22' then Speed = 1.65 * EMT.S end + local bOnlyCharY = true + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + -- se Split e non Caduta lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + local bFall = ( bSplitCut and FindFallAtEndAux( EMT.PATHID)) + if ( bSplitCut and not bFall and #EMT.MDCHAR > 0) then + EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = 1 + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + if EMT.MDCHAR[i].MovType ~= 1 then bOnlyCharY = false end + end + EMT.MDCHAR = {} + EmitMoveStartChars( EgtIf( bOnlyCharY, 1, 3)) + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- se testa 1 + if nHSet == 1 then + -- selezione testa (posso muovere X solo a Zmax) + local MyMaxZ1 = EgtGetAxisMax( 'Z1') + -- in caso di rotazione della lama lontano dalla posizione di home degli assi rotanti + local bXSpec = EgtIf( BD.RIGHT_LOAD, ( EMT.L2 > -DeltaTabY), ( EMT.L2 < -DeltaTabY)) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=MyMaxZ1, S=Speed}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( PrevR1 - EMT.R1) > 1 or abs( PrevR2 - EMT.R2) > 1) and ( abs( HomeR1 - EMT.R1) > 30.1 or abs( HomeR2 - EMT.R2) > 30.1) then + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=MyMaxZ1, B=ParkB1, C=ParkC1, S=Speed}) + else + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=MyMaxZ1, S=Speed}) + end + EmitMoveDataHead( 1, { B=0, S=Speed}) + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + EmitMoveDataHead( 1, { Z=EMT.L3, B=EMT.R2, S=Speed}) + -- caso standard + else + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + -- se sega a catena + if EMT.HEAD == 'H13' then + EmitMoveDataHead( 1, { X=-ParkCSawX1, Z=HomeZ1, B=HomeR2, C=HomeR1, TRad=dTRad, TLen=dTLen, S=Speed}) + -- utensili standard + else + -- utensili lunghi + if EMT.TTOTLEN > LongTool then + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=EMT.L3, B=ParkLongB1, C=ParkLongTc1C1, S=Speed}) + else + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=EMT.L3, B=ParkB1, C=ParkC1, S=Speed}) + end + end + end + if EMT.HEAD ~= 'H13' then + EmitMoveDataHead( 1, { Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 1, { B=EMT.R2, S=Speed}) + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + else + EmitMoveDataHead( 1, { Z=EMT.L3, B=EMT.R2, S=Speed}) + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + end + end + EmitMoveStartHead( 1) + -- se lavorazione in doppio + if EMT.DOU_TYPE == 2 then + local dX2 = Delta2TabY + EMT.DOU_TLEN - ( -DeltaTabY - EMT.L2 + EMT.TLEN + EgtIf( BD.RIGHT_LOAD, -EMT.HB, EMT.HB)) + local dZ2 = -Head2Z + MillOffs + Mill2Offs + EMT.L3 + dZ2 = min( dZ2, MinZ2) + local dC2 = EMT.R1 + local dB2 = EMT.R2 + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 2, { X=dX2, Z=MinZ2, B=ParkB2, C=ParkC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + else + EmitMoveDataHead( 2, { X=dX2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + EmitMoveDataHead( 2, { Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + elseif EMT.DOU_TYPE == 3 then + local dX2 = -Head2Y - EMT.L2 + local dZ2 = Delta2TabZ - EMT.DOU_TLEN - ( -DeltaTabZ + EMT.L3 - EMT.TLEN - EMT.SB) + dZ2 = max( dZ2, MinZ2) + local dC2 = EMT.R1 + local dB2 = EMT.R2 + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 2, { X=dX2, Z=MinZ2, B=ParkB2, C=ParkC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + else + EmitMoveDataHead( 2, { X=dX2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + EmitMoveDataHead( 2, { Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + else + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + end + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- se altrimenti testa 2 + elseif nHSet == 2 then + -- selezione testa (non posso muovere X) + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + if EMT.HEAD == 'H22' then + EmitMoveDataHead( 2, { X=ParkSawX2, Z=ParkZ2, B=0, C=ParkC2, S=Speed}) + EMT.L2pp = ParkSawX2 + else + EmitMoveDataHead( 2, { X=ParkX2, Z=ParkZ2, B=ParkB2, C=ParkC2, S=Speed}) + EMT.L2pp = ParkX2 + end + else + if EMT.HEAD == 'H22' then + EmitMoveDataHead( 2, { X=ParkSawX2, S=Speed}) + EMT.L2pp = ParkSawX2 + else + EmitMoveDataHead( 2, { X=ParkX2, S=Speed}) + EMT.L2pp = ParkX2 + end + end + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- vado a quota sicurezza in X per permettere rotazione assi rotanti + if ( not EMT.L2pp or ( EMT.L2pp and EMT.L2pp > ParkMchY2)) and ( ParkB2 ~= EMT.R2 or ParkC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { X=ParkMchY2, Z=ParkZ2, B=ParkB2, C=ParkC2, S=Speed}) + end + -- scrivo solo se gli assi rotanti sono cambiati + if EMT.HEAD == 'H22' and ( CurrB2 ~= EMT.R2 or CurrC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { B=EMT.R2, C=EMT.R1, S=Speed}) + end + if EMT.ZMAX then + EmitMoveDataHead( 2, { X=EMT.L2, B=EMT.R2, C=EMT.R1, S=Speed}) + else + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + end + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + -- altrimenti testa 3 + else + -- selezione testa (posso muovere X solo a Zmax) + local MaxZ3 = EgtGetAxisMax( 'Z3') + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 3, { X=EMT.L2, Z=MaxZ3, B=ParkB3, C=0, S=Speed}) + else + EmitMoveDataHead( 3, { X=EMT.L2, Z=MaxZ3, S=Speed}) + end + EmitMoveStartHead( 3) + EmitMoveWaitHead( 3) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- eseguo movimenti + local Speed = EMT.S + EmitMoveDataHead( 3, { Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 3, { B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 3) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 3 + EmitMoveWaitHead( 3) + end + -- dati aggancio a trave + local BhData = { T=EMT.L1, SetHead=0} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA + BhData.ViseY1 = 1 + else + BhData.Y1 = ParkY1 + BhData.ViseY1 = 2 + end + if bSplitCut and EMT.Y2DELTA then + BhData.ViseY1 = 3 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToCloseTPA() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToCloseTPA() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + local ProdId = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PRODID', 'i') or 0 + MyOutput( ';LISTA = ' .. tostring( ProdId)) + EmitParkedLines() + -- se sfrido grande, emetto comando speciale + if EMT.HOVM > 99 then + if EgtGetHeadId( 'H31') then + MyOutput( 'M107') + else + MyOutput( ';M107') + end + end + -- altrimenti lavorazione successiva + else + --MyOutput( string.format( 'V1Pos=%.3f V2Pos=%.3f', EMT.V1POS, EMT.V2POS)) + if not EMT.RELOAD and not EMT.ZMAX and #EMT.AUXCMD > 0 and EMT.TO_ZMAX then + -- caso speciale in cui bisogna solo cambiare presa aggregato lama sotto + if EMT.R3_CHANGED then + -- EmitZmax è fatta per essere chiamata con utensile attuale. In questo caso l'attuale è già quello con nuova rotazione + -- Allora salvo l'attuale e imposto il vecchio solo momentanemente, per poi ripristinarlo + local sBckTcPos = EMT.TCPOS + EMT.TCPOS = EMT.PREVTCPOSREAL_H2 + EmitZmax( false, false, PrevR1, PrevR2) + EMT.TCPOS = sBckTcPos + EMT.R3_CHANGED = nil + else + EmitZmax( false, false, PrevR1, PrevR2) + end + EMT.ZMAX = true + EMT.TO_ZMAX = nil + PrevR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + PrevR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + end + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- eventuale movimento carrelli + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + -- se Split e non Caduta lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + local bFall = ( bSplitCut and FindFallAtEndAux( EMT.PATHID)) + if ( bSplitCut and not bFall and #EMT.MDCHAR > 0) then + EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = 1 + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + local nMoveType = EgtIf( EMT.POSTROT or EMT.RELOAD, 1, 3) + EmitMoveStartChars( nMoveType) + EmitMoveWaitChars( nMoveType) + end + EMT.MDCHAR = {} + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- se taglio di coda senza residuo da scaricare + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut', 1, true) then + -- se sfrido grande, emetto comando speciale + if EMT.LB - EMT.LT > 99 then + if EgtGetHeadId( 'H31') then + MyOutput( 'M107') + else + MyOutput( ';M107') + end + end + -- emetto M175 per accelerare il carico della barra successiva + MyOutput( ';M175') + end + -- se testa 1 + if nHSet == 1 then + -- movimento testa + local HomeZ1 = EgtGetAxisHomePos( 'Z1') + local MyMaxZ1 = EgtGetAxisMax( 'Z1') + local HomeC1 = EgtGetAxisHomePos( 'C1') + local HomeB1 = EgtGetAxisHomePos( 'B1') + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12' and EMT.HEAD ~= 'H16', 1, 1.65) + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + local CurrZ1 = EMT.L3pp or MyMaxZ1 + local CurrB1 = PrevR2 + local CurrC1 = PrevR1 + -- muovo asse X + local bXSpec = EgtIf( BD.RIGHT_LOAD, ( EMT.L2 > -DeltaTabY), ( EMT.L2 < -DeltaTabY)) + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=CurrZ1, B=CurrB1, C=CurrC1, S=Speed}) + end + -- in caso di rotazione della lama lontano dalla posizione di home degli assi rotanti + if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( PrevR1 - EMT.R1) > 1 or abs( PrevR2 - EMT.R2) > 1) and ( abs( HomeC1 - EMT.R1) > 30.1 or abs( HomeB1 - EMT.R2) > 30.1) then + -- se non bisogna scrivere tutti gli assi, comunque ribadisco X in caso di lama. Altrimenti ho già scritto prima + if not WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), S=Speed}) + end + EmitMoveDataHead( 1, { Z=MyMaxZ1, B=0, S=Speed}) + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + EmitMoveDataHead( 1, { Z=EMT.L3, B=EMT.R2, S=Speed}) + -- caso standard + else + EmitMoveDataHead( 1, { Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 1, { B=EMT.R2, S=Speed}) + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + end + -- altrimenti sega a catena + else + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + local dSafeZ1 = EgtIf( EMT.TTOTLEN < MinLengthLongCSaw, ParkCSawZ1, ParkLongCSawZ1) + EmitMoveDataHead( 1, { X=-ParkCSawX1, Z=dSafeZ1, B=HomeB1, C=HomeC1, TRad=dTRad, TLen=dTLen, S=Speed}) + end + -- Porto la Z alla giusta quota + if EMT.L3 > HomeZ1 + 1 and abs( EMT.R2) > 89.9 then + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + EmitMoveDataHead( 1, { Z=HomeZ1, S=Speed}) + end + EmitMoveDataHead( 1, { Z=EMT.L3, B=EMT.R2, S=Speed}) + -- se motosega molto lunga, ruoto prima di muovermi in X + if EMT.TTOTLEN >= MinLengthLongCSaw then + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + end + end + end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + -- se lavorazione in doppio + if EMT.DOU_TYPE == 2 then + local dC2 = EMT.R1 + local dB2 = EMT.R2 + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 2, { X=SafeX2, Z=MinZ2, B=ParkB2, C=ParkC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + else + EmitMoveDataHead( 2, { X=SafeX2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + + EmitMoveDataHead( 2, { Z=-dSafeZ2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveDataHead( 2, { B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + else + local dX2 = Delta2TabY + EMT.DOU_TLEN - ( -DeltaTabY - EMT.L2 + EMT.TLEN + EgtIf( BD.RIGHT_LOAD, -EMT.HB, EMT.HB)) + local dZ2 = EgtClamp( -Head2Z + MillOffs + Mill2Offs + EMT.L3, MinZ2, MaxZ2) + EmitMoveDataHead( 2, { X=dX2, Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + elseif EMT.DOU_TYPE == 3 then + local dX2 = -Head2Y - EMT.L2 + local dZ2 = Delta2TabZ - EMT.DOU_TLEN - ( -DeltaTabZ + EMT.L3 - EMT.TLEN - EMT.SB) + dZ2 = max( dZ2, MinZ2) + local dC2 = EMT.R1 + local dB2 = EMT.R2 + if EMT.ZMAX then + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 2, { X=SafeX2, Z=-dSafeZ2, B=ParkB2, C=ParkC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + else + EmitMoveDataHead( 2, { Z=-dSafeZ2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + EmitMoveDataHead( 2, { X=dX2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + end + EmitMoveDataHead( 2, { X=dX2, Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + else + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + end + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti testa 2 + elseif nHSet == 2 then + local MyMinZ2 = EgtGetAxisMin( 'Z2') + local CurrZ2 = EMT.L3pp or MyMinZ2 + local CurrB2 = PrevR2 + local CurrC2 = PrevR1 + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H22', 1, 1.65) + if not EMT.L2pp then EMT.L2pp = EgtGetAxisHomePos( 'X2') end + -- calcolo posizione reale + EMT.TCPOSREAL = 'T' .. AdjustTcPos( false, EMT.TCPOS, EMT.R3) + -- se utensile cambiato (controllo il reale perchè per aggregato dipende come è stato caricato) + if EMT.PREVTCPOSREAL_H2 ~= EMT.TCPOSREAL then + if EMT.ZMAX then + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + if EMT.HEAD == 'H22' then + EmitMoveDataHead( 2, { X=ParkSawX2, Z=-dSafeZ2, B=0, C=CurrC2, S=Speed}) + EMT.L2pp = ParkSawX2 + else + EmitMoveDataHead( 2, { X=SafeX2, Z=-dSafeZ2, B=CurrB2, C=CurrC2, S=Speed}) + EMT.L2pp = SafeX2 + end + else + if EMT.HEAD == 'H22' then + EmitMoveDataHead( 2, { X=ParkSawX2, S=Speed}) + EMT.L2pp = ParkSawX2 + else + EmitMoveDataHead( 2, { X=SafeX2, S=Speed}) + EMT.L2pp = SafeX2 + end + end + -- scrivo solo se gli assi rotanti sono cambiati + EmitMoveDataHead( 2, { Z=-dSafeZ2, S=Speed}) + if EMT.L2pp > ParkMchY2 and ( CurrB2 ~= EMT.R2 or CurrC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { X=ParkMchY2, Z=-dSafeZ2, B=CurrB2, C=CurrC2, S=Speed}) + end + else + -- scrivo solo se gli assi rotanti sono cambiati + if EMT.L2pp > ParkMchY2 and ( CurrB2 ~= EMT.R2 or CurrC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { X=ParkMchY2, Z=-dSafeZ2, B=CurrB2, C=CurrC2, S=Speed}) + end + end + -- se stesso utensile vado già alla X di lavoro + else + -- scrivo solo se gli assi rotanti sono cambiati + if EMT.ZMAX and EMT.L2pp > ParkMchY2 and ( CurrB2 ~= EMT.R2 or CurrC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { X=ParkMchY2, Z=-dSafeZ2, B=CurrB2, C=CurrC2, S=Speed}) + end + end + -- scrivo solo se gli assi rotanti sono cambiati + if EMT.HEAD == 'H22' and ( CurrB2 ~= EMT.R2 or CurrC2 ~= EMT.R1) then + EmitMoveDataHead( 2, { B=EMT.R2, C=EMT.R1, S=Speed}) + end + if EMT.ZMAX then + EmitMoveDataHead( 2, { X=EMT.L2, B=EMT.R2, C=EMT.R1, S=Speed}) + else + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + end + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + -- altrimenti testa 3 + else + -- selezione testa (posso muovere X solo a Zmax) + local MyMaxZ3 = EgtGetAxisMax( 'Z3') + local dSafeZ3 = EgtGetAxisHomePos( 'Z3') + local HomeC3 = EgtGetAxisHomePos( 'C3') + local HomeB3 = EgtGetAxisHomePos( 'B3') + local Speed = EMT.S + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + local CurrB3 = PrevR2 + local CurrC3 = PrevR1 + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + EmitMoveDataHead( 3, { X=EMT.L2, Z=MyMaxZ3, B=CurrB3, C=CurrC3, S=Speed}) + else + EmitMoveDataHead( 3, { X=EMT.L2, Z=MyMaxZ3, S=Speed}) + end + + EmitMoveDataHead( 3, { Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + else + EmitMoveDataHead( 3, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + end + EmitMoveStartHead( 3) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 3 + EmitMoveWaitHead( 3) + end + -- dati aggancio a trave + local BhData = { T=EMT.L1} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA - ( EMT.X_OFF or 0) + BhData.ViseY1 = 1 + else + BhData.Y1 = ( EMT.Y1POS or ParkY1) + BhData.ViseY1 = 2 + end + if bSplitCut and EMT.Y2DELTA then + BhData.ViseY1 = 3 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA - ( EMT.X_OFF or 0) + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToCloseTPA() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToCloseTPA() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- se lavorazione in doppio + if EMT.DOU_TYPE == 2 then + -- aggiusto assi + EMT.L2 = -EMT.L2 + -- emetto movimenti in Zero macchina + local Speed = EMT.S + if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' or EMT.HEAD == 'H22' then Speed = 1.65 * EMT.S end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + local dX2 = Delta2TabY + EMT.DOU_TLEN - ( -DeltaTabY - EMT.L2 + EMT.TLEN + EgtIf( BD.RIGHT_LOAD, -EMT.HB, EMT.HB)) + local dZ2 = -Head2Z + MillOffs + Mill2Offs + EMT.L3 + -- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post + if dZ2 > MaxZ2 then + EmtSetLastError( 1220, EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( dZ2-MaxZ2, 2)) + end + local dC2 = EMT.R1 + local dB2 = EMT.R2 + EmitMoveDataHead( 2, { Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveDataHead( 2, { X=dX2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 e 1 + EmitMoveWaitHead( 2) + EmitMoveWaitHead( 1) + -- ripristino assi + EMT.L2 = -EMT.L2 + elseif EMT.DOU_TYPE == 3 then + -- aggiusto assi + EMT.L2 = -EMT.L2 + -- emetto movimenti in Zero macchina + local Speed = EMT.S + if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' or EMT.HEAD == 'H22' then Speed = 1.65 * EMT.S end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + local dX2 = -Head2Y - EMT.L2 + local dZ2 = Delta2TabZ - EMT.DOU_TLEN - ( -DeltaTabZ + EMT.L3 - EMT.TLEN - EMT.SB) + local dC2 = EMT.R1 + local dB2 = EMT.R2 + EmitMoveDataHead( 2, { X=dX2, Z=-dZ2, B=dB2, C=dC2, TPos=EMT.DOU_TPOS, S=EMT.DOU_SPEED}) + EmitMoveStartHead( 2) + -- aspetto esecuzione movimento testa 2 e 1 + EmitMoveWaitHead( 2) + EmitMoveWaitHead( 1) + -- ripristino assi + EMT.L2 = -EMT.L2 + end + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..GetHeadSetCode()..' P3='..EgtIf( EMT.DOU_TYPE, 2, 0)) + MyOutput( 'M98') + MyOutput( 'M6 ' .. GetHeadToolCode() .. AdjustTcPos( true)) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + -- se lavorazione in doppio controllo le corse + if EMT.DOU_TYPE == 2 then + local dZ2 = -Head2Z + MillOffs + Mill2Offs + EMT.L3 + -- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post + if dZ2 > MaxZ2 then + EmtSetLastError( 1220, EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( dZ2-MaxZ2, 2)) + end + end + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + if #sAxes > 0 then + if EmitRapidInG1 then + local sFeed = ' F30000' + MyOutput( 'G1' .. sAxes .. sFeed) + else + MyOutput( 'G0' .. sAxes) + end + end + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- se Split lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + -- porto in home la testa corrente se lavorazione successiva sopra con testa diversa oppure se punta lunga + local nNextTopHSet = GetNextTopHSet( EMT.MCHID) + local bTopGoHome = ( nHSet ~= 2 and nNextTopHSet ~= 0 and nHSet ~= nNextTopHSet) or ( nHSet == 1 and EMT.TTOTLEN > LongTool) + EmitZmax( true, true, EMT.R1p, EMT.R2p, bSplitCut, bTopGoHome) + -- aggiorno quota finale trave dopo Zmax + EMT.L1o = EMT.TPOS + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + EmtSetLastError( 1212, "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..GetHeadSetCode()..' P3='..EgtIf( EMT.DOU_TYPE, 2, 0)) + MyOutput( 'M98') + MyOutput( 'M6 ' .. GetHeadToolCode() .. AdjustTcPos( true)) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + if EmitRapidInG1 then + local sFeed = ' F30000' + sOut = 'G1'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1')..sFeed + else + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + end + + MyOutput( sOut) + -- aggiorno precedenti + EMT.MOVE = 0 + EmtUpdatePrev() + EMT.MOVE = 1 + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- se lavorazione in doppio e fondo foro, inverto movimento punta doppia + local bDouHoleBott = ( EMT.MCHTYPE == MCH_MY.DRILLING and ( EMT.DOU_TYPE == 2 or EMT.DOU_TYPE == 3) and EMT.FLAG == 101) + if bDouHoleBott then + MyOutput( "M106 P1=1") + end + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- feed + local sFeed = EmtGetFeed() + -- se da emettere + if #sAxes > 0 then + MyOutput( "G1" .. sAxes .. sFeed) + end + + -- se lavorazione in doppio e fondo foro, muovo punta 2 e poi ripristino movimento standard punta doppia + if bDouHoleBott then + if EMT.DOU_TYPE == 2 or EMT.DOU_TYPE == 3 then + local dZ = 2 * EMT.L3p - EMT.L3 + MyOutput( "G1 Z" .. EgtNumToString( dZ, 3)) + MyOutput( "G1 Z" .. EgtNumToString( EMT.L3p, 3)) + end + MyOutput( "M106 P1=2") + end + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..GetHeadSetCode()..' P3='..EgtIf( EMT.DOU_TYPE, 2, 0)) + MyOutput( 'M98') + MyOutput( 'M6 ' .. GetHeadToolCode() .. AdjustTcPos( true)) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + if EmitRapidInG1 then + local sFeed = ' F30000' + sOut = 'G1'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1')..sFeed + else + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + end + + MyOutput( sOut) + -- aggiorno precedenti + local nOriginalMove = EMT.MOVE + EMT.MOVE = 0 + EmtUpdatePrev() + EMT.MOVE = nOriginalMove + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + 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 string.len( 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, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + MyOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcDinamicaPinze( dH, dS, dL) + local MinTempoAcc = 0.6 -- [s] + local MaxTempoAcc = 6.0 -- [s] + local KgMtCubo= WoodDensity or 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 TempoAcc * 1000, MinTempoAcc * 1000, RidFeed +end + +--------------------------------------------------------------------- +function CalcForzaPinze( dH, dS, dL, dT) + local MassaRef = 1500 -- [Kg] + local dMinJoin = BD.GetMinJoin( dS, dH, dT) + if dMinJoin < 0.9 * BD.MIN_JOIN_L then + return MinForzaPinze + else + local KgMtCubo= WoodDensity or 550 -- densità legno [Kg / metro cubo] + local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg] + local Forza = Massa / MassaRef * MaxForzaPinze + return EgtClamp( Forza, MinForzaPinze, MaxForzaPinze) + end +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + else + return '-1' + end +end + +--------------------------------------------------------------------- +function CalcCharStatusN( sCmd) + -- aperto + if sCmd == '0' then + return 1 + -- chiuso + elseif sCmd == '1' then + return -1 + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, nInd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = 1 + EMT.FSY1 = EMT.ISY1 -- ??? -1 + EMT.ISY2 = 1 + EMT.FSY2 = EMT.ISY2 + EMT.BV = 0 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + -- se in riposizionamento carrelli + if #EMT.MDCHAR > 0 and EMT.MDCHAR[1].MovType == 3 then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[2] == 'Y1' then + local MoveY1 = tonumber( Cmd[3]) + TurnerOffs + local MDChar = { Y1=MoveY1, V1=ParkV1, IniStatY1=-75, FinStatY1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + SetStartValue( 4, MoveY1) + SetStartValue( 5, 110) + EMT.V1POS = ParkV1 + elseif Cmd[2] == 'T' then + local sDeltaY1 = 'Delta=' .. EgtNumToString( tonumber(Cmd[5]) - tonumber(Cmd[3]), 1) + local MDChar = { Y1=tonumber(Cmd[3]), IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1, Remark=sDeltaY1} + table.insert( EMT.MDCHAR, MDChar) + end + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + if not FindReadHeadWithLaser( EMT.MDCHAR) then + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + EMT.ROLL_OPEN = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + -- se pinza due in presa, non attivo la 1 + if EMT.BV ~= 2 then + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + end + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.UNL then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY2=1, FinStatY2=-84, BeamVise=0} + end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV1=1, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y1' then + local MDChar = { Y1=tonumber(Cmd[3]), V1=ParkV1, IniStatY1=-1, FinStatY1=-1, BeamVise=2, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = tonumber( Cmd[3]) + EMT.V1POS = ParkV1 + end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd, nInd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y2' then + -- se non è ultima fase e non è fase successiva a scarico su carico c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[3]), V2=ParkV2, IniStatY2=1, FinStatY2=-84, BeamVise=EgtIf( bBarOnY, 1, 0), MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + if Cmd[4] == 'Y2' then + -- se non è ultima fase c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[5]), IniStatY1=EgtIf( bBarOnY, -1, 1), FinStatY1=EgtIf( bBarOnY, -1, 1), IniStatY2=-1, FinStatY2=1, IniStatV2=1, BeamVise=2, MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '4' then + -- non interessa + elseif Cmd[1] == '11' then + -- non interessa + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + -- non interessa + elseif Cmd[1] == '22' then + -- non interessa ?? + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + 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 + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.PREROT then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=86, FinStatY1=87, IniStatY2=1, BeamVise=0} + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + if EMT.SPLITROT then + EMT.ISY1 = EgtIf( Cmd[2] ~= '0', CalcCharStatusN( Cmd[2]), 86) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + else + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + end + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = CalcCharStatusN( Cmd[2]) end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd, nInd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.FSY1 = -1 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + -- non interessa + elseif Cmd[1] == '2' then + if Cmd[2] == 'Y1' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local MDChar = { Y1=tonumber(Cmd[3])-EMT.HOVM, IniStatY2=-75, FinStatY2=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '11' then + EMT.FSY1 = CalcCharStatusN( Cmd[2]) + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function GetV1ToCloseTPA() + local dMaxHeadPos = EMT.MAXMAX[1] + ( EMT.HOVM or 0) - ( EMT.X_OFF or 0) + local dMinTailPos = EMT.MAXMIN[1] + EMT.LB + EgtIf( IsStartOrMidPhase( EMT.PHASE), 0, ( EMT.HOVM or 0)) - ( EMT.X_OFF or 0) + --MyOutput( string.format( 'V1 MaxHeadPos=%.3f MinTailPos=%.3f BarLen=%.3f HeadOvm=%.3f V1NextPos=%.3f', dMaxHeadPos, dMinTailPos, EMT.LB, ( EMT.HOVM or 0), EMT.V1NEXTPOS)) + return ( dMaxHeadPos <= EMT.V1NEXTPOS + RollCageMin and dMinTailPos >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToCloseTPA() + local dMaxHeadPos = EMT.MAXMAX[1] + ( EMT.HOVM or 0) - ( EMT.X_OFF or 0) + local dMinTailPos = EMT.MAXMIN[1] + EMT.LB + EgtIf( IsStartOrMidPhase( EMT.PHASE), 0, ( EMT.HOVM or 0)) - ( EMT.X_OFF or 0) + --MyOutput( string.format( 'V2 MaxHeadPos=%.3f MinTailPos=%.3f BarLen=%.3f HeadOvm=%.3f', dMaxHeadPos, dMinTailPos, EMT.LB, ( EMT.HOVM or 0))) + return ( dMaxHeadPos <= EMT.V2NEXTPOS - RollCageMax and dMinTailPos >= EMT.V2NEXTPOS - RollCageMin) +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + local MyL1o = EMT.L1 + local MyL2o = EMT.L2 + local MyL3o = EMT.L3 + local nHSet = GetHeadSet( EMT.HEAD) + if EMT.REFLOC then + local vtE + -- se testa 1 + if nHSet == 1 then + if EMT.HEAD == 'H13' then + local Len = ( EMT.TDIST or ChSawLen) + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.ADIR) * Len - Z_AX() * LenRef + else + local dAddLen = 0 + if EMT.HEAD == 'H12' then + dAddLen = -SawOffsZ + elseif EMT.HEAD == 'H16' then + dAddLen = -Saw2OffsZ + end + local Len = EMT.TLEN + dAddLen + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.TDIR) * Len - Z_AX() * LenRef + end + -- se testa 2 + elseif nHSet == 2 then + local dAddLen = 0 + if EMT.HEAD == 'H22' then + dAddLen = SawUnderOffsZ + end + local Len = EMT.TLEN + dAddLen + Mill2Offs + local LenRef = Mill2Offs + vtE = Vector3d( EMT.TDIR) * Len + Z_AX() * LenRef + -- se testa 3 + else + local Len = EMT.TLEN + Mill3Offs + local LenRef = Mill3Offs + vtE = Vector3d( EMT.TDIR) * Len - 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 + + if not EMT.REFLOC then + if EMT.HEAD ~= 'H21' and EMT.HEAD ~= 'H22' then + EMT.L2 = -EMT.L2 + else + EMT.L3 = -EMT.L3 + end + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3, sTcPos, dAxR3) + if not sTcPos then sTcPos = EMT.TCPOS end + local sPos = sTcPos:gsub( 'T', '') + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + if sPos == '101' then + if not dAxR3 then dAxR3 = EMT.R3 end + if abs( dAxR3 - 0) < 0.1 then + sPos = '101' + elseif abs( dAxR3 - 270) < 0.1 then + sPos = '102' + elseif abs( dAxR3 - 180) < 0.1 then + sPos = '103' + elseif abs( dAxR3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + if sPos == '111' then + if not dAxR3 then dAxR3 = EMT.R3 end + if abs( dAxR3 - 0) < 0.1 then + sPos = '111' + elseif abs( dAxR3 - 270) < 0.1 then + sPos = '112' + elseif abs( dAxR3 - 180) < 0.1 then + sPos = '113' + elseif abs( dAxR3 - 90) < 0.1 then + sPos = '114' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + if sPos == '201' then + if not dAxR3 then dAxR3 = EMT.R3 end + if abs( dAxR3 - 0) < 0.1 then + sPos = '201' + elseif abs( dAxR3 - 90) < 0.1 then + sPos = '204' + -- Lama su aggregato da sotto non può essere presa in queste posizioni per problemi di collisione durante parcheggio + --elseif abs( dAxR3 - 270) < 0.1 then + -- sPos = '202' + --elseif abs( dAxR3 - 180) < 0.1 then + -- sPos = '203' + else + EmtSetLastError( 1210, 'Saw orientation not allowed') + end + end + return sPos +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, 0, 0) + local nHSet = GetHeadSet( EMT.HEAD) + if nHSet == 1 then + ptS = ptS + Vector3d( 0, DeltaTabY, DeltaTabZ) + elseif nHSet == 2 then + ptS = ptS + Vector3d( 0, Delta2TabY, Delta2TabZ) + else + ptS = ptS + Vector3d( 0, Delta3TabY, Delta3TabZ) + end + + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H13' then + if EMT.MCHTYPE ~= MCH_OY.GENMACHINING then + vtE = Vector3d( EMT.EXTR) + else + vtE = Z_AX() + end + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --MyOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + local nHSet = GetHeadSet( EMT.HEAD) + if nHSet ~= 2 then + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( -vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( -vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( -vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + else + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( -vtX:getZ(), 6) .. + ' I' .. EgtNumToString( vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( -vtY:getZ(), 6) .. + ' P' .. EgtNumToString( vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( -vtZ:getZ(), 6) + end + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.Y1DELTA and EMT.Y2DELTA then + return '3' + elseif EMT.Y1DELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function GetHeadSetCode() + local nSetHead = GetHeadSet( EMT.HEAD) + if nSetHead == 1 then + return '1' + elseif nSetHead == 2 then + return '2' + elseif nSetHead == 3 then + return '3' + else + EmtSetLastError( 1211, 'Error Unknown Head Set') + end +end + +--------------------------------------------------------------------- +function GetHeadToolCode() + local nSetHead = GetHeadSet( EMT.HEAD) + if nSetHead == 1 then + return 'T101' + elseif nSetHead == 2 then + return 'T202' + elseif nSetHead == 3 then + return 'T303' + else + EmtSetLastError( 1211, 'Error Unknown Head Set') + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset, bEnd, PrevR1, PrevR2, bSplitCut, bTopGoHome) + if bReset then + EmitResetMachining() + end + local nSetHead = GetHeadSet( EMT.HEAD) + -- se testa 1 + if nSetHead == 1 then + -- posizioni sicure + local dMaxZ1 = EgtGetAxisMax( 'Z1') + local dHomeX1 = EgtGetAxisHomePos( 'X1') + local dHomeZ1 = EgtGetAxisHomePos( 'Z1') + local dHomeB1 = EgtGetAxisHomePos( 'B1') + local dHomeC1 = EgtGetAxisHomePos( 'C1') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dHomeC1, dHomeB1) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSplitCut) + end + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- eseguo la salita a Z1max (oriento solo se assi rotanti non già a posto) + if abs( dHomeC1 - PrevR1) > 0.1 or abs( dHomeB1 - PrevR2) > 0.1 then + local dZref = dHomeZ1 + GetZExtra( EMT.HEAD, PrevR2) + dZref = min( dZref, dMaxZ1) + local MovH = { Z = EgtIf( dZref > EMT.L3o, dZref, EMT.L3o)} + MovH.X = -EMT.L2o ; MovH.B = EgtClamp( PrevR2, -90, 90) ; MovH.C = PrevR1 ; + EmitMoveDataHead( 1, MovH) + if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( dHomeC1 - PrevR1) > 30.1 or abs( dHomeB1 - PrevR2) > 30.1) then + EmitMoveDataHead( 1, { Z=dMaxZ1, B=0, Fmt=1}) + end + if EgtIf( BD.RIGHT_LOAD, ( EMT.L2 > -DeltaTabY), ( EMT.L2 < -DeltaTabY)) then + EmitMoveDataHead( 1, { X=-DeltaTabY, Fmt=1}) + end + EmitMoveDataHead( 1, { C=dHomeC1, Fmt=1}) + EmitMoveDataHead( 1, { B=dHomeB1, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dMaxZ1, Fmt=1}) + if bTopGoHome then + EmitMoveDataHead( 1, { X=-ParkX1, Fmt=1}) + end + EmitMoveStartHead( 1) + -- se lavorazione in doppio + if EMT.DOU_TYPE == 2 or EMT.DOU_TYPE == 3 then + EmitDouZMax( EMT.DOU_TYPE) + end + -- attesa fine movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti sega a catena + else + -- salgo in Z sicurezza raddrizzando la B + local dSafeZ1 = EgtIf( EMT.TTOTLEN < MinLengthLongCSaw, ParkCSawZ1, ParkLongCSawZ1) + EmitMoveDataHead( 1, { Z=dSafeZ1, B=dHomeB1, Fmt=1}) + EmitMoveDataHead( 1, { X=-dHomeX1, C=dHomeC1, Fmt=1}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + end + -- se altrimenti testa 2 + elseif nSetHead == 2 then + -- posizioni sicure + local dHomeX2 = EgtGetAxisHomePos( 'X2') + local dHomeZ2 = EgtGetAxisHomePos( 'Z2') + local dHomeB2 = EgtGetAxisHomePos( 'B2') + local dHomeC2 = EgtGetAxisHomePos( 'C2') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dHomeC2, dHomeB2) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSplitCut) + end + -- eseguo la discesa a Z2max + EmitMoveDataHead( 2, { Z=-dHomeZ2, Fmt=1}) + EmitMoveDataHead( 2, { B=dHomeB2, C=dHomeC2, Fmt=1}) + if EMT.HEAD == 'H22' then + EmitMoveDataHead( 2, { X=SafeX2, Fmt=1}) + else + EmitMoveDataHead( 2, { X=dHomeX2, Fmt=1}) + end + -- solo se è macchina a 3 teste, devo stare più alto + if EgtGetHeadId( 'H31') then + EmitMoveDataHead( 2, { Z=-ParkInLavZ2, Fmt=1}) + end + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + -- altrimenti testa 3 + else + -- posizioni sicure + local dMaxZ3 = EgtGetAxisMax( 'Z3') + local dHomeX3 = EgtGetAxisHomePos( 'X3') + local dHomeB3 = EgtGetAxisHomePos( 'B3') + -- eseguo la salita a Z3max + EmitMoveDataHead( 3, { Z=dMaxZ3, Fmt=1}) + if bTopGoHome then + EmitMoveDataHead( 3, { X=-dHomeX3, B=dHomeB3, Fmt=1}) + end + EmitMoveStartHead( 3) + EmitMoveWaitHead( 3) + end + -- resetto posizione precedente assi + EMT.L2pp = nil + EMT.L3pp = nil + EMT.R1pp = nil + EMT.R2pp = nil +end + +--------------------------------------------------------------------- +function EmitDouZMax( nDouType) + -- posizioni sicure + local dHomeX2 = EgtGetAxisHomePos( 'X2') + local dHomeZ2 = EgtGetAxisHomePos( 'Z2') + local dHomeB2 = EgtGetAxisHomePos( 'B2') + local dHomeC2 = EgtGetAxisHomePos( 'C2') + -- se lavorazione in doppio in Y (prima mi allontano in Y) + if nDouType == 2 then + EmitMoveDataHead( 2, { X=SafeX2, TPos=EMT.DOU_TPOS, Fmt=1}) + end + -- scendo in Z, sistemo B e C porto X in home + EmitMoveDataHead( 2, { Z=-dHomeZ2, TPos=EMT.DOU_TPOS, Fmt=1}) + EmitMoveDataHead( 2, { B=dHomeB2, C=dHomeC2, TPos=EMT.DOU_TPOS, Fmt=1}) + EmitMoveDataHead( 2, { X=dHomeX2, TPos=EMT.DOU_TPOS, Fmt=1}) + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + -- dichiaro eseguito + EMT.DOU_TO_ZMAX = nil +end + +--------------------------------------------------------------------- +function EmitResetMachining() + MyOutput( 'G27') + if EMT.PREFALLCUT then + MyOutput( 'M29') + EMT.PREFALLCUT = nil + end + local sP12 = '' + if EMT.TOOL ~= GetNextTool( EMT.MCHID) then sP12 = EgtIf( EMT.HEAD ~= 'H21', ' P1=0'..EgtIf( EMT.DOU_TYPE, ' P2=0', ''), ' P2=0') end + local sP4 = EgtIf( EMT.MCHUSERNOTES:find( 'Split', 1, true), ' P4=1', '') + MyOutput( 'M99'..sP12..sP4) +end + +--------------------------------------------------------------------- +function EmitParkRoller( dPosT, bSplitCut) + -- se entrambe già parcheggiate, non devo fare alcunché + if ( EMT.V1POS - ParkV1) > -0.1 and ( EMT.V2POS - ParkV2) < 0.1 then return end + -- Parcheggi pinze + local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT') + local MyParkY1 = ParkY1 + EgtIf( bAgg, AggLoad, 0) + local MyParkY2 = ParkY2 + -- le parcheggio + local MDChar = {} + if EMT.Y1DELTA and EMT.Y2DELTA then + local dPosY1 = dPosT + EMT.Y1DELTA + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY1 = MyParkY1 - dPosY1 + local DiffY2 = MyParkY2 - dPosY2 + --MyOutput( string.format( 'PosT=%.3f DiffY1=%.3f DiffY2=%.3f', dPosT, DiffY1, DiffY2)) + if bSplitCut then + if DiffY1 > 0.1 then + MDChar.Y1 = dPosY1 + DiffY1 + end + if DiffY2 < -0.1 then + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + if dPosY2 + DiffY1 > MyParkY2 + 0.1 then + EmtSetLastError( 1201, 'Error Collision Y2 in ParkRoller') + else + MDChar.Y1 = dPosY1 + DiffY1 + MDChar.Y2 = dPosY2 + DiffY1 + dPosT = dPosT + DiffY1 + end + elseif DiffY2 < -0.1 then + if dPosY1 + DiffY2 < MyParkY1 - 0.1 then + EmtSetLastError( 1201, 'Error Collision Y1 in ParkRoller') + else + MDChar.Y1 = dPosY1 + DiffY2 + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + end + MDChar.MovType = 3 + MDChar.BeamVise = ( EMT.BV or 1) + elseif EMT.Y1DELTA then + local dMoveV1 = ParkV1 - EMT.V1POS + local dPosY1 = dPosT + EMT.Y1DELTA + local DiffY1 = MyParkY1 - dPosY1 + local dMoveY1 = EgtIf( DiffY1 > 0.1, dMoveV1, 0) + local dTryMoveY1 = min( ParkV1 - dPosT - EgtIf( bSplitCut or EMT.FALL, EMT.LT, 0), MaxY1 - dPosY1 - 10) + if ( dPosT > ParkV2 - ExtraParkV and dPosT < ParkV1 and dPosY1 + dTryMoveY1 < MaxY1) then dMoveY1 = max( dMoveY1, dTryMoveY1) end + --MyOutput( string.format( 'PosT=%.3f PosY1=%.3f V1POS=%.3f Split=%s', dPosT, dPosY1, EMT.V1POS, EgtIf( bSplitCut, '1', '0'))) + MDChar.Y1 = dPosY1 + dMoveY1 + MDChar.MovType = 1 + MDChar.BeamVise = 1 + dPosT = dPosT + dMoveY1 + elseif EMT.Y2DELTA then + local dMoveV2 = ParkV2 - EMT.V2POS + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY2 = MyParkY2 - dPosY2 + local dMoveY2 = EgtIf( DiffY2 < -0.1, dMoveV2, 0) + local dTryMoveY2 = max( ParkV2 - dPosT - EMT.LT - EMT.HOVM, MinY2 - dPosY2 + 10) + if ( dPosT + EMT.LT + EMT.HOVM < ParkV1 + ExtraParkV and dPosT + EMT.LT + EMT.HOVM > ParkV2 and dPosY2 + dTryMoveY2 > MinY2) then dMoveY2 = min( dMoveY2, dTryMoveY2) end + --MyOutput( string.format( 'PosT=%.3f LT=%.3f PosY2=%.3f V2POS=%.3f', dPosT, EMT.LT, dPosY2, EMT.V2POS)) + MDChar.Y2 = dPosY2 + dMoveY2 + MDChar.MovType = 2 + MDChar.BeamVise = 2 + dPosT = dPosT + dMoveY2 + end + if abs( ParkV1 - EMT.V1POS) > 0.1 then + MDChar.V1 = ParkV1 + MDChar.IniStatV1 = 1 + end + if abs( ParkV2 - EMT.V2POS) > 0.1 then + MDChar.V2 = ParkV2 + MDChar.IniStatV2 = 1 + end + EmitMoveDataChars( MDChar) + EmitMoveStartChars( MDChar.MovType) + EmitMoveWaitChars( MDChar.MovType) + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 + EMT.TPOS = dPosT +end + +--------------------------------------------------------------------- +function GetNextTool( nMchId) + -- inizializzo prossimo utensile + local sNextTool + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then + break + end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + -- se trovata + if nNextMchId and EgtSetCurrMachining( nNextMchId) then + sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) + return sNextTool +end + +--------------------------------------------------------------------- +function PreselectNextDiffHead( nMchId, sHead) + -- recupero lavorazione successiva, se non esiste esco subito + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then break end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + if not nNextMchId then return end + + -- se esiste lavorazione successiva + if EgtSetCurrMachining( nNextMchId) then + local sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sNextTool) then + local nHSet = GetHeadSet( sHead) + local sNextHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nNextHSet = GetHeadSet( sNextHead) + -- se utensile su altra testa + if nNextHSet ~= nHSet then + local sNextTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + local dNextTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + + -- se sto lavorando con testa 1 + if nHSet == 1 then + -- se preselezione testa 2 + if nNextHSet == 2 then + -- se agregato lama speciale non preseleziono mai + if sNextHead == 'H22' or EMT.PREVHEAD_H2 == 'H22' then return end + -- se la Z di lavoro è più bassa del cambio della minima Z + if EMT.MAXMIN[3] < MinZ1ToChangeH2 then + -- se diametro utensile più del truciolatore standard grande, si rischia di collidere anche con il carro X testa sotto (quindi indipendentemente dalla Y della lavorazione) + if EMT.TTOTDIAM > 201 then return end + -- verifico quota del TC + if BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( DeltaTabY + MaxHoOpen + 200) then return end + if not BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( DeltaTabY + 200) then return end + end + -- se preselezione testa 3 + else + ; -- non devo fare nulla + end + -- se sto lavorando con testa 2 + elseif nHSet == 2 then + -- se preselezione testa 1 + if nNextHSet == 1 then + -- se sopra Z oltre la faccia sotto della trave, controllo il cambio utensile + if EMT.MAXMIN[3] > Delta2TabZ then + local nNextTc = GetTcForTopHeadTool( sNextTcPos) -- utensile da caricare + local nPrevTc = GetTcForTopHeadTool( EMT.PREVTCPOS_H1) -- utensile da depositare + -- se deposito e carico da diversi TC non faccio preselezione + if nNextTc ~= nPrevTc and nPrevTc ~= 0 then return + -- altrimenti se operazione su stesso TC + else + -- TC su montante destro oppure non so cosa c'è montato + if nNextTc == 1 or nPrevTc == 0 then + if BD.RIGHT_LOAD and EMT.MAXMIN[2] < ( Delta2TabY - 200) then return end + if not BD.RIGHT_LOAD and EMT.MAXMIN[2] < ( Delta2TabY - MaxHoOpen - 200) then return end + end + -- TC su montante sinistro oppure non so cosa c'è montato + if nNextTc == 2 or nPrevTc == 0 then + if BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( Delta2TabY + MaxHoOpen + 200) then return end + if not BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( Delta2TabY + 200) then return end + end + end + end + -- se preselezione testa 3 + else + ; -- non devo fare nulla + end + -- altrimenti (testa 3) + else + -- se preselezione testa 1 + if nNextHSet == 1 then + -- TC su montante destro + if nPrevTc == 1 then return + -- TC su montante sinistro + else + if BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( DeltaTabY + MaxHoOpen + 200) then return end + if not BD.RIGHT_LOAD and EMT.MAXMAX[2] > DeltaTabY then return end + end + -- se preselezione testa 2 + else + -- se agregato lama speciale non preseleziono mai + if sNextHead == 'H22' or EMT.PREVHEAD_H2 == 'H22' then return end + -- se la Z di lavoro è più bassa del cambio utensili, verifico quota X (la nostra Y) + if EMT.MAXMIN[3] < MinZ1ToChangeH2 then + if BD.RIGHT_LOAD and EMT.MAXMAX[2] > ( DeltaTabY + MaxHoOpen + 200) then return end + if not BD.RIGHT_LOAD and EMT.MAXMAX[2] > DeltaTabY then return end + end + end + end + + -- faccio preselezione ( se sono arrivato qui, vuol dire che posso preselezionare) + if nNextHSet == 1 then + -- Recupero quota X1 (nostro L2) + local dNextX = GetStartMachiningXaxis( nNextMchId) + -- Emetto preselezione + if sNextHead == 'H11' then + if dNextTotLen < LongTool then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + else + local nNextTc = GetTcForTopHeadTool( sNextTcPos) + EmitMoveDataHead( 1, { X=dNextX, B=ParkLongB1, C=EgtIf( nPrevTc ~= 2, ParkLongTc1C1, ParkLongTc2C1), TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + end + EmitMoveStartHead( 1) + elseif sNextHead == 'H12' or sNextHead == 'H16' then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 1) + elseif sNextHead == 'H13' then + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA, EMT.TTOTLEN) + local bXSpec = EgtIf( BD.RIGHT_LOAD, ( dNextX > -DeltaTabY), ( dNextX < -DeltaTabY)) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, dNextX), B=ParkCSawB1, C=MyParkCSawC1, TPos=AdjustTcPos( false, sNextTcPos, dPosA), Fmt=2}) + EmitMoveStartHead( 1) + end + else + EmitMoveDataHead( 2, { B=ParkB2, C=ParkC2, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 2) + end + end + end + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) +end + +--------------------------------------------------------------------- +function GetNextTopHSet( nMchId) + local nNextTopHSet = 0 + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then + if EgtSetCurrMachining( nNextMchId) then + local sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sNextTool) then + local sNextHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nNextHSet = GetHeadSet( sNextHead) + if nNextHSet ~= 2 then + nNextTopHSet = nNextHSet + break + end + end + end + end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) + return nNextTopHSet +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindReadHeadWithLaser( vMDChar) + for i = 1, #vMDChar do + if vMDChar[i].IniStatY1 == -76 then + return true + end + end + return false +end + +--------------------------------------------------------------------- +function FindFallAtEndAux( nPathId) + for nInd = 1, 100 do + local sInfo = EgtGetInfo( nPathId, 'AE'..tostring( nInd)) + if sInfo then + local Cmd = EgtSplitString( sInfo) + if ( Cmd[1] == '0' and Cmd[2] == 'Fall') then + return true + end + else + return false + end + end + return false +end + +--------------------------------------------------------------------- +function EmitRemark( sOut) + sOut = string.gsub( string.gsub( sOut, '%(', '['), '%)', ']') + MyOutput( '(' .. sOut .. ')') +end + +--------------------------------------------------------------------- +function EmitMoveDataHead( nHead, MoData) + local sOut = 'M101' + local sRealTcPos + + if EMT.TCPOS then + sRealTcPos = AdjustTcPos( false) + end + + if nHead == 1 then + sOut = 'M101' + EMT.PREVTCPOSREAL_H1 = 'T' .. sRealTcPos + elseif nHead == 2 then + sOut = 'M102' + EMT.PREVTCPOSREAL_H2 = 'T' .. sRealTcPos + elseif nHead == 3 then + sOut = 'M103' + end + sOut = sOut .. ' P1=1' + if MoData.X then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.X, 3) end + if MoData.Z then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Z, 3) end + if MoData.B then sOut = sOut .. ' P4=' .. EmtLenToString( MoData.B, 3) end + if MoData.C then sOut = sOut .. ' P5=' .. EmtLenToString( MoData.C, 3) end + if MoData.TPos then sOut = sOut .. ' P6=' .. MoData.TPos elseif EMT.TCPOS then sOut = sOut .. ' P6=' .. sRealTcPos end + if MoData.S then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.S, 0) end + if not MoData.Fmt then + if MoData.F then sOut = sOut .. ' P8=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P8=0' end + sOut = sOut .. ' P9=0 P10=4 P11=1' + elseif MoData.Fmt == 1 then + sOut = sOut .. ' P10=4 P11=1' + end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartHead( nHead) + local sOut = 'M101' + if nHead == 2 then + sOut = 'M102' + elseif nHead == 3 then + sOut = 'M103' + end + sOut = sOut .. ' P1=2' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveWaitHead( nHead) + local sOut = 'M101' + if nHead == 2 then + sOut = 'M102' + elseif nHead == 3 then + sOut = 'M103' + end + sOut = sOut .. ' P1=3' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveDataChars( MoData) + local sOut = 'M111' + if MoData.MovType == 1 then sOut = sOut .. ' P1=11' elseif MoData.MovType == 2 then sOut = sOut .. ' P1=12' else sOut = sOut .. ' P1=10' end + if MoData.Y1 then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.Y1, 3) end + if MoData.Y2 then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Y2, 3) end + if MoData.IniStatY1 then sOut = sOut .. ' P4=' .. EgtNumToString( MoData.IniStatY1, 0) end + if MoData.FinStatY1 then sOut = sOut .. ' P5=' .. EgtNumToString( MoData.FinStatY1, 0) end + if MoData.IniStatY2 then sOut = sOut .. ' P6=' .. EgtNumToString( MoData.IniStatY2, 0) end + if MoData.FinStatY2 then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.FinStatY2, 0) end + if MoData.BeamVise then sOut = sOut .. ' P8=' .. EgtNumToString( MoData.BeamVise, 0) end + if MoData.F then sOut = sOut .. ' P9=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if MoData.V1 then sOut = sOut .. ' P15=' .. EmtLenToString( MoData.V1, 3) end + if MoData.V2 then sOut = sOut .. ' P16=' .. EmtLenToString( MoData.V2, 3) end + if MoData.IniStatV1 then local sVal = EgtNumToString( MoData.IniStatV1, 0) ; sOut = sOut .. ' P17=' .. sVal .. ' P18=' .. sVal end + if MoData.FinStatV1 then local sVal = EgtNumToString( MoData.FinStatV1, 0) ; sOut = sOut .. ' P19=' .. sVal .. ' P20=' .. sVal end + if MoData.IniStatV2 then local sVal = EgtNumToString( MoData.IniStatV2, 0) ; sOut = sOut .. ' P21=' .. sVal .. ' P22=' .. sVal end + if MoData.FinStatV2 then local sVal = EgtNumToString( MoData.FinStatV2, 0) ; sOut = sOut .. ' P23=' .. sVal .. ' P24=' .. sVal end + if MoData.Remark then sOut = sOut .. ' ('.. MoData.Remark .. ')' end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartChars( MovType) + local sMovType = ' P1=20' + if MovType == 1 then + sMovType = ' P1=21' + elseif MovType == 2 then + sMovType = ' P1=22' + end + MyOutput( 'M111' .. sMovType) +end + +--------------------------------------------------------------------- +function EmitMoveWaitChars( MovType, bRun) + local sMovType = ' P1=30' + if MovType == 1 then + sMovType = ' P1=31' + elseif MovType == 2 then + sMovType = ' P1=32' + end + if bRun == nil or bRun then + MyOutput( 'M111' .. sMovType) + else + MyOutput( ';M111' .. sMovType) + end +end + +--------------------------------------------------------------------- +function EmitBeamHeadData( BhData) + local sOut = 'M112' + if BhData.T then sOut = sOut .. ' P1=' .. EmtLenToString( BhData.T, 3) end + if BhData.ViseY1 then sOut = sOut .. ' P3=' .. EgtNumToString( BhData.ViseY1, 0) end + if BhData.ViseY2 then sOut = sOut .. ' P4=' .. EgtNumToString( BhData.ViseY2, 0) end + if BhData.SetHead then sOut = sOut .. ' P5=' .. EgtNumToString( BhData.SetHead, 0) end + if BhData.Y1 then sOut = sOut .. ' P6=' .. EmtLenToString( BhData.Y1, 3) end + if BhData.Y2 then sOut = sOut .. ' P7=' .. EmtLenToString( BhData.Y2, 3) end + if BhData.F then sOut = sOut .. EgtIf( BhData.F >= 1, ' P9=' .. EmtLenToString( BhData.F, 0), '') else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if BhData.StatV1 then sOut = sOut .. ' P10=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.V1 then sOut = sOut .. ' P11=' .. EmtLenToString( BhData.V1, 3) end + if BhData.StatV1 then sOut = sOut .. ' P12=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.StatV2 then sOut = sOut .. ' P13=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.V2 then sOut = sOut .. ' P14=' .. EmtLenToString( BhData.V2, 3) end + if BhData.StatV2 then sOut = sOut .. ' P15=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.ViseY1 == 3 then sOut = sOut .. ' P16=1' end + if BhData.ViseY2 == 3 then sOut = sOut .. ' P17=1' end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local bToPark = true + +--------------------------------------------------------------------- +function SetToParkLine() + bToPark = true +end + +--------------------------------------------------------------------- +function MyOutput( sOut) + if not bToPark then + EmtOutput( sOut) + else + ParkLine( sOut) + end +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + bToPark = false + for i = 1, #ParkedLines do + EmtOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + bToPark = false + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + EmtOutput( sLine) + StartValues = {} +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/Common_PF1250.mlpe b/Common_PF1250.mlpe new file mode 100644 index 0000000..f6d1697 --- /dev/null +++ b/Common_PF1250.mlpe @@ -0,0 +1,2514 @@ +-- Processore standard macchine tipo PF1250 by EgalWare s.r.l. 2024/01/22 + +-- Funzioni generiche indipendenti dal controllo + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico libreria +local BD = require( 'BeamData') + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetCurrMachineDir() +if NumericalControl == 'NUM' then + error( 'Numerical Control error : NUM not yet managed') +elseif NumericalControl == 'TPA' then + dofile( sBaseDir .. '\\Common_PF1250.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 3 + +--------------------------------------------------------------------- +function OnSimulInit() + -- se macchina con carico destro, imposto offset direzioni di vista standard + if BD.RIGHT_LOAD then + local nOrigViewOffs = EgtGetViewOrizzOffsStep() + local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView() + if nOrigViewOffs ~= 2 then + EgtSetViewOrizzOffsStep( 2) + if dOrigViewAngV < 0.1 then + EgtSetView( SCE_VD.TOP, false) + elseif dOrigViewAngV > 179.9 then + EgtSetView( SCE_VD.BOTTOM, false) + else + local dViewAngH = dOrigViewAngH + EgtIf( dOrigViewAngH > 180, 2 * 90, 0) + EgtSetGenericView( dOrigViewAngV, dViewAngH, false) + end + end + end +end + +--------------------------------------------------------------------- +function OnSimulExit() + -- se macchina con carico destro, annullo offset direzioni di vista standard + if BD.RIGHT_LOAD then + local nOrigViewOffs = EgtGetViewOrizzOffsStep() + local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView() + if nOrigViewOffs == 2 then + EgtSetViewOrizzOffsStep( 0) + if dOrigViewAngV < 0.1 then + EgtSetView( SCE_VD.TOP, false) + elseif dOrigViewAngV > 179.9 then + EgtSetView( SCE_VD.BOTTOM, false) + else + EgtSetGenericView( dOrigViewAngV, dOrigViewAngH - 2 * 90, false) + end + end + end +end + +--------------------------------------------------------------------- +function OnSimulStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < MIN_MACH_VER then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum EgtMachKernel '..MIN_MACH_VER..')') + end + -- 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] and #(vTools[1]) > 0 then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Carico gli utensili iniziali o di default sulle due teste + LoadFirstTool( 1, DefTcPos1) + LoadFirstTool( 2, DefTcPos2) + ExecStartHome() + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- 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( 'Z1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'X2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ) + if EgtGetHeadId('H31') then + AddToCollisionCheck( 'Z3', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C3', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B3', 'COLLISION', EMT.COLLOBJ) + end + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + local McdData = { { Grp = 'V1', Sub = 'COLLISION', Name = 'STM'}, + { Grp = 'V2', Sub = 'COLLISION', Name = 'STM'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'TRAV'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'COL1'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'COL2'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'CHSAW'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'CEIL'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'TC1'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'TC2'}, + { Grp = 'Base', Sub = 'COLLISION', Name = 'TCR'}, + { Grp = 'Z2', Sub = 'COLLISION', Name = 'COL1'}, + { Grp = 'Z2', Sub = 'COLLISION', Name = 'CHAIN'}, + { Grp = 'Z2', Sub = 'COLLISION', Name = 'COL2'}, + { Grp = 'X1', Sub = 'COLLISION', Name = 'STM'}} + + if EgtGetHeadId('H31') then + table.insert( McdData, { Grp = 'X3', Sub = 'COLLISION', Name = 'STM'}) + end + + -- inserisco gruppi opzionali + if SecondChain then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'CHSAW2'}) end + if TcSpecialTools then table.insert( McdData, {Grp = 'Base', Sub = 'COLLISION', Name = 'SPTOOLS'}) end + if TcAggreBladeUnder then table.insert( McdData, {Grp = 'Base', Sub = 'COLLISION', Name = 'AGGREBLADEUNDER'}) end + + EgtOutLog( 'MCODET Objects :', 4) + local nMcdNullCnt = 0 + for i = 1, #McdData do + local nGrpId + if McdData[i].Grp == 'Base' then + nGrpId = EgtGetBaseId( 'Base') + else + nGrpId = EgtGetAxisId( McdData[i].Grp) + end + local nId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nGrpId, McdData[i].Sub), McdData[i].Name) + if nId then + table.insert( EMT.MCODET, nId) + EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' (' .. tostring( nId) .. ') is ok', 4) + else + nMcdNullCnt = nMcdNullCnt + 1 + EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' is null', 4) + end + end + if nMcdNullCnt > 0 then + EgtOutLog( 'Warning : MCODET with one or more null Element(s) ') + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +function OnSimulEnd() + EMT.Y1DELTA = nil + EMT.Y2DELTA = nil + ExecParkRoller() +end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + local ParkT = GetParkT() + EgtSetAxisPos( 'T', ParkT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino sezione del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.HB = 0 + EMT.SB = 0 + if b3Sol then + EMT.HB = b3Sol:getDimY() + EMT.SB = b3Sol:getDimZ() + end + -- 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.51 + if dArea < CoeffVM * 0.5e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 2.5e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 5.0e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 10.0e6 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 + end + + -- 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( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local b3Bar = BBox3d() + local b3Part = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Bar:Add( b3Tmp) + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw:Add( b3Tmp) + b3Part:Add( b3Tmp) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + 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 + EMT.LB = b3Bar:getDimX() + EMT.LR = b3Raw:getDimX() + EMT.LT = b3Part:getDimX() + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.Y1SPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #EMT.MCODET 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 and #EMT.VMILL > 0 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 + -- verifico posizione di carico + local ParkT = GetParkT() + -- 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( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + 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') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- verifico posizione di carico + local ParkT = GetParkT() + -- 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( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + 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') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'Y1') + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.SPLIT = false + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosA) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + EMT.TUSERNOTES = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES) + -- recupero il gruppo + local nSetHead = GetHeadSet( EMT.HEAD) + -- se fresa o lama su testa 1, reset assi rotanti + if nSetHead == 1 then + -- se ho la testa 3, la mando a parcheggio + if EgtGetHeadId( 'H31') then + EgtSetAxisPos( 'X3', ParkX3) + end + if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' then + EgtSetAxisPos( 'Z1', MaxZ1Blade) + end + EgtResetAxisPos( 'C1') + EgtResetAxisPos( 'B1') + -- se testa 3 parcheggio la 1 + elseif nSetHead == 3 then + EgtSetAxisPos( 'X1', ParkX1) + end + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = dPosA or GetNextChainSawingVirtualAxis( EMT.MCHID) + -- imposto il valore di A + EgtSetAxisPos( 'A1', dPosA) + -- imposto home dell'asse C1 (A1=0 -> T101, A1=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA, EMT.TTOTLEN) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + EgtSetAxisPos( 'C1', MyParkCSawC1) + -- Imposto visualizzazione + EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) + end + -- se lama su aggregato da sotto, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H22' then + -- se c'era un altro utensile, imposto subito asse virtuale + if EMT.PREVHEAD_H2 ~= 'H22' then + dPosA = dPosA or GetNextSawingVirtualAxis( EMT.MCHID) + end + if dPosA then + -- imposto il valore di A + EgtSetAxisPos( 'A2', dPosA) + -- imposto home dell'asse C1 (A2=0 -> T201, A2=90 -> T204) + local MyParkSawC2 = GetSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C2', MyParkSawC2) + EgtSetAxisPos( 'C2', MyParkSawC2) + -- Imposto visualizzazione + EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) + end + end + -- carico utensile, con breve pausa + EgtPause( 100) + EgtOutText( '') + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 4 + EMT.A1n = 'Y1' + EMT.A2n = 'Y2' + EMT.A3n = 'V1' + EMT.A4n = 'V2' + -- se attivo Vmill + EmtSetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + local nInd = EgtIf( nSetHead ~= 2, 1001, 1011) + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd, true) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1) + for i, Coll in ipairs( EMT.COLLOBJ or {}) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect( dPrevA) + -- se prossimo utensile non cambia e non è sega a catena o lama su rinvio da sotto, esco + if ( EMT.NEXTTOOL == EMT.PREVTOOL_H1 or EMT.NEXTTOOL == EMT.PREVTOOL_H2) and EMT.NEXTHEAD ~= 'H13' and ( EMT.NEXTHEAD ~= 'H22' or not dPrevA) then return end + -- deposito utensile + EgtOutText( 'Tool change in progress...') + -- recupero il gruppo attuale e il successivo + local nNextSetHead = GetHeadSet( EMT.NEXTHEAD) + local nSetHead = GetHeadSet( EMT.HEAD) + -- se devo deselezionare testa 3, la mando a parcheggio + if nSetHead == 3 then + SimulMoveAxis( 'X3', ParkX3, MCH_SIM_STEP.RAPID) + -- per testa gruppo 2 + elseif nNextSetHead == 2 then + -- deposito lama su aggregato testa sotto + if EMT.PREVHEAD_H2 == 'H22' then + -- simulo movimento + local ParkC2 = EgtGetAxisHomePos( 'C2') + if dPrevA then + ParkC2 = GetSawCHomeFromVirtualAxis( dPrevA) + end + SimulMoveAxis( 'Z2', MinZ2, MCH_SIM_STEP.RAPID) + SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkSawB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) + end + -- breve pausa + EgtPause( 100) + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H2, true) + -- nascondo l'utensile sulla testa + EgtSetStatus( EgtGetHeadId( EMT.PREVHEAD_H2 or '') or GDB_ID.NULL, GDB_ST.OFF) + -- se testa gruppo 1 + elseif nNextSetHead == 1 and EMT.PREVTCPOS_H1 then + -- deposito utensile fresa + if EMT.PREVHEAD_H1 == 'H11' then + -- simulo movimento + local nPrevTc = GetTcForTopHeadTool( EMT.PREVTCPOS_H1) + if EMT.PREVTTOTLEN_H1 < LongTool then + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + local dPosX = EgtIf( nPrevTc ~= 2, ParkTc1X1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID) + else + if nPrevTc ~= 2 then + SimulMoveAxes( 'B1', ParkLongB1, MCH_SIM_STEP.RAPROT, 'C1', ParkLongTc1C1, MCH_SIM_STEP.RAPROT) + local dPosX = ParkTc1X1 + SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID) + else + SimulMoveAxes( 'B1', ParkLongB1, MCH_SIM_STEP.RAPROT, 'C1', ParkLongTc2C1, MCH_SIM_STEP.RAPROT) + local dPosX = ParkTc2X1 + SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID) + end + end + -- deposito utensile lama + elseif EMT.PREVHEAD_H1 == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X1', ParkTc1X1, MCH_SIM_STEP.RAPID) + -- deposito utensile sega a catena + elseif EMT.PREVHEAD_H1 == 'H13' then + -- simulo movimento + local ParkC1 = EgtGetAxisHomePos( 'C1') + if dPrevA then + ParkC1 = GetChainSawCHomeFromVirtualAxis( dPrevA, EMT.TTOTLEN) + end + SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID) + -- deposito utensile seconda lama + elseif EMT.PREVHEAD_H1 == 'H16' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X1', ParkTc2X1, MCH_SIM_STEP.RAPID) + end + -- breve pausa + EgtPause( 100) + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H1, true) + -- nascondo l'utensile sulla testa + EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) + end + -- se passo da testa 1 a 3 o viceversa + if nNextSetHead == 3 then + -- deposito eventuale sega a catena + if EMT.PREVHEAD_H1 == 'H13' then + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H1, true) + -- nascondo l'utensile sulla testa + EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) + end + SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) + end + -- movimento per prendere nuovo utensile + -- prendo utensile fresa + if EMT.NEXTHEAD == 'H11' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + local dPosX = EgtIf( GetTcForTopHeadTool( EMT.NEXTTCPOS) ~= 2, ParkTc1X1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID) + SimulMoveAxis( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID) + -- prendo utensile lama + elseif EMT.NEXTHEAD == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X1', ParkTc1X1, MCH_SIM_STEP.RAPID) + -- prendo utensile sega a catena + elseif EMT.NEXTHEAD == 'H13' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', EgtGetAxisHomePos( 'C1'), MCH_SIM_STEP.RAPROT) + SimulMoveAxes( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID, 'Z1', ParkCSawZ1, MCH_SIM_STEP.RAPID) + -- prendo utensile seconda lama + elseif EMT.NEXTHEAD == 'H16' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X1', ParkTc2X1, MCH_SIM_STEP.RAPID) + -- prendo utensile su CU margherita testa sotto + elseif EMT.NEXTHEAD == 'H21' then + -- simulo movimento + SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.RAPROT, 'C2', ParkC2, MCH_SIM_STEP.RAPROT) + SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) + -- prendo utensile lama su aggregato + elseif EMT.NEXTHEAD == 'H22' then + -- aggiungo utensile per verifica collisione + AddToolToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, 1011, false) + AddToolHolderToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, 1011 + 1) + -- simulo movimento + SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkSawB2, MCH_SIM_STEP.COLLROT, 'C2', ParkSawC2, MCH_SIM_STEP.COLLROT) + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H13' and EMT.HEAD == EMT.PREVHEAD_H1 then + local dPrevA = EgtGetAxisPos( 'A1') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 4)) + if abs( dPosA - dPrevA) > 1 then + OnSimulToolDeselect( dPrevA) + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + end + end + -- se lavorazione attuale e precedente con aggregato lama da sotto con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H22' and EMT.HEAD == EMT.PREVHEAD_H2 then + local dPrevA = EgtGetAxisPos( 'A2') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 4)) or 0 + if abs( dPosA - dPrevA) > 1 then + ExecParkRoller( nil, nil, nil, nil, false, bAgg) + -- setto i valori per la funzione ToolDesel + EMT.NEXTHEAD = EMT.HEAD + EMT.NEXTTOOL = EMT.TOOL + EMT.NEXTEXIT = EMT.EXIT + OnSimulToolDeselect( dPrevA) + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + -- aggiorno dati utensile su testa + EMT.TCPOSREAL = 'T' .. AdjustTcPos( false, EMT.TCPOS, dPosA) + EMT.PREVTCPOSREAL_H2 = EMT.TCPOSREAL + end + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) or '' + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not EMT.MCHUSERNOTES:find( 'VMRS=0;', 1, true)) + EMT.MCHSPLIT = ( EMT.MCHUSERNOTES:find( 'Split;', 1, true) ~= nil) + -- recupero TASKID e CUTID della feature lavorata (CUTID va recuperato qui per le pareti) + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + local nPartId = EgtGetParent( EgtGetParent( vId[1][1]) or GDB_ID.NULL) + EMT.CUTID = EgtGetInfo( nPartId or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.CUTID = 0 + EMT.TASKID = 0 + end + -- gestione eventuale lavorazione in doppio + local nDouType = EgtGetValInNotes( EMT.MCHUSERNOTES, 'DOUBLE', 'i') + if nDouType == 2 or nDouType == 3 then + local sDouTool = EgtGetValInNotes( EMT.TUSERNOTES, 'DOUBLE', 's') or '' + local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if EgtTdbSetCurrTool( sDouTool) and EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) then + local sDouHead = 'H21' + local nDouExit = 1 + -- carico l'utensile sulla testa + local sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + EgtLoadTool( sDouHead, nDouExit, sDouTool) + ShowToolInTcPos( sTcPos, false) + -- dichiaro utensile per Vmill + EmtAddToolForVmill( sDouTool, sDouHead, nDouExit, EMT.VMILL) + -- dichiaro utensile per verifica collisioni + local nInd = 1011 + AddToolToCollisionObj( sDouTool, sDouHead, nDouExit, nInd, true) + AddToolHolderToCollisionObj( sDouTool, sDouHead, nDouExit, nInd + 1) + -- salvo dati + EMT.DOU_TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.DOU_TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + EMT.DOU_TYPE = nDouType + EMT.DOU_TOOL = sDouTool + -- reset necessità movimento in sicurezza sola testa in doppio + EMT.DOU_TO_ZMAX = nil + else + EmtSetLastError( 1211, 'Missing or not active double tool of '..sOldTool) + end + EgtTdbSetCurrTool( sOldTool) + else + -- recupero il gruppo + local nSetHead = GetHeadSet( EMT.HEAD) + if nSetHead ~= 1 and ( EMT.PREVTOOL_H1 and EMT.PREVHEAD_H1) then + local nPrevExit_H1 = 1 + local nInd_H1 = 1001 + AddToolToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1, true) + AddToolHolderToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1 + 1) + end + if nSetHead ~= 2 and ( EMT.PREVTOOL_H2 and EMT.PREVHEAD_H2) then + local nPrevExit_H2 = 1 + local nInd_H2 = 1011 + AddToolToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2, true) + AddToolHolderToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2 + 1) + end + if nSetHead ~= 3 and EgtGetHeadId( 'H31') then + local nPrevExit_H3 = 1 + local nInd_H3 = 1001 + AddToolToCollisionObj( nil, 'H31', nPrevExit_H3, 1001) + AddToolHolderToCollisionObj( nil, 'H31', nPrevExit_H3, 1002) + end + end + -- se precedente in doppio ma ora solo testa 1 e non in sicurezza + if EMT.DOU_TO_ZMAX then + -- parcheggio i rulli + local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT') + ExecParkRoller( nil, nil, nil, nil, false, bAgg) + -- eseguo + if EMT.DOU_TO_ZMAX == 2 then + SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID) + end + SimulMoveAxes( 'Z2', MinZ2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) + EMT.DOU_TO_ZMAX = nil + end + + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.MCHSPLIT = nil + EMT.SPLIT = nil + if EMT.DOU_TYPE and not EMT.ZMAX then EMT.DOU_TO_ZMAX = EMT.DOU_TYPE end + EMT.DOU_TYPE = nil + EMT.DOU_TOOL = nil + + -- salvo dati utensile + local nSetHead = GetHeadSet( EMT.HEAD) + -- per gruppo testa 1 + if nSetHead == 1 then + EMT.PREVTOOL_H1 = EMT.TOOL + EMT.PREVHEAD_H1 = EMT.HEAD + EMT.PREVTCPOS_H1 = EMT.TCPOS + EMT.PREVTTOTLEN_H1 = EMT.TTOTLEN + EMT.PREVTCPOSREAL_H1 = EMT.TCPOSREAL + -- per gruppo testa 2 + elseif nSetHead == 2 then + EMT.PREVTOOL_H2 = EMT.TOOL + EMT.PREVHEAD_H2 = EMT.HEAD + EMT.PREVTCPOS_H2 = EMT.TCPOS + EMT.PREVTTOTLEN_H2 = EMT.TTOTLEN + EMT.PREVTCPOSREAL_H2 = EMT.TCPOSREAL + -- per gruppo testa 3 (resetto dati testa 1) + else + EMT.PREVTOOL_H3 = nil + EMT.PREVHEAD_H3 = nil + EMT.PREVTCPOS_H3 = nil + EMT.PREVTTOTLEN_H3 = nil + end + +end + +--------------------------------------------------------------------- +function OnSimulPathStart() + -- se taglio di separazione, verifico se ci sarà caduta + if EMT.MCHSPLIT then + local sCmd = EgtGetInfo( EMT.PATHID, 'AE1') or '' + if sCmd:find( 'Fall', 1, true) then + EMT.TO_FALL = true + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- rimozione sfridi + ExecRemoveScraps() + -- se non ci sono comandi ausiliari associati e richiesta risalita a Zmax + if EMT.AUXTOT == 0 and EMT.TO_ZMAX then + if EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + ExecMovePY1( false) + end + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX, true) + -- se ultimo comando e lavorazione di split, sgancio il carro Y1 + if EMT.AUXIND == EMT.AUXTOT and EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + ExecMovePY1( false) + end +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX, false) + -- se ultimo comando e richiesta risalita a Zmax + if EMT.AUXIND == EMT.AUXTOT and EMT.TO_ZMAX then + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + if EMT.MCHFIRST then EgtOutText( '') end + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- Posizioni correnti + local Y1Pos = EgtGetAxisPos( 'Y1') + local Y2Pos = EgtGetAxisPos( 'Y2') + local V1Pos = EgtGetAxisPos( 'V1') + local V2Pos = EgtGetAxisPos( 'V2') + -- Imposto movimento pinze e rulli insieme con la tavola : + EMT.AuxAxes = 4 + -- pinze + EMT.A1n = 'Y1' + if EMT.Y1DELTA then + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.Y1DELTA + else + EMT.A1m = nil + EMT.A1 = EgtIf( EMT.Y1SPEC, EgtGetAxisPos( 'Y1'), ParkY1) + end + EMT.A2n = 'Y2' + if EMT.Y2DELTA then + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.Y2DELTA + else + EMT.A2m = nil + EMT.A2 = ParkY2 + end + -- Controllo scorrimento pinze chiuse Y1 e Y2 + if EMT.Y1DELTA then + local dY1DeltaP = Y1Pos - EMT.L1p + if abs( EMT.Y1DELTA - dY1DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.Y1DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + if EMT.Y2DELTA then + local dY2DeltaP = Y2Pos - EMT.L1p + if abs( EMT.Y2DELTA - dY2DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y2 slide : ' .. EgtNumToString( dY2DeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.Y2DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- rulli + EMT.A3n = 'V1' + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4n = 'V2' + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + local bParkV = false + if EMT.MCHFIRST then + -- se rulli più chiusi del richiesto o cambio direzione utensile (tranne solo asse B con C0 o equivalenti) devo mettere i rulli in parcheggio + if V1Pos < EMT.V1NEXTPOS - 1 or V2Pos > EMT.V2NEXTPOS + 1 or RollerParkingNeeded( EMT.HEAD, EMT.R1p, EMT.R2p, EMT.R1, EMT.R2) then + bParkV = true + EMT.A3 = ParkV1 + EMT.A4 = ParkV2 + end + end + -- Controllo corse assi ausiliari + VerifyY1Stroke( EMT.A1) + VerifyY2Stroke( EMT.A2) + VerifyV1Stroke( EMT.A3) + VerifyV2Stroke( EMT.A4) + -- se devo subito parcheggiare i rulli + local nRes = 0 + if bParkV then + local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT') + nRes = ExecParkRoller( Y1Pos, Y2Pos, V1Pos, V2Pos, false, bAgg) + end + -- se movimento in rapido + if EMT.MOVE == 0 then + -- se testa 1 + if nSetHead == 1 then + -- Dati + local B1Pos = EgtGetAxisPos( 'B1') + local B1Home = EgtGetAxisHomePos( 'B1') + local C1Pos = EgtGetAxisPos( 'C1') + local C1Home = EgtGetAxisHomePos( 'C1') + local Z1Pos = EgtGetAxisPos( 'Z1') + local Z1Home = EgtGetAxisHomePos( 'Z1') + local MyMaxZ1 = EgtGetAxisMax( 'Z1') + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- se movimento iniziale da Zmax con lama o fresa + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + local bXSpec = EgtIf( BD.RIGHT_LOAD, EMT.L2 < DeltaTabY, EMT.L2 > DeltaTabY) + -- in caso di rotazione della lama lontano dalla posizione di home degli assi rotanti + if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( C1Pos - EMT.R1) > 1 or abs( B1Pos - EMT.R2) > 1) and ( abs( C1Home - EMT.R1) > 30.1 or abs( B1Home - EMT.R2) > 30.1) then + SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) + -- caso standard + else + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), MCH_SIM_STEP.RAPID) + end + SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) + SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) + end + end + -- altrimenti sega a catena + else + -- Porto la Z alla giusta quota + if Z1Pos > Z1Home + 1 and abs( B1Pos) > 89.9 then + SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) + SimulMoveAxis( 'Z1', Z1Home, MCH_SIM_STEP.RAPID) + end + -- se movimento iniziale da Zmax + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + SimulMoveAxes( 'Z1', Z1Home, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) + -- se motosega molto lunga, ruoto prima di muovermi in X + if EMT.TTOTLEN >= MinLengthLongCSaw then + SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) + end + end + end + -- se altrimenti testa 2 + elseif nSetHead == 2 then + local B2Home = EgtGetAxisHomePos( 'B2') + local C2Home = EgtGetAxisHomePos( 'C2') + local Z2Home = EgtGetAxisHomePos( 'Z2') + local X2Home = EgtGetAxisHomePos( 'X2') + local X2Pos = EgtGetAxisPos( 'X2') + local B2Pos = EgtGetAxisPos( 'B2') + local C2Pos = EgtGetAxisPos( 'C2') + -- calcolo posizione reale + EMT.TCPOSREAL = 'T' .. AdjustTcPos( false, EMT.TCPOS, EMT.R3) + -- se utensile cambiato (controllo il reale perchè per aggregato dipende come è stato caricato) + if EMT.PREVTCPOSREAL_H2 ~= EMT.TCPOSREAL then + if EMT.ZMAX then + -- se bisogna scrivere tutti gli assi + if WriteAllCoordsOnFirstM101 then + if EMT.HEAD == 'H22' then + SimulMoveAxes( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID, 'B2', 0, MCH_SIM_STEP.COLLROT, 'C2', C2Home, MCH_SIM_STEP.COLLROT) + X2Pos = ParkSawX2 + else + SimulMoveAxes( 'X2', SafeX2, MCH_SIM_STEP.RAPID, 'B2', B2Home, MCH_SIM_STEP.COLLROT, 'C2', C2Home, MCH_SIM_STEP.COLLROT) + X2Pos = SafeX2 + end + else + if EMT.HEAD == 'H22' then + SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID) + X2Pos = ParkSawX2 + else + SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID) + X2Pos = SafeX2 + end + end + SimulMoveAxis( 'Z2', Z2Home, MCH_SIM_STEP.RAPID) + -- Porto la X alla giusta quota + if X2Pos > ParkMchY2 and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then + SimulMoveAxis( 'X2', ParkMchY2, MCH_SIM_STEP.RAPID) + end + end + else + -- Porto la X alla giusta quota + if EMT.ZMAX and X2Pos > ParkMchY2 and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then + SimulMoveAxis( 'X2', ParkMchY2, MCH_SIM_STEP.RAPID) + end + end + if EMT.HEAD == 'H22' then + SimulMoveAxes( 'B2', EMT.R2, MCH_SIM_STEP.COLLROT, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) + end + -- se ero a ZMAX, mi sposto in posizione a Z home. Ultimo movimento muove in Z + if EMT.ZMAX then + SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID, 'B2', EMT.R2, MCH_SIM_STEP.COLLROT, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) + end + -- altrimenti testa 3 + else + ; -- non devo fare alcunchè di speciale + end + end + -- se lavorazione split, muovo per riaggancio del carro Y1 + if EMT.SPLIT_Y1DELTA then + EMT.Y1DELTA = EMT.SPLIT_Y1DELTA + EMT.A1 = EMT.L1 + EMT.Y1DELTA + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- demando movimento completo a MoveEnd + EMT.EnabAxes = false + EMT.ShowAxes = true + end + -- se lavorazione in doppio + if not ( EMT.MOVE == 0 and EMT.FLAG == 3) then + -- doppio in orizzontale + if EMT.DOU_TYPE == 2 then + -- se primo movimento, eseguo movimento rotatorio preliminare + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'C2', EMT.R1, MCH_SIM_STEP.RAPROT, 'B2', EMT.R2, MCH_SIM_STEP.RAPROT) + else + EMT.AuxAxes = 4 + 4 + EMT.A5n = 'X2' + local X2 = Delta2TabY + EMT.DOU_TLEN - ( -DeltaTabY + EMT.L2 + EMT.TLEN + EgtIf( BD.RIGHT_LOAD, -EMT.HB, EMT.HB)) + if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then + EMT.DOU_DRILL_END = -( EMT.L2p - EMT.L2) + X2 = X2 + 2 * EMT.DOU_DRILL_END + end + EMT.A5 = X2 + EMT.A5m = nil + EMT.A6n = 'Z2' + local Z2 = -Head2Z + MillOffs + Mill2Offs + EMT.L3 + EMT.A6 = EgtClamp( Z2, MinZ2, MaxZ2) + EMT.A6m = EgtIf( ( EMT.MOVE == 2 or EMT.MOVE == 3), 'Z1', nil) + EMT.A7n = 'C2' + EMT.A7 = EMT.R1 + EMT.A8n = 'B2' + EMT.A8 = EMT.R2 + -- controllo minima distanza tra utensili di X1 e X2 + local dDeltaX1X2 = EMT.L2 - EMT.A5 - Head2Y + local dDistToolX1X2 = -dDeltaX1X2 - MillOffs - EMT.TTOTLEN - Mill2Offs - EMT.DOU_TTOTLEN + if dDistToolX1X2 < MinDistToolX1X2 then + local sErr = 'X1 X2 tools in collision (distance=' .. EgtNumToString( dDistToolX1X2, 1) .. ')' + EmtSetLastError( 1208, sErr) + end + -- se appena sopra inizio, sistemo subito la quota in Z + if EMT.MOVE == 0 then + SimulMoveAxes( 'Z2', EMT.A6, MCH_SIM_STEP.RAPID) + end + end + -- doppio in verticale + elseif EMT.DOU_TYPE == 3 then + EMT.AuxAxes = 4 + 4 + EMT.A5n = 'X2' + local X2 = -Head2Y + EMT.L2 + EMT.A5 = X2 + EMT.A5m = EgtIf( ( EMT.MOVE == 2 or EMT.MOVE == 3), 'X1', nil) + EMT.A6n = 'Z2' + local Z2 = Delta2TabZ - EMT.DOU_TLEN - ( -DeltaTabZ + EMT.L3 - EMT.TLEN - EMT.SB) + if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then + EMT.DOU_DRILL_END = EMT.L3p - EMT.L3 + Z2 = Z2 - 2 * EMT.DOU_DRILL_END + end + EMT.A6 = EgtClamp( Z2, MinZ2, MaxZ2) + EMT.A6m = nil + EMT.A7n = 'C2' + EMT.A7 = EMT.R1 + EMT.A8n = 'B2' + EMT.A8 = EMT.R2 + -- controllo minima distanza tra utensili di X1 e X2 (lungo Z) + local dDeltaZ1Z2 = EMT.L3 - EMT.A6 - Head2Z + local dDistToolZ1Z2 = dDeltaZ1Z2 - EMT.TTOTLEN - EMT.DOU_TTOTLEN + if dDistToolZ1Z2 < MinDistToolX1X2 then + local sErr = 'Z1 Z2 tools in collision (distance=' .. EgtNumToString( dDistToolZ1Z2, 1) .. ')' + EmtSetLastError( 1208, sErr) + end + end + end + -- se necessario ... + if EMT.MCHFIRST and EMT.EnabAxes ~= false then + if nSetHead == 1 then + SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, + 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, + 'C1', EMT.R1, MCH_SIM_STEP.COLLROT, + 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) + if EMT.DOU_TYPE and EMT.AuxAxes == 8 then + SimulMoveAxes( 'X2', EMT.A5, MCH_SIM_STEP.RAPID, + 'Z2', EMT.A6, MCH_SIM_STEP.RAPID, + 'C2', EMT.A7, MCH_SIM_STEP.COLLROT, + 'B2', EMT.A8, MCH_SIM_STEP.COLLROT) + end + elseif nSetHead == 2 then + SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID, + 'Z2', EMT.L3, MCH_SIM_STEP.RAPID, + 'C2', EMT.R1, MCH_SIM_STEP.COLLROT, + 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) + else + SimulMoveAxes( 'X3', EMT.L2, MCH_SIM_STEP.RAPID, + 'Z3', EMT.L3, MCH_SIM_STEP.RAPID, + 'C3', EMT.R1, MCH_SIM_STEP.COLLROT, + 'B3', EMT.R2, MCH_SIM_STEP.COLLROT) + end + end + if nRes ~= 0 then + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + end + EMT.ZMAX = nil + EMT.TO_ZMAX = nil +end + +--------------------------------------------------------------------- +function OnSimulMoveEnd() + -- rimozione eventuali sfridi + if EMT.FLAG == 301 then + ExecRemoveScraps() + end + -- se primo rapido della lavorazione + if EMT.MCHFIRST and EMT.MOVE == 0 then + -- se lavorazione split, dichiaro carro Y1 riagganciato + if EMT.SPLIT_Y1DELTA then + EMT.SPLIT_Y1DELTA = nil + ExecMovePY1( true) + end + -- chiusura o apertura rulli V1 + if GetV1ToClose() then + ExecCloseRoller( 1) + else + ExecOpenRoller( 1) + end + -- chiusura o apertura rulli V2 + if GetV2ToClose() then + ExecCloseRoller( 2) + else + ExecOpenRoller( 2) + end + EMT.MCHFIRST = false + EgtOutText( '') + end + -- se movimento finale di foratura in doppio in Z + if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then + if EMT.DOU_TYPE == 2 then + SimulMoveAxes( 1, 'X1', EMT.L2 - 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED, + 'X2', EMT.A5 - 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED) + SimulMoveAxes( 1, 'X1', EMT.L2 - EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED, + 'X2', EMT.A5 - EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED) + elseif EMT.DOU_TYPE == 3 then + SimulMoveAxes( 1, 'Z1', EMT.L3 + 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED, + 'Z2', EMT.A6 + 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED) + SimulMoveAxes( 1, 'Z1', EMT.L3 + EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED, + 'Z2', EMT.A6 + EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED) + end + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- eventuale rimozione sfridi + ExecRemoveScraps() + -- eseguo + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then + Class = 'T_'..EMT.HEAD + elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then + Class = 'TH_'..EMT.HEAD + 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 = 11 + 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, bPathStart) + -- analizzo il comando + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Split' then + EMT.SPLIT = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( Cmd[2]) + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, + sV1, MoveV1, MCH_SIM_STEP.RAPID, + sV2, MoveV2, MCH_SIM_STEP.RAPID) + if not bOk then + if not bOk1 then + if VerifyY1Y2Stroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk2 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk3 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + end + elseif Cmd[1] == '2' then + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo i movimenti necessari + ExecOpenRoller( 1) + ExecOpenRoller( 2) + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, + Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID, + sV1, MoveV1, MCH_SIM_STEP.RAPID, + sV2, MoveV2, MCH_SIM_STEP.RAPID) + if not bOk then + if not bOk1 or not bOk2 then + local nI = EgtIf( not bOk1, 2, 4) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk3 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk4 then + VerifyV1V2Stroke( sV2, MoveV2) + 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 i movimenti necessari + ExecOpenRoller( 1) + ExecOpenRoller( 2) + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4, bOk5 = 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, + sV1, MoveV1, MCH_SIM_STEP.RAPID, + sV2, MoveV2, MCH_SIM_STEP.RAPID) + if not bOk then + if not bOk1 or not bOk2 or not bOk3 then + local nI = EgtIf( not bOk1, 2, EgtIf( not bOk2, 4, 6)) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk4 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk5 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '4' then + ExecMoveHome( Cmd[2] == '1', EgtIf( bPathStart, false, EMT.MCHSPLIT)) + elseif Cmd[1] == '11' then + local bClose = Cmd[2] ~= '0' + if bPathStart and EMT.MCHSPLIT and not ( EMT.FALL or EMT.TO_FALL) and GetPY2Light() then bClose = false end + ExecMovePY1( bClose) + elseif Cmd[1] == '12' then + ExecMovePY2( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + EMT.Y1DELTA = EgtIf( nY1Delta > 0.01, nY1Delta, nil) + EMT.Y2DELTA = EgtIf( nY2Delta > 0.01, nY2Delta, nil) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.Y1SPEC = true + elseif Cmd[1] == '99' then + EMT.ERR = Cmd[2] + EmtSetLastError( 1200 + EMT.ERR, Cmd[3]) + end +end + +--------------------------------------------------------------------- +function CalcMoveV1V2ForAuxCmd( Cmd) + -- verifico se necessario muovere V1 + local MoveV1 + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local V1Pos = EgtGetAxisPos( 'V1') + if MoveY1 and V1Pos > MoveY1 - MinDeltaYV + 0.1 then + MoveV1 = MoveY1 - MinDeltaYV + end + local sV1 = EgtIf( MoveV1, 'V1', nil) + -- verifico se necessario muovere V2 + local MoveV2 + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + local V2Pos = EgtGetAxisPos( 'V2') + if MoveY2 and V2Pos < MoveY2 + MinDeltaYV - 0.1 then + MoveV2 = MoveY2 + MinDeltaYV + end + local sV2 = EgtIf( MoveV2, 'V2', nil) + -- restituisco i risultati + if MoveV1 and MoveV2 then + return sV1, MoveV1, sV2, MoveV2 + elseif MoveV1 then + return sV1, MoveV1 + elseif MoveV2 then + return sV2, MoveV2 + end +end + +--------------------------------------------------------------------- +function ExecStartHome() + -- Testa 1 + EgtResetAxisPos( 'X1') + EgtSetAxisPos( 'Z1', MaxZ1) + EgtResetAxisPos( 'C1') + EgtResetAxisPos( 'B1') + -- Testa 2 + EgtSetAxisPos( 'X2', SafeX2) + EgtSetAxisPos( 'Z2', MinZ2) + EgtResetAxisPos( 'C2') + EgtResetAxisPos( 'B2') +end + +--------------------------------------------------------------------- +function ExecMoveHome( bNearV, bMchSplit) + -- risalita a Zmax + ExecMoveZmax( bMchSplit) + -- se testa sotto e macchian a 3 teste + if GetHeadSet( EMT.HEAD) == 2 and EgtGetHeadId( 'H31') then + if not SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) then + EgtOutLog( 'Error on MoveHome : X2') + end + if not SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID) then + EgtOutLog( 'Error on MoveHome : X2') + end + end + EMT.TO_ZMAX = nil + -- se richiesto, avvicino i rulli + if bNearV then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + if not SimulMoveAxes( 'V1', MinV1, MCH_SIM_STEP.RAPID, + 'V2', MaxV2, MCH_SIM_STEP.RAPID) then + EgtOutLog( 'Error on MoveHome : NearV1V2') + end + end +end + +--------------------------------------------------------------------- +function ExecMoveZmax( bMchSplit) + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- posizioni correnti degli assi testa + local CurrX = EgtGetAxisPos( EgtIf( nSetHead == 1, 'X1', 'X2')) + local CurrZ = EgtGetAxisPos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local CurrC = EgtGetAxisPos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local CurrB = EgtGetAxisPos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- posizioni home degli assi testa + local HomeX = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'X1', 'X2')) + local HomeZ = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local HomeC = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local HomeB = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- verifico se necessario ruotare la testa + local bRot = ( abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1) + -- se necessario ruotare la testa, allargo i carrelli + if RollerParkingNeeded( EMT.HEAD, CurrC, CurrB, HomeC, HomeB) then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT') + ExecParkRoller( nil, nil, nil, nil, bMchSplit, bAgg) + end + -- se testa sopra + if nSetHead == 1 then + local MyMaxZ1 = EgtGetAxisMax( 'Z1') + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then + local dZref = HomeZ + GetZExtra( EMT.HEAD, CurrB) + SimulMoveAxes( 'Z1', EgtIf( dZref > CurrZ, dZref, CurrZ), MCH_SIM_STEP.RAPID, 'B1', EgtClamp( CurrB, -90, 90), MCH_SIM_STEP.COLLROT) + if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( HomeC - CurrC) > 30.1 or abs( HomeB - CurrB) > 30.1) then + SimulMoveAxes( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT) + end + if ( not BD.RIGHT_LOAD and EMT.L2 > DeltaTabY) or ( BD.RIGHT_LOAD and EMT.L2 < DeltaTabY) then + SimulMoveAxis( 'X1', DeltaTabY, MCH_SIM_STEP.RAPID) + end + SimulMoveAxis( 'C1', HomeC, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'B1', HomeB, MCH_SIM_STEP.COLLROT) + end + SimulMoveAxis( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID) + -- altrimenti sega a catena + else + -- salgo in Z sicurezza raddrizzando la B + local SafeZ1 = EgtIf( EMT.TTOTLEN < MinLengthLongCSaw, ParkCSawZ1, ParkLongCSawZ1) + SimulMoveAxes( 'Z1', SafeZ1, MCH_SIM_STEP.RAPID, 'B1', HomeB, MCH_SIM_STEP.COLLROT) + SimulMoveAxes( 'X1', HomeX, MCH_SIM_STEP.RAPID, 'C1', HomeC, MCH_SIM_STEP.COLLROT) + end + -- se lavorazione in doppio + if EMT.DOU_TYPE == 2 then + SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID) + SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) + EMT.DOU_TO_ZMAX = nil + elseif EMT.DOU_TYPE == 3 then + SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) + SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) + EMT.DOU_TO_ZMAX = nil + end + -- se altrimenti testa sotto + elseif nSetHead == 2 then + SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) + if EMT.HEAD == 'H22' then + SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID) + else + SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) + end + -- solo se è macchina a 3 teste, devo stare più alto + if EgtGetHeadId( 'H31') then + SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID) + end + -- altrimenti testa 3 + else + SimulMoveAxes( 'Z3', MaxZ3, MCH_SIM_STEP.RAPID) + SimulMoveAxes( 'B3', ParkB3, MCH_SIM_STEP.COLLROT) + end + EMT.ZMAX = true +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, EgtIf( BD.RIGHT_LOAD, ( EMT.HB + 50.0), -( EMT.HB + 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, EgtIf( BD.RIGHT_LOAD, 1600, -1600), 0) + if EMT.FALL then vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 3200, -2600), -1150) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + if EgtVolZmapSetShowEdges then + EgtVolZmapSetShowEdges( vMillId, true) + else + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + 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) + 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 + +--------------------------------------------------------------------- +function ExecMovePY1( bClose) + SimulMoveAxes( 'PY1', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID) + SetPY1Light( bClose) +end + +--------------------------------------------------------------------- +function ExecMovePY2( bClose) + SimulMoveAxes( 'PY2', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID) + SetPY2Light( bClose) +end + +--------------------------------------------------------------------- +local function LinkRemainingPartsToY1() + local nCurrOrd = GetPhaseOrd( EMT.PHASE) + local TabId = EgtGetTableId( 'Tab') + local RawId = EgtGetFirstInGroup( TabId) + while RawId do + local NextRawId = EgtGetNext( RawId) + if EgtGetName( RawId) == 'RawPart' then + local nRawOrd = EgtGetInfo( RawId, 'ORD', 'i') + if nRawOrd and nRawOrd ~= nCurrOrd then + local bUlOk = EmtUnlinkRawPartFromGroup( RawId) + local bLkOk = EmtLinkRawPartToGroup( RawId, 'Y1') + end + end + RawId = NextRawId + end +end + +--------------------------------------------------------------------- +function ExecParkRoller( PosY1, PosY2, PosV1, PosV2, bSpliCut, bAgg) + -- Posizioni + local PosT = EgtGetAxisPos( 'T') + PosY1 = PosY1 or EgtGetAxisPos( 'Y1') + PosY2 = PosY2 or EgtGetAxisPos( 'Y2') + PosV1 = PosV1 or EgtGetAxisPos( 'V1') + PosV2 = PosV2 or EgtGetAxisPos( 'V2') + -- Parcheggi pinze + local MyParkY1 = ParkY1 + EgtIf( bAgg, AggLoad, 0) + local MyParkY2 = ParkY2 + -- Apro i rulli, se necessario + if abs( ParkV1 - PosV1) > 0.1 then ExecOpenRoller( 1) end + if abs( ParkV2 - PosV2) > 0.1 then ExecOpenRoller( 2) end + -- Eseguo spostamenti + if EMT.Y1DELTA and EMT.Y2DELTA then + local DiffY1 = MyParkY1 - PosY1 + local DiffY2 = MyParkY2 - PosY2 + -- se appena eseguito taglio di separazione + if bSpliCut then + -- aggancio i pezzi rimanenti all'asse Y1 + LinkRemainingPartsToY1() + -- eseguo i movimenti + if not SimulMoveAxes( 'T', PosT + min( DiffY2, 0.0), MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', PosY1 + max( DiffY1, 0.0), MCH_SIM_STEP.RAPID, + 'Y2', PosY2 + min( DiffY2, 0.0), MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12A)') + end + return 32 + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EMT.ERR = 2 + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY1, MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', PosY1 + DiffY1, MCH_SIM_STEP.RAPID, + 'Y2', PosY2 + DiffY1, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12B)') + end + return 12 + elseif DiffY2 < -0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY2, MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', PosY1 + DiffY2, MCH_SIM_STEP.RAPID, + 'Y2', PosY2 + DiffY2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1203, 'Error on MoveAxes in ParkRoller (12C)') + end + return 21 + else + if not SimulMoveAxes( 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1204, 'Error on MoveAxes in MoveStart') + end + return 30 + end + elseif EMT.Y1DELTA then + local MoveV1 = ParkV1 - PosV1 + local DiffY1 = MyParkY1 - PosY1 + local MoveY1 = EgtIf( DiffY1 > 0.1, MoveV1, 0) + local TryMoveY1 = min( ParkV1 - PosT - EgtIf( bSpliCut or EMT.FALL, EMT.LT, 0), MaxY1 - PosY1 - 10) + if ( PosT > ParkV2 - ExtraParkV and PosT < ParkV1 and PosY1 + TryMoveY1 < MaxY1) then MoveY1 = max( MoveY1, TryMoveY1) end + -- se appena eseguito taglio di separazione + if bSpliCut then + -- aggancio i pezzi rimanenti all'asse Y1 + LinkRemainingPartsToY1() + -- eseguo movimenti + if not SimulMoveAxes( 'T', PosT, MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', PosY1 + MoveY1, MCH_SIM_STEP.RAPID, + 'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)') + end + else + if not SimulMoveAxes( 'T', PosT + MoveY1, MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', PosY1 + MoveY1, MCH_SIM_STEP.RAPID, + 'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)') + end + end + return 11 + elseif EMT.Y2DELTA then + local MoveV2 = ParkV2 - PosV2 + local DiffY2 = MyParkY2 - PosY2 + local MoveY2 = EgtIf( DiffY2 < -0.1, MoveV2, 0) + local TryMoveY2 = max( ParkV2 - PosT - EMT.LT, MinY2 - PosY2 + 10) + if ( PosT + EMT.LT < ParkV1 + ExtraParkV and PosT + EMT.LT > ParkV2 and PosY2 + TryMoveY2 > MinY2) then MoveY2 = min( MoveY2, TryMoveY2) end + if not SimulMoveAxes( 'T', PosT + MoveY2, MCH_SIM_STEP.RAPID, + 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', EgtIf( PosY1 > MyParkY1, PosY1, MyParkY1), MCH_SIM_STEP.RAPID, + 'Y2', PosY2 + MoveY2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1206, 'Error on MoveAxes in ParkRoller (2)') + end + return 22 + else + if not SimulMoveAxes( 'V1', ParkV1, MCH_SIM_STEP.RAPID, + 'V2', ParkV2, MCH_SIM_STEP.RAPID, + 'Y1', MyParkY1, MCH_SIM_STEP.RAPID, + 'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then + EMT.ERR = 2 + EmtSetLastError( 1207, 'Error on MoveAxes in ParkRoller (0)') + end + return 0 + end +end + +--------------------------------------------------------------------- +function ExecCloseRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), EMT.HB) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), EMT.SB) +end + +--------------------------------------------------------------------- +function ExecOpenRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), MaxHoOpen) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), MaxVeOpen) +end + +--------------------------------------------------------------------- +function ExecRemoveScraps() + -- 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 + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local dTCenX = -EgtGetAxisPos( 'T') - EMT.LT / 2 + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + local b3VmPart = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD) + if b3VmPart and b3VmPart:getMax():getX() > dTCenX and b3VmPart:getMin():getX() < dTCenX then + dVolMax = dVol + nPartMax = i + end + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + -- aggiorno visualizzazione + EgtDraw() + end + EMT.VMRS = false + end +end + +--------------------------------------------------------------------- +function VerifyY1Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y1 + if sName1 == 'T' and sName2 == 'Y1' and GetPY1Light() then + local dY1DeltaP = EgtGetAxisPos( 'Y1') - EgtGetAxisPos( 'T') + local dY1DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y1DeltaP=%.3f Y1DeltaA=%.3f', dY1DeltaP, dY1DeltaA), 5) + if abs( dY1DeltaA - dY1DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( dY1DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyY2Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y2 + if sName1 == 'T' and sName2 == 'Y2' and GetPY2Light() then + local dY2DeltaP = EgtGetAxisPos( 'Y2') - EgtGetAxisPos( 'T') + local dY2DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y2VDeltaP=%.3f Y2DeltaA=%.3f', dY2DeltaP, dY2DeltaA), 5) + if abs( dY2DeltaA - dY2DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y2 slide : ' .. EmtLenToString( dY2DeltaP, 3) .. ' -> ' .. EmtLenToString( dY2DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + 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 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'Y2' then + return VerifyY2Slide( 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 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) and VerifyY2Slide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'Y2' then + return VerifyY2Slide( sName1, dVal1, sName2, dVal2) and VerifyY1Slide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Stroke( dY1) + if dY1 < MinY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MinY1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MinY1, 3) + EgtOutLog( sErr) + return false + elseif dY1 > MaxY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MaxY1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MaxY1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY2Stroke( dY2) + if dY2 < MinY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MinY2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y2 axis outstroke ' .. EgtNumToString( dY2 - MinY2, 3) + EgtOutLog( sErr) + return false + elseif dY2 > MaxY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MaxY2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY2 - MaxY2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Y2Stroke( sName, dVal) + if sName == 'Y1' then + return VerifyY1Stroke( dVal) + elseif sName == 'Y2' then + return VerifyY2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function VerifyV1Stroke( dV1) + if dV1 < MinV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MinV1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MinV1, 3) + EgtOutLog( sErr) + return false + elseif dV1 > MaxV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MaxV1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MaxV1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV2Stroke( dV2) + if dV2 < MinV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MinV2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MinV2, 3) + EgtOutLog( sErr) + return false + elseif dV2 > MaxV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MaxV2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MaxV2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV1V2Stroke( sName, dVal) + if sName == 'V1' then + return VerifyV1Stroke( dVal) + elseif sName == 'V2' then + return VerifyV2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function GetV1ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin) +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 LoadFirstTool( nHSet, sTcPosDef) + if nHSet ~= 1 and nHSet ~= 2 then return end + EgtUnloadTool( EgtIf( nHSet == 1, 'H11', 'H21'), 1) + if GetHeadSetFromTcPos( sTcPosDef) ~= nHSet then return end + local sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis = FindFirstToolOnHeadSet( nHSet) + if not sTool then + local vTools = EgtGetToolsInCurrSetupPos( sTcPosDef) + if vTools and vTools[1] then + sTool = vTools[1] + sTcPos = sTcPosDef + sHead = GetAdjHeadFromTcPos( nHSet, sTcPos) + end + end + if sTool then + -- imposto correttamente i dati di testa + local OrigEMC = EMC + EMC = { HEAD = sHead, TOOL = sTool, TCPOS = sTcPos, TOTLEN = sTTotLen, TOTDIAM = sTotDiam, BLOCKEDAXIS = sBlockedAxis} + OnSetHead() + EMC = OrigEMC + if sBlockedAxis then + local dPosA = tonumber( sBlockedAxis:sub( 4) or '') or 0 + if dPosA ~= 0 then + -- imposto il valore di A + EgtSetAxisPos( EgtIf( nHSet == 1 , 'A1', 'A2'), dPosA) + end + end + -- carico l'utensile + EgtLoadTool( sHead, 1, sTool) + ShowToolInTcPos( sTcPos, false) + -- salvo utensili caricati + if nHSet == 1 then + EMT.PREVTOOL_H1 = sTool + EMT.PREVHEAD_H1 = sHead + EMT.PREVTCPOS_H1 = sTcPos + EMT.PREVTTOTLEN_H1 = sTTotLen + -- per gruppo testa 2 + elseif nHSet == 2 then + EMT.PREVTOOL_H2 = sTool + EMT.PREVHEAD_H2 = sHead + EMT.PREVTCPOS_H2 = sTcPos + EMT.PREVTTOTLEN_H2 = sTTotLen + end + end + return sTool +end + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 70000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 32000 -- 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 = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- 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( 'X1') + EMT.L3 = EgtGetAxisHomePos( 'Z1') + EMT.R1 = EgtGetAxisHomePos( 'C1') + EMT.R2 = EgtGetAxisHomePos( 'B1') + -- 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, eventuale rotazione + elseif IsMidPhase( 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 +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 + if EMT.AUXTOT > 3 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 3) * 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 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 IsStartOrMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or 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 GetParkT() + local dTmp = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EgtGetInfo( EMT.DISPID, 'TPARK', 'd') + if dTmp then + return dTmp + else + return LoadT + end +end + +--------------------------------------------------------------------- +function FindFirstToolOnHeadSet( nHSet) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su gruppo testa indicato + local sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis + 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 + sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if GetHeadSet( sHead) == nHSet then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + -- aggregato lama non si può mai preselezionare e viene sempre scaricato, quindi non sarà mai già caricato + if nHSet == 2 and sTcPos == 'T201' then + sTcPos = nil + break + end + sTool = sTest + sTTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + sTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + sBlockedAxis = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + EgtSetCurrMachining( CurrMachId or GDB_ID.NULL) + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis +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 + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTcPos +end + +--------------------------------------------------------------------- +function GetNextChainSawingVirtualAxis( MchId) + -- recupero la lavorazione successiva + local NextMchId + if MchId then + NextMchId = EgtGetNextActiveOperation( MchId) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + -- verifico sia un taglio con sega a catena + if EgtGetOperationType( NextMchId) ~= MCH_OY.MORTISING then + return nil + end + -- la imposto come lavorazione corrente + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + -- ripristino la lavorazione corrente + if MchId then + EgtSetCurrMachining( MchId) + end + return dPosA +end + +--------------------------------------------------------------------- +function GetCurrSawingVirtualAxis() + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A2=0' + local dPosA = tonumber( sVal:sub( 4)) or 0 + return dPosA +end + +--------------------------------------------------------------------- +function GetNextSawingVirtualAxis( MchId) + -- recupero la lavorazione successiva + local NextMchId + if MchId then + NextMchId = EgtGetNextActiveOperation( MchId) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + -- verifico sia un taglio o fresatura con lama su aggregato da sotto + if ( EgtGetOperationType( NextMchId) ~= MCH_OY.MILLING and EgtGetOperationType( NextMchId) ~= MCH_OY.SAWING) or EMT.HEAD ~= 'H22' then + return nil + end + -- la imposto come lavorazione corrente + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrSawingVirtualAxis() + -- ripristino la lavorazione corrente + if MchId then + EgtSetCurrMachining( MchId) + end + return dPosA +end +--------------------------------------------------------------------- +function GetStartMachiningXaxis( nMchId) + -- Recupero quota X (nostro -L2) + local nClEntId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nMchId, 'CL') or GDB_ID.NULL, 'P1') or GDB_ID.NULL) + local vAxes = EmtGetAxesPos( nClEntId or GDB_ID.NULL) + if vAxes and #vAxes >= 2 then + return -vAxes[2] + else + return nil + end +end + +--------------------------------------------------------------------- +function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H16' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + elseif sHead == 'H21' or sHead == 'H22' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + end +end + +--------------------------------------------------------------------- +function GetCmdAxMove( Cmd, sAx) + if #Cmd >= 3 and Cmd[2] == sAx then + return tonumber( Cmd[3]) + elseif #Cmd >= 5 and Cmd[4] == sAx then + return tonumber( Cmd[5]) + elseif #Cmd >= 7 and Cmd[6] == sAx then + return tonumber( Cmd[7]) + end +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** diff --git a/Common_PF1250.mlse b/Common_PF1250.mlse new file mode 100644 index 0000000..792b8eb --- /dev/null +++ b/Common_PF1250.mlse @@ -0,0 +1,2557 @@ +-- Special Operations macchina Essetre-PF1250 by Egalware s.r.l. 2024/04/09 +-- Intestazioni + +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico libreria +local BD = require( 'BeamData') + +--------------------------------------------------------------------- +-- *** Special Z moves *** +--------------------------------------------------------------------- +---------------------- OnSpecialGetMaxZ ----------------------------- +local function CalcExtraZ( vtTp, vtT, vMZ) + -- la tabella deve esistere ed essere non vuota + if not vMZ or #vMZ == 0 then return 0 end + -- componente Z di riferimento è la minima + local vtTz = min( vtTp:getZ(), vtT:getZ()) + -- se oltre il massimo + if vtTz > vMZ[1].Tz then return vMZ[1].Ez end + -- interpolo + for i = 2, #vMZ do + if vtTz > vMZ[i].Tz then + local dCoeff = ( vtTz - vMZ[i-1].Tz) / ( vMZ[i].Tz - vMZ[i-1].Tz) + return (( 1 - dCoeff) * vMZ[i-1].Ez + dCoeff * vMZ[i].Ez) + end + end + -- sotto il minimo + return 0 +end + +--------------------------------------------------------------------- +function OnSpecialGetMaxZ() + -- Inizializzazioni + EMC.ERR = 0 + + -- Gestione speciale per sega a catena + if EMC.HEAD == 'H13' then + EMC.MAXZ = EgtGetAxisHomePos( 'Z1') + return + end + + -- Sistemazione dati di input + local vtTp = Vector3d( EMC.TDIRp) + local bFromZmax = false + -- recupero il gruppo + local nSetHead = GetHeadSet( EMC.HEAD) + if vtTp:isSmall() then + vtTp = X_AX() + bFromZmax = true + if nSetHead == 1 then + EMC.R1p = ParkC1 + EMC.R2p = ParkB1 + elseif nSetHead == 2 then + EMC.R1p = ParkC2 + EMC.R2p = ParkB2 + end + end + local vtT = Vector3d( EMC.TDIR) + local vtTpZm = EgtIf( bFromZmax, vtT, vtTp) + local bBSameSign = (( EMC.R2p < 10 and EMC.R2 < 10) or ( EMC.R2p > -10 and EMC.R2 > -10)) + + -- Calcolo in funzione della testa e dei parametri + if EMC.HEAD == 'H11' then + if bBSameSign and vtTp:getX() > -0.1 and vtT:getX() > -0.1 then + EMC.MAXZ = MaxZ1 + else + local vMZ = {{ Tz=0.85, Ez=390}, { Tz=0.5, Ez=280}, { Tz=-0.01, Ez=160}} + EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) + end + elseif EMC.HEAD == 'H12' then + if vtTp:getX() > 0.3 and vtT:getX() > 0.3 then + if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then + EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130) + elseif vtTp:getZ() > 0.707 or vtT:getZ() > 0.707 then + EMC.MAXZ = ParkZ1 + 200 + else + EMC.MAXZ = ParkZ1 + 1 + end + elseif bBSameSign and EMC.R1p > 29.9 and EMC.R1p < 180.1 and EMC.R1 > 29.9 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then + EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130) + elseif bBSameSign and EMC.R1p > -0.1 and EMC.R1p < 180.1 and EMC.R1 > -0.1 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then + local vMZ = {{ Tz=0.85, Ez=440}, { Tz=0.5, Ez=200}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}} + EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) + else + local vMZ = {{ Tz=0.85, Ez=400}, { Tz=0.7, Ez=300}, { Tz=0.5, Ez=195}, { Tz=0.15, Ez=70}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}} + EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) + end + elseif EMC.HEAD == 'H16' then + if vtTp:getX() > 0.3 and vtT:getX() > 0.3 then + if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then + EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130) + elseif vtTp:getZ() > 0.707 or vtT:getZ() > 0.707 then + EMC.MAXZ = ParkZ1 + 200 + else + EMC.MAXZ = ParkZ1 + 1 + end + elseif bBSameSign and EMC.R1p > 29.9 and EMC.R1p < 180.1 and EMC.R1 > 29.9 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then + EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130) + elseif bBSameSign and EMC.R1p > -0.1 and EMC.R1p < 180.1 and EMC.R1 > -0.1 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then + local vMZ = {{ Tz=0.85, Ez=440}, { Tz=0.5, Ez=200}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}} + EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) + else + local vMZ = {{ Tz=0.85, Ez=400}, { Tz=0.7, Ez=300}, { Tz=0.5, Ez=195}, { Tz=0.15, Ez=70}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}} + EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) + end + elseif EMC.HEAD == 'H21' then + if bBSameSign and vtTp:getX() > -0.1 and vtT:getX() > -0.1 then + EMC.MAXZ = MaxZ2 + else + local vMZ = {{ Tz=0.85, Ez=390}, { Tz=0.5, Ez=280}, { Tz=-0.01, Ez=160}} + EMC.MAXZ = ParkZ2 + CalcExtraZ( vtTpZm, vtT, vMZ) + end + end +end + +---------------------- OnSpecialMoveZup ----------------------------- +function OnSpecialMoveZup() + + --EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT)) + + -- Inizializzazioni + EMC.ERR = 0 + EMC.MODIF = false + + -- Direzione utensile + local vtT = Vector3d( EMC.TDIR) + + -- recupero Z1 home + local nHeadSet = GetHeadSet( EMC.HEAD) + local dZmax = EgtGetAxisHomePos( EgtIf( nHeadSet ~= 2, 'Z1', 'Z2')) + + + -- se fresa su testa1 o testa 2 + if EMC.HEAD == 'H11' or EMC.HEAD == 'H21' or EMC.HEAD == 'H22' then + ; + -- se lama + else + -- riporto i valori tra -179 e + 180 + local dCheckAxR1 = EMC.R1 + if dCheckAxR1 < -180 then + dCheckAxR1 = dCheckAxR1 + 360 + elseif dCheckAxR1 > 180 then + dCheckAxR1 = dCheckAxR1 - 360 + end + -- se lama su testa1 + if EMC.HEAD == 'H12' then + -- se inclinata oltre 90 gradi e interferisce con la trave + if ( EMC.R2 > 87.9 and ( dCheckAxR1 < 15.0 or dCheckAxR1 > 180.0)) or ( EMC.R2 < -87.9 and ( dCheckAxR1 > -15.0 and dCheckAxR1 < 180.0)) then + local dZref = dZmax + min( 330 * vtT:getZ(), 0) + 260 * ( 1 - sqrt( 1- vtT:getZ() * vtT:getZ())) + -- se troppo in alto + if EMC.L3 > dZref + 1 then + ---- sistemo asse rotante + --EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + ---- ricalcolo versore utensile + --EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + ---- porto alla giusta quota + --EMC.L3 = dZmax + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + -- se seconda lama su testa1 + elseif EMC.HEAD == 'H16' then + -- se inclinata oltre 90 gradi e interferisce con la trave + if ( EMC.R2 > 87.9 and ( dCheckAxR1 < 15.0 or dCheckAxR1 > 180.0)) or ( EMC.R2 < -87.9 and ( dCheckAxR1 > -15.0 and dCheckAxR1< 180.0)) then + local dZref = dZmax + min( 330 * vtT:getZ(), 0) + 260 * ( 1 - sqrt( 1- vtT:getZ() * vtT:getZ())) + -- se troppo in alto + if EMC.L3 > dZref + 1 then + ---- sistemo asse rotante + --EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + ---- ricalcolo versore utensile + --EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + ---- porto alla giusta quota + --EMC.L3 = dZmax + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + end + end +end + +--------------------------------------------------------------------- +-- *** OnSpecialApplyDisposition & OnPostApplyMachining *** +--------------------------------------------------------------------- +----------------------- Costanti ------------------------------------ +local DELTA_SIC = 1 +local MinJoin = BD.MIN_JOIN_S +local MinOther = abs( MinY1) + abs( MaxY2) + MinJoin +local SIC_V = 50 -- sicurezza da testa +local MIN_ENG_V = 115 -- ingombro asse Z +local MIN_ENG_RACK_V = 161 -- ingombro asse Z con cremagliera +local MIN_ENG_XZ2_V = 180 -- ingombro assi XZ sotto +local MIN_Z2_FOR_ENG_XZ2_V = 270 -- quota Z2 da cui considerare ingombro assi XZ sotto +local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza +local MaxLenSmT = 1500 -- massima lunghezza pezzo scaricato con nastri verdi +local DIST_Y1MAX_LOAD = 100 -- distanza carrello Y1 da massimo asse al carico + +----------------------- Variabili ----------------------------------- +local Test = false +local SPLIT + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiungo + 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 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 IsFirstMachiningOfStart( nMchId) + -- se non è fase inizio di pezzo, ritorno risultato negativo + if not 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 + -- è la prima + return true +end + +--------------------------------------------------------------------- +local function UpdateMinJoin() + MinJoin = BD.GetMinJoin( EMC.SB, EMC.HB, EMC.LB) + MinOther = abs( MinY1) + abs( MaxY2) + 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 GetNextRawInOrd( nCurrRawId) + local nCurrOrd = EgtGetInfo( nCurrRawId, 'ORD', 'i') + if not nCurrOrd then return end + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nCurrOrd + 1 then + return nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end +end + +----------------------------------------------------------------------- +local function EnsureZmax( bCloseV, vCmd) + -- verifico non sia già inserito nella lista dei comandi + for i = 1, #vCmd do + if vCmd[i][1] == 4 then + -- se richiesta chiusura, eventuale inserimento se non già presente + if bCloseV and vCmd[i][2] == 0 then + vCmd[i][2] = 1 + end + return true + end + end + -- posizionamento sicuro teste e rulli + table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)}) + 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 + SPLIT = IsEndPhase( 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 + EMC.MSG = ' Error : creation CL group failed' + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + EMC.MSG = ' Error : creation path in CL group failed' + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and SPLIT 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.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- 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() + 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 + if nRawCount > 1 then + EMC.ERR = 10 + EMC.MSG = ' Error : too many Raw Parts in current Phase' + return + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if not b3Raw or b3Raw:isEmpty() then + EMC.ERR = 11 + EMC.MSG = ' Error : null Raw Part' + return + end + EMC.LB = b3Raw:getDimX() + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- 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 eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 then + dPosT = LoadT + vCmd = SpecCalcLoad( dPosT, 0, 0) + -- 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 dPosY1 = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd') + if not dPosY1 then + EMC.ERR = 14 + EMC.MSG = ' Error : Y1 non clamped (start or rest)' + return + end + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY1 - dPosT, 0}) + -- recupero posizione rulli + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- altrimenti fase successiva pari + else + EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd') + EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') + EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EMC.LB - MinJoin + 10 * GEO.EPS_SMALL + local dDistBack = 0 + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + if EMC.PHASE == 1 then EMC.LOAD = true end + vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL) + EMC.LOAD = nil + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) 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) .. ' (' .. tostring( EMC.MCHID) .. ')') + + -- 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 + EMC.MSG = ' Error : previous Disposition not found' + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 then + -- posizioni home + EMC.TPOS = nil + EMC.Y1DELTA = nil + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = nil + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'Y1POS', 'd') + EMC.TPOS = dPosT + EMC.Y1DELTA = dPosY - dPosT + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 1 + EMC.MSG = ' Error : previous Disposition not found' + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local bAtZMax = ( EgtGetClEntMove( nLastEntId) == 0 and EgtGetClEntFlag( nLastEntId) == 3) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtIf( bAtZMax, ParkV1, EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1) + EMC.V2POS = EgtIf( bAtZMax, ParkV2, EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2) + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + + -- bPreSplit sempre a falso per obbligare a pinzare il pezzo con 1 morsa anche se iniziato il taglio che dividerà grezzo e finito (in genere per sezioni grandi con 2 tagli di lama) + -- Tra un taglio e l'altro infatti c'e' inversione del braccio e quindi un'apertura delle rulliere. Se pinzano entrambe le pinze, potrebbero esserci problemi di collisone rulli-morse + local bPreSplit = false --( sNotes:find( 'Presplit', 1, true) ~= nil) + + local bSplitting = ( sNotes:find( 'Split', 1, true) ~= nil) + local bPreCut = ( sNotes:find( 'Precut', 1, true) ~= nil) + local bCutting = ( sNotes:find( 'Cut', 1, true) ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) + + -- 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 dei carrelli + local OriTPos = EMC.TPOS + local OriY1Delta = EMC.Y1DELTA + local OriY2Delta = EMC.Y2DELTA + local OriV1Pos = EMC.V1POS + local OriV2Pos = EMC.V2POS + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload) + -- 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 dei carrelli + EMC.TPOS = OriTPos + EMC.Y1DELTA = OriY1Delta + EMC.Y2DELTA = OriY2Delta + EMC.V1POS = OriV1Pos + EMC.V2POS = OriV2Pos + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload) + -- 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) + + -- Verifico se lavorazione pareti + local bWall = ( EgtGetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', 'd') == 1) + + -- mi salvo info lavorazione su una lista + local AuxInfoMach = {} + AuxInfoMach.bPreSplit = bPreSplit + AuxInfoMach.bSplitting = bSplitting + AuxInfoMach.bPreCut = bPreCut + AuxInfoMach.bCutting = bCutting + AuxInfoMach.bUnload = bUnload + + -- Assegno flag di pezzo separato dal resto del grezzo + SPLIT = IsEndPhase( EMC.PHASE) + + -- 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 + EMC.MSG = ' Error : null Raw Parts' + return + end + EMC.LB = EgtIf( SPLIT, b3Raw:getDimX(), b3Tot:getDimX()) + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LT = b3Raw:getDimX() + EgtOutLog( ' BarLen='..EgtNumToString( EMC.LB, 1), 3) + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- 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 + -- Recupero ingombro dei tagli di testa del prossimo pezzo (se esiste) + EMC.NEXT_HCING = 0 + local nNextRawId = GetNextRawInOrd( nCurrRawId) + if nNextRawId then + EMC.NEXT_HCING = EgtGetInfo( nNextRawId, 'HCING', 'd') or 0 + end + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack, dRollFront, dRollBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront then return end + local dMaxLenLeft = 0 + if bPreSplit or bSplitting then + local dDistF, dDistB, dRollF, dRollB, dMaxLF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = dDistBack + if bSplitting then dMaxLenLeft = dMaxLF end + elseif bPreCut or bCutting then + local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + + -- Verifico lunghezza pezzo + if not SPLIT and not VerifyPartLength() then + return + end + + -- Calcolo quali carrelli sono necessari + local nChar + if bPreSplit or bSplitting then + nChar = 2 + elseif bPreCut or bCutting then + nChar = 3 + end + local dY1DeltaMaxSP + if nChar == 2 then + dY1DeltaMaxSP = MaxY1 - LoadT + EMC.LT + end + local dY2DeltaMinUL + if ( nChar == 2 or nChar == 3) and not bWall then + dY2DeltaMinUL = EMC.LT + MinY2 - EgtIf( EMC.LT < MaxLenSmT, UnloadSmT, UnloadT) + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6)) + EMC.LOAD = true + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) + EMC.LOAD = nil + if bSplitting and EMC.ERR == 18 then + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + if vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti non eseguito SPLIT, eseguo calcoli per carrelli + elseif not SPLIT then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) + -- Se non ci sono spostamenti, confermo i parametri di aggancio e di posizione roller + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave ma impongo la posizione dei rulli + else + SpecOutputCNT() + local vCmd = {} + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + SpecOutputCmds( vCmd) + end + + -- 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.Y2DELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + SpecOutputCNT() + 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 + -- forzo l'errore 18 + EMC.ERR = 18 + -- verifico che la barra sia agganciata anche al primo carrello + elseif not EMC.Y1DELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y1 or Y2 not clamped' + return false + end + -- eseguo la separazione + EgtOutLog( 'MaxLenLeft=' .. EgtNumToString( dMaxLenLeft, 1), 1) + vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft) + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello Y2 da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'Y2POS', EMC.Y2DELTA) + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + local vCmdTmp = SpecCalcUnload() + 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 + EMC.MSG = ' Error : CL group path not found' + 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 + EMC.MSG = ' Error : machining Min or Max not found' + 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 testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Recupero minimi e massimi degli assi macchina della lavorazione + local vAxMin = EgtGetInfo( nClId, 'MAXMIN', 'vd') + local vAxMax = EgtGetInfo( nClId, 'MAXMAX', 'vd') + if not vAxMin or not vAxMax or #vAxMin < 5 or ( sHead == 'H13' and #vAxMin < 6) then + EMC.ERR = 15 + EMC.MSG = ' Error : machine axes Min or Max not found' + return + end + local vAxMid = {} + for i = 1, #vAxMin do + vAxMid[i] = ( vAxMin[i] + vAxMax[i]) / 2 + end + -- recupero il gruppo + local nSetHead = GetHeadSet( sHead) + -- Calcolo dell'ingombro della testa rispetto allo Zero Macchina (assi rotanti fissi, C=4, B=5, A=6) + local b3Enc + if nSetHead == 1 then + EgtSetAxisPos( 'C1', vAxMid[4]) + EgtSetAxisPos( 'B1', vAxMid[5]) + if sHead == 'H13' then + EgtSetAxisPos( 'A1', vAxMid[6]) + end + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE) + elseif nSetHead == 2 then + EgtSetAxisPos( 'C2', vAxMid[4]) + EgtSetAxisPos( 'B2', vAxMid[5]) + if sHead == 'H22' then + EgtSetAxisPos( 'A2', vAxMid[6]) + end + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), GDB_BB.ONLY_VISIBLE) + else -- 'H31' + EgtSetAxisPos( 'C3', vAxMid[4]) + EgtSetAxisPos( 'B3', vAxMid[5]) + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C3'), GDB_BB.ONLY_VISIBLE) + end + + -- Forzo la distanza di sicurezza da utensile + local nSecRollerDist = EgtGetValInNotes( EgtTdbGetCurrToolParam( MCH_TP.USERNOTES), 'SECDIST', 'i') or SIC_V + + local dMinFrontEng = EgtIf( nSetHead ~= 2, MIN_ENG_RACK_V, EgtIf( vAxMax[3] < MIN_Z2_FOR_ENG_XZ2_V, MIN_ENG_V, MIN_ENG_XZ2_V)) + local dRollFront = max( b3Enc:getMax():getX(), dMinFrontEng) + nSecRollerDist + local dMinBackEng = EgtIf( nSetHead ~= 2, MIN_ENG_V, EgtIf( vAxMax[3] < MIN_Z2_FOR_ENG_XZ2_V, MIN_ENG_V, MIN_ENG_XZ2_V)) + local dRollBack = max( -b3Enc:getMin():getX(), dMinBackEng) + nSecRollerDist + EgtOutLog( ' RollFront = ' .. EgtNumToString( dRollFront, 1) .. ' RollBack = ' .. EgtNumToString( dRollBack, 1), 3) + -- Calcolo della posizione della Punta Utensile rispetto allo Zero Macchina + local ptTip + ptTip = EgtGetCalcTipFromPositions( 0, 0, 0, vAxMid[4], vAxMid[5], vAxMid[6] or 0, false) + EgtOutLog( ' ToolTip = ' .. tostring( ptTip), 5) + -- Calcolo dell'ingombro della testa rispetto alla Punta Utensile + local dHeadFront = dRollFront + AGG_V - ptTip:getX() + local dHeadBack = dRollBack + AGG_V + ptTip:getX() + EgtOutLog( ' HeadFront = ' .. EgtNumToString( dHeadFront, 1) .. ' HeadBack = ' .. EgtNumToString( dHeadBack, 1), 5) + -- Distanze limiti della pinza di destra da testa trave e della pinza di sinistra da coda trave + local dDistFront = - ptMax:getX() - LoadT - dHeadFront + local dDistBack = ptMin:getX() + LoadT + EMC.LB - dHeadBack + EgtOutLog( ' DistFront = ' .. EgtNumToString( dDistFront, 1) .. ' DistBack = ' .. EgtNumToString( dDistBack, 1), 3) + return dDistFront, dDistBack, dRollFront, dRollBack +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 + local dRollFront = 0 + local dRollBack = 0 + local dMaxLenLeft = 0 + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- 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 sTool or not EgtTdbSetCurrTool( sTool) then + local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + sTool = EgtTdbGetToolFromUUID( sTuuid) or '' + EgtTdbSetCurrTool( sTool) + end + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + EgtSetCalcTool( sTool, sHead, 1) + -- calcolo ingombri + local dDistF, dDistB, dRollF, dRollB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + dRollFront = max( dRollFront, dRollF) + dRollBack = max( dRollBack, dRollB) + local dMaxLenL = EMC.LT - dDistF - AGG_V - dRollF + EgtOutLog( ' MaxLenLeft = ' .. EgtNumToString( dMaxLenL, 1), 3) + dMaxLenLeft = max( dMaxLenLeft, dMaxLenL) + 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 then EgtSetCalcTool( sOrigTool, sOrigHead, 1) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack, dRollFront, dRollBack, dMaxLenLeft +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 VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AggLoad + EMC.HCING + EMC.HOVM then + EMC.ERR = 17 + EMC.MSG = ' Error CLAMP : part too short' + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dNewY1min = max( EMC.LB - dDistBack, MinOther + AggLoad + EMC.HCING + EMC.HOVM) + local dNewY1max = min( ( MaxY1 - MinY1) - 5, EMC.LB - MinJoin) + if dNewY1min > dNewY1max then return nil end + -- minimo posizionamento pinza 1 per permettere scarico del restante + local dMinLengthRestToUnload = abs( MinY1) + abs( MinV1) + abs( MaxV2) + abs( MaxY2) + MinJoin + AggLoad + EMC.LT + 10 + -- calcolo posizionamento con i coefficienti, ma verifico che sia tra il minimo e il massimo pinzabile + local dNewY1DeltaMax = EgtClamp( 0.25 * dNewY1min + 0.75 * dNewY1max, dMinLengthRestToUnload, dNewY1max) + local dNewY1Delta = EgtClamp( BD.CHAR_LOAD_DIST or 3000, 0.75 * dNewY1min + 0.25 * dNewY1max, dNewY1DeltaMax) + local dNewY2Delta = nil + local dNewY1 = dPosT + dNewY1Delta + local vCmd = {} + EgtOutLog( ' *[L]', 1) + -- [L-1] + if dNewY1 + TurnerOffs + DIST_Y1MAX_LOAD - MaxY1 > 0 then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD) + EgtOutLog( ' *[L1]', 1) + end --[L-2] + if EMC.LB - dNewY1Delta < MinJoin then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD) + EgtOutLog( ' *[L2]', 1) + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- posizionamento sicuro teste e rulli + EnsureZmax( false, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'Y1', dPosT + dNewY1Delta, 'Y2', ParkY2}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, 1}) + -- Sposto il carrello Y con la testa trave al parcheggio V1 + table.insert( vCmd, { 2, 'T', ParkV1, 'Y1', ParkV1 + dNewY1Delta}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewY1Delta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = ParkV1 + EMC.Y1DELTA = dNewY1Delta + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AggLoad, 0) + local dMyDistBack = dDistBack - EgtIf( EMC.CNT == 1, AggLoad, 0) + + local sMaxSplit = '' + if dY1DeltaMaxSP then sMaxSplit = '/'..EgtNumToString( dY1DeltaMaxSP, 1)..'(MaxSplit)' end + local sMinUnload = '' + if dY2DeltaMinUL then sMinUnload = '/'..EgtNumToString( dY2DeltaMinUL, 1)..'(MinUnload)' end + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dMyDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit .. + ' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3) + + local bBackOk = ( dMyDistBack > MinJoin - GEO.EPS_SMALL) + local bFrontOk = ( dDistFront > MinFrontJoin - GEO.EPS_SMALL) + + -- [A] se non richiesto solo carrello Y2 e posso mettere solo carrello Y1 + if ( nChar ~= 2 and nChar ~= 3 and bBackOk) or + ( nChar == 2 and bBackOk and not bFrontOk) then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dMyDistBack, MyMinOther + EMC.HCING + EMC.HOVM) + WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V) + WorkTab.dY2DeltaMinF = nil + WorkTab.dY2DeltaMaxF = nil + if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare + if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF) + end + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + -- al carico o con prima lavorazione di un pezzo si deve ignorare l'ingombro delle lavorazioni di testa per il pinzaggio + if EMC.LOAD or IsFirstMachiningOfStart( EMC.MCHID) then EMC.HCING = 0 end + + return SpecAdjustCarriages( WorkTab) + + -- [B] se richiesti entrambi e posso metterli + elseif nChar == 2 and bBackOk and bFrontOk then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dMyDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING) + WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V) + WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dMyDistBack - AGG_V - dRollBack) + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther) -- - EMC.TCING + if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare + if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF) + end + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- [C] se non richiesti entrambi e posso mettere carrello Y2 + elseif bFrontOk then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = nil + WorkTab.dY1DeltaMaxF = nil + WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dMyDistBack - AGG_V - dRollBack) + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther) -- - EMC.TCING + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dMyDistBack) .. + ' MinJoin=' .. EgtNumToString( MinJoin) .. ' MinFrontJoin=' .. EgtNumToString( MinFrontJoin)) + end + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP impossible' + return {} + end +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw, dMaxLenLeft) + local vCmd = {} + EgtOutLog( ' *[S]', 1) + local bSplit = ( EMC.Y2DELTA ~= nil) + local ParkT = ParkV1 + if bSplit then + if dMaxLenLeft + 100 > LoadT then + ParkT = dMaxLenLeft + 300 + elseif dMaxLenLeft + 100 > ParkV1 then + ParkT = LoadT + end + end + table.insert( vCmd, { 0, EgtIf( bSplit, 'Split', 'Fall')}) + if not bSplit then EnsureZmax( false, vCmd) end + -- 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, 'Y1'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.Y1DELTA - dLenRaw + table.insert( vCmd, { 1, 'Y1', ParkT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.Y1DELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + if not bSplit then + EgtSetInfo( PostDispId, 'TPOS', ParkT) + else + EgtRemoveInfo( PostDispId, 'TPOS') + EgtSetInfo( PostDispId, 'TPARK', ParkT) + end + EgtSetInfo( PostDispId, 'Y1POS', ParkT + 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', ParkT) + EgtSetInfo( NextDispId, 'Y1POS', ParkT + dLDelta) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]', 1) + if not EMC.Y1DELTA and not EMC.Y2DELTA then + EMC.ERR = 21 + EMC.MSG = ' Error : Y1 and Y2 not clamped for unloading' + return {} + end + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + -- Se pinza Y1 chiusa o Y2 troppo a destra, devo effettuare uno scambio + if EMC.Y1DELTA or EMC.Y2DELTA < dY2DeltaMinUL then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + if not nLastEntId then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL')) + nLastEntId = EgtGetLastInGroup( nPathId) + end + 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 - MinJoin - EMC.HOVM + 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- imposto rulli aperti (in ogni caso pezzo sicuramente grande) + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, nil, dY2DeltaMinUL) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]', 1) + end + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Unloading'}) + -- posizionamento sicuro teste e rulli (non serve ?) + --table.insert( vCmd, { 4, 0}) + -- Se pinza Y chiusa, la apro + if EMC.Y1DELTA then + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + end + -- Sposto il pezzo in posizione di scarico + local dFinT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) - EMC.LB + local dFinY2 = dFinT + EMC.Y2DELTA + table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2}) + EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2), 1) + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y2', ParkY2}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +local function ChangedTool( nMchId) + local nChanged = 0 + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigBlockedAx = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + -- Recupero l'utensile della lavorazione precedente + local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL) + if nPrevMchId and EgtGetOperationType( nPrevMchId) ~= MCH_OY.DISP then + EgtSetCurrMachining( nPrevMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + nChanged = EgtIf( sTool ~= sOrigTool, 1 , 0) + local sBlockedAx = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + -- se stesso utensile, ma modo caricamento diverso, è come se fosse un cambio utensile. Vale solo se aggregato su lama da sotto. + if sTool == sOrigTool then + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if sHead == 'H22' and sOrigBlockedAx ~= sBlockedAx then + nChanged = 2 + end + end + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + return nChanged +end + +-------------------------------------------------------------------------------------------------------- +-- **CHIAMATA DELLE FUNZIONI Spec** +-------------------------------------------------------------------------------------------------------- +function SpecAdjustCarriages( WorkTab) + + --EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_')) + local bChangedTool = ChangedTool( EMC.MCHID) + -- Aggiorno la posizione dei rulli per eventuale cambio utensile + if bChangedTool ~= 0 then + WorkTab.dV1PosI = ParkV1 + WorkTab.dV2PosI = ParkV2 + end + -- Verifico se compattare i rulli + local bCloseV = false + if WorkTab.dY1DeltaI then + local dY1DeltaLim = MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0) + if WorkTab.dY1DeltaI <= dY1DeltaLim or ( WorkTab.dY1DeltaMaxF and WorkTab.dY1DeltaMaxF <= dY1DeltaLim) then + bCloseV = true + end + end + if WorkTab.dY2DeltaI then + local dY2DeltaLim = MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + if EMC.LB - WorkTab.dY2DeltaI <= dY2DeltaLim or ( WorkTab.dY2DeltaMinF and EMC.LB - WorkTab.dY2DeltaMinF <= dY2DeltaLim) then + bCloseV = true + end + end + -- se ho cambiato modo di prendere utensile, forzo chiusura + if bChangedTool == 2 then + bCloseV = true + end + -- se i pezzi del cliente sono molto storti, si forza la chiusura per evitare che vada a sbattere. Se parametro non presente, si chiude solo se necessario + if ForceToCloseRollersGate then + bCloseV = true + end + + WorkTab.bCloseV = bCloseV + + -- |POSIZIONO Y1| **[A]** + if WorkTab.dY1DeltaMinF and ( not WorkTab.dY2DeltaMinF) then + -- [A1]/[A2] continuazione da morsa Y1 ( Y1 -> Y1 ) scambio Y2 (Y2 -> Y1) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrA( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y1 impossibile') + error( 'Error CLAMP NULL-> Y1 impossibile') + end + + -- |POSIZIONO Y1Y2| **[B]** + elseif WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [B1] passo da carrello Y1 a entrambi + if WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI) then + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrB1( WorkTab) + -- [B2] passo da carrello Y2 a entrambi + elseif WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI) then + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + return SpecAdjustCarrB2(WorkTab) + -- [B3] rimango con due carrelli ( per ora accetto solo il caso in cui le posizioni sono già valide) + elseif WorkTab.dY1DeltaI > WorkTab.dY1DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY1DeltaI < WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and + WorkTab.dY2DeltaI > WorkTab.dY2DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI < WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EgtOutLog( '*[B3]', 1) + return {} + else + EgtOutLog( ' Error CLAMP NULL-> Y1+Y2 impossibile') + error( 'Error CLAMP NULL-> Y1+Y2 impossibile') + end + + -- |POSIZIONO Y2| **[C]** + elseif not WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [C1]/[C2] continuazione da morsa Y2 ( Y2 -> Y2 ) sacmbio Y1 (Y1 -> Y2) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrC( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y2 impossibile') + error( 'Error CLAMP NULL-> Y2 impossibile') + end + end + +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **accentramento** +local function PosForCent1FY1( dY1a, dY2a, dTa, dExtraY1, dCorsaY1c, dCorsaY2Tc) + local dY2Delta = dY2a - dTa + local dDispl = dCorsaY1c - dExtraY1 + if dDispl / 2 <= dCorsaY2Tc then + if dDispl / 2 <= dCorsaY1c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY1a = dY1a - dCorsaY1c + dY2a = dY2a + dDispl - dCorsaY1c + end + else + dY2a = dY2a + dCorsaY2Tc + dY1a = dY1a - (dDispl - dCorsaY2Tc) + end + dTa = dY2a - dY2Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **accentramento** +local function PosForCent1FY2( dY1a, dY2a, dTa, dExtraY2, dCorsaY1Tc, dCorsaY2c) + local dY1Delta = dY1a - dTa + local dDispl = dCorsaY2c + dExtraY2 + if dDispl / 2 <= dCorsaY1Tc then + if dDispl / 2 <= dCorsaY2c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY2a = dY2a + dCorsaY2c + dY1a = dY1a - min( dDispl - dCorsaY2c, dCorsaY1Tc) + end + else + dY1a = dY1a - dCorsaY1Tc + dY2a = dY2a + min( dDispl - dCorsaY1Tc, dCorsaY2c) + end + dTa = dY1a - dY1Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **allontanamento** +local function PosForEnl1FY1( dY1a, dY2a, dTa, dExtra, dCorsaY1e, dCorsaY2Te) + local dDispl = MaxY1 - dY1a + dExtra + -- eseguo il posizionamento di Y1 allontanando Y1 e (Y2+T) + if dDispl/2 <= dCorsaY2Te then + if dDispl/2 <= dCorsaY1e then + dY1a = dY1a + dDispl / 2 + dY2a = dY2a - dDispl / 2 + dTa = dTa - dDispl / 2 + else + dY1a = dY1a + dCorsaY1e + dY2a = dY2a - (dDispl - dCorsaY1e) + dTa = dTa - (dDispl - dCorsaY1e) + end + else + dY2a = dY2a - dCorsaY2Te + dTa = dTa - dCorsaY2Te + dY1a = dY1a + (dDispl - dCorsaY2Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **allontanamento** +local function PosForEnl1FY2( dY1a, dY2a, dTa, dExtra, dCorsaY1Te, dCorsaY2e) + local dDispl = dY2a - MinY2 - dExtra + -- eseguo il posizionamento di Y2 allontanando (Y1+T) e Y2 + if dDispl/2 <= dCorsaY1Te then + if dDispl/2 <= dCorsaY2e then + dY1a = dY1a + dDispl / 2 + dTa = dTa + dDispl / 2 + dY2a = dY2a - dDispl / 2 + else + dY2a = dY2a - dCorsaY2e + dY1a = dY1a + (dDispl - dCorsaY2e) + dTa = dTa + (dDispl - dCorsaY2e) + end + else + dY1a = dY1a + dCorsaY1Te + dTa = dTa + dCorsaY1Te + dY2a = dY2a - (dDispl - dCorsaY1Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +local function MaxDispl( TabI, vCmd, sType) + local dY1a, dY2a + local dTa = TabI.dTPosI + -- **[M1]** = allontanamento dei trascinatori con Y1 in presa + if sType == 'M1' then + EmitComment( vCmd, '[M1]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- allontano (Y1+T) e (Y2) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( dY1a - TabI.dY1PosI) + dTa + -- **[M2]** = allontanamento dei trascinatori con Y2 in presa + elseif sType == 'M2' then + EmitComment( vCmd, '[M2]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- allontano (Y2+T) e (Y1) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( dY2a - TabI.dY2PosI) + dTa + -- **[M3]** = accentramento dei trascinatori con Y1 in presa + elseif sType == 'M3' then + EmitComment( vCmd, '[M3]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro (Y1+T) e (Y2) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( dY1a - TabI.dY1PosI) + dTa + -- **[M4]** = accentramento dei trascinatori con Y2 in presa + elseif sType == 'M4' then + EmitComment( vCmd, '[M4]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- accentro (Y2+T) e (Y1) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( dY2a - TabI.dY2PosI) + dTa + end + -- + table.insert( vCmd, { 3, 'Y1', dY1a, 'Y2', dY2a, 'T', dTa, EMC.CNT}) + TabI.dY1PosI = dY1a + TabI.dY2PosI = dY2a + TabI.dTPosI = dTa +end -- MaxDisplForRiXw + +----------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1** +------------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - MaxY1 --se > 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per Y1 e (Y2+T) + t.dCorsaY1eI = MaxY1 - TabI.dY1PosI + t.dCorsaY2TeI= TabI.dY2PosI - MinY2 + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + --return t.dY1DeltaI + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY1New > t.dCorsaY2TeI then + EmitComment( vCmd, '[Y1A-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M2') + --t.bXW = true + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- **1:** calcolo pos. di allontanamento per (Y1) e (Y2+T) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1eI, t.dCorsaY2TeI) + -- aggiornamento posizioni e dY1Delta dopo + -- chiusura di Y1, apertura e parcheggio di Y2 a fine funzione + -- ev' chiudo Y2 e apro Y1 ed eseguo allontanamento + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2A + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = ( TabI.dTPosI + t.dY2NewDelta) - MinY2 --se < 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per (Y1+T) e Y2 + t.dCorsaY1Te = MaxY1 - TabI.dY1PosI + t.dCorsaY2e = TabI.dY2PosI - MinY2 + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI- TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY2New > t.dCorsaY1Te then + EmitComment( vCmd, '[Y2A-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M1') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- **1:** calcolo pos. di allontanamento per (Y1+T) e (Y2) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1Te, t.dCorsaY2e) + -- chiudo Y1 e apro Y2 ed eseguo allontanamento (finale) + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, ev' apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1A + +------------------------------------------------------------------------------------------------------------ +-- **ACCENTRAMENTO di Y1** +------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - TabI.MyMinY1V1 -- se < 0, la posizione non è raggiunginile + -- corse in accentramento disponibili per Y1 e (Y2+T) dalle posizioni iniziali + t.dCorsaY1cI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2TcI = TabI.MaxY2V2 - TabI.dY2PosI + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY1New > t.dCorsaY2TcI then + EmitComment( vCmd, '[Y1B-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M4') + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- **1: calcolo accentramento di (Y1) e (Y2+T)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1cI, t.dCorsaY2TcI) + -- posizionamento efettivo e aggiornamento di vCmd e dY1Delta dopo + -- ch. di Y1 e ap. e parcheggio di Y2 a fine funzione chiamante + -- chiudo Y2 e apro Y1 ed eseguo accentramento (finale) + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2B + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = (TabI.dTPosI + t.dY2NewDelta) - TabI.MaxY2V2 -- se > 0 la posizione non è raggiunginile + -- corse in accentramento disponibili per (Y1+T) e (Y2) dalle posizioni iniziali + t.dCorsaY1TcI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2cI = TabI.MaxY2V2 - TabI.dY2PosI + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI-TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY2New > t.dCorsaY1TcI then + EmitComment( vCmd, '[Y2B-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M3') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + -- Y1 chiuso, Y2 aperto + -- **1: calcolo accentramento di (Y1+T) e (Y2)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1TcI, t.dCorsaY2cI) + -- ev' chiudo Y1 e apro Y2 ed eseguo movimento accentramento + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2A]') + -- |RICONOSCO I CASI| + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **allontanamento** + PosY1FromY2A( TabI, vCmd) + -- |POSIZIONO MORSA 2| + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 raggiungibile in una sola fase + if - (( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + else + -- in **accentramento** + -- sempre se intervallo per Y2 raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa ( casi **[xw]**) + EmitComment( vCmd, '[Y1A-xw]') + if TabI.dY1PosI ~= TabI.MyMinY1V1 then + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + else + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + end + end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY1DeltaMaxF) - TabI.MyMinY1V1) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **accentramento** + PosY1FromY2B( TabI, vCmd) + -- |POSIZIONO MORSA 2| + local dY2DeltaI = TabI.dY2PosI - TabI.dTPosI + -- Se il trascinatore 2 non è già nell'intervallo richiesto + if dY2DeltaI > TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL or dY2DeltaI < TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI <= TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]** ) + -- se Y1 non è a f.c. e se Y1 può afferrare la trave + EmitComment( vCmd, '[Y1B-xw]') + if TabI.dY1PosI ~= MaxY1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M1') + else + -- accentramento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M4') + end + end + nCnt = nCnt + 1 + if nCnt > 10 then return end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1A]') + -- |RICONOSCO I CASI| + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo <=> ( -ExtraI2MaxF < Corsa Y1Te and) + -- e Y1 è in posizione per aggancio su T + if MinY2 - ( TabI.dTPosI + TabI.dY2DeltaMaxF) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **allontanamento** + PosY2FromY1A( TabI, vCmd) + -- |POSIZIONO MORSA 1| + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- caso di allontanamento + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se l'intervallo per Y1 è raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se l'intervallo per Y1 è raggiungibile in una sola fase + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]**) + EmitComment( vCmd, '[Y2A-xw]') + -- accentramento morse, trascinamento trave con Y2 + if TabI.dY2PosI ~= TabI.MaxY2V2 then + MaxDispl( TabI, vCmd, 'M4') + -- allontanamento morse, trascinamento trave con Y1 + else + MaxDispl( TabI, vCmd, 'M1') + end + end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 <=> (-ExtraI2MinF < Corsa Y1Tc) + -- e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **accentramento** + PosY2FromY1B( TabI, vCmd) + -- |POSIZIONO MORSA 1| + local dY1DeltaI = TabI.dY1PosI - TabI.dTPosI + -- Se il trascinatore 1 non è già nell'intervallo richiesto + if dY1DeltaI > TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL or dY1DeltaI < TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- in **allontanamento** + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se intervallo per Y1 è raggiungibile in una sola fase e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- se (-ExtraI1MaxF < Corsa Y2Tc) e (Y2 è in posizione per aggancio su T) + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI >= TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa (casi x[w]) + EmitComment( vCmd, '[Y2B-xw]') + -- se Y2 non è a f.c. e se Y2 può afferrare la trave + if TabI.dY2PosI > MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HOVM + EMC.HCING - 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + else + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + end + end + nCnt = nCnt + 1 + if nCnt > 10 then return end + until ( not bXW) + -- la chiusura delle morse è fatta sopra + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1FromY1B + +--------------------------------------------------------------------- +-- **[A] Posizionamento trascinatore Y1 da (Y1 o Y2) <=> Y1/Y2 -> Y1** +--------------------------------------------------------------------- +function SpecAdjustCarrA( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y1'}) + EmitComment( vCmd, '*[A]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) + + -- [A(1)] - Se il trascinatore Y1 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF - GEO.EPS_SMALL or WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[A(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 2| + -- ------------------------------------------ + WorkTab.dY2DeltaMaxF = WorkTab.dY1DeltaMinF - ( MyMinY1V1 - MaxY2V2) + ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + WorkTab.dY2DeltaMinF = WorkTab.dY1DeltaMaxF - ( MaxY1 - MinY2) - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + -- se Y2 deve allontanarsi assegno il primo punto valido (altrimenti mantengo tutto l'intervallo valido) + if WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF then + WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF), MinJoin + EMC.HCING + EMC.HOVM) + end + -- se la trave è più 'corta' dell'intervallo per Y2 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY2DeltaMinF < MinJoin + EMC.HCING + EMC.HOVM then + WorkTab.dY2DeltaMinF = MinJoin + EMC.HCING + EMC.HOVM + -- se Y2 deve accentrarsi + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF then + WorkTab.dY2DeltaMaxF = 2 * MinJoin + EMC.HCING + EMC.HOVM + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -------------------------------------------- + -- |RICONOSCO I CASI| + -------------------------------------------- + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + if WorkTab.dY1DeltaI > dY1NewDelta then + --[A(1)B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[A-Y1B]') + dY1DeltaF = PosY1Y2B( TabValI, vCmd) + else + --[A(1)A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[A-Y1A]') + dY1DeltaF = PosY1Y2A( TabValI, vCmd) + end + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + -- dichiaro Y2 da parcheggiare + WorkTab.bY2Parked = false + + -- [A(0)] - Se Y1 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[A(0)]') + if not WorkTab.bY2Parked then + -- dichiaro posizione di Y2 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y2', dY2PosI}) + end + if WorkTab.bY1Parked then + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + end + dY1DeltaF = WorkTab.dY1DeltaI + end + + if not WorkTab.bY2Parked then + -- apro e parcheggio Y2 + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 1, 'Y2', ParkY2}) + end + + -- aggiorno e segnalo la posizione finale Y1Delta + table.insert( vCmd, { 21, dY1DeltaF, 0}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF), 1) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrAA + +-------------------------------------------------------------------- +-- **[B1] da trascinatore Y1 a entrambi <=> Y1 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB1( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1 -> Y1+Y2'}) + EmitComment( vCmd, '*[B1]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF, dY2DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B1-Y2A] **ALLONTANAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + if WorkTab.dY2DeltaI > dY2NewDelta then + EmitComment( vCmd, '[B1-Y2A]') + dY1DeltaF, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + else + -- [B1-Y2B] **ACCENTRAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + EmitComment( vCmd, '[B1-Y2B] ') + dY1DeltaF, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + end + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT}) + end + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- **[B2] da trascinatore Y2 a entrambi <=> Y2 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB2( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y2 -> Y1+Y2'}) + EmitComment( vCmd, '*[B2]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- definisco le posizioni **Iniziali** (= recupero le posizioni correnti) + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF, dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI)..' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B2-Y1A] **ALLONTANAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + if WorkTab.dY1DeltaI < dY1NewDelta then + EmitComment( vCmd, '[B2-Y1A]') + dY1DeltaF, dY2DeltaF = PosY1Y2A( TabValI, vCmd) + else + -- [B2-Y1B] **ACCENTRAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + EmitComment( vCmd, '[B2-Y1B]') + dY1DeltaF, dY2DeltaF = PosY1Y2B( TabValI, vCmd) + end + + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT}) + end + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB2 + +--------------------------------------------------------------------- +-- **[C] ex[C1]/[C2] Posizionamento trascinatore Y2 da (Y1 o Y2) <=> Y1/Y2 -> Y2** +--------------------------------------------------------------------- +function SpecAdjustCarrC( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y2'}) + EmitComment( vCmd, '*[C]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + local MyTCING = EgtIf( SPLIT, EMC.TCING, 0) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF + -- + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) + + -- [C(1)] - Se il trascinatore Y2 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF - GEO.EPS_SMALL or WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[C(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 1| + -- ------------------------------------------ + WorkTab.dY1DeltaMaxF = WorkTab.dY2DeltaMinF + (MaxY1 - MinY2) + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + WorkTab.dY1DeltaMinF = WorkTab.dY2DeltaMaxF + (MyMinY1V1 - MaxY2V2) - (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + -- se Y1 deve allontanarsi assegno il primo punto valido (altrimenti lascio l'intervallo) + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF then + WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF), EMC.LB - MinJoin - MyTCING) + end + -- se la trave è più 'corta' dell'intervallo per Y1 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY1DeltaMaxF > EMC.LB - ( MinJoin + MyTCING) then + WorkTab.dY1DeltaMaxF = EMC.LB - ( MinJoin + MyTCING) + -- se Y1 deve accentrarsi + if WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF then + WorkTab.dY1DeltaMinF = EMC.LB - 2 * MinJoin - MyTCING + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + + -- ------------------------------------------ + -- |RICONOSCO I CASI| + -- ------------------------------------------ + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF} + if WorkTab.dY2DeltaI < dY2NewDelta then + -- [C-Y2B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2B]') + _, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + else + -- [C-Y2A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2A]') + _, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + end + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + -- dichiaro Y1 da parcheggiare + WorkTab.bY1Parked = false + + -- [C(0)] - Se Y2 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[C(0)]') + if not WorkTab.bY1Parked then + -- dichiaro posizione di Y1 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y1', dY1PosI, EMC.CNT}) + end + if WorkTab.bY2Parked then + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + end + dY2DeltaF = WorkTab.dY2DeltaI + end + + if not WorkTab.bY1Parked then + -- apro e parcheggio Y1 + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 1, 'Y1', ParkY1}) + end + + -- aggiorno e segnalo la posizione finale Y2Delta + table.insert( vCmd, { 21, 0, dY2DeltaF}) + EgtOutLog( ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrC2 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecGetCNT( CurrOpeId) + while CurrOpeId do + local nPrevOpeId = EgtGetPrevActiveOperation( CurrOpeId) + if not nPrevOpeId then + return nil + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + if nLastPathId then + return EgtGetInfo( nLastPathId, 'CNT', 'i') + end + CurrOpeId = nPrevOpeId + end + return nil +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + -- Registro il numero di comandi + if vCmd and #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #(vCmd or {}) do + local Cmd = vCmd[i] + local sKey = sRoot .. tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..EgtIf( Cmd[4], ',*', '') + 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)..EgtIf( Cmd[6], ',*', '') + 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)..EgtIf( Cmd[8], ',*', '') + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- posizione sicura per movimento carrelli + elseif Cmd[1] == 4 then + local sInfo = '4,'..EgtNumToString( Cmd[2],0) + 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) + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- 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.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + -- impostazione nuova posizione dei rulli + elseif Cmd[1] == 22 then + local sInfo = '22,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- segnalazione errore + elseif Cmd[1] == 99 then + local sInfo = '99,' .. Cmd[2] .. ',' .. Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.Y1DELTA then + EgtSetInfo( EMC.PATHID, 'Y1DELTA', EMC.Y1DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y1DELTA') + end + if EMC.Y2DELTA then + EgtSetInfo( EMC.PATHID, 'Y2DELTA', EMC.Y2DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y2DELTA') + end + + --Salvo le nuove posizioni dei rulli + EgtSetInfo( EMC.PATHID, 'V1POS', EMC.V1POS) + EgtSetInfo( EMC.PATHID, 'V2POS', EMC.V2POS) + -- Se comandi finali + if bEnd then + -- Se operazione successiva è disposizione, salvo anche lì le posizioni dei rulli + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId and NextDispId == EgtGetNextActiveOperation( EMC.DISPID or EMC.MCHID) then + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #(vCmd or {}) do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + elseif Cmd[1] == 22 then + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + 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 + +--------------------------------------------------------------------- +function SpecTestSomeMoveInCmds( vCmd) + if not vCmd then return false end + -- verifico se nella lista dei comandi c'è almeno un movimento + for i = 1, #vCmd do + if vCmd[i][1] == 1 or vCmd[i][1] == 2 or vCmd[i][1] == 3 then + return true + end + end + return false +end diff --git a/Compile.bat b/Compile.bat new file mode 100644 index 0000000..aa23176 --- /dev/null +++ b/Compile.bat @@ -0,0 +1,36 @@ + +REM Compilazione degli script macchina Egaltech 2024.02.22 +REM Per togliere info di debug aggiungere flag -s prima del nome del file di input + +REM Compilazione 32 bit e copia file da non compilare + +@echo off + +REM chiedo all'utente la versione da assegnare alla macchina da compilare +set /p "machineVersion=Inserisci versione: " + +REM variabili per costruire i percorsi delle cartelle +set "machineName=Essetre-PF1500rl" +set "deployFolder=C:\MachinesDeploy" +set "machinePath=%deployFolder%\%machineName%\" +set "fullPathSource=%deployFolder%\%machineName%\%machineVersion%\%machineName%" +set "fullPathZip=%deployFolder%\%machineName%\%machineVersion%" + +REM elimino eventuale cartella esistente +rmdir /s /Q %fullPathZip% + +REM copio i sorgenti nel percorso di destinazione +ROBOCOPY . %fullPathSource%\ /E /XF "Compile.bat" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" +REM copio i sorgenti nel percorso temporaneo per i compilati +ROBOCOPY . %fullPathSource%\bin\%machineName%\ /E /XF "Compile.bat" /XF ".gitignore" /XD ".git" /XF "UpdateLog.txt" + +REM copio i file compilati nel percorso temporaneo per i compilati +\EgtProg\Dll32\luac54 -o %fullPathSource%\bin\%machineName%\Common_PF1250.mlpe Common_PF1250.mlpe +\EgtProg\Dll32\luac54 -o %fullPathSource%\bin\%machineName%\Common_PF1250.mlse Common_PF1250.mlse +\EgtProg\Dll32\luac54 -o %fullPathSource%\bin\%machineName%\Common_PF1250.TPA.mlpe Common_PF1250.TPA.mlpe + +REM comprimo i file compilati in uno zip pronto per essere distribuito +tar.exe acvf %fullPathZip%\%machineName%.zip -C %fullPathSource%\bin\ %machineName%\*.* + +REM elimino il percorso temporaneo +rmdir /s /Q %fullPathSource%\bin\ \ No newline at end of file diff --git a/Essetre-PF1500MAXrl-3T.ini b/Essetre-PF1500MAXrl-3T.ini new file mode 100644 index 0000000..c0de924 --- /dev/null +++ b/Essetre-PF1500MAXrl-3T.ini @@ -0,0 +1,73 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam + +[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=1 + +[ToolHolder] +H11.1=Standard.nge +H11.1:MILL_NOTIP=MillNoTip.nge +H12.1=Saw.nge +H13.1=ChainSaw.nge +H16.1=Saw.nge +H21.1=Standard.nge +H21.1:MILL_NOTIP=MillNoTip.nge +H21.1:SAW_STD=SawH2Std.nge +H21.1:SAW_FLAT=SawH2Flat.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +GenMachining=0 +SurfRoughing=0 +SurfFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H11=6608 +; 5 axis saw +H12=6615 +; Second 5 axis saw +H16=6623 +; Chainsaw +H13=6616 +; Second 5 axis head +H21=6620 +; Second 5 axis bottom saw +H22=6628 +; 5 axis head +H31=6608 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,514,138,628,810 + +[VMill] +Enable=1 +Save=0 + diff --git a/Essetre-PF1500MAXrl-3T.mlde b/Essetre-PF1500MAXrl-3T.mlde new file mode 100644 index 0000000..73df357 --- /dev/null +++ b/Essetre-PF1500MAXrl-3T.mlde @@ -0,0 +1,1367 @@ +-- Descrizione macchina Essetre-PF1500rl by EgalWare s.r.l. 2024/10/16 +-- 2024/10/16 ver 2.6j1 Prima versione + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.6j1' +PP_NVER = '2.6.10.1' +MIN_MACH_VER = '2.5k1' +MACH_NAME = 'Essetre-PF1500MAXrl-3T' + +-- Carico i dati globali +local sMachDir = EgtGetCurrMachineDir() +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') +EgtAddToPackagePath( sMachDir .. '\\?.lua') +INFO_STD_PP = require( 'Version') +-- prendo la versione kernel minima necessaria piu' nuova tra macchina e script comuni +if INFO_STD_PP.MIN_MACH_VER_PP_COMMON > MIN_MACH_VER then + MIN_MACH_VER = INFO_STD_PP.MIN_MACH_VER_PP_COMMON +end + +EgtOutLog ( '** ' .. MACH_NAME..' '..PP_VER..' ** ( '..INFO_STD_PP.NAME..': '..INFO_STD_PP.VERSION..' - MinMach: '.. MIN_MACH_VER ..') **', 1) + +-- Parametri macchina +NumericalControl = 'TPA' -- NUM o TPA +MinMchY1 = 335 +MaxMchY1 = 5790.0 +ParkMchY1 = 970.0 +MinMchY2 = -5775.0 +MaxMchY2 = -324 +ParkMchY2 = -955.0 +MinV1 = 5.0 +MaxV1 = 640.0 +ParkV1 = 609.0 +MinV2 = -635.0 +MaxV2 = -5.0 +ParkV2 = -609.0 +MinDeltaYV = 317 + 0.1 +ExtraParkV = 600 +MinY1 = MinV1 + MinDeltaYV +MaxY1 = MaxMchY1 +MaxY2 = MaxV2 - MinDeltaYV +MinY2 = MinMchY2 +ParkY1 = ParkV1 + MinDeltaYV +ParkY2 = ParkV2 - MinDeltaYV +LoadT = 2172.8 +UnloadT = -2400 +UnloadSmT = UnloadT - 300 +MaxHoOpen = 1520 +MaxVeOpen = 600 +RollCageMin = 120 +RollCageMax = 250 +MillOffs = 170.0 +SawOffsX = 110.0 +SawOffsY = 0 +SawOffsZ = -150.25 +SawC1Offs = 0 +SawB1Offs = 0 +Saw2OffsX = -110.0 +Saw2OffsY = 0 +Saw2OffsZ = -150.25 +Saw2C1Offs = 0 +Saw2B1Offs = 0 +SawUnderOffsX = 0 +SawUnderOffsY = -111 +SawUnderOffsZ = 150.25 +SawUnderC2Offs = 0 +SawUnderB2Offs = 0 +ChSawLen = 91.0 +Mill2Offs = 170.0 +SawC2Offs = 0 +SawB2Offs = 0 +Mill3Offs = 163.0 +MinX1 = 0 +MaxX1 = 4750 +MinZ1 = -1850 +MaxZ1 = -50 +MaxZ1Blade = -100 +MinC1 = -275 +MaxC1 = 275 +MinB1 = -127 +MaxB1 = 127 +MinB1b = -119 +MaxB1b = 119 +ParkX1 = 4700 +ParkTc2X1 = 4000 +ParkTc1X1 = 1000 +ParkZ1 = -525 +ParkC1 = -90 +ParkB1 = -90 +ParkCSawX1 = 1700 +ParkCSawZ1 = -100 +ParkCSaw0Z1 = -400 +ParkCSawC1 = -90 +ParkCSaw0C1 = 0 +ParkCSawB1 = 0 +MinLengthLongCSaw = 580 -- gestione speciale per motosega molto lunga. Lunghezza al di sopra della quale e' considerata motosega lunga +ParkLongCSawZ1 = -50 -- gestione speciale per motosega molto lunga. Parcheggio asse Z +ParkLongCSawC1 = 0 -- gestione speciale per motosega molto lunga. Parcheggio asse C +ParkLongCSawB1 = -90 -- gestione speciale per motosega molto lunga. Parcheggio asse B +LongTool = 390 +MinLongTc1C1 = -91 +MaxLongTc1C1 = 91 +ParkLongTc1C1 = 0 +MinLongTc2C1 = -271 +MaxLongTc2C1 = -89 +ParkLongTc2C1 = -180 +ParkLongB1 = 0 +MinZ1ToChangeH2 = -1400 +MinZ3 = -1550 +MaxZ3 = 0 +MinX3 = 0 +MaxX3 = 3300 +MinB3 = 0 +MaxB3 = 180 +ParkX3 = 0 +ParkZ3 = 0 +ParkB3 = 0 +MinX2 = -2760 +MaxX2 = 0 +MinZ2 = 0 +MaxZ2 = 1450 +MinC2 = -275 +MaxC2 = 275 +MinB2 = -127 +MaxB2 = 127 +MinB2b = -119 +MaxB2b = 119 +ParkX2 = -100 +SafeX2 = -400 +ParkZ2 = 0 +ParkInLavZ2 = 200 +ParkC2 = -90 +ParkB2 = -90 +ParkSawX2 = MinX2 +ParkSawZ2 = 0 +ParkSaw0Z2 = 0 +ParkSawC2 = -90 +ParkSaw0C2 = -90 +ParkSawB2 = 0 +MinDistToolX1X2 = 40 +TurnerOffs = 120.0 +AggLoad = 50 +DeltaTabY = 1915.5 +DeltaTabZ = -1491.0 + MillOffs -- per TPA : -1228.0 + MillOffs -- per NUM : -1058.0 +DeltaRulliTraveZ = -1266 +DimTabY = 1600 +DimTabX = 24000 +Delta2TabY = -2907.4 +Delta2TabZ = 693.0 - Mill2Offs -- per TPA : 543.0 - Mill2Offs -- per NUM : 373.0 +Delta3TabY = 1915.5 +Delta3TabZ = -1430.25 +Head3X = -163 +Head3Y = DeltaTabY - Delta3TabY +Head3Z = DeltaTabZ - Delta3TabZ +Head2X = 0 +Head2Y = DeltaTabY - Delta2TabY +Head2Z = DeltaTabZ - Delta2TabZ +DefTcPos1 = 'T1' +DefTcPos2 = 'T220' +CoeffVM = 0.5 +MinForzaPinze = 400 -- [Kgf] +MaxForzaPinze = 1000 -- [Kgf] +Tc2Active = true +SecondSaw = true +SecondChain = true -- magazzino seconda sega a catena +TcSpecialTools = true -- magarzzino per utensili speciali. In genere truciolatore +TcAggreBladeUnder = true -- lama su aggregato per testa da sotto +EmitAccClamps = true +WriteAllCoordsOnFirstM101 = true +ForceToCloseRollersGate = false +Motors23KW = true + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1500MAXrl-3T.data" +local sDataBeam = sMachDir.."\\Beam\\Ts3Data.lua" +local sDataWall = sMachDir.."\\Wall\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sDataBeam) + EgtCopyFile( sTs3Data, sDataWall) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if false and EgtExistsFile( sDataBeam) then + local Machine = dofile( sDataBeam) + if Machine then + if Machine.Offsets then + --NumericalControl = EgtIf( Machine.Offsets.TIPO_CN == 0, 'NUM', 'TPA') + if Machine.Offsets.X1_POS then MinX1 = -Machine.Offsets.X1_POS end + if Machine.Offsets.X1_NEG then MaxX1 = -Machine.Offsets.X1_NEG end + if Machine.Offsets.PARK_X1 then ParkX1 = -Machine.Offsets.PARK_X1 end + if Machine.Offsets.Z1_NEG then MinZ1 = Machine.Offsets.Z1_NEG end + if Machine.Offsets.Z1_POS then MaxZ1 = min( MaxZ1, Machine.Offsets.Z1_POS) end + if Machine.Offsets.Z1_POS_LAMA then MaxZ1Blade = min( MaxZ1Blade, Machine.Offsets.Z1_POS_LAMA) end + if Machine.Offsets.PARK_Z1 then ParkZ1 = Machine.Offsets.PARK_Z1 end + if Machine.Offsets.C1_NEG then MinC1 = Machine.Offsets.C1_NEG end + if Machine.Offsets.C1_POS then MaxC1 = Machine.Offsets.C1_POS end + if Machine.Offsets.B1_NEG then MinB1 = Machine.Offsets.B1_NEG end + if Machine.Offsets.B1_POS then MaxB1 = Machine.Offsets.B1_POS end + if Machine.Offsets.B1_NEG1 then MinB1b = Machine.Offsets.B1_NEG1 end + if Machine.Offsets.B1_POS1 then MaxB1b = Machine.Offsets.B1_POS1 end + if Machine.Offsets.X2_NEG then MinX2 = Machine.Offsets.X2_NEG end + if Machine.Offsets.X2_POS then MaxX2 = Machine.Offsets.X2_POS end + if Machine.Offsets.PARK_X2 then ParkX2 = Machine.Offsets.PARK_X2 end + if Machine.Offsets.Z2_POS then MinZ2 = -Machine.Offsets.Z2_POS end + if Machine.Offsets.Z2_NEG then MaxZ2 = -Machine.Offsets.Z2_NEG end + if Machine.Offsets.PARK_Z2 then ParkZ2 = -Machine.Offsets.PARK_Z2 end + if Machine.Offsets.PARK_Z2_INLAV then ParkInLavZ2 = -Machine.Offsets.PARK_Z2_INLAV end + if Machine.Offsets.C2_NEG then MinC2 = Machine.Offsets.C2_NEG end + if Machine.Offsets.C2_POS then MaxC2 = Machine.Offsets.C2_POS end + if Machine.Offsets.B2_NEG then MinB2 = Machine.Offsets.B2_NEG end + if Machine.Offsets.B2_POS then MaxB2 = Machine.Offsets.B2_POS end + if Machine.Offsets.B2_NEG1 then MinB2b = Machine.Offsets.B2_NEG1 end + if Machine.Offsets.B2_POS1 then MaxB2b = Machine.Offsets.B2_POS1 end + if Machine.Offsets.X3_POS then MinX3 = -Machine.Offsets.X3_POS end + if Machine.Offsets.X3_NEG then MaxX3 = -Machine.Offsets.X3_NEG end + if Machine.Offsets.PARK_X3 then ParkX3 = -Machine.Offsets.PARK_X3 end + if Machine.Offsets.Z3_NEG then MinZ3 = Machine.Offsets.Z3_NEG end + if Machine.Offsets.Z3_POS then MaxZ3 = Machine.Offsets.Z3_POS end + if Machine.Offsets.PARK_Z3 then ParkZ3 = Machine.Offsets.PARK_Z3 end + if Machine.Offsets.B3_NEG then MinB3 = Machine.Offsets.B3_NEG end + if Machine.Offsets.B3_POS then MaxB3 = Machine.Offsets.B3_POS end + if Machine.Offsets.MIN_Y1 then MinMchY1 = Machine.Offsets.MIN_Y1 end + if Machine.Offsets.MAX_Y1 then MaxMchY1 = Machine.Offsets.MAX_Y1 end + if Machine.Offsets.PARK_Y1 then ParkMchY1 = Machine.Offsets.PARK_Y1 end + if Machine.Offsets.MIN_V1 then MinV1 = Machine.Offsets.MIN_V1 end + if Machine.Offsets.MAX_V1 then MaxV1 = Machine.Offsets.MAX_V1 end + if Machine.Offsets.MIN_Y2 then MinMchY2 = Machine.Offsets.MIN_Y2 end + if Machine.Offsets.MAX_Y2 then MaxMchY2 = Machine.Offsets.MAX_Y2 end + if Machine.Offsets.PARK_Y2 then ParkMchY2 = Machine.Offsets.PARK_Y2 end + if Machine.Offsets.MIN_V2 then MinV2 = Machine.Offsets.MIN_V2 end + if Machine.Offsets.MAX_V2 then MaxV2 = Machine.Offsets.MAX_V2 end + if Machine.Offsets.DIST_FTZERO then LoadT = Machine.Offsets.DIST_FTZERO end + if Machine.Offsets.DELTA_CARICZERO then TurnerOffs = Machine.Offsets.DELTA_CARICZERO end + if Machine.Offsets.MIN_DELTAVY then MinDeltaYV = Machine.Offsets.MIN_DELTAVY + 0.1 end + if Machine.Offsets.DIST_UNLOAD then UnloadT = Machine.Offsets.DIST_UNLOAD end + if Machine.Offsets.PIVOT_T1 then MillOffs = Machine.Offsets.PIVOT_T1 end + if Machine.Offsets.PIVOT_T2 then Mill2Offs = Machine.Offsets.PIVOT_T2 end + if Machine.Offsets.PIVOT_T3 then Mill3Offs = Machine.Offsets.PIVOT_T3 end + if Machine.Offsets.OFFSETCLAMAT1 then SawC1Offs= Machine.Offsets.OFFSETCLAMAT1 end + if Machine.Offsets.OFFSETBLAMAT1 then SawB1Offs= Machine.Offsets.OFFSETBLAMAT1 end + if Machine.Offsets.OFFSETCLAMAT2 then Saw2C1Offs= Machine.Offsets.OFFSETCLAMAT2 end + if Machine.Offsets.OFFSETBLAMAT2 then Saw2B1Offs= Machine.Offsets.OFFSETBLAMAT2 end + if Machine.Offsets.OFFSETCLAMAUNDER then SawUnderC2Offs= Machine.Offsets.OFFSETCLAMAUNDER end + if Machine.Offsets.OFFSETBLAMAUNDER then SawUnderB2Offs= Machine.Offsets.OFFSETBLAMAUNDER end + if Machine.Offsets.OFFSETXT1 then DeltaTabY = -Machine.Offsets.OFFSETXT1 end + if Machine.Offsets.OFFSETZT1 then DeltaTabZ = Machine.Offsets.OFFSETZT1 + MillOffs end + if Machine.Offsets.OFFSETXT2 then Delta2TabY = Machine.Offsets.OFFSETXT2 end + if Machine.Offsets.OFFSETZT2 then Delta2TabZ = -Machine.Offsets.OFFSETZT2 - Mill2Offs end + if Machine.Offsets.OFFSETXT3 then Delta3TabY = -Machine.Offsets.OFFSETXT3 end + if Machine.Offsets.OFFSETZT3 then Delta3TabZ = Machine.Offsets.OFFSETZT3 + Mill3Offs end + if Machine.Offsets.OFFSETZSOTTOTRAVE then DeltaRulliTraveZ = -abs( Machine.Offsets.OFFSETZSOTTOTRAVE) end + if Machine.Offsets.SECONDSAW then SecondSaw = ( Machine.Offsets.SECONDSAW == 1) end + if Machine.Offsets.SAWOFFSX then SawOffsX = Machine.Offsets.SAWOFFSX end + if Machine.Offsets.SAWOFFSZ then SawOffsZ = Machine.Offsets.SAWOFFSZ end + if Machine.Offsets.SAW2OFFSX then Saw2OffsX = Machine.Offsets.SAW2OFFSX end + if Machine.Offsets.SAW2OFFSZ then Saw2OffsZ = Machine.Offsets.SAW2OFFSZ end + if Machine.Offsets.SAWUNDEROFFSY then SawUnderOffsY = Machine.Offsets.SAWUNDEROFFSY end + if Machine.Offsets.SAWUNDEROFFSZ then SawUnderOffsZ = Machine.Offsets.SAWUNDEROFFSZ end + if Machine.Offsets.DEFTCPOS1 then DefTcPos1 = ( 'T' .. Machine.Offsets.DEFTCPOS1) end + if Machine.Offsets.DEFTCPOS2 then DefTcPos2 = ( 'T' .. Machine.Offsets.DEFTCPOS2) end + if Machine.Offsets.MINPRESS then MinForzaPinze = Machine.Offsets.MINPRESS end + if Machine.Offsets.MAXPRESS then MaxForzaPinze = Machine.Offsets.MAXPRESS end + if Machine.Offsets.CHIUDI_PINZE_2_3_SCAMBIO then ForceToCloseRollersGate = Machine.Offsets.CHIUDI_PINZE_2_3_SCAMBIO == 1 end + if Machine.Offsets.WOOD_DENSITY then WoodDensity = Machine.Offsets.WOOD_DENSITY end + if Machine.Offsets.MOTORS23KW then Motors23KW = Machine.Offsets.MOTORS23KW end + + -- aggiustamenti + MinY1 = MinV1 + MinDeltaYV + MaxY1 = MaxMchY1 + ParkV1 = MaxV1 + ParkY1 = ParkV1 + MinDeltaYV + MinY2 = MinMchY2 + MaxY2 = MaxV2 - MinDeltaYV + ParkV2 = MinV2 + ParkY2 = ParkV2 - MinDeltaYV + UnloadSmT = UnloadT - 300 + MaxZ1Blade = min( MaxZ1Blade, MaxZ1) + ParkX1 = EgtClamp( ParkX1, MinX1, MaxX1) + ParkTc1X1 = EgtClamp( ParkTc1X1, MinX1, MaxX1) + ParkZ1 = EgtClamp( ParkZ1, MinZ1, MaxZ1) + ParkCSawZ1 = min( ParkCSawZ1, MaxZ1) + ParkX2 = EgtClamp( ParkX2, MinX2, MaxX2) + ParkZ2 = EgtClamp( ParkZ2, MinZ2, MaxZ2) + ParkInLavZ2 = EgtClamp( ParkInLavZ2, MinZ2, MaxZ2) + ParkX3 = EgtClamp( ParkX3, MinX3, MaxX3) + ParkZ3 = EgtClamp( ParkZ3, MinZ3, MaxZ3) + Head2Y = DeltaTabY - Delta2TabY + Head2Z = DeltaTabZ - Delta2TabZ + Head3Y = DeltaTabY - Delta3TabY + Head3Z = DeltaTabZ - Delta3TabZ + end + end +end +SecondSaw = ( SecondSaw and Tc2Active) +local vtOffset23KW = Vector3d( 0, 0, EgtIf( Motors23KW, 37, 0)) + +EmtGeneral { + File='Essetre-PF1500MAXrl-3T.nge', + Offset = Vector3d(0.0,2497,-2193.0), + AxisMaxAdjust = 300, + AxisMaxRotAdj = 0.5, + ExitMaxAdjust = 300, + ExitMaxRotAdj = 0.5, + AngDeltaMinForHome = 80, + Special = 'Common_PF1250.mlse', + Processor = 'Common_PF1250.mlpe'} +-- in base alla corsa macchina, si carica la rulliera di carico/scarico appropriata +local sGeomConvoyer = EgtIf( MaxY1 > 6500, '_8M', '_5M') +local sBaseAux = {'BASE/SOLID', 'BASE/CONVOYER'..sGeomConvoyer, 'BASE/COLLISION', 'BASE/TC1', 'BASE/TCR', 'BASE/TC3'} +if Tc2Active then table.insert( sBaseAux, 5, 'BASE/TC2') end +if TcSpecialTools then table.insert( sBaseAux, 'BASE/TC4') end +if SecondChain then table.insert( sBaseAux, 'BASE/TC5') end +if TcAggreBladeUnder then table.insert( sBaseAux, 'BASE/TCS') end +local BaseId = EmtBase { + Name = 'Base', + Geo = 'BASE/GEO', + Aux = sBaseAux} +local X1Id = EmtAxis { + Name = 'X1', + Parent = 'Base', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(207.0,-300.0,104.0), + Stroke = {MinX1, MaxX1}, + Home = ParkX1, + Invert = true, + Geo = 'X1_AXIS/GEO', + Aux = {'X1_AXIS/SOLID', 'X1_AXIS/COLLISION'}} +-- *** Testa 1 *** +local Z1Id = EmtAxis { + Name = 'Z1', + Parent = 'X1', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(0.0,-140.1,563.0), + Stroke = {MinZ1, MaxZ1}, + Home = ParkZ1, + Geo = 'Z1_AXIS/GEO', + Aux = {'Z1_AXIS/SOLID', 'Z1_AXIS/COLLISION'}} +EmtAxis { + Name = 'C1', + Parent = 'Z1', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d(0.0,0.0,503.0), + Stroke = {MinC1, MaxC1}, + Home = ParkC1, + Geo = EgtIf( Motors23KW, 'C1_AXIS_23KW/GEO', 'C1_AXIS/GEO'), + Aux = {EgtIf( Motors23KW, 'C1_AXIS_23KW/SOLID', 'C1_AXIS/SOLID'), EgtIf( Motors23KW, 'C1_AXIS_23KW/COLLISION', 'C1_AXIS/COLLISION')}} +EmtAxis { + Name = 'B1', + Parent = 'C1', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d(-108.4,0.0,MillOffs), + Stroke = {MinB1, MaxB1}, + Home = ParkB1, + Geo = EgtIf( Motors23KW, 'B1_AXIS_23KW/GEO', 'B1_AXIS/GEO'), + Aux = {EgtIf( Motors23KW, 'B1_AXIS_23KW/SOLID', 'B1_AXIS/SOLID'), EgtIf( Motors23KW, 'B1_AXIS_23KW/COLLISION', 'B1_AXIS/COLLISION')}} +-- Frese +local H11Id = EmtHead { + Name = 'H11', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,0), + TDir = Z_AX(), + ADir = -Y_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB1, MaxB1}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H11_HEAD/GEO'} +-- Lama +local H12Id = EmtHead { + Name = 'H12', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d( SawOffsX, SawOffsY, SawOffsZ), + TDir = Vector3d( 0, sin( SawB1Offs), cos( SawB1Offs)), + ADir = -X_AX(), + Rot1W = 0.5, + Rot2Stroke = { MinB1b, MaxB1b}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H12_HEAD/GEO'} +EgtSetInfo( H12Id, 'ZMAXONROT', '1,190') +-- Lama 2 +if SecondSaw then + local H16Id = EmtHead { + Name = 'H16', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d( Saw2OffsX, Saw2OffsY, Saw2OffsZ), + TDir = Vector3d( 0, -sin( Saw2B1Offs), cos( Saw2B1Offs)), + ADir = X_AX(), + Rot1W = 0.5, + Rot2Stroke = { MinB1b, MaxB1b}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H16_HEAD/GEO'} + EgtSetInfo( H16Id, 'ZMAXONROT', '1,190') +end +-- Sega a catena +EmtAxis { + Name = 'A1', + Parent = 'B1', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A1_AXIS/GEO'} +local H13Id = EmtHead { + Name = 'H13', + Parent = 'A1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,-ChSawLen), + TDir = -X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { -90.1, 90.1}, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H13_HEAD/GEO'} +EgtSetInfo( H13Id, 'ZSAFEDELTA', '60') +EgtSetInfo( H13Id, 'ZMAXONROT', '1,80') +-- *** Testa 3 *** +local X3Id = EmtAxis { + Name = 'X3', + Parent = 'Base', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( -163, 0, 109.0), + Stroke = {MinX3, MaxX3}, + Home = ParkX3, + Invert = true, + Geo = 'X3_AXIS/GEO', + Aux = {'X3_AXIS/SOLID', 'X3_AXIS/COLLISION'}} +local Z3Id = EmtAxis { + Name = 'Z3', + Parent = 'X3', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0, 0, -140), + Stroke = {MinZ3, MaxZ3}, + Home = ParkZ3, + Geo = 'Z3_AXIS/GEO', + Aux = {'Z3_AXIS/SOLID', 'Z3_AXIS/COLLISION'}} +local C3Id = EmtAxis { + Name = 'C3', + Parent = 'Z3', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( Head3X+163, Head3Y, 503.0), + Stroke = {-181, 1}, + Home = 0, + Geo = 'C3_AXIS/GEO', + Aux = {'C3_AXIS/SOLID', 'C3_AXIS/COLLISION'}} +local B3Id = EmtAxis { + Name = 'B3', + Parent = 'C3', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = -Y_AX(), + Pos = Point3d( 0, -163, Head3Z), + Stroke = {MinB3, MaxB3}, + Home = ParkB3, + Geo = 'B3_AXIS/GEO', + Aux = {'B3_AXIS/SOLID', 'B3_AXIS/COLLISION'}} +local vtMoveX3 = Vector3d( 0, Head3Y, 0) +EgtMove( EgtGetFirstNameInGroup( X3Id, 'SOLID'), vtMoveX3, GDB_RT.GLOB) +local vtMoveZ3 = Vector3d( 0, Head3Y, Head3Z -109.25) +EgtMove( EgtGetFirstNameInGroup( Z3Id, 'SOLID'), vtMoveZ3, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z3Id, 'COLLISION'), vtMoveZ3, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C3Id, 'SOLID'), vtMoveZ3, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C3Id, 'COLLISION'), vtMoveZ3, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B3Id, 'SOLID'), vtMoveZ3, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B3Id, 'COLLISION'), vtMoveZ3, GDB_RT.GLOB) +-- Frese +local H31Id = EmtHead { + Name = 'H31', + Parent = 'B3', + HSet = 'H31', + Type = MCH_HT.STD, + Pos = Point3d( Head3X, Head3Y, Head3Z), + TDir = X_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB1, MaxB1}, + OthColl = {'B3/SOLID', 'C3/SOLID'}, + Geo = 'H31_HEAD/GEO'} +-- *** Testa 2 *** +local Z2Id = EmtAxis { + Name = 'Z2', + Parent = 'Base', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(291.0,-866,-2858.3), + Stroke = {MinZ2, MaxZ2}, + Home = ParkZ2, + Invert = true, + Geo = 'Z2_AXIS/GEO', + Aux = {'Z2_AXIS/SOLID', 'Z2_AXIS/COLLISION'}} +local X2Id = EmtAxis { + Name = 'X2', + Parent = 'Z2', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 115.8, 4452.9, -2840), + Stroke = {MinX2, MaxX2}, + Home = ParkX2, + Geo = 'X2_AXIS/GEO', + Aux = {'X2_AXIS/SOLID', 'X2_AXIS/COLLISION'}} +local C2Id = EmtAxis { + Name = 'C2', + Parent = 'X2', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = -Z_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z-480), + Stroke = {MinC2, MaxC2}, + Home = ParkC2, + Geo = EgtIf( Motors23KW, 'C2_AXIS_23KW/GEO', 'C2_AXIS/GEO'), + Aux = {EgtIf( Motors23KW, 'C2_AXIS_23KW/SOLID', 'C2_AXIS/SOLID'), EgtIf( Motors23KW, 'C2_AXIS_23KW/COLLISION', 'C2_AXIS/COLLISION')}} +local B2Id = EmtAxis { + Name = 'B2', + Parent = 'C2', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d( Head2X-110, Head2Y, Head2Z-Mill2Offs), + Stroke = {MinB2, MaxB2}, + Home = ParkB2, + Geo = EgtIf( Motors23KW, 'B2_AXIS_23KW/GEO', 'B2_AXIS/GEO'), + Aux = {EgtIf( Motors23KW, 'B2_AXIS_23KW/SOLID', 'B2_AXIS/SOLID'), EgtIf( Motors23KW, 'B2_AXIS_23KW/COLLISION', 'B2_AXIS/COLLISION')}} +EmtAxis { + Name = 'A2', + Parent = 'B2', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = -Z_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A2_AXIS/GEO'} + +local vtMoveZ2 = Vector3d( 0, 0, Head2Z + 1844.0) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'SOLID'), vtMoveZ2 - vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'COLLISION'), vtMoveZ2 - vtOffset23KW, GDB_RT.GLOB) +local vtMoveX2 = Vector3d( 0, Head2Y - 4822.9, Head2Z + 1844.0) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'SOLID'), vtMoveX2 - vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'COLLISION'), vtMoveX2 - vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +-- Frese +local H21Id = EmtHead { + Name = 'H21', + Parent = 'B2', + HSet = 'H21', + Type = MCH_HT.STD, + Pos = Point3d( Head2X, Head2Y, Head2Z), + TDir = -Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB2, MaxB2}, + OthColl = {'B2/SOLID', 'C2/SOLID'}, + Geo = 'H21_HEAD/GEO'} +EgtSetInfo( H21Id, 'ABOVE', '0') +EgtSetInfo( H21Id, 'ZHOMEDOWN', '1') +-- Lama +if TcAggreBladeUnder then + local H22Id = EmtHead { + Name = 'H22', + Parent = 'A2', + HSet = 'H21', + Type = MCH_HT.STD, + Pos = Point3d( SawUnderOffsX+Head2X, SawUnderOffsY+Head2Y, SawUnderOffsZ+Head2Z), + TDir = Vector3d( 0, sin( SawUnderB2Offs), -cos( SawUnderB2Offs)), + ADir = Y_AX(), + Rot1W = 0.5, + Rot2Stroke = { MinB2b, MaxB2b}, + OthColl = {'B2/SOLID', 'C2/SOLID'}, + Geo = 'H22_HEAD/GEO'} + EgtSetInfo( H22Id, 'ABOVE', '0') + EgtSetInfo( H22Id, 'ZHOMEDOWN', '1') +end +-- *** Carrelli *** +-- Morse +local Y1Id = EmtAxis { + Name = 'Y1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-865.7,2626.8,-866.0), + Stroke = { MinY1, MaxY1}, + Home = ParkY1, + Geo = 'Y1_AXIS/GEO', + Aux = 'Y1_AXIS/SOLID'} +local PY1Id = EmtAxis { + Name = 'PY1', + Parent = 'Y1', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(-469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY1_AXIS/GEO', + Aux = 'PY1_AXIS/SOLID'} +local Y2Id = EmtAxis { + Name = 'Y2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(865.7,2626.8,-866.0), + Stroke = { MinY2, MaxY2}, + Home = ParkY2, + Geo = 'Y2_AXIS/GEO', + Aux = 'Y2_AXIS/SOLID'} +local PY2Id = EmtAxis { + Name = 'PY2', + Parent = 'Y2', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY2_AXIS/GEO', + Aux = 'PY2_AXIS/SOLID'} +-- Rulli +local V1Id = EmtAxis { + Name = 'V1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-875.5,1072.0,-1509.1), + Stroke = { MinV1, MaxV1}, + Home = ParkV1, + Geo = 'V1_AXIS/GEO', + Aux = {'V1_AXIS/SOLID', 'V1_AXIS/COLLISION'}} +local PV1Id = EmtAxis { + Name = 'PV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(-194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV1_AXIS/GEO', + Aux = 'PV1_AXIS/SOLID'} +local QV1Id = EmtAxis { + Name = 'QV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(-287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV1_AXIS/GEO', + Aux = 'QV1_AXIS/SOLID'} +local V2Id = EmtAxis { + Name = 'V2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(875.5,1072.0,-1509.1), + Stroke = { MinV2, MaxV2}, + Home = ParkV2, + Geo = 'V2_AXIS/GEO', + Aux = {'V2_AXIS/SOLID', 'V2_AXIS/COLLISION'}} +local PV2Id = EmtAxis { + Name = 'PV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV2_AXIS/GEO', + Aux = 'PV2_AXIS/SOLID'} +local QV2Id = EmtAxis { + Name = 'QV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV2_AXIS/GEO', + Aux = 'QV2_AXIS/SOLID'} +-- *** Tavola *** +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d(0.0,2450.0,-958.0), + Stroke = {-20000, 20000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( - DimTabX, DeltaTabY, DeltaTabZ), + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- *** ToolChanger *** +local ptTc1 = Point3d( 150, 351, -221 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +local vtDt1 = Vector3d( 0, 0, - 102.5) +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = ptTc1 + Vector3d( SawOffsX, SawOffsZ, 0), + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T2', + Parent = 'Base', + Pos = ptTc1 + vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T2'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = ptTc1 + 2 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = ptTc1 + 3 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = ptTc1 + 4 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = ptTc1 + 5 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = ptTc1 + 6 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = ptTc1 + 7 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = ptTc1 + 8 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = ptTc1 + 9 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T10'} +EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = ptTc1 + 10 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T11'} +EmtTcPos { + Name = 'T12', + Parent = 'Base', + Pos = ptTc1 + 11 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T12'} +EmtTcPos { + Name = 'T13', + Parent = 'Base', + Pos = ptTc1 + 12 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T13'} + +if Tc2Active then + local ptTc2 = Point3d( 150, 5018.75, -221 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW + local vtDt2 = Vector3d( 0, 0, - 102.5) + EmtTcPos { + Name = 'T21', + Parent = 'Base', + Pos = ptTc2 + EgtIf( SecondSaw, Vector3d( -Saw2OffsX, -Saw2OffsZ, 0), V_NULL()), + TDir = -Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T21'} + EmtTcPos { + Name = 'T22', + Parent = 'Base', + Pos = ptTc2 + vtDt2, + TDir = -Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T22'} + EmtTcPos { + Name = 'T23', + Parent = 'Base', + Pos = ptTc2 + 2 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T23'} + EmtTcPos { + Name = 'T24', + Parent = 'Base', + Pos = ptTc2 + 3 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T24'} + EmtTcPos { + Name = 'T25', + Parent = 'Base', + Pos = ptTc2 + 4 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T25'} + EmtTcPos { + Name = 'T26', + Parent = 'Base', + Pos = ptTc2 + 5 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T26'} + EmtTcPos { + Name = 'T27', + Parent = 'Base', + Pos = ptTc2 + 6 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T27'} + EmtTcPos { + Name = 'T28', + Parent = 'Base', + Pos = ptTc2 + 7 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T28'} + EmtTcPos { + Name = 'T29', + Parent = 'Base', + Pos = ptTc2 + 8 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T29'} + EmtTcPos { + Name = 'T30', + Parent = 'Base', + Pos = ptTc2 + 9 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T30'} +end +local ptTc3 = Point3d( 600, 1031, -200.8 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = ptTc3, + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101'} +local ptTc4 = Point3d( 750, 1411, -200.8 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +EmtTcPos { + Name = 'T111', + Parent = 'Base', + Pos = ptTc4, + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T111'} +local ptTc5 = Point3d( 750, 1811, -115 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +EmtTcPos { + Name = 'T121', + Parent = 'Base', + Pos = ptTc5, + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'BASE/T121'} +local ptTcS = Point3d( -1, 369.75, -1675 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +EmtTcPos { + Name = 'T201', + Parent = 'Base', + Pos = ptTcS + EgtIf( TcAggreBladeUnder, Vector3d( 0, SawUnderOffsY, SawUnderOffsZ), V_NULL()), + TDir = -Z_AX(), + ADir = Y_AX(), + Geo = 'BASE/T201'} +local ptTcR = Point3d( -0.5, 5202, -1973 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + vtOffset23KW +EmtTcPos { + Name = 'T220', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -30, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T220'} +EmtTcPos { + Name = 'T221', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -60, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T221'} +EmtTcPos { + Name = 'T222', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -90, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T222'} +EmtTcPos { + Name = 'T223', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -120, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T223'} +EmtTcPos { + Name = 'T224', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -150, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T224'} +EmtTcPos { + Name = 'T225', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -180, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T225'} +EmtTcPos { + Name = 'T226', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -210, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T226'} +EmtTcPos { + Name = 'T227', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -240, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T227'} +EmtTcPos { + Name = 'T228', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -270, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T228'} +EmtTcPos { + Name = 'T229', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -300, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T229'} +EmtTcPos { + Name = 'T230', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -330, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T230'} + +-- Aggiusto posizioni geometriche +local vtMovB = Vector3d( 0, 0, ( DeltaTabZ - DeltaRulliTraveZ + 55)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC1') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC2') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC3') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) +if TcSpecialTools then EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC4') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) end +if SecondChain then EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC5') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) end +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TCR') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) +if TcSpecialTools then EgtMove( EgtGetFirstNameInGroup( BaseId, 'TCS') or GDB_ID.NULL, vtMovB + vtOffset23KW, GDB_RT.GLOB) end +EgtMove( EgtGetFirstNameInGroup( X1Id, 'SOLID'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X1Id, 'COLLISION'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z1Id, 'SOLID'), vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z1Id, 'COLLISION'), vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X3Id, 'SOLID'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X3Id, 'COLLISION'), vtMovB + vtOffset23KW, GDB_RT.GLOB) +local vtMove = Vector3d( 0, ( DeltaTabY - 1915.5), ( DeltaTabZ + 1321.0)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'CONVOYER'..sGeomConvoyer), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V1Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V2Id, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +local vtMoveColl = Vector3d( 0, 0, MaxZ1Blade) +EgtMove( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), 'CEIL'), vtMoveColl, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PY1LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y1Id, 'SOLID') or GDB_ID.NULL, 'Light') +PY2LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y2Id, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- se testa H11 (fresa) + if EMC.HEAD == 'H11' then + local nTc = GetTcForTopHeadTool( EMC.TCPOS) + if nTc ~= 2 then + EmtModifyAxisHome( 'X1', ParkX1) + else + EmtModifyAxisHome( 'X1', ParkTc2X1) + end + EmtModifyAxisStroke( 'Z1', {MinZ1, MaxZ1}) + if EMC.TOTLEN < LongTool then + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisStroke( 'C1', {MinC1, MaxC1}) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + else + EmtModifyAxisHome( 'Z1', MaxZ1) + if nTc ~= 2 then + EmtModifyAxisStroke( 'C1', { ParkLongTc1C1 - 20, ParkLongTc1C1 + 20}) + EmtModifyAxisHome( 'C1', ParkLongTc1C1) + else + EmtModifyAxisStroke( 'C1', { ParkLongTc2C1 - 20, ParkLongTc2C1 + 20}) + EmtModifyAxisHome( 'C1', ParkLongTc2C1) + end + EmtModifyAxisHome( 'B1', ParkLongB1) + end + EmtModifyAxisDirection( 'B1', X_AX()) + -- se testa H12 (lama) + elseif EMC.HEAD == 'H12' then + EmtModifyAxisHome( 'X1', ParkX1) + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisStroke( 'Z1', {MinZ1, MaxZ1Blade}) + EmtModifyAxisStroke( 'C1', {MinC1, MaxC1}) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + EmtModifyAxisDirection( 'B1', Vector3d( cos( SawC1Offs), -sin( SawC1Offs), 0)) + -- se testa H13 (sega a catena) + elseif EMC.HEAD == 'H13' then + -- aggiustamenti per distanza + local dDist = EgtIf( EMC.DIST and abs( EMC.DIST) > 1, EMC.DIST, ChSawLen) + EMC.EXIT = EMC.EXIT or 1 + EmtModifyExitPosition( EMC.HEAD, EMC.EXIT, Point3d( 0, 0, -dDist)) + local vtMove = Point3d( 0, 0, -dDist) - Point3d( EMC.EXITPOS) + local ExitId = EgtGetFirstNameInGroup( EgtGetHeadId( EMC.HEAD), 'T'..tostring( EMC.EXIT)) + EgtMove( ExitId, vtMove) + -- recupero il valore dell'asse virtuale bloccato A + local CSawPosA = GetCurrChainSawingVirtualAxis() + EmtModifyAxisHome( 'X1', ParkCSawX1) + EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( CSawPosA, EMC.TOTLEN)) + EmtModifyAxisStroke( 'Z1', {MinZ1, MaxZ1}) + EmtModifyAxisStroke( 'C1', {MinC1, MaxC1}) + EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA, EMC.TOTLEN)) + EmtModifyAxisHome( 'B1', EgtIf( EMC.TOTLEN < MinLengthLongCSaw, ParkCSawB1, ParkLongCSawB1)) + EmtModifyAxisDirection( 'B1', X_AX()) + -- se testa H16 ( seconda lama) + elseif EMC.HEAD == 'H16' then + EmtModifyAxisHome( 'X1', ParkTc2X1) + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisStroke( 'Z1', {MinZ1, MaxZ1Blade}) + EmtModifyAxisStroke( 'C1', {MinC1, MaxC1}) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + EmtModifyAxisDirection( 'B1', Vector3d( cos( Saw2C1Offs), sin( Saw2C1Offs), 0)) + elseif EMC.HEAD == 'H21' then + if not EMC.TOTDIAM or EMC.TOTDIAM > 300 then + EmtModifyAxisStroke( 'B2', {MinB2b, MaxB2b}) + else + EmtModifyAxisStroke( 'B2', {MinB2, MaxB2}) + end + end +end + +--------------------------------------------------------------------- +-- Funzione che riconosce TC per utensili testa sopra +function GetTcForTopHeadTool( sTcPos) + if sTcPos == 'T1' or sTcPos == 'T2' or sTcPos == 'T3' or sTcPos == 'T4' or sTcPos == 'T5' or + sTcPos == 'T6' or sTcPos == 'T7' or sTcPos == 'T8' or sTcPos == 'T9' or + sTcPos == 'T10' or sTcPos == 'T11' or sTcPos == 'T12' or sTcPos == 'T13' or + sTcPos == 'T101' or sTcPos == 'T121' or sTcPos == 'T111' then + return 1 + elseif sTcPos == 'T21' or sTcPos == 'T22' or sTcPos == 'T23' or sTcPos == 'T24' or sTcPos == 'T25' or + sTcPos == 'T26' or sTcPos == 'T27' or sTcPos == 'T28' or sTcPos == 'T29' or sTcPos == 'T30' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +function GetHeadSet( sHead) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H16' then + return 1 + elseif sHead == 'H21' or sHead == 'H22' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +function GetHeadSetFromTcPos( sTcPos) + local TCPOS_1A = { 'T1', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10', 'T11', 'T12', 'T13'} -- CU montante DX + local TCPOS_1B = { 'T101', 'T121', 'T111'} -- CU sotto traversa + local TCPOS_1C = { 'T21', 'T22', 'T23', 'T24', 'T25', 'T26', 'T27', 'T28', 'T29', 'T30'} -- CU montante sinistro + local TCPOS_2A = { 'T220', 'T221', 'T222', 'T223', 'T224', 'T225', 'T226', 'T227', 'T228', 'T229', 'T230'} -- CU margherita testa 2 + local TCPOS_2B = { 'T201'} + local TCPOS_3 = { 'T301'} -- CU lama su aggregato testa 2 + for _, sVal in ipairs( TCPOS_1A) do + if sVal == sTcPos then return 1, 1 end + end + for _, sVal in ipairs( TCPOS_1B) do + if sVal == sTcPos then return 1, 2 end + end + for _, sVal in ipairs( TCPOS_1C) do + if sVal == sTcPos then return 1, 3 end + end + for _, sVal in ipairs( TCPOS_2A) do + if sVal == sTcPos then return 2, 1 end + end + for _, sVal in ipairs( TCPOS_2B) do + if sVal == sTcPos then return 2, 2 end + end + for _, sVal in ipairs( TCPOS_3) do + if sVal == sTcPos then return 3, 1 end + end + return 0, 0 +end + +--------------------------------------------------------------------- +-- Funzione che ritorna il nome della testa in base alla posizione utensile (ATT: deve rispecchiare il setup) +function GetAdjHeadFromTcPos( nHeadSet, sTcPos) + if nHeadSet == 1 then + -- seconda lama + if SecondSaw and sTcPos == 'T21' then + return 'H16' + -- utensili speciali + elseif TcSpecialTools and sTcPos == 'T121' then + return 'H11' + -- motoseghe + elseif sTcPos == 'T101' or sTcPos == 'T111' then + return 'H13' + -- utensili standard o prima lama + else + return EgtIf( sTcPos == 'T1', 'H12', 'H11') + end + elseif nHeadSet == 2 then + -- lama su aggregato da sotto + if TcAggreBladeUnder and sTcPos == 'T201' then + return 'H22' + -- utensili standard da sotto + else + return 'H21' + end + elseif nHeadSet == 3 then + return 'H31' + else + return '' + end +end +--------------------------------------------------------------------- +-- Funzione che riconosce testa per sega a catena +function HeadIsChainSaw( sHead) + return ( sHead == 'H13' or sHead == 'H15') +end + +--------------------------------------------------------------------- +function GetCurrChainSawingVirtualAxis() + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + if not sVal or sVal == '' then + if EMC then + sVal = EMC.BLOCKEDAXIS or 'A1=0' + else + sVal = 'A1=0' + end + end + local dPosA = tonumber( sVal:sub( 4)) or 0 + return dPosA +end + +--------------------------------------------------------------------- +-- Funzione che calcola la posizione Home di Z per la sega a catena dal valore dell'asse virtuale +function GetChainSawZHomeFromVirtualAxis( dPosA, dCSawLength) + -- se A=0 -> T101 -> HomeZ = -400 + if abs( dPosA) < 0.1 then + if dCSawLength >= MinLengthLongCSaw then + EmtSetLastError( 1200, 'ChainSaw too long: orientation forbidden') + end + return ParkCSaw0Z1 + -- altrimenti A=-90 -> T102 o A=90 -> T104 -> HomeZ = -100 + else + if dCSawLength >= MinLengthLongCSaw then + return ParkLongCSawZ1 + else + return ParkCSawZ1 + end + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la sega a catena dal valore dell'asse virtuale +--------------------------------------------------------------------- +function GetChainSawCHomeFromVirtualAxis( dPosA, dCSawLength) + -- se A=0 -> T101 -> HomeC = 0 + if abs( dPosA) < 0.1 then + return ParkCSaw0C1 + -- altrimenti A=90 -> T104 -> HomeC = -90 + else + if dCSawLength >= MinLengthLongCSaw then + return ParkLongCSawC1 + else + return ParkCSawC1 + end + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la lama su aggregato dal valore dell'asse virtuale +function GetSawCHomeFromVirtualAxis( dPosA) + -- se A2=0 -> 201 -> HomeC = -90 + if abs( dPosA) < 0.1 then + return ParkSaw0C2 + -- altrimenti A2=90 -> T204 -> HomeC = -90 + else + return ParkSawC2 + end + end + +--------------------------------------------------------------------- +-- Funzione che ritorna ZExtra partendo dalla testa e dall'angolo verticale +function GetZExtra( sHead, dAngV) + -- se testa standard + if sHead == 'H11' then + if abs( dAngV) < 30.1 then + return 400 + elseif abs( dAngV) < 45.1 then + return 300 + elseif abs( dAngV) < 60.1 then + return 200 + elseif abs( dAngV) < 90.1 then + return 10 + else + return 0 + end + -- se aggregato lama + elseif sHead == 'H12' or sHead == 'H16' then + if abs( dAngV) < 30.1 then + return 400 + elseif abs( dAngV) < 45.1 then + return 300 + elseif abs( dAngV) < 60.1 then + return 200 + elseif abs( dAngV) < 90.1 then + return 10 + else + return 0 + end + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y1 +function SetPY1Light( bClosed) + if not PY1LightId then return end + EgtSetColor( PY1LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY1LightId, 'On', '1') + else + EgtRemoveInfo( PY1LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y1 +function GetPY1Light() + if not PY1LightId then return false end + return ( EgtGetInfo( PY1LightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y2 +function SetPY2Light( bClosed) + if not PY2LightId then return end + EgtSetColor( PY2LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY2LightId, 'On', '1') + else + EgtRemoveInfo( PY2LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y2 +function GetPY2Light() + if not PY2LightId then return false end + return ( EgtGetInfo( PY2LightId, 'On') == '1') +end + + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPY1Light( false) + SetPY2Light( 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/Essetre-PF1500MAXrl-3T.nge b/Essetre-PF1500MAXrl-3T.nge new file mode 100644 index 0000000..dc07078 Binary files /dev/null and b/Essetre-PF1500MAXrl-3T.nge differ diff --git a/MachNotes.ini b/MachNotes.ini new file mode 100644 index 0000000..5f58449 --- /dev/null +++ b/MachNotes.ini @@ -0,0 +1,50 @@ +; Commento per evitare BOM con UTF-8 +;Index = Type, Description, Default Value +; Type : b=boolean, d=double, l=lenght, s=string + +[Drilling] + +[Sawing] + +[Milling] +0=d,MaxElev,0 +1=d,OutRaw,0 +2=d,SideElev,0 +3=d,TrimExt,0 +4=sr,VtFaceUse,0,0,0 + +[Pocketing] +0=d,MaxElev,0 +1=b,Open,0 +2=d,OpenMinSave,0 +3=d,OpenOutRaw,0 +4=d,MaxOptSize,0 + +[Mortising] +0=d,MaxElev,0 + +[Chiseling] + +[SawRoughing] + +[SawFinishing] + +[GenMachining] +0=l,LinTol,0.1 +1=l,MaxLen,2 +2=s,Type,ZigZag +3=d,SideAng,90 +4=l,Step,10 +5=l,OffsProj,0 +6=l,LiTang,0 +7=l,LiOrth,0 +8=l,LiElev,0 +9=l,LoTang,0 +10=l,LoOrth,0 +11=l,LoElev,0 +12=b,DirFromGuide,1 + +[SurfRoughing] + +[SurfFinishing] +0=b,SkipMaxDown,1 diff --git a/Scripts/ExitMach.lua b/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST 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..6ac761b --- /dev/null +++ b/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST 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..0055eaa --- /dev/null +++ b/Scripts/SetUp.lua @@ -0,0 +1,288 @@ +-- 2023/11/13 +-- Gestione attrezzaggio per Essetre-PF1500rl + +-- 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 (con o senza TC2) +local PositionTable = {} +local bTc2Active = ( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TC2') ~= nil) +local SecondSaw = ( EgtGetHeadId( 'H16') ~= nil) +local SecondChain = ( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TC4') ~= nil) +local TcSpecialTools = ( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TC5') ~= nil) +local TcAggreBladeUnder = ( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TCS') ~= nil) + +local bFullOpt = bTc2Active and SecondSaw and SecondChain and TcSpecialTools and TcAggreBladeUnder -- se ha tutti gli optional attivati +if bFullOpt then + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, -- TC 1 + {Pos = "Pos2", TcPos = "T2", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos11", TcPos = "T11", Head = "H11", Group = "G1"}, + {Pos = "Pos12", TcPos = "T12", Head = "H11", Group = "G1"}, + {Pos = "Pos13", TcPos = "T13", Head = "H11", Group = "G1"}, + {Pos = "Pos14", TcPos = "T101", Head = "H13", Group = "G2"}, -- motosega + {Pos = "Pos15", TcPos = "T111", Head = "H13", Group = "G2"}, -- motosega 2 + {Pos = "Pos16", TcPos = "T121", Head = "H11", Group = "G2"}, -- utensile speciale + {Pos = "Pos17", TcPos = "T21", Head = "H16", Group = "G3"}, -- TC 2 + {Pos = "Pos18", TcPos = "T22", Head = "H11", Group = "G3"}, + {Pos = "Pos19", TcPos = "T23", Head = "H11", Group = "G3"}, + {Pos = "Pos20", TcPos = "T24", Head = "H11", Group = "G3"}, + {Pos = "Pos21", TcPos = "T25", Head = "H11", Group = "G3"}, + {Pos = "Pos22", TcPos = "T26", Head = "H11", Group = "G3"}, + {Pos = "Pos23", TcPos = "T27", Head = "H11", Group = "G3"}, + {Pos = "Pos24", TcPos = "T28", Head = "H11", Group = "G3"}, + {Pos = "Pos25", TcPos = "T29", Head = "H11", Group = "G3"}, + {Pos = "Pos26", TcPos = "T30", Head = "H11", Group = "G3"}, + {Pos = "Pos27", TcPos = "T201", Head = "H22", Group = "G4"}, -- lama con aggregatop da sotto + {Pos = "Pos28", TcPos = "T220", Head = "H21", Group = "G4"}, -- TC margherita + {Pos = "Pos29", TcPos = "T221", Head = "H21", Group = "G4"}, + {Pos = "Pos30", TcPos = "T222", Head = "H21", Group = "G4"}, + {Pos = "Pos31", TcPos = "T223", Head = "H21", Group = "G4"}, + {Pos = "Pos32", TcPos = "T224", Head = "H21", Group = "G4"}, + {Pos = "Pos33", TcPos = "T225", Head = "H21", Group = "G4"}, + {Pos = "Pos34", TcPos = "T226", Head = "H21", Group = "G4"}, + {Pos = "Pos35", TcPos = "T227", Head = "H21", Group = "G4"}, + {Pos = "Pos36", TcPos = "T228", Head = "H21", Group = "G4"}, + {Pos = "Pos37", TcPos = "T229", Head = "H21", Group = "G4"}, + {Pos = "Pos38", TcPos = "T230", Head = "H21", Group = "G4"}, + {Pos = "Pos39", TcPos = "T301", Head = "H31", Group = "G5"}} +elseif bTc2Active then + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101",Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T11", Head = "H11", Group = "G3"}, + {Pos = "Pos12", TcPos = "T12", Head = "H11", Group = "G3"}, + {Pos = "Pos13", TcPos = "T13", Head = "H11", Group = "G3"}, + {Pos = "Pos14", TcPos = "T14", Head = "H11", Group = "G3"}, + {Pos = "Pos15", TcPos = "T15", Head = "H11", Group = "G3"}, + {Pos = "Pos16", TcPos = "T20", Head = "H21", Group = "G4"}, + {Pos = "Pos17", TcPos = "T21", Head = "H21", Group = "G4"}, + {Pos = "Pos18", TcPos = "T22", Head = "H21", Group = "G4"}, + {Pos = "Pos19", TcPos = "T23", Head = "H21", Group = "G4"}, + {Pos = "Pos20", TcPos = "T24", Head = "H21", Group = "G4"}, + {Pos = "Pos21", TcPos = "T25", Head = "H21", Group = "G4"}, + {Pos = "Pos22", TcPos = "T26", Head = "H21", Group = "G4"}, + {Pos = "Pos23", TcPos = "T27", Head = "H21", Group = "G4"}, + {Pos = "Pos24", TcPos = "T28", Head = "H21", Group = "G4"}, + {Pos = "Pos25", TcPos = "T29", Head = "H21", Group = "G4"}, + {Pos = "Pos26", TcPos = "T30", Head = "H21", Group = "G4"}, + {Pos = "Pos27", TcPos = "T301", Head = "H31", Group = "G4"}} +else + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101",Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T20", Head = "H21", Group = "G3"}, + {Pos = "Pos12", TcPos = "T21", Head = "H21", Group = "G3"}, + {Pos = "Pos13", TcPos = "T22", Head = "H21", Group = "G3"}, + {Pos = "Pos14", TcPos = "T23", Head = "H21", Group = "G3"}, + {Pos = "Pos15", TcPos = "T24", Head = "H21", Group = "G3"}, + {Pos = "Pos16", TcPos = "T25", Head = "H21", Group = "G3"}, + {Pos = "Pos17", TcPos = "T26", Head = "H21", Group = "G3"}, + {Pos = "Pos18", TcPos = "T27", Head = "H21", Group = "G3"}, + {Pos = "Pos19", TcPos = "T28", Head = "H21", Group = "G3"}, + {Pos = "Pos20", TcPos = "T29", Head = "H21", Group = "G3"}, + {Pos = "Pos21", TcPos = "T30", Head = "H21", Group = "G3"}, + {Pos = "Pos22", TcPos = "T301", Head = "H31", Group = "G4"}} +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..d29af27 Binary files /dev/null and b/THolders/ChainSaw.nge differ diff --git a/THolders/ChainSawLong.nge b/THolders/ChainSawLong.nge new file mode 100644 index 0000000..a8416ae Binary files /dev/null and b/THolders/ChainSawLong.nge differ diff --git a/THolders/HSK-F63_MillWeld12.nge b/THolders/HSK-F63_MillWeld12.nge new file mode 100644 index 0000000..6d316ee Binary files /dev/null and b/THolders/HSK-F63_MillWeld12.nge differ diff --git a/THolders/HSK-F63_MillWeld20.nge b/THolders/HSK-F63_MillWeld20.nge new file mode 100644 index 0000000..14752b3 Binary files /dev/null and b/THolders/HSK-F63_MillWeld20.nge differ diff --git a/THolders/MillNoTip.nge b/THolders/MillNoTip.nge new file mode 100644 index 0000000..5b2fe8a Binary files /dev/null and b/THolders/MillNoTip.nge differ diff --git a/THolders/Saw.nge b/THolders/Saw.nge new file mode 100644 index 0000000..5d6b54b Binary files /dev/null and b/THolders/Saw.nge differ diff --git a/THolders/SawH2Flat.nge b/THolders/SawH2Flat.nge new file mode 100644 index 0000000..b49c93e Binary files /dev/null and b/THolders/SawH2Flat.nge differ diff --git a/THolders/SawH2Std.nge b/THolders/SawH2Std.nge new file mode 100644 index 0000000..d1bc0cc Binary files /dev/null and b/THolders/SawH2Std.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/Standard_LC_108.nge b/THolders/Standard_LC_108.nge new file mode 100644 index 0000000..9e11ea0 Binary files /dev/null and b/THolders/Standard_LC_108.nge differ diff --git a/ToolNotes.ini b/ToolNotes.ini new file mode 100644 index 0000000..0d2c1ef --- /dev/null +++ b/ToolNotes.ini @@ -0,0 +1,41 @@ +; Commento per evitare BOM con UTF-8 +; Index, Type, Description, Value +; Index = 0,1,..,n +; Type : d=double, l=lenght, s=string, b=boolean, dr=double recalc, sr= string recalc, lr=lenght recalc, br=boolean recalc, th=toolholder +; Description : STEP, SIDESTEP, ... + +[DRILL_STD] +0=th,TH, +1=d,STEP +2=s,DOUBLE + +[SAW_STD] +0=th,TH, +1=d,STEP +2=d,SIDESTEP +3=b,LONGCUT + +[SAW_FLAT] +0=th,TH, +1=d,STEP +2=d,SIDESTEP +3=b,LONGCUT + +[MILL_STD] +0=th,TH, +1=d,STEP +2=d,SIDESTEP +3=d,SIDEDEPTH +4=s,DOUBLE + +[MILL_NOTIP] +0=th,TH, +1=d,STEP +2=d,SIDESTEP +3=d,SIDEDEPTH +4=s,DOUBLE + +[MORTISE_STD] +0=b,MORTISE +1=d,STEP +2=d,SIDESTEP diff --git a/UpdateLog.txt b/UpdateLog.txt new file mode 100644 index 0000000..471ee3f --- /dev/null +++ b/UpdateLog.txt @@ -0,0 +1,147 @@ + ==== Common_PF1250 Update Log ==== + +Versione 2.6j1 (01/10/2024) +- (GEN) Migliorato calcolo chiusura paratia rulli con aggiornamento lunghezza della barra in caso di ultimo taglio e grezzo residuo in coda. Ticket#2017 +- (NGE-SIM) Aggiunta gestione solidi collisione per TC verticali e TC rotante sotto +- (GEN) Per lavorazione in doppio: messaggio bloccante in caso di extra-corsa durante un movimento standard su piano generico della lavorazione. + +Versione 2.6i1 (10/09/2024) +- (GEN) Se diametro utensile più del truciolatore standard grande, non si preseleziona. Ticket#2028 + +Versione 2.6h2 (28/08/2024) +- (SIM-GEN) Quando si aprono i rulli, se la trave non può seguire i rulli perchè la pinza andrebbe in extra-corsa, si sposta comunque la pinza fino al massimo della sua corsa. Ticket#1949 +- (GEN) La testa veniva spostata a quota X sicurezza rotazione assi rotanti prima di aprire le rulliere. Ticket#1991 + +Versione 2.6h1 (07/08/2024) +- (GEN) Gestione creazione piano generico in caso il primo movimento della lavorazione sia un arco. Ticket#1891 +- (SIM-GEN) Migliorata gestione riposizionamenti fatta con la 2.6g1. Ticket#1836 +- (MLDE-SIM-GEN) Rinominato file da "Common-" a "Common_" per uniformità con i file common delle altre macchine. Serve modifica a MLDE macchina. + +Versione 2.6g5 (24/07/2024) +- (SIM) Per OnSetHead chiamata da simulazione, aggiunta lettura TOTDIAM. Serve per limitare corse assi testa sotto. Ticket#1946 + +Versione 2.6g4 (23/07/2024) +- (SIM) Corretta ultima modifica per controllo collisioni testa non utilizzata. Trovava collisioni in lavorazioni in doppio. + +Versione 2.6g3 (22/07/2024) +- (SIM) Si aggiunge al controllo collisioni anche Tool e ToolHolder della testa non utilizzata. Ticket#1937 +- (SIM-GEN) In caso di grezzo piuttosto piccolo, concesso pinzaggio fino al massimo possibile, oltre al calcolo con coefficienti. Ticket#1942 + +Versione 2.6g2 (12/07/2024) +- (SIM-GEN) Corretto movimento testa sotto che andava in collisione tra una lavorazione e la successiva se tra le due c'era un riposizionamento pinze. Ticket#1925 + +Versione 2.6g1 (08/07/2024) +- (SIM-GEN) Corretto movimento che pinzava nel vuoto durante riposizionamento. Ticket#1836 + +Versione 2.6f2 (06/06/2024) +- (GEN) Quando si va a ZMAX, si azzerano tutte le coordinate ".pp". Scriveva una Z bassa quando era a Z massima. Ticket#1839 + +Versione 2.6f1 (03/06/2024) +- (SIM-GEN) Migliorata gestione approccio al pezzo con lama aggregato da sotto. Va al minimo in X solo se necessario. + +Versione 2.6e6 (28/05/2024) +- (GEN) Aggiunta possibilità di scrivere nome utensile doppio anche in lavorazione con parametro "TOOLDOUBLE". Note sulla lavorazione hanno precedenza su note utensile. +- (GEN) Ripristinato controllo extra-corsa per testa 2 in caso di lavorazioni in doppio in Y (si era perso in un vecchio commit) +- (SIM-GEN) Corretto movimento testa sotto su prima lavorazione. Ruotava a parcheggio invece di andare a quota sicurezza rotazione assi. + +Versione 2.6e5 (23/05/2024) +- (GEN) Controllo extra-corsa per testa 2 in caso di lavorazioni in doppio in Y +- (GEN) Corretta lettura e salvataggio coordinala asse L2 con coordinate rispetto origine. Prima erano locali e sbagliava alcuni calcoli +- (SIM-GEN) Se lavorazione con testa 2 e stesso utensile, piccola correzione che manda a parcheggio se cambiano assi rotanti solo se si trova a ZMAX + +Versione 2.6e4 (15/05/2024) +- (SIM-GEN) Miglioramento gestione lama su aggregato da sotto + +Versione 2.6e3 (09/05/2024) +- (SIM) Corretto prelievo lama 2 (H16). Prima di visualizzare utensile, si sposta la Z alla quota massima. Prima trovava collisione in caso utensile precedente non lama (perchè era già oltre la quota massima). + +Versione 2.6e2 (06/05/2024) +- (GEN) In parcheggio paratie/pinze, viene considerato sovramateriale di testa. Simulazione era corretta. Ticket#1789 + +Versione 2.6e1 (30/04/2024) +- (SIM-GEN) Per macchina a 3 teste, ripristinato posizionamento testa 2 tramite parametro ParkInLavZ2. La gestione era stata persa dal common. +- (MLDE-GEN) Gestione facoltativa parametro WOOD_DENSITY settabile in Ts3. In MLDE, mettere il valore di WOOD_DENSITY nella nostra variabile 'WoodDensity'. + +Versione 2.6d2 (23/04/2024) +- (MLDE-GEN) Aggiunto parametro 'IS_TEST_MACHINE' FACOLTATIVO. Se non esiste o 'false' è macchina standard, se 'true' è una macchina utilizzata per i test Egalware interni +- (GEN) Chiamando la macchina con un nome che termini con '.TEST' si abilita come macchina per test interni, equivalente a settare 'IS_TEST_MACHINE' (che comunque rimane) +- (SIM-GEN) Modificato movimenti testa sotto. Prima si muove in quota 'ParkMchY2' e poi va alla coordinata di lavoro ruotando gli assi +- (SIM) Per lavorazioni in doppio, viene subito scritta la quota Z. La generazione era già corretta. Ticket#1377 +- (GEN) Ripristinato movimento iniziale testa sopra assieme alle pinze. Spostato comando wait dopo primo movimento testa. Ticket#1730 +- (MLDE-SIM-GEN) Aggiunto parametro MaxZ1Blade per differenziare Z massima aggregato lama e altri utensili. +- (SIM) Aggiunto controllo con solido di collisione per verificare di non salire oltre il massimo +- (SIM) Corretta simulazione scambio testa 3 -> testa 1 + +Versione 2.6d1 (09/04/2024) +- (GEN) Corretto impostazione piano G24 con testa da sotto con aggregato +- (SIM-GEN) Corretta posizione prelievo/parcheggio se lama su aggregato da sotto +- (MLDE-SIM-GEN) Aggiunta variabile FACOLTATIVA 'ForceToCloseRollersGate' ( che legge la variabile da TS3 'CHIUDI_PINZE_2_3_SCAMBIO') in mlde per forzare chiusura paratie rulli + durante scambio pinze per facilitare passaggio pezzi molto storti. Se non presente chiude solo se necessario. +- (GEN) Corretta scrittura lista utensili iniziale M992 per doppia motosega e aggregato lama sotto +- (SIM-GEN) Corretto movimento punte lunghe +- (GEN) Corretto adeguamento speed per aggregato lama da sotto con coefficiente moltiplicativo +- (SIM-GEN) Aumentato numero riposizionamenti possibili a 10 ( per pezzi molto lunghi non bastava il valore precedente: 5) +- (GEN) Corretto posizionamento assi in home se primo utensile punta lunga + +Versione 2.6c5 (26/03/2024) +- (SIM) Corretto primo movimento in rapido della lavorazione per testa sotto. Ora allineata a generazione +- (SIM-GEN) Aggiunta gestione parametro "SECDIST". Distanza di sicurezza tra paratia con rulli e utensile/testa. Parametro da inserire nelle note utensile +- (MLDE-SIM) Modificate collisioni traversa. Ora non comprende carro X1, il quale ha il proprio oggetto di collisione + +Versione 2.6c4 (14/03/2024) +- (SIM) Miglioramento visualizzazione spigoli VMILL alla fine della simulazione. Funzione: EgtVolZmapSetShowEdges. N.B.= serve CAM5 2.6c2 NON OBBLIGATORIO +- (GEN) Modifica controlli a preselezione utensile. Margine ridotto da 400m a 200mm. +- (GEN) Corretto controllo preselezione testa H1 quando H2 in lavoro + +Versione 2.6c3 (12/03/2024) +- (SIM-GEN) Migliorata gestione movimenti con lama su aggregato su testa sotto + +Versione 2.6c2 (04/03/2024) +- (GEN) I commenti iniziali si scrivono in modo standard, per poterli commentare nella macchina di test +- (MLDE-GEN) Aggiunta variabile 'MACH_NAME' in MLDE con nome macchina + +Versione 2.6c1 (29/02/2024) +- (SIM) Gestione rimozione VMILL per tagli a cubetti Zig-Zag + +Versione 2.6b4 (23/02/2024) +- (MLDE-SIM-GEN) EgtAddToPackagePath spostato in mlde + +Versione 2.6b3 (20/02/2024) +- (SIM) Aggiunta funzioni "OnSimulInit" e "OnSimulExit" per orientare vista corretta in caso di macchina con carico destro. N.B.= serve CAM5 2.6b4 NON OBBLIGATORIO +- (SIM-GEN) "BeamData" caricato come libreria con 'require' anziché come file con 'dofile' + +Versione 2.6b2 (15/02/2024) +- (SIM-GEN) Primo movimento in X per testa 2 a SafeX2 anziché a ParkX2 + +Versione 2.6b1 (07/02/2024) +- (MLDE-SIM-GEN) Inserito parametro 'MinLengthLongCSaw' per gestione motosega molto lunga +- (MLDE) funzione 'GetCurrChainSawingVirtualAxis' spostata in MLDE + +Versione 2.6a5 (31/01/2024) +- (SIM) Migliorata simulazione apertura/chiusura morse in caso di separazione +- (SIM-GEN) Migliorata gestione movimenti con motosega e adeguato simulazione +- (GEN) Corretta scrittura assi in caso di 'WriteAllCoordsOnFirstM101' per testa 2 +- (SIM-GEN) Caricamento BeamData come local + +Versione 2.6a4 (25/01/2024) +- (SIM-GEN) Corretto movimento in caso di cambio assi rotanti tra due lavorazioni +- (GEN) Corretta emissione coordinate assi in caso di 'WriteAllCoordsOnFirstM101' + +Versione 2.6a3 (22/01/2024) +- (SIM-GEN) Correzione gestione apertura/chiusura rulli sul fine barra (#1630) e in generale +- (GEN) Modificato flag 'EmitRapidInG0' in 'EmitRapidInG1' per decidere se scrivere G1 anziché G0. Se flag a nil, scrive i rapidi in G0 +- (SIM) Correzione movimenti pinze prima di separazione + +Versione 2.6a2 (19/01/2024) +- (GEN) Corretta inversione coordinata X per Lama su aggregato da sotto +- (SIM) Se modalità 'WriteAllCoordsOnFirstM101', oltre alla X si scive quota di parcheggio assi B2 e C2 come in generazione +- (SIM-GEN) Tolta gestione rotazione pezzo (di derivazione PF), in macchina non è previsto ribaltamento +- (GEN) Migliorata gestione preselezione utensile +- (MLDE-GEN) Aggiunto flag 'EmitRapidInG0' per decidere se scrivere G0 anziché G1. Se flag a nil, scrive i rapidi in G1 + +Versione 2.6a1 (09/01/2024) +- Prima versione post-proc comune tra macchine PF1250 e PF1500 +- (SIM-GEN) Corretto movimento testa 2 in ToolDesel e movimento controllo collisione +- (GEN) Tolta testa H14 per utensili speciali. Si utilizza H11 per frese standard +- (MLDE-GEN) Costanti 'MinForzaPinze' e 'MaxForzaPinze' portati in mlde/Ts3data (erano hardcoded) +- (MLDE-SIM-GEN) Aggiunto parametro 'WriteAllCoordsOnFirstM101' per decidere se stampare tutti gli assi sulla prima M101 \ No newline at end of file diff --git a/Version.lua b/Version.lua new file mode 100644 index 0000000..ff3e9a7 --- /dev/null +++ b/Version.lua @@ -0,0 +1,10 @@ +-- Version.lua by EgalWare s.r.l. 2024/01/22 +-- Gestione della versione dei file comuni post-processori macchine PF1250 e PF1500 di Essetre + +local InfoCommon_STD_PP = { + NAME = 'Common_PF1250', -- nome script PP standard + VERSION = '2.6j1', -- versione script + MIN_MACH_VER_PP_COMMON = '2.5k1' -- versione minima kernel +} + +return InfoCommon_STD_PP diff --git a/Wall/MachData.ini b/Wall/MachData.ini new file mode 100644 index 0000000..04a78ac --- /dev/null +++ b/Wall/MachData.ini @@ -0,0 +1,80 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,X1_NEG,-3450,MIN_X1 +2=l,X1_POS,0,MAX_X1 +3=l,PARK_X1,-250,--- +4=l,Z1_NEG,-1565,MIN_Z1 +5=l,Z1_POS,0,MAX_Z1 +6=l,PARK_Z1,-545,PARK_Z1 +7=l,PARK_SAWZ1,-150,--- +8=d,B1_NEG,-127.0,MIN_B1 +9=d,B1_NEG1,-119.0,MIN_B1_SAW +10=d,B1_POS,127.0,MAX_B1 +11=d,B1_POS1,119.0,MAX_B1_SAW +12=d,PARK_B1,-90.0,--- +13=d,PARK_SAWB1,0.0,--- +14=d,C1_NEG,-275.0,MIN_C1 +15=d,C1_POS,275.0,MAX_C1 +16=d,PARK_C1,-90.0,--- +17=d,PARK_SAWC1,-90.0,--- +18=l,PIVOT_T1,170.02,PIVOT_HEAD1 +19=l,X2_NEG,-2950,MIN_X2 +20=l,X2_POS,0,MAX_X2 +21=l,PARK_X2,-70,--- +22=l,Z2_NEG,-880,MIN_Z2 +23=l,Z2_POS,0,MAX_Z2 +24=l,PARK_Z2,0,PARK_Z2 +25=d,B2_NEG,-127.0,MIN_B2 +26=d,B2_NEG1,-119.0,--- +27=d,B2_POS,127.0,MAX_B2 +28=d,B2_POS1,119.0,--- +29=d,PARK_B2,-90.0,--- +30=d,C2_NEG,-275.0,MIN_C2 +31=d,C2_POS,275.0,MAX_C2 +32=d,PARK_C2,-90.0,--- +33=l,PIVOT_T2,169.93,PIVOT_HEAD2 +34=l,MIN_Y1,378,MIN_Y1 +35=l,MAX_Y1,5771,MAX_Y1 +36=l,PARK_Y1,1036,PARK_Y1 +37=l,MIN_V1,10,MIN_V1 +38=l,MAX_V1,670,MAX_V1 +39=l,MIN_Y2,-5773,MIN_Y2 +40=l,MAX_Y2,-378,MAX_Y2 +41=l,PARK_Y2,-1036,PARK_Y2 +42=l,MIN_V2,-670,MIN_V2 +43=l,MAX_V2,-10,MAX_V2 +44=l,MIN_DELTAVY,391,MIN_DELTAVY +45=l,DIST_FTZERO,2206.1,CARICO_Y +46=l,DELTA_CARICZERO,45,OFFSET_RIB +47=l,DIST_UNLOAD,-2250,UNLOAD_Y +48=d,OFFSETBLAMAT1,0,OFFSET B SAW1 +49=d,OFFSETCLAMAT1,0,OFFSET C SAW1 +50=d,OFFSETBLAMAT2,0,OFFSET B SAW2 +51=d,OFFSETCLAMAT2,0,OFFSET C SAW2 +52=l,OFFSETXT1,-1178.6,OFFSET_X_HEAD1 +53=l,OFFSETZT1,-1243.7,OFFSET_Z_HEAD1 +54=l,OFFSETXT2,-2460.3,OFFSET_X_HEAD2 +55=l,OFFSETZT2,-444.0,OFFSET_Z_HEAD2 +56=l,OFFSETZSOTTOTRAVE,1005,OFFSET_Z_SOTTOTRAVE +57=d,SECONDSAW,1,SECOND_SAW +58=d,DOUBLE_HEAD_DOVETAIL,1,DT_MORTISE_IN_DOUBLE +59=d,DOUBLE_HEAD_POCKET,1,POCKET_IN_DOUBLE +60=d,DOUBLE_HEAD_DRILLING,1,DRILLING_IN_DOUBLE + +[2] +Name=Trave +1=l,XMIN,30,XMIN +2=l,XMAX,1250,XMAX +3=l,ZMIN,30,ZMIN +4=l,ZMAX,400,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/Wall/MachiningTypes.ini b/Wall/MachiningTypes.ini new file mode 100644 index 0000000..414615b --- /dev/null +++ b/Wall/MachiningTypes.ini @@ -0,0 +1,23 @@ +[Cut] +1=Standard + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=FreeContour +2=Side +3=SideGroove +4=DtMortise +5=Mark +6=Text +7=CleanCorner60 +8=CleanCorner30 + +[Pocketing] +1=Pocket +2=OpenPocket + +[Sawing] +1=Sawing diff --git a/Wall/NestingData.ini b/Wall/NestingData.ini new file mode 100644 index 0000000..3ef74c1 --- /dev/null +++ b/Wall/NestingData.ini @@ -0,0 +1,3 @@ +[WALL] +Kerf=10 +Offset=25 diff --git a/Wall/WallData.lua b/Wall/WallData.lua new file mode 100644 index 0000000..5beb585 --- /dev/null +++ b/Wall/WallData.lua @@ -0,0 +1,67 @@ +-- WallData.lua by Egaltech s.r.l. 2021/03/08 +-- Raccolta dati generali per Pareti + +EgtOutLog( ' WALL-WallData started', 1) + +-- Tabella per definizione modulo +local WallData = { + MIN_LENGTH = 4000, -- lunghezza minima del grezzo + MIN_WIDTH = 100, -- larghezza minima del grezzo + MIN_HEIGHT = 10, -- altezza minima del grezzo + MAX_LENGTH = 14000, -- lunghezza massima del grezzo + MAX_WIDTH = 1250, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + STD_RAW_LENGTH = 10000, -- lunghezza standard del grezzo + STD_RAW_WIDTH = 1250, -- larghezza standard del grezzo + OVM_HEAD = 60, -- sovramateriale testa + OVM_MID = 50, -- sovramateriale intermedio + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 0, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 0, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = 0.5, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.5, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = 0.5, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.866, -- 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 + CHECK_MIN_Z_SAW = true, -- controlla la quota minima della lama rispetto alla tavola (default true) + MIN_Z_SAW = -10, -- quota minima rispetto alla tavola (default 0) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + ORIG_CORNER = 'BR', -- angolo tavola per origine di battuta (BR (default), TR, BL, TL) + MAX_CLEAN_CRN30 = 120, -- massimo spessore per pulitura angolo con fresa 30deg + MIN_DIM_ALLOW_CLEAN = 200, -- apertura minima per lavorazione pulitura spigolo + MILL_MAX_DEPTH_AS_MAT = true, -- massimo affondamento frese uguale ad altezza tagliente (max materiale) + CUT_MAX_LENGTH = 3000, -- massima lunghezza di un taglio + SIMUL_VIEW_DIR = 1, -- direzione di vista predefinita per la simulazione (1=NW, 2=SW, 3=NE, 4=SE) + BEAM_MACHINE = true -- lavorazione pareti su macchina travi (PF...) +} + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Wall', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1500rl.data" +local sDataWall = EgtGetSourceDir().."\\Ts3Data.lua" +local sDataBeam = EgtGetCurrMachineDir()..'\\Beam\\Ts3Data.lua' +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sDataWall) + EgtCopyFile( sTs3Data, sDataBeam) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sDataWall) then + local Machine = dofile( sDataWall) + if Machine then + if Machine.Trave then + WallData.MIN_LENGTH = Machine.Trave.YMIN or WallData.MIN_LENGTH + WallData.MIN_WIDTH = Machine.Trave.XMIN or WallData.MIN_WIDTH + WallData.MIN_HEIGHT = Machine.Trave.ZMIN or WallData.MIN_HEIGHT + WallData.MAX_LENGTH = Machine.Trave.YMAX or WallData.MAX_LENGTH + WallData.MAX_WIDTH = Machine.Trave.XMAX or WallData.MAX_WIDTH + WallData.MAX_HEIGHT = Machine.Trave.ZMAX or WallData.MAX_HEIGHT + end + end +end + +--------------------------------------------------------------------- +return WallData diff --git a/Wall/WallTableTemplate.ini b/Wall/WallTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/Wall/WallTableTemplate.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%