-- 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]) for j = 1, #( vTools or {}) do if vTools[j] ~= '' then EgtLoadTool( vTcPos[i], j, vTools[j]) -- Aggiunto controllo lunghezza lama minima * 0.9 per ricavare la tolleranza del VMILL if EgtTdbSetCurrTool(vTools[j]) then -- set utensile corrente if EgtTdbGetCurrToolParam( MCH_TP.TYPE) == MCH_TY.SAW_STD or EgtTdbGetCurrToolParam( MCH_TP.TYPE) == MCH_TY.SAW_FLAT then -- controllo tipo utensile sega local dCurrSawLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) * 0.9 -- se non definito o minore del valore precedente aggiorna la tolleranza EMT.VMILLTOL = EgtIf( not EMT.VMILLTOL or dCurrSawLen < EMT.VMILLTOL, dCurrSawLen, EMT.VMILLTOL) end end end end ShowToolInTcPos( vTcPos[i], true) 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 IsHeadExisting( 3) 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 IsHeadExisting( 3) 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 = {} -- si crea gruppo temporaneo appoggio controllo clamping CLAMP_CHECK_GROUP = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'CLAMP_CHECK') CLAMP_CHECK_INTERS = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'CLAMP_INTERS') if CLAMP_CHECK_GROUP then EgtEmptyGroup( CLAMP_CHECK_GROUP) else local frClampCheckGroup = Frame3d( ORIG(), GDB_FR.FRONT) CLAMP_CHECK_GROUP = EgtGroup( GDB_ID.ROOT, frClampCheckGroup) EgtSetName( CLAMP_CHECK_GROUP, 'CLAMP_CHECK') EgtSetLevel( CLAMP_CHECK_GROUP, GDB_LV.TEMP) EgtSetStatus( CLAMP_CHECK_GROUP, GDB_ST.OFF) end if CLAMP_CHECK_INTERS then EgtEmptyGroup( CLAMP_CHECK_INTERS) else CLAMP_CHECK_INTERS = EgtGroup( GDB_ID.ROOT) EgtSetName( CLAMP_CHECK_INTERS, 'CLAMP_INTERS') EgtSetLevel( CLAMP_CHECK_INTERS, GDB_LV.TEMP) EgtSetStatus( CLAMP_CHECK_INTERS, GDB_ST.OFF) end 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 dTol = 4.71 if EmtGetVMillStep then dTol = EmtGetVMillStep( b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol) else local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() if dArea < 0.075e6 then dTol = 0.71 elseif dArea < 0.15e6 then dTol = 1.01 elseif dArea < 0.3e6 then dTol = 1.51 elseif dArea < 0.6e6 then dTol = 1.97 elseif dArea < 1.2e6 then dTol = 2.81 elseif dArea < 2.4e6 then dTol = 3.77 end end dTol = min( dTol, EMT.VMILLTOL or dTol) -- imposto dTol al valore minore tra quello per volume e quello per spessore lama -- 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() if b3Part:getMin() then EMT.XMINT = b3Part:getMin():getX() + ( EgtGetAxisPos( 'T') - EgtGetAxisHomePos( 'T')) end EMT.HOVM = EgtGetInfo( nPartRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 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) EgtOutLog( '===> ToolSelect : Reset CollisionObj', 4) -- se utensile non definito, è disposizione ed esco if EMT.TOOL == '' then return end -- recupero dati utensile EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) 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 IsHeadExisting( 3) then EgtSetAxisPos( 'X3', ParkX3) end if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' then EgtSetAxisPos( 'Z1', MaxZ1Blade) elseif EMT.HEAD == 'H13' then EgtSetAxisPos( 'Z1', ParkCSawZ1) else EgtSetAxisPos( 'Z1', MaxZ1) 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 -- se prima lavorazione con motosega, parto dalla sua posizione di parcheggio EgtSetAxisPos( 'X1', ParkCSawX1) -- 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 aggregato foratura multipla, imposto subito angolo scelto per asse virtuale A if EMT.HEAD == 'H14' then -- valore dell'asse virtuale dPosA = dPosA or GetNextMultiDrillVirtualAxis( EMT.MCHID) -- imposto il valore di A EgtSetAxisPos( 'A1', dPosA) -- imposto home dell'asse C1 (A1=0 -> T121, A1=90 -> T124) local MyParkCSawC1 = GetMultiDrillCHomeFromVirtualAxis( 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 utensile non flottante, abilito per Vmill if not EMT.TFLOAT then EmtSetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) end -- se attivo Collision Check EMT.SAFEDIST = COLL_SAFE_DIST if EMT.COLLOBJ then local nInd = 1000 + tonumber( string.sub( EMT.HEAD, 2)) AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd, true) AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 100) 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' or EMT.NEXTHEAD ~= 'H14') 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) end -- per testa gruppo 2 if 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 EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H2 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) -- 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 aggregato foratore multiplo elseif EMT.PREVHEAD_H1 == 'H14' then -- simulo movimento local ParkC1 = EgtGetAxisHomePos( 'C1') if dPrevA then ParkC1 = GetMultiDrillCHomeFromVirtualAxis( dPrevA) end -- simulo movimento SimulMoveAxes( 'B1', ParkMultiDrillB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkMultiDrillX1, 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 scarico aggregato if nNextSetHead == 3 then -- deposito utensile prelevato da posizioni speciali if EMT.PREVTCPOS_H1 == 'T101' or EMT.PREVTCPOS_H1 == 'T111' or EMT.PREVTCPOS_H1 == 'T121' 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) local sTool, sTcPos, sHead local vTools = EgtGetToolsInCurrSetupPos( DefTcPos1) if vTools and vTools[1] then sTool = vTools[1] sTcPos = DefTcPos1 sHead = GetAdjHeadFromTcPos( 1, sTcPos) -- carico l'utensile EgtLoadTool( sHead, 1, sTool) ShowToolInTcPos( DefTcPos1, false) end EMT.PREVTOOL_H1 = sTool EMT.PREVHEAD_H1 = sHead EMT.PREVTCPOS_H1 = DefTcPos1 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 aggregato multi drill elseif EMT.NEXTHEAD == 'H14' then -- simulo movimento SimulMoveAxes( 'B1', ParkMultiDrillB1, MCH_SIM_STEP.RAPROT, 'C1', EgtGetAxisHomePos( 'C1'), MCH_SIM_STEP.RAPROT) SimulMoveAxes( 'X1', ParkMultiDrillX1, MCH_SIM_STEP.RAPID, 'Z1', ParkMultiDrillZ1, 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 local nInd = 1000 + tonumber( string.sub( EMT.NEXTHEAD, 2)) AddToolToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, nInd, false) AddToolHolderToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, nInd + 100) -- 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() EgtOutLog( '===> Start Machining : ' .. EgtGetName( EMT.MCHID), 4) -- se lavorazione è con gruppo a forare, abilito le altre punte alla lavorazione del VMILL if EMT.HEAD == 'H14' then local OtherTools = EgtGetToolsInCurrSetupPos( 'T121') if OtherTools and #OtherTools > 1 then for i = 1, #OtherTools do if OtherTools[i] ~= '' and OtherTools[i] ~= EMT.TOOL then EmtAddToolForVmill( OtherTools[i], 'H14', i, EMT.VMILL) -- dichiaro utensile per verifica collisioni local nInd = 1000 + tonumber( string.sub( 'H14', 2)) AddToolToCollisionObj( OtherTools[i], 'H14', i, nInd, true) end end end end -- se lavorazione attuale e precedente con sega a catena o aggregato foratore multiplo e con angolo A diverso, devo scaricare e ricaricare if ( EMT.HEAD == 'H13' or EMT.HEAD == 'H14') 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) EMT.MCHPRECUT = ( EMT.MCHUSERNOTES:find( 'Precut;', 1, true) ~= nil) EMT.MCHCUT = ( EMT.MCHUSERNOTES:find( 'Cut;', 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 = 1000 + tonumber( string.sub( sDouHead, 2)) AddToolToCollisionObj( sDouTool, sDouHead, nDouExit, nInd, true) AddToolHolderToCollisionObj( sDouTool, sDouHead, nDouExit, nInd + 100) -- 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 = 1000 + tonumber( string.sub( EMT.PREVHEAD_H1, 2)) AddToolToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1, true) AddToolHolderToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1 + 100) end if nSetHead ~= 2 and ( EMT.PREVTOOL_H2 and EMT.PREVHEAD_H2) then local nPrevExit_H2 = 1 local nInd_H2 = 1000 + tonumber( string.sub( EMT.PREVHEAD_H2, 2)) AddToolToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2, true) AddToolHolderToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2 + 100) end if nSetHead ~= 3 and IsHeadExisting( 3) then local sHeadName if EgtGetHeadId( 'H39') then sHeadName = 'H39' elseif EgtGetHeadId( 'H38') then sHeadName = 'H38' else EmtSetLastError( 1212, "HEAD not managed") end local nPrevExit_H3 = 1 local nInd_H3 = 1000 + tonumber( string.sub( sHeadName, 2)) AddToolToCollisionObj( nil, sHeadName, nPrevExit_H3, nInd_H3) AddToolHolderToCollisionObj( nil, sHeadName, nPrevExit_H3, nInd_H3 + 100) 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 else EMT.PREVTOOL_H3 = EMT.TOOL EMT.PREVHEAD_H3 = EMT.HEAD EMT.PREVTCPOS_H3 = EMT.TCPOS EMT.PREVTTOTLEN_H3 = EMT.TTOTLEN 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 -- dump oggetti di collisione if DumpCollisionObj then DumpCollisionObj( ' ==> CollisionObj :', 4) end -- se taglio di precut verifico quanto è più lungo il grezzo rispetto al pezzo (non tiene conto dell'ultimo cubetto) EMT.DELTA_LT = 0 if EMT.MCHPRECUT then local dCosA = sqrt( max( 1 - EMT.EXTR[1] * EMT.EXTR[1], 0)) EMT.DELTA_LT = max( EMT.XMINT - Point3d( EMT.MMAX):getX() - dCosA * EMT.TDIAM / 2, 0) EgtOutLog( 'PreCutDeltaLT='..EgtNumToString( EMT.DELTA_LT, 3), 5) 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) -- se movimento di B > di 90°, spezza il movimento in 2 arrivando alla quota Z con B+-90 e poi muove l'ultimo segmento -- evita collisione con carro X if EMT.R2 > 91 or EMT.R2 < -91 then local dBref = EgtClamp( EMT.R2, -91, 91) SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', dBref, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) else SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end -- caso standard else -- se bisogna scrivere tutti gli assi if WriteAllCoordsOnFirstM101 then SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), MCH_SIM_STEP.RAPID) end -- se ero in posizione speciale, prima ruoto poi scendo if bXSpec then local dZPos = max( Z1Home, EMT.L3) SimulMoveAxis( 'Z1', dZPos, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) if abs( dZPos - EMT.L3) > 1 then SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) end else SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) SimulMoveAxes( '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 end -- altrimenti sega a catena else local dSafeZ1 = EgtIf( EMT.TTOTLEN < MinLengthLongCSaw, ParkCSawZ1, ParkLongCSawZ1) -- Porto la Z alla giusta quota if Z1Pos > dSafeZ1 + 1 and abs( B1Pos) > 89.9 then SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'Z1', dSafeZ1, MCH_SIM_STEP.RAPID) end -- se movimento iniziale da Zmax if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then local dChSawEncumbrance = EMT.L3 + MillOffs - ( ( ChSawLen + MillOffs) * EMT.ADIR[3]) - ( EMT.TTOTLEN * EMT.TDIR[3]) local dBeamQuote = DeltaTabZ + EMT.SB + 30 if dChSawEncumbrance < dBeamQuote then SimulMoveAxes( 'Z1', dSafeZ1, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) else SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end -- 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 > SafeX2RotAxis and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then SimulMoveAxis( 'X2', SafeX2RotAxis, MCH_SIM_STEP.RAPID) end end else -- solo se è macchina a 3 teste con gruppo truciolatore 4 assi, devo andare prima in Z0 if EgtGetHeadId( 'H39') then SimulMoveAxis( 'Z2', Z2Home, MCH_SIM_STEP.RAPID) end -- Porto la X alla giusta quota if EMT.ZMAX and X2Pos > SafeX2RotAxis and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then SimulMoveAxis( 'X2', SafeX2RotAxis, 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 -- testa 4 assi dedicata truciolatore if EgtGetHeadId( 'H39') then if EMT.ZMAX then local MaxZ3 = EgtGetAxisMax( 'Z3') SimulMoveAxes( 'X3', EMT.L2, MCH_SIM_STEP.RAPID, 'Z3', MaxZ3, MCH_SIM_STEP.RAPID) end SimulMoveAxis( 'Z3', EMT.L3, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B3', EMT.R2, MCH_SIM_STEP.COLLROT, 'C3', EMT.R1, MCH_SIM_STEP.COLLROT) -- testa 5 assi dedicata lama elseif EgtGetHeadId( 'H38') then if EMT.ZMAX then local B3Home = EgtGetAxisHomePos( 'B3') local C3Home = EgtGetAxisHomePos( 'C3') SimulMoveAxis( 'X3', SafeX3RotAxis, MCH_SIM_STEP.RAPID) -- se non sono esattamente in home, devo ruotare in zona sicura if abs( C3Home - EMT.R1) > 1 or abs( B3Home - EMT.R2) > 1 then EMT.L3 = min( EMT.L3, SafeZ3RotAxis) SimulMoveAxis( 'Z3', SafeZ3RotAxis, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B3', EMT.R2, MCH_SIM_STEP.COLLROT, 'C3', EMT.R1, MCH_SIM_STEP.COLLROT) if ( EMT.L3 - SafeZ3RotAxis) > 100 * GEO.EPS_SMALL then SimulMoveAxis( 'Z3', EMT.L3, MCH_SIM_STEP.RAPID) end SimulMoveAxis( 'X3', EMT.L2, MCH_SIM_STEP.RAPID) end end -- si muovono tutti gli assi assieme -- altre configurazioni else EmtSetLastError( 1212, "HEAD not managed") end 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) -- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post if not( EMT.MOVE == 0 and EMT.FLAG == 2) and Z2 > MaxZ2 then local sErr = EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( dZ2-MaxZ2, 2) EmtSetLastError( 1220, sErr, true) EgtOutBox( sErr, 'ERROR') end 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 -- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post if not( EMT.MOVE == 0 and EMT.FLAG == 2) and Z2 < MinZ2 then local sErr = EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( MinZ2-Z2, 2) EmtSetLastError( 1220, sErr, true) EgtOutBox( sErr, 'ERROR') 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 if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then local B2Home = EgtGetAxisHomePos( 'B2') local C2Home = EgtGetAxisHomePos( 'C2') SimulMoveAxes( 'X2', SafeX2, MCH_SIM_STEP.RAPID, 'C2', C2Home, MCH_SIM_STEP.RAPROT, 'B2', B2Home, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X2', X2, MCH_SIM_STEP.RAPID) 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 -- se aggregato flottante su inizio attacco va compresso if EMT.TFLOAT and not EMT.TFLOAT_CMP and EMT.MOVE == 1 and EgtGetName( EMT.MOVEID) == 'LI' then -- recupero lunghezza local dOffsL = - EgtGetMachiningParam( MCH_MP.OFFSL) -- imposto compressione della parte flottante SetFloatPos( EMT.HEAD, dOffsL) -- imposto dati utensile in posizione compressa EmtSetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL, 2, -dOffsL) -- dichiaro che è compresso (assegnando Id entità di movimento) EMT.TFLOAT_CMP = EMT.MOVEID end end --------------------------------------------------------------------- function OnSimulMoveEnd() -- gruppo della testa local nHSet = GetHeadSet( EMT.HEAD) -- 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() -- ricavo prossimo utensile local sNextTool = GetNextTool( EMT.MCHID) -- vado in home se è ultimo movimento ed è ultima lavorazione local bToXhome = ( IsLastPath( EMT.PATHID) and not sNextTool and nHSet == 3) or EMT.HEAD == 'H38' or ( nHSet == 1 and EMT.TTOTLEN > LongTool) -- eseguo ExecMoveZmax( EMT.MCHSPLIT, bToXhome) EMT.TO_ZMAX = nil end -- se utensile flottante e movimento di compressione if EMT.TFLOAT and EMT.MOVEID == EMT.TFLOAT_CMP then -- verifico ci sia stata collisione tra ghiera flottante (portautensile e pezzo) if not EMT.TFLOAT_TH_COMPR_COLL then local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Floating Ring not compressed on approach' EmtSetLastError( 1222, sErr) EgtOutLog( 'Error : ' .. sErr, 1) else EgtOutLog( 'Floating Ring compressed on approach (MOVEID='..EgtNumToString( EMT.MOVEID)..')', 1) end EMT.TFLOAT_TH_COMPR_COLL = nil end -- se aggregato flottante su fine uscita va rilasciato if EMT.TFLOAT and EMT.TFLOAT_CMP and EMT.MOVE == 1 and EgtGetName( EMT.MOVEID) == 'LO' and EgtGetName( EgtGetNext( EMT.MOVEID) or GDB_ID.NULL) ~= 'LO' then -- reset compressione della parte flottante SetFloatPos( EMT.HEAD, 0) -- dichiaro che è rilasciato EMT.TFLOAT_CMP = nil end end --------------------------------------------------------------------- function OnSimulCollision() -- se prima collisione della lavorazione, la segnalo if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then -- speciale per utensile flottante (suo holder contro il grezzo) if EMT.TFLOAT and EMT.TFLOAT_CMP and EMT.SIMCOBIND == 1002 and EMT.SIMVMID == EMT.VMILL[1] then if EMT.MOVEID == EMT.TFLOAT_CMP then EMT.TFLOAT_TH_COMPR_COLL = true end return end local Class = '' if EMT.SIMCOBIND > 1000 and EMT.SIMCOBIND < 1099 then Class = 'T_H'.. tostring( EMT.SIMCOBIND - 1000) elseif EMT.SIMCOBIND > 1100 and EMT.SIMCOBIND < 1199 then Class = 'TH_H'..tostring( EMT.SIMCOBIND - 1100) 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) if Cmd[4] and Cmd[4] == 'Manual Unloading' then ExecMovePY2( false) end 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 local _, sHead, _, _, _, _ = FindFirstToolOnHeadSet( 2) local PosXStart = EgtIf( sHead == 'H22', SafeX2, ParkX2) EgtSetAxisPos( 'X2', PosXStart) EgtSetAxisPos( 'Z2', MinZ2) EgtResetAxisPos( 'C2') EgtResetAxisPos( 'B2') end --------------------------------------------------------------------- function ExecMoveHome( bNearV, bMchSplit) -- risalita a Zmax ExecMoveZmax( bMchSplit, true) -- se testa sotto e macchina a 3 teste if GetHeadSet( EMT.HEAD) == 2 and IsHeadExisting( 3) then if not SimulMoveAxis( 'X2', EgtIf( EMT.HEAD == 'H22', SafeX2, ParkX2), MCH_SIM_STEP.RAPID) then EgtOutLog( 'Error on MoveHome : X2') end -- se gruppo truciolatore a 4 assi if EgtGetHeadId( 'H39') then if not SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID) then EgtOutLog( 'Error on MoveHome : Z2') end 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, bGoToHome) -- set della testa local nSetHead = GetHeadSet( EMT.HEAD) -- posizioni correnti degli assi testa local CurrX = EgtGetAxisPos( 'X'..nSetHead) local CurrZ = EgtGetAxisPos( 'Z'..nSetHead) local CurrC = EgtGetAxisPos( 'C'..nSetHead) local CurrB = EgtGetAxisPos( 'B'..nSetHead) -- posizioni home degli assi testa local HomeX = EgtGetAxisHomePos( 'X'..nSetHead) local HomeZ = EgtGetAxisHomePos( 'Z'..nSetHead) local HomeC = EgtGetAxisHomePos( 'C'..nSetHead) local HomeB = EgtGetAxisHomePos( 'B'..nSetHead) -- 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) if bGoToHome then SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) end -- 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 con gruppo truciolatore 4 assi, devo stare più alto if EgtGetHeadId( 'H39') then SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID) end -- altrimenti testa 3 else if EgtGetHeadId( 'H39') then SimulMoveAxes( 'Z3', MaxZ3, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B3', ParkB3, MCH_SIM_STEP.COLLROT) elseif EgtGetHeadId( 'H38') then local MyMaxZ3 = EgtGetAxisMax( 'Z3') -- se non sono esattamente in home, ruoto dove sono if abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1 then -- SimulMoveAxis( 'X3', SafeX3RotAxis, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'Z3', SafeZ3RotAxis, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'C3', HomeC, MCH_SIM_STEP.COLLROT, 'B3', HomeB, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'Z3', MyMaxZ3, MCH_SIM_STEP.RAPID) if bGoToHome then SimulMoveAxis( 'X3', ParkX3, MCH_SIM_STEP.RAPID) end else EmtSetLastError( 1212, "HEAD not managed") end 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 CheckClamping( sClampName) nIndexClamp = EgtGetAxisId( sClampName) local idClampPath = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nIndexClamp, 'CLAMP_CHECK') or GDB_ID.NULL) local b3ClampingArea = EgtGetBBoxGlob( idClampPath or GDB_ID.NULL, GDB_BB.STANDARD) -- se non trovo percorso area di clamping, esco subito if not idClampPath or not EMT.VMILL or not ClampingCoeffMin then return end local function GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth) local idCurveList = {} local vtIntersPlane -- piano di interpolazione if sIntersPlane == 'X' then vtIntersPlane = X_AX() elseif sIntersPlane == 'Y' then vtIntersPlane = Y_AX() elseif sIntersPlane == 'Z' then vtIntersPlane = Z_AX() end for i = 1, #EMT.VMILL do local b3VMill = EgtGetBBoxGlob( EMT.VMILL[i], GDB_BB.EXACT) local ptPosIntersPlane if sPosIntersPlane == 'MIN' then ptPosIntersPlane = b3VMill:getMin() + dDepth * vtIntersPlane elseif sPosIntersPlane == 'MAX' then ptPosIntersPlane = b3VMill:getMax() - dDepth * vtIntersPlane end local idLoop, nLoopCnt = EgtPlaneVolZmapInters( ptPosIntersPlane, vtIntersPlane, EMT.VMILL[i], CLAMP_CHECK_INTERS, GDB_RT.GLOB) -- se c'è almeno una curva if idLoop then for j = 1, nLoopCnt do local idLoopTemp = idLoop + j - 1 table.insert( idCurveList, idLoopTemp) end end end return idCurveList end local function CalculateIntersectionArea( sPosIntersPlane, sIntersPlane, dDepth) -- test piano frontale local idCurveList = GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth) -- si copia curva intersezione e curva pinza in gruppo di confronto local idFlatSurf, nFlatSurfCnt = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, idCurveList) local idClampSurf = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, idClampPath) if idFlatSurf then local dTotalArea = 0 local dTotalXLenght = 0 for k = 1, nFlatSurfCnt do local idTempSurf = idFlatSurf + k - 1 EgtSurfFrIntersect( idTempSurf, idClampSurf) if idTempSurf then dTotalArea = dTotalArea + ceil( EgtSurfArea( idTempSurf) or 0) local b3BoxIntersectionBox = EgtGetBBoxGlob( idTempSurf, GDB_BB.STANDARD) if b3BoxIntersectionBox then dTotalXLenght = dTotalXLenght + ceil( b3BoxIntersectionBox:getDimX()) -- somma lunghezze (x) delle aree pinzate end end end return dTotalArea, dTotalXLenght end return 0 end -- minima area considerata per un corretto pinzaggio DistZClampToTable = DistZClampToTable or 0 local MinJoin = BD.GetMinJoin( EMT.HB, EMT.SB, EgtIf( EMT.SPLIT, EMT.LT, EMT.LB)) local MinZClamping = min( b3ClampingArea:getDimZ() + DistZClampToTable, EMT.SB) - DistZClampToTable -- si moltiplica per un coefficiente minimo sotto al quale si da l'errore di pinzaggio ClampingCoeffMin = EgtClamp( ClampingCoeffMin, 0.01, 1) local dMinClampingAreaWarn = ( MinJoin * MinZClamping) * ClampingCoeffMin local dMinClampingAreaErr = ( MinJoin * MinZClamping) * ( ClampingCoeffMin / 3) local bError = true local sWrn, sErr local bWriteWarnMessage = false local bWriteErrMessage = false -- controllo faccia frontale local dArea, dXClampedLenght = CalculateIntersectionArea( 'MIN', 'Y', 3) -- ERRORE: pinza troppo poco (meno di 1/3 del minimo richiesto) if dArea and dArea < dMinClampingAreaErr then -- solo se pinza almeno 1cm2, e la somma della lunghezza pinzata è maggiore della lunghezza minima pinzabile da Warning e non errore if dXClampedLenght >= MinJoin * ClampingCoeffMin and dArea > 1000 then bError = false end -- pinzaggio non fattibile, errore if bError then sErr = 'ERROR CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)' bWriteErrMessage = true end end -- WARNING: pinza meno del minimo richiesto if dArea and dArea < dMinClampingAreaWarn and not bWriteErrMessage then sWrn = 'WARNING CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)' bWriteWarnMessage = true end EgtEmptyGroup( CLAMP_CHECK_GROUP) EgtEmptyGroup( CLAMP_CHECK_INTERS) -- controllo altro lato solo se non sono già in errore if not bWriteErrMessage then -- controllo faccia posteriore dArea = CalculateIntersectionArea( 'MAX', 'Y', 3) -- ERRORE: pinza troppo poco (meno di 1/3 del minimo richiesto) if dArea and dArea < dMinClampingAreaErr then -- solo se pinza almeno 1cm2, e la somma della lunghezza pinzata è maggiore della lunghezza minima pinzabile da Warning e non errore if dXClampedLenght >= MinJoin * ClampingCoeffMin and dArea > 1000 then bError = false end -- pinzaggio non fattibile, errore if bError then sErr = 'ERROR CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)' bWriteErrMessage = true end end -- WARNING: pinza meno del minimo richiesto if dArea and dArea < dMinClampingAreaWarn and not bWriteWarnMessage and not bWriteErrMessage then sWrn = 'WARNING CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)' bWriteWarnMessage = true end EgtEmptyGroup( CLAMP_CHECK_GROUP) EgtEmptyGroup( CLAMP_CHECK_INTERS) end if bWriteErrMessage then EmtSetLastError( 1213, sErr, EgtGetEnableUI()) EgtOutBox( sErr, 'CLAMPING', 'ERROR', 'OK') EmtSetSimulPause() elseif bWriteWarnMessage then EgtOutLog( sWrn) EgtOutBox( sWrn, 'CLAMPING', 'WARNING', 'OK') EmtSetSimulPause() end end --------------------------------------------------------------------- function ExecMovePY1( bClose) SimulMoveAxes( 'PY1', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID) SetPY1Light( bClose) if bClose then CheckClamping( 'PY1') end end --------------------------------------------------------------------- function ExecMovePY2( bClose) SimulMoveAxes( 'PY2', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID) SetPY2Light( bClose) if bClose then CheckClamping( 'PY2') end 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 - EMT.DELTA_LT - EMT.HOVM, MinY2 - PosY2 + 10) if ( PosT + EMT.LT + EMT.DELTA_LT + EMT.HOVM < ParkV1 + ExtraParkV and PosT + EMT.LT + EMT.DELTA_LT + EMT.HOVM > 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() if EMT.MCHPRECUT or EMT.MCHCUT then return false end --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 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 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) -- se primo utensile motosega, non lo carico e visualizzo quello di default if sHead == 'H13' then sTool = nil end 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 ESTIMATION_RAPID_COEFF = EstimationRapidMultiplier or 1 local RAPID_X_FEED = 70000 / ESTIMATION_RAPID_COEFF -- mm/min local RAPID_Y_FEED = 100000 / ESTIMATION_RAPID_COEFF -- mm/min local RAPID_Z_FEED = 32000 / ESTIMATION_RAPID_COEFF -- mm/min local RAPID_C_FEED = 15000 / ESTIMATION_RAPID_COEFF -- deg/min local RAPID_B_FEED = 15000 / ESTIMATION_RAPID_COEFF -- deg/min local RAPID_MIN_T = 0.1 * ESTIMATION_RAPID_COEFF -- s local LOAD_T = 2 * ESTIMATION_RAPID_COEFF -- s local CHAR_ONE_MOVE_T = 1 * ESTIMATION_RAPID_COEFF -- s local ROTATION_T = 40 * ESTIMATION_RAPID_COEFF -- s local SPLIT_T = 6 * ESTIMATION_RAPID_COEFF -- s local UNLOAD_T = 4 * ESTIMATION_RAPID_COEFF -- s local FALL_T = 2 * ESTIMATION_RAPID_COEFF -- s --------------------------------------------------------------------- function OnEstimStart() EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches EMT.FMAXPINZE = EgtClamp( MaxFeedPinze or 116000, 20000, 130000) -- feed massima pinze EMT.MAXACC = MaxAcc or 6000 -- accelerazione massima pinze. In realtà è il tempo in millisecondi, quindi MAXACC corrisponde al tempo massimo per raggiungere la velocità desiderata EMT.MINACC = MinAcc or 600 -- accelerazione minima pinze. In realtà è il tempo in millisecondi, quindi MINACC corrisponde al tempo massimo per raggiungere la velocità desiderata 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 OnEstimRawMoveData() -- se start del pezzo if IsStartOrRestPhase( EMT.PHASE) then EMT.SPLIT = false end OnRawMoveData() 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 EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) or '' EMT.MCHSPLIT = ( EMT.MCHUSERNOTES:find( 'Split;', 1, true) ~= nil) if EMT.MCHSPLIT then EMT.SPLIT = true 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 = CalcMoveTime( abs( dL1), RAPID_X_FEED, EMT.SPLIT) if dT1 > dTime then dTime = dT1 end local dT2 = CalcMoveTime( abs( dL2), EMT.FMAXPINZE, EMT.SPLIT) if dT2 > dTime then dTime = dT2 end local dT3 = CalcMoveTime( abs( dL3), RAPID_Z_FEED, EMT.SPLIT) 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 = CalcMoveTime( dLen, EMT.F, EMT.SPLIT) 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 GetNextMultiDrillVirtualAxis( 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.DRILLING then return nil end -- la imposto come lavorazione corrente EgtSetCurrMachining( NextMchId) -- recupero il valore dell'asse virtuale bloccato A local dPosA = GetCurrMultiDrillVirtualAxis() -- 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 IsLastPath( nPathId) return not EgtGetNext( nPathId) 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)) elseif sHead == 'H38' then return ( abs( dAng1 - dAng1p) > 1 or abs( dAng2 - dAng2p) > 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 --------------------------------------------------------------------- function CalcDinamicaPinze( dH, dS, dL) local MinTempoAcc = EMT.MINACC -- [ms] ~600 local MaxTempoAcc = EMT.MAXACC -- [ms] ~6000 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 = EgtClamp( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito), MinTempoAcc, MaxTempoAcc) local RidFeed = 100 / Massa * 100 if RidFeed > 100 then RidFeed = 100 elseif RidFeed < 10 then RidFeed = 10 end return TempoAcc, MinTempoAcc, RidFeed end --------------------------------------------------------------------- function CalcMoveTime( dPathLen, dFeed, bIsSplitted) local dTime local dFeedInSec = dFeed / 60 local dTempoAcc, _, _ = CalcDinamicaPinze( EMT.HB, EMT.SB, EgtIf( bIsSplitted, EMT.LT, EMT.LB)) dTempoAcc = dTempoAcc / 1000 -- se si raggiunge la velocità massima if dPathLen >= dFeedInSec * dTempoAcc then dTime = dTempoAcc * 2 + ( ( dPathLen - dFeedInSec * dTempoAcc) / dFeedInSec) else dTime = 2 * sqrt( (dPathLen * dTempoAcc) / dFeedInSec) end return dTime end --------------------------------------------------------------------- -- *** END GENERAL ***