-- Processore macchina Essetre-FAST by EgalWare s.r.l. 2024/03/09 -- Intestazioni require( 'EmtGenerator') EgtEnableDebug( false) -- carico librerie local BD = require( 'BeamData') LONG_TOOL_MINLEN = 221 BIG_TOOL_DIAM = 300 --------------------------------------------------------------------- -- *** GENERATION *** --------------------------------------------------------------------- local sBaseDir = EgtGetCurrMachineDir() if NumericalControl == 'NUM' then dofile( sBaseDir .. '\\Common_FAST.NUM.mlpe') elseif NumericalControl == 'TPA' then dofile( sBaseDir .. '\\Common_FAST.TPA.mlpe') elseif NumericalControl == 'NUM_PLUS' then dofile( sBaseDir .. '\\Common_FAST.NUM_PLUS.mlpe') else EmtSetLastError( 1201, '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]) for j = 1, #( vTools or {}) do if vTools[j] ~= '' then EgtLoadTool( vTcPos[i], j, vTools[j]) end end ShowToolInTcPos( vTcPos[i], true) end end -- 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( 'Z', 'COLLISION', EMT.COLLOBJ) AddToCollisionCheck( 'B', 'COLLISION', EMT.COLLOBJ) AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ) AddToCollisionCheck( 'H5', 'COLLISION', EMT.COLLOBJ) AddToolToCollisionCheck( 'H2', 1, EMT.COLLOBJ) AddToolHolderToCollisionCheck( 'H2', 1, EMT.COLLOBJ) DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) EMT.MCODET = {} local McdData = { { Grp = 'Y', Sub = 'COLLISION', Name = 'VOL1'}, { Grp = 'Y', Sub = 'COLLISION', Name = 'VOL2'}, { Grp = 'PY', Sub = 'COLLISION', Name = 'VOL'}, { Grp = 'V', Sub = 'COLLISION', Name = 'VOL1'}, { Grp = 'V', Sub = 'COLLISION', Name = 'VOL2'}, { Grp = 'PV', Sub = 'COLLISION', Name = 'VOL'}, { Grp = 'Base', Sub = 'COLLISION', Name = 'SIDE1'}, { Grp = 'Base', Sub = 'COLLISION', Name = 'SIDE2'}} 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 or GDB_ID.NULL, McdData[i].Sub) or GDB_ID.NULL, 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() --end --------------------------------------------------------------------- function OnSimulDispositionStarting() EmtUnlinkAllRawPartsFromGroups() if EMT.PHASE > 1 then if IsStartOrRestPhase( EMT.PHASE) then EgtSetAxisPos( 'T', LoadT) end end end --------------------------------------------------------------------- function OnSimulDispositionStart() EMT.OPEISDISP = true -- Se prima disposizione if EMT.PHASE == 1 then -- Determino dimensioni del grezzo local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) EMT.LB = 0 EMT.SB = 0 EMT.HB = 0 if b3Sol then EMT.LB = b3Sol:getDimX() EMT.SB = b3Sol:getDimY() EMT.HB = b3Sol:getDimZ() end -- Carico primo utensile sulla testa 1 local sTool, nTlen = FindFirstToolOnHead( 'H1') if sTool and nTlen < LONG_TOOL_MINLEN then EMT.TOOL_1 = sTool else EMT.TOOL_1 = GetDefaultToolName() end EgtLoadTool( 'H1', 1, EMT.TOOL_1) EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) ShowToolInTcPos( EMT.TCPOS_1, false) EMT.LOAD = true -- Se vero inizio e abilitato creo gli Zmap EMT.VMILL = {} if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) local nPartRawId = EgtGetFirstRawPart() while nPartRawId do -- se è lo scarto finale tagliato a pezzi, esco local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') if nRawOrd == nLastOrd + 1 then break end -- elimino eventuale vecchio Zmap EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) -- recupero il solido local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) -- aggiungo eventuale scrap successivo if nRawOrd == nLastOrd then local nScrapId = EgtGetNextRawPart( nPartRawId) if nScrapId then local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) if b3ScrapRaw then b3Raw:Add( b3ScrapRaw) end end end -- determino la risoluzione dello Zmap local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() local dTol = 4.71 if dArea < CoeffVM * 0.15e6 then dTol = 0.71 elseif dArea < CoeffVM * 0.3e6 then dTol = 1.01 elseif dArea < CoeffVM * 0.6e6 then dTol = 1.51 elseif dArea < CoeffVM * 1.2e6 then dTol = 1.97 elseif dArea < CoeffVM * 2.4e6 then dTol = 2.81 elseif dArea < CoeffVM * 4.8e6 then dTol = 3.77 end -- creo lo Zmap local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) if VMillId then EgtSetName( VMillId, 'VMill') EgtSetLevel( VMillId, GDB_LV.TEMP) EgtSetColor( VMillId, EgtGetColor( nSolId), false) -- nascondo le altre geometrie local nId = EgtGetFirstInGroup( nPartRawId) while nId do if nId ~= VMillId then EgtSetStatus( nId, GDB_ST.OFF) end nId = EgtGetNext( nId) end table.insert( EMT.VMILL, VMillId) end nPartRawId = EgtGetNextRawPart( nPartRawId) end end -- fasi successive else EMT.LOAD = false end -- recupero sovramateriale di testa del pezzo corrente local nCurrRawId = EgtGetFirstRawPart() while nCurrRawId do if EgtVerifyRawPartPhase( nCurrRawId, EMT.PHASE) then break end nCurrRawId = EgtGetNextRawPart( nCurrRawId) end EMT.HOVM = EgtGetInfo( nCurrRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 -- Nascondo tutte le lavorazioni local nMchId = EgtGetFirstOperation() while nMchId do if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then EgtSetOperationStatus( nMchId, false) end nMchId = EgtGetNextOperation( nMchId) end -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola if IsStartOrRestPhase( EMT.PHASE) then -- se fase inizio, segnalo giacitura del grezzo if IsStartPhase( EMT.PHASE) then local nRot = GetPhaseRot( EMT.PHASE) if nRot ~= 0 then EgtOutText( tostring( -90 * nRot) .. '° rotated bar') else EgtOutText( 'Not rotated bar') end end -- indice primo grezzo della fase local nOrd = GetPhaseOrd( EMT.PHASE) local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 local b3Raw = BBox3d() local nPartRawId, nScrapRawId local nRawId = EgtGetFirstRawPart() while nRawId do local nNextRawId = EgtGetNextRawPart( nRawId) if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then EmtLinkRawPartToGroup( nRawId, 'Tab') local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') if nRawOrd == nOrd then b3Raw = EgtGetRawPartBBox( nRawId) nPartRawId = nRawId elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then local b3Tmp = EgtGetRawPartBBox( nRawId) or BBox3d() b3Raw:Add( b3Tmp) nScrapRawId = nRawId end end nRawId = nNextRawId end -- gestione eventuale scarto affettato successivo if EMT.VMILL and #EMT.VMILL > 0 then EMT.SCRAP = nScrapRawId EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) else EMT.SCRAP = nil end -- recupero CutId del pezzo in lavorazione EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 EMT.YSPEC = nil -- se vero inizio, assegno solidi per verifica collisione if not EMT.SIM1ST then EMT.CODET = {} for i = 1, #( EMT.MCODET or {}) do EMT.CODET[i] = EMT.MCODET[i] end for i = 1, #( EMT.VMILL or {}) do table.insert( EMT.CODET, EMT.VMILL[i]) end end -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola elseif IsMidPhase( EMT.PHASE) then -- se cambiata giacitura, lo segnalo local nPrevRot = GetPhaseRot( EMT.PHASE - 1) local nRot = GetPhaseRot( EMT.PHASE) if nRot ~= nPrevRot then if nRot ~= 0 then EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') else EgtOutText( 'Barra non ruotata') end end -- eseguo aggancio local nRawId = EgtGetFirstRawPart() while nRawId do local nNextRawId = EgtGetNextRawPart( nRawId) if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then EmtLinkRawPartToGroup( nRawId, 'Tab') end nRawId = nNextRawId end -- se Vmill, nascondo eventuale scrap if EMT.VMILL then EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) end -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then -- se cambiata giacitura, lo segnalo local nPrevRot = GetPhaseRot( EMT.PHASE - 1) local nRot = GetPhaseRot( EMT.PHASE) if nRot ~= nPrevRot then if nRot ~= 0 then EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') else EgtOutText( 'Barra non ruotata') end end -- indice primo grezzo della fase local nOrd = GetPhaseOrd( EMT.PHASE) -- ricerco vettore movimento per i successivi local vtMove = Vector3d() local nRawId = EgtGetFirstRawPart() while nRawId do if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) break end nRawId = EgtGetNextRawPart( nRawId) end -- eseguo nRawId = EgtGetFirstRawPart() while nRawId do local nNextRawId = EgtGetNextRawPart( nRawId) if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then EmtLinkRawPartToGroup( nRawId, 'Tab') else EgtMove( nRawId, vtMove, GDB_RT.GLOB) EgtSetStatus( nRawId, GDB_ST.OFF) end end nRawId = nNextRawId end -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y else -- indice primo grezzo della fase local nOrd = GetPhaseOrd( EMT.PHASE) -- ricerco vettore movimento per i successivi local vtMove = Vector3d() local nRawId = EgtGetFirstRawPart() while nRawId do if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) break end nRawId = EgtGetNextRawPart( nRawId) end -- eseguo nRawId = EgtGetFirstRawPart() while nRawId do local nNextRawId = EgtGetNextRawPart( nRawId) if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then EmtLinkRawPartToGroup( nRawId, 'Tab') else EgtMove( nRawId, vtMove, GDB_RT.GLOB) EmtLinkRawPartToGroup( nRawId, 'Y') end end nRawId = nNextRawId end end -- Indicazione angolo rotazione pezzo EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0 local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN') EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF)) EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF)) EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF)) end --------------------------------------------------------------------- function OnSimulDispositionEnd() if EMT.UNLOADING or EMT.FALL then ExecUnloading() EMT.UNLOADING = false EMT.FALL = false end -- se disposizione intermedia if IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then -- se le rotazioni delle fasi corrente e precedente sono diverse if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then -- imposto stato post-rotazione EMT.POSTROT = true end -- se altrimenti disposizione intermedia speciale con eventuale rotazione elseif IsMid2Phase( EMT.PHASE) then -- se le rotazioni delle fasi corrente e precedente sono diverse if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then -- imposto stato post-rotazione EMT.POSTROT = true end end EMT.OPEISDISP = false end --------------------------------------------------------------------- function OnSimulToolSelect( dPosA) -- se utensile non definito, è disposizione ed esco if EMT.TOOL == '' then return end -- recupero dati utensile EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) EMT.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) EMT.TOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) -- se non è chiamato da altro script (non c'è parametro) if not dPosA then -- se attivo Vmill SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) -- se attivo Collision Check EMT.SAFEDIST = COLL_SAFE_DIST if EMT.COLLOBJ then for i, Coll in ipairs( EMT.COLLOBJ) do EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) end if EMT.HEAD ~= 'H2' then AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001) AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002) else AddToolToCollisionObj( nil, 'H1', 1, 1001) AddToolHolderToCollisionObj( nil, 'H1', 1, 1002) end end -- dichiaro assi ausiliari da visualizzare EMT.AuxAxes = 2 EMT.A1n = 'Y' EMT.A2n = 'V' end -- carico utensile se non lama su sua testa o dummy if EMT.HEAD ~= 'H2' and EMT.HEAD ~= 'H4' then -- se sega a catena, imposto subito angolo scelto per asse virtuale A if EMT.HEAD == 'H3' then if not dPosA then -- recupero la lavorazione successiva local NextMchId if EMT.MCHID then NextMchId = EgtGetNextActiveOperation( EMT.MCHID) else NextMchId = EgtGetFirstActiveOperation() end while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do NextMchId = EgtGetNextActiveOperation( NextMchId) end EgtSetCurrMachining( NextMchId) -- recupero il valore dell'asse virtuale bloccato A local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) dPosA = tonumber( sVal:sub( 3)) else -- imposto visualizzazione EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) end -- imposto il valore di A EgtSetAxisPos( 'A', dPosA) if abs( dPosA) < 0.1 then EgtSetAxisPos( 'C', EgtIf( BD.RIGHT_LOAD, 180, 0)) end EgtSetAxisPos( 'B', 0) end -- se punta lunga if EMT.TOTLEN > LONG_TOOL_MINLEN then -- se su cambio utensile T111 if EMT.TCPOS == 'T111' then EgtSetAxisPos( 'B', 0) end end -- breve pausa EgtPause( 100) EgtOutText( '') EMT.TOOL_1 = EMT.TOOL EMT.TCPOS_1 = EMT.TCPOS -- lo nascondo sul portautensili ShowToolInTcPos( EMT.TCPOS, false) end end --------------------------------------------------------------------- function OnSimulToolDeselect() -- se prossimo utensile non definito, è disposizione ed esco if EMT.NEXTTOOL == '' then return end -- se cambia uscita su rinvio non devo fare alcunché if EMT.HEAD == 'H5' and EMT.NEXTHEAD == 'H5' then return end -- se sega a catena o rinvio o punta lunga o utensile di grosso diametro, devo cambiare if EMT.HEAD == 'H3' or EMT.HEAD == 'H5' or ( EMT.HEAD == 'H1' and ( EMT.TOTLEN > LONG_TOOL_MINLEN or EMT.TOTDIAM > BIG_TOOL_DIAM)) then EgtOutText( 'Tool change in progress...') -- movimento scarico sega a catena if EMT.HEAD == 'H3' then -- se avevo motosega, torno in zona sicura senza ruotare assi rotanti if EMT.HB > BeamHeightForFixRot then SimulMoveAxis( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID) end local dPosA = EgtGetAxisPos( 'A') if abs( dPosA) < 0.1 then SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 180, 0), MCH_SIM_STEP.COLLROT) else SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) -- movimento scarico rinvio elseif EMT.HEAD == 'H5' then SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', -90, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) -- movimento scarico punta lunga su T111 elseif EMT.TOTLEN > LONG_TOOL_MINLEN then -- se su cambio utensile T111 if EMT.TCPOS == 'T111' then SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', 0, MCH_SIM_STEP.COLLROT) -- altrimenti posizioni standard rastrelliera else SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B', 90, MCH_SIM_STEP.COLLROT, 'C', -90, MCH_SIM_STEP.COLLROT) end -- movimento scarico utensile di grosso diametro (su T111) else local dPosB = EgtGetAxisPos( 'B') local dNewB = EgtIf( dPosB < 0, -90, 90) SimulMoveAxes( 'B', dNewB, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 180, 0), MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) end -- breve pausa EgtPause( 100) -- nascondo utensile su testa e lo visualizzo su TcPos EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) ShowToolInTcPos( EMT.TCPOS_1, true) -- movimento per carico utensile if EMT.NEXTHEAD ~= 'H3' and EMT.NEXTHEAD ~= 'H5' then SimulMoveAxes( 'B', 90, MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT) else SimulMoveAxes( 'B', 0, MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT) end -- se segue lama, carico utensile di default if EMT.NEXTHEAD == 'H2' then local sDefTool = GetDefaultToolName() EgtLoadTool( 'H1', 1, sDefTool) EMT.TOOL_1 = sDefTool EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) -- lo nascondo sul portautensili ShowToolInTcPos( EMT.TCPOS_1, false) end EgtOutText( '') -- deposito utensile se prossimo non lama su sua testa o dummy elseif EMT.NEXTHEAD ~= 'H2' and EMT.NEXTHEAD ~= 'H4' then if EMT.NEXTTOOL ~= EMT.TOOL_1 then EgtOutText( 'Tool change in progress...') -- simulo movimento SimulMoveAxes( 'B', 90, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID) -- breve pausa EgtPause( 100) ShowToolInTcPos( EMT.TCPOS_1, true) -- se segue sega a catena if EMT.NEXTHEAD == 'H3' or EMT.NEXTHEAD == 'H5' then -- se non lama, nascondo l'utensile corrente if EMT.HEAD ~= 'H2' then EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) end -- eseguo movimento opportuno SimulMoveAxes( 'B', 0, MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT) -- se altrimenti lama su cambio utensile elseif EMT.NEXTHEAD == 'H1' and SpecialBH and EMT.NEXTTCPOS == 'T111' then -- se non lama, nascondo l'utensile corrente if EMT.HEAD ~= 'H2' then EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) end -- eseguo movimento opportuno SimulMoveAxes( 'B', -90, MCH_SIM_STEP.RAPROT, 'C', 0, MCH_SIM_STEP.RAPROT) end else EMT.TOOL_1 = nil EMT.TCPOS_1 = nil end end end --------------------------------------------------------------------- function OnSimulMachiningStart() -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then local dPrevA = EgtGetAxisPos( 'A') local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) local dPosA = tonumber( sVal:sub( 3)) if abs( dPosA - dPrevA) > 1 then OnSimulToolDeselect() EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) OnSimulToolSelect( dPosA) end end -- recupero alcuni dati della lavorazione EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) -- recupero TASKID della feature lavorata local vId = EgtGetMachiningGeometry() if vId and #vId > 0 and #vId[1] > 0 then EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; else EMT.TASKID = 0 end -- non ancora iniziata la lavorazione EMT.MCHFIRST = true end --------------------------------------------------------------------- function OnSimulMachiningEnd() if EMT.LOAD then EMT.LOAD = false elseif EMT.UNLOADING or EMT.FALL then ExecUnloading() EMT.UNLOADING = false EMT.FALL = false end EMT.PREVHEAD = EMT.HEAD EMT.PREVEXIT = EMT.EXIT end --------------------------------------------------------------------- --function OnSimulPathStart() --end --------------------------------------------------------------------- function OnSimulPathEnd() -- rimozione eventuali sfridi ExecRemoveScraps() end --------------------------------------------------------------------- function OnSimulPathStartAux() --EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) EgtOutLog( 'OnSimulPathStartAux', 5) -- eseguo il comando ExecAuxCmd( EMT.AUX) end --------------------------------------------------------------------- function OnSimulPathEndAux() --EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) EgtOutLog( 'OnSimulPathEndAux', 5) -- eseguo il comando ExecAuxCmd( EMT.AUX) end --------------------------------------------------------------------- function OnSimulMoveStart() -- Recupero la posizione corrente dei carrelli local Yp = EgtGetAxisPos( 'Y') local Vp = EgtGetAxisPos( 'V') -- Imposto movimento carrelli insieme con la tavola : -- entrambe le pinze if EMT.YDELTA and EMT.VDELTA then EMT.AuxAxes = 2 EMT.A1n = 'Y' EMT.A1m = 'T' EMT.A1 = EMT.L1 + EMT.YDELTA EMT.A2n = 'V' EMT.A2m = 'T' EMT.A2 = EMT.L1 + EMT.VDELTA -- solo pinza Y elseif EMT.YDELTA then EMT.AuxAxes = 2 EMT.A1n = 'Y' EMT.A1m = 'T' EMT.A1 = EMT.L1 + EMT.YDELTA EMT.A2n = 'V' EMT.A2m = nil EMT.A2 = ParkV -- solo pinza V elseif EMT.VDELTA then EMT.AuxAxes = 2 EMT.A1n = 'Y' EMT.A1m = nil EMT.A1 = EgtIf( EMT.YSPEC, Yp, ParkY) EMT.A2n = 'V' EMT.A2m = 'T' EMT.A2 = EMT.L1 + EMT.VDELTA end -- Controllo scorrimento pinze chiuse Y e V if EMT.YDELTA then local dYDeltaP = Yp - EMT.L1p if abs( EMT.YDELTA - dYDeltaP) > 0.1 then EMT.ERR = 2 local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.YDELTA, 3) EmtSetLastError( 1202, sErr) end end if EMT.VDELTA then local dVDeltaP = Vp - EMT.L1p if abs( EMT.VDELTA - dVDeltaP) > 0.1 then EMT.ERR = 2 local sErr = 'V slide : ' .. EgtNumToString( dVDeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.VDELTA, 3) EmtSetLastError( 1202, sErr) end end -- Controllo corse assi Y e V VerifyYStroke( EMT.A1) VerifyVStroke( EMT.A2) -- se inizio lavorazione if EMT.MCHFIRST then EgtOutText( '') EMT.MCHFIRST = false -- con pezzi alti aggiorno gli assi rotanti prima di muovermi sopra il pezzo if not EMT.LOAD and EMT.MOVE == 0 and EMT.HB > BeamHeightForFixRot and EMT.FLAG2 == 1 then -- se motosega mi muovo a X di sicurezza per ruotare if EMT.HEAD == 'H3' or EMT.TOTLEN > 200 then SimulMoveAxes( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID, 'C', EMT.R1, MCH_SIM_STEP.COLLROT, 'B', EMT.R2, MCH_SIM_STEP.COLLROT) end end EMT.POSTROT = nil end end --------------------------------------------------------------------- function OnSimulMoveEnd() if EMT.FLAG == 301 then -- rimozione eventuali sfridi ExecRemoveScraps() 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 then Class = 'T_H1' elseif EMT.SIMCOBIND == 1002 then Class = 'TH_H1' else Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl end table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME EMT.ERR = 1 local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID EmtSetLastError( 1221, sErr, true) EgtOutLog( 'Collision : ' .. sErr, 1) end end --------------------------------------------------------------------- function ExecAuxCmd( sCmd) local Cmd = EgtSplitString( sCmd) if Cmd[1] == '0' then if Cmd[2] == 'Unloading' then EMT.UNLOADING = true elseif Cmd[2] == 'Fall' then EMT.FALL = true end EgtOutText( EgtIf( Cmd[3], Cmd[3], Cmd[2])) elseif Cmd[1] == '1' then if not SimulMoveAxis( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID) then if VerifyYVStroke( Cmd[2], tonumber( Cmd[3])) == nil then EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) end end elseif Cmd[1] == '2' then if Cmd[2] == 'Y' and EMT.POSTROT then local dPosY = tonumber( Cmd[3]) - EMT.HOVM Cmd[3] = EgtNumToString( dPosY, 3) EMT.HOVM = 0 end -- Verifico movimento carrello con trave agganciata VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) -- Eseguo il movimento local _, bOk, bOk2 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID) if not ( bOk and bOk2) then local nI = EgtIf( not bOk, 2, 4) if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) end end elseif Cmd[1] == '3' then -- Verifico movimento carrelli con trave agganciata VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) -- Eseguo il movimento local _, bOk, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID, Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID, Cmd[6], tonumber( Cmd[7]), MCH_SIM_STEP.RAPID) if not ( bOk and bOk2 and bOk3) then local nI = EgtIf( not bOk, 2, EgtIf( not bOk2, 4, 6)) if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) end end elseif Cmd[1] == '11' then local dPY = MaxOpen if Cmd[2] ~= '0' then dPY = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) end SimulMoveAxis( 'PY', dPY, MCH_SIM_STEP.RAPID) SetPYLight( Cmd[2] ~= '0') elseif Cmd[1] == '12' then local dPV = MaxOpen if Cmd[2] ~= '0' then dPV = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) end SimulMoveAxis( 'PV', dPV, MCH_SIM_STEP.RAPID) SetPVLight( Cmd[2] ~= '0') elseif Cmd[1] == '21' then local nYDelta = tonumber( Cmd[2]) local nVDelta = tonumber( Cmd[3]) if nYDelta > 0.01 and nVDelta > 0.01 then EMT.YDELTA = nYDelta EMT.VDELTA = nVDelta elseif nYDelta > 0.01 then EMT.YDELTA = nYDelta EMT.VDELTA = nil elseif nVDelta > 0.01 then EMT.YDELTA = nil EMT.VDELTA = nVDelta end elseif Cmd[1] == '31' then local nRawId = tonumber( Cmd[2]) EmtUnlinkRawPartFromGroup( nRawId) EmtLinkRawPartToGroup( nRawId, Cmd[3]) EMT.YSPEC = true end 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 EgtOutLog( 'OnSimulPathEnd', 5) local vMillId = EMT.VMILL[1] local nPart = EgtVolZmapPartCount( vMillId) if nPart > 1 then -- ricerca del pezzo con massimo volume local nPartMax = 0 local dVolMax = 0 for i = 1, nPart do local dVol = EgtVolZmapPartVolume( vMillId, i - 1) if dVol > dVolMax then dVolMax = dVol nPartMax = i end end -- eliminazione di tutti i pezzi piccoli for i = nPart, 1, -1 do if i ~= nPartMax then local b3Vmill = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD) if b3Vmill:getDimX() < 1200 then EgtRemoveVolZmapPart( vMillId, i - 1) end end end -- aggiorno visualizzazione EgtDraw() end end end --------------------------------------------------------------------- function 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.SB + 50.0), -( EMT.SB + 50.0)), 0), GDB_RT.GLOB) nId = EgtGetNext( nId) end -- creo un nuovo layer e vi inserisco il nuovo pezzo local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) EgtRelocate( vMillId, nLayId) local vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 450, -450), 0) if EMT.FALL then vtMove = Vector3d( -500, 0, EgtIf( BD.RIGHT_LOAD, 750, -750)) 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) if sExt and sExt:lower() == ".nge" then sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) EgtSetLevel( nVmGrpId, GDB_LV.USER) EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') EgtSetLevel( nVmGrpId, GDB_LV.TEMP) end end end end end end --------------------------------------------------------------------- function VerifyYSlide( sName1, dVal1, sName2, dVal2) -- Se movimento trave agganciata con carrello Y if sName1 == 'T' and sName2 == 'Y' and GetPYLight() then local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'Y') local dYDeltaA = tonumber( dVal1) - tonumber( dVal2) EgtOutLog( string.format( 'YDeltaP=%.3f YDeltaA=%.3f', dYDeltaP, dYDeltaA), 5) if abs( dYDeltaA - dYDeltaP) > 0.5 then EMT.ERR = 2 local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( dYDeltaA, 3) EmtSetLastError( 1202, sErr) end end -- Tutto bene return true end --------------------------------------------------------------------- function VerifyVSlide( sName1, dVal1, sName2, dVal2) -- Se movimento trave agganciata con carrello V if sName1 == 'T' and sName2 == 'V' and GetPVLight() then local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'V') local dVDeltaA = tonumber( dVal1) - tonumber( dVal2) EgtOutLog( string.format( 'VDeltaP=%.3f VDeltaA=%.3f', dVDeltaP, dVDeltaA), 5) if abs( dVDeltaA - dVDeltaP) > 0.5 then EMT.ERR = 2 local sErr = 'V slide : ' .. EmtLenToString( dVDeltaP, 3) .. ' -> ' .. EmtLenToString( dVDeltaA, 3) EmtSetLastError( 1202, sErr) end end return true end --------------------------------------------------------------------- function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) -- Metto in prima posizione la trave if sName2 == 'T' then sName1, sName2 = sName2, sName1 dVal1, dVal2 = dVal2, dVal1 end -- Eseguo verifica if sName2 == 'Y' then return VerifyYSlide( sName1, dVal1, sName2, dVal2) elseif sName2 == 'V' then return VerifyVSlide( sName1, dVal1, sName2, dVal2) end return true end --------------------------------------------------------------------- function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) -- Metto in prima posizione la trave if sName2 == 'T' then sName1, sName2 = sName2, sName1 dVal1, dVal2 = dVal2, dVal1 elseif sName3 == 'T' then sName1, sName3 = sName3, sName1 dVal1, dVal3 = dVal3, dVal1 end -- Eseguo verifica if sName2 == 'Y' then return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3) elseif sName2 == 'V' then return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3) end return true end --------------------------------------------------------------------- function VerifyYStroke( dY) if dY < MinY then EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MinY, ' (L1-)') EMT.ERR = 1 local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MinY, 3) EgtOutLog( sErr) return false elseif dY > MaxY then EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MaxY, ' (L1+)') EMT.ERR = 1 local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MaxY, 3) EgtOutLog( sErr) return false end return true end --------------------------------------------------------------------- function VerifyVStroke( dV) if dV > MaxV then EmtSetOutstrokeInfo( 'V', 'V', true, dV - MaxV, ' (L1+)') EMT.ERR = 1 local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MaxV, 3) EgtOutLog( sErr) return false elseif dV < MinV then EmtSetOutstrokeInfo( 'V', 'V', true, dV - MinV, ' (L1-)') EMT.ERR = 1 local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MinV, 3) EgtOutLog( sErr) return false end return true end --------------------------------------------------------------------- function VerifyYVStroke( sName, dVal) if sName == 'Y' then return VerifyYStroke( dVal) elseif sName == 'V' then return VerifyVStroke( dVal) else return nil end end --------------------------------------------------------------------- function ShowToolInTcPos( sTcPos, bShow) -- recupero identificativo della posizione sul TC local TcPosId = EgtGetTcPosId( sTcPos or '') if not TcPosId then return end -- ciclo sulle possibili uscite for i = 1, 100 do -- recupero il gruppo dell'utensile local TcExitId = EgtGetFirstNameInGroup( TcPosId, 'T'..tostring( i)) if not TcExitId then break end -- imposto lo stato di visualizzazione EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) end -- recupero eventuale gruppo ausiliario da visualizzare/nascondere local TcHSId = EgtGetFirstNameInGroup( TcPosId, sTcPos..'_HS') if TcHSId then EgtSetStatus( TcHSId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) end end --------------------------------------------------------------------- function GetToolTcPos( sTool) -- salvo stato iniziale local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) -- recupero la posizione di cambio utensile dell'utensile indicato local sTcPos if EgtTdbSetCurrTool( sTool) then sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) end -- ripristino stato iniziale if CurrTool then EgtTdbSetCurrTool( CurrTool) else EgtTdbSetCurrTool( '') end -- restituisco risultato return sTcPos end --------------------------------------------------------------------- -- *** ESTIMATION T&L *** --------------------------------------------------------------------- local RAPID_X_FEED = 75000 -- mm/min local RAPID_Y_FEED = 100000 -- mm/min local RAPID_Z_FEED = 50000 -- mm/min local RAPID_C_FEED = 15000 -- deg/min local RAPID_B_FEED = 15000 -- deg/min local RAPID_MIN_T = 0.1 -- s local LOAD_T = 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( 'X') EMT.L3 = EgtGetAxisHomePos( 'Z') EMT.R1 = EgtGetAxisHomePos( 'C') EMT.R2 = EgtGetAxisHomePos( 'B') -- aggiorno valori come precedenti EmtUpdatePrev() -- totalizzatori tempi e lunghezze EMT.TOTCUTLEN = 0 EMT.TOTCUTTIME = 0 EMT.TOTEXTLEN = 0 EMT.TOTEXTTIME = 0 -- variabile per lunghezza taglio utensili EMT.TOOLCUTLEN = {} -- intestazioni EmtTleStart( EMT.INFO) end --------------------------------------------------------------------- function OnEstimProgramEnd() -- stampa dei totali delle lavorazioni EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) -- stampa dei totali degli utensili for i = 1, #EMT.TOOLCUTLEN do local TCL = EMT.TOOLCUTLEN[i] EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) end -- completo il file local _, _, sExt = EgtSplitPath( EMT.FILE) EmtTleEnd( sExt:sub( 2)) -- salvo i dati principali nel progetto EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) end --------------------------------------------------------------------- function OnEstimDispositionStart() -- inizio disposizione EMT.OPEISDISP = true -- sulla prima fase dichiaro carico barra if EMT.PHASE == 1 then EMT.LOAD = true else EMT.LOAD = false end end --------------------------------------------------------------------- function OnEstimDispositionEnd() -- Se disposizione inizio o rimanenza if IsStartOrRestPhase( EMT.PHASE) then ; -- se altrimenti disposizione intermedia o finale dopo separazione e rotazione, eventuale rotazione elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then -- recupero le rotazioni delle fasi corrente e precedente local nRot = GetPhaseRot( EMT.PHASE) local nPrevRot = GetPhaseRot( EMT.PHASE - 1) -- verifico se sono diverse if nRot ~= nPrevRot then -- imposto stato post-rotazione EMT.POSTROT = true end -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni else ; end -- emetto dati in sospeso if EMT.TLE_NAME then EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') EMT.TLE_NAME = nil EMT.TLE_TIME = nil end -- termine disposizione EMT.OPEISDISP = false end --------------------------------------------------------------------- function OnEstimToolSelect() -- reset indice utensile in tabella lunghezze EMT.TCLIND = 0 -- verifico che l'utensile sia definito if #EMT.TOOL == 0 then return end -- cerco l'utensile nella tabella for i = 1, #EMT.TOOLCUTLEN do if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then EMT.TCLIND = i break end end -- se non trovato, lo aggiungo if EMT.TCLIND == 0 then table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) EMT.TCLIND = #EMT.TOOLCUTLEN end end --------------------------------------------------------------------- function OnEstimToolDeselect() end --------------------------------------------------------------------- function OnEstimMachiningStart() EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) -- reset contatori di lavorazione EMT.MCHCUTLEN = 0 EMT.MCHCUTTIME = 0 EMT.MCHEXTLEN = 0 EMT.MCHEXTTIME = 0 end --------------------------------------------------------------------- function OnEstimMachiningEnd() -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita if EMT.MCHTYPE == MCH_MY.DRILLING then EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 end local sName = EgtGetName( EMT.MCHID) EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) -- aggiorno totali e utensili EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN -- emetto dati in sospeso if EMT.TLE_NAME then EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') EMT.TLE_NAME = nil EMT.TLE_TIME = nil end end --------------------------------------------------------------------- function OnEstimPathStart() EMT.AUXTYPE = nil EMT.MCHMOVEFIRST = true EMT.CHARMOVE = nil end --------------------------------------------------------------------- function OnEstimPathEnd() EMT.AUXTYPE = nil end --------------------------------------------------------------------- function OnEstimPathStartAux() -- se richiesto, preparo il carico barra if EMT.LOAD then if EMT.AUXIND == EMT.AUXTOT then local dTime = LOAD_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') EMT.LOAD = false end -- se altrimenti carico dopo rotazione elseif EMT.POSTROT then if EMT.AUXIND == EMT.AUXTOT then local dTime = ROTATION_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') EMT.POSTROT = false end -- altrimenti, spostamento carrelli else local Cmd = EgtSplitString( EMT.AUX) if ( Cmd[1] == '1' and Cmd[2] ~= 'Z') or Cmd[1] == '2' or Cmd[1] == '3' then EMT.CHARMOVE = true end if EMT.AUXIND == EMT.AUXTOT and EMT.CHARMOVE then local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') end end end --------------------------------------------------------------------- function OnEstimPathEndAux() -- verifico tipo di emissione if EMT.OPEISDISP then if not EMT.AUXTYPE then local Cmd = EgtSplitString( EMT.AUX) if Cmd[1] == '0' and Cmd[2] == 'Unloading' then EMT.AUXTYPE = 'U' else EMT.AUXTYPE = 'R' end end else if not EMT.AUXTYPE then local Cmd = EgtSplitString( EMT.AUX) if Cmd[1] == '0' and Cmd[2] == 'Split' then EMT.AUXTYPE = 'S' elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then EMT.AUXTYPE = 'U' elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then EMT.AUXTYPE = 'F' else EMT.AUXTYPE = 'P' end end end -- per lo scarico della rimanenza if EMT.AUXTYPE == 'R' then if EMT.AUXIND == EMT.AUXTOT then local dTime = LOAD_T + UNLOAD_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EMT.TLE_NAME = 'Remnant unloading' EMT.TLE_TIME = dTime end -- per lo split elseif EMT.AUXTYPE == 'S' then if EMT.AUXIND == EMT.AUXTOT then local dTime = SPLIT_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EMT.TLE_NAME = 'Splitting' EMT.TLE_TIME = dTime end -- per lo scarico elseif EMT.AUXTYPE == 'U' then if EMT.AUXIND == EMT.AUXTOT then local dTime = UNLOAD_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EMT.TLE_NAME = 'Unloading' EMT.TLE_TIME = dTime end -- per lo scarico a caduta elseif EMT.AUXTYPE == 'F' then if EMT.AUXIND == EMT.AUXTOT then local dTime = FALL_T EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime EMT.TLE_NAME = 'Fall' EMT.TLE_TIME = dTime end -- per la pre-rotazione elseif EMT.AUXTYPE == 'P' then ; -- calcolato come parte della rotazione end end --------------------------------------------------------------------- function OnEstimRapid() -- dati movimento local dL1 = EMT.L1 - EMT.L1p local dL2 = EMT.L2 - EMT.L2p local dL3 = EMT.L3 - EMT.L3p local dR1 = 0 if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end local dR2 = 0 if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli if EMT.MCHMOVEFIRST then EMT.MCHMOVEFIRST = false dL1 = 0 end -- calcolo lunghezza local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen -- calcolo tempo local dTime = RAPID_MIN_T local dT1 = abs( dL1) / RAPID_X_FEED * 60 if dT1 > dTime then dTime = dT1 end local dT2 = abs( dL2) / RAPID_Y_FEED * 60 if dT2 > dTime then dTime = dT2 end local dT3 = abs( dL3) / RAPID_Z_FEED * 60 if dT3 > dTime then dTime = dT3 end local dT4 = abs( dR1) / RAPID_C_FEED * 60 if dT4 > dTime then dTime = dT4 end local dT5 = abs( dR2) / RAPID_B_FEED * 60 if dT5 > dTime then dTime = dT5 end EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) -- aggiorno valori come precedenti EmtUpdatePrev() end --------------------------------------------------------------------- function OnEstimLinear() -- dati movimento local dL1 = EMT.L1 - EMT.L1p local dL2 = EMT.L2 - EMT.L2p local dL3 = EMT.L3 - EMT.L3p -- calcolo lunghezza local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen -- calcolo tempo local dTime = dLen / EMT.F * 60 EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) -- aggiorno valori come precedenti EmtUpdatePrev() end --------------------------------------------------------------------- function OnEstimArc() -- dati movimento local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) -- calcolo lunghezza local dLen = sqrt( dLxy * dLxy + dLz * dLz) EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen -- calcolo tempo local dTime = dLen / EMT.F * 60 EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) -- aggiorno valori come precedenti EmtUpdatePrev() end --------------------------------------------------------------------- -- *** GENERAL *** --------------------------------------------------------------------- function FindFirstToolOnHead( sH1) -- salvo stato iniziale local CurrMachId = EgtGetCurrMachining() local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) -- cerco lavorazione con utensile su testa indicata local sTool, nTlen local OpId = EgtGetFirstActiveOperation() while OpId do local nType = EgtGetOperationType( OpId) if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then if EgtSetCurrMachining( OpId) then local sTest = EgtGetMachiningParam( MCH_MP.TOOL) if EgtTdbSetCurrTool( sTest) then local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) if sHead and ( sHead == sH1) then sTool = sTest nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) break end end end end OpId = EgtGetNextActiveOperation( OpId) end -- ripristino stato iniziale if CurrMachId then EgtSetCurrMachining( CurrMachId) else EgtResetCurrMachining() end if CurrTool then EgtTdbSetCurrTool( CurrTool) else EgtTdbSetCurrTool( '') end -- restituisco risultato return sTool, nTlen end --------------------------------------------------------------------- function GetDefaultToolName() local vTools = EgtGetToolsInCurrSetupPos( DefTcPos) if vTools and vTools[1] and #vTools[1] > 0 then return vTools[1] else local sErr = 'Missing tool in Default Position ' .. DefTcPos EgtOutLog( 'Error : ' .. sErr) if EMT.VER and EMT.VER >= '2.3a2' and EMT.SIM1ST then EgtOutBox( sErr, 'ERROR', 'ERROR') end return '' end end --------------------------------------------------------------------- function IsStartPhase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'START') end --------------------------------------------------------------------- function IsRestPhase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'REST') end --------------------------------------------------------------------- function IsStartOrRestPhase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'START' or sVal == 'REST') end --------------------------------------------------------------------- function IsEndPhase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'END') end --------------------------------------------------------------------- function IsMidPhase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'MID') end --------------------------------------------------------------------- function IsMid2Phase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'MID2') end --------------------------------------------------------------------- function IsEnd2Phase( nPhase) local sVal = GetPhaseType( nPhase) return ( sVal == 'END2') end --------------------------------------------------------------------- function GetPhaseType( nPhase) return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') end --------------------------------------------------------------------- function GetPhaseOrd( nPhase) return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) end --------------------------------------------------------------------- function GetPhaseRot( nPhase) return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) end --------------------------------------------------------------------- -- *** END GENERAL *** ---------------------------------------------------------------------