-- Processore standard macchine ONE e PF by EgalWare s.r.l. 2023/11/24 -- Funzioni generiche indipendenti dal controllo -- Intestazioni require( 'EmtGenerator') EgtEnableDebug( false) -- Carico libreria local BD = require( 'BeamData') --------------------------------------------------------------------- -- *** GENERATION *** --------------------------------------------------------------------- local sBaseDir = EgtGetCurrMachineDir() if NumericalControl == 'NUM' or NumericalControl == 'NUM_FLEX' then dofile( sBaseDir .. '\\Common_ONE-PF.NUM.mlpe') elseif NumericalControl == 'TPA' then error( 'Numerical Control error : TPA not yet managed') else error( 'Numerical Control error : unkwnown type') end --------------------------------------------------------------------- -- *** SIMULATION *** --------------------------------------------------------------------- local COLL_SAFE_DIST = 3 --------------------------------------------------------------------- function OnSimulInit() -- se macchina con carico destro, imposto offset direzioni di vista standard if BD.RIGHT_LOAD then local nOrigViewOffs = EgtGetViewOrizzOffsStep() local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView() if nOrigViewOffs ~= 2 then EgtSetViewOrizzOffsStep( 2) if dOrigViewAngV < 0.1 then EgtSetView( SCE_VD.TOP, false) elseif dOrigViewAngV > 179.9 then EgtSetView( SCE_VD.BOTTOM, false) else local dViewAngH = dOrigViewAngH + EgtIf( dOrigViewAngH > 180, 2 * 90, 0) EgtSetGenericView( dOrigViewAngV, dViewAngH, false) end end end end --------------------------------------------------------------------- function OnSimulExit() -- se macchina con carico destro, annullo offset direzioni di vista standard if BD.RIGHT_LOAD then local nOrigViewOffs = EgtGetViewOrizzOffsStep() local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView() if nOrigViewOffs == 2 then EgtSetViewOrizzOffsStep( 0) if dOrigViewAngV < 0.1 then EgtSetView( SCE_VD.TOP, false) elseif dOrigViewAngV > 179.9 then EgtSetView( SCE_VD.BOTTOM, false) else EgtSetGenericView( dOrigViewAngV, dOrigViewAngH - 2 * 90, false) end end end end --------------------------------------------------------------------- function OnSimulStart() -- controllo versione programma if not EMT.VER or EMT.VER < MIN_MACH_VER then EmtSetLastError( 1200, 'A newer version of the program is required (minimum EgtMachKernel '..MIN_MACH_VER..')') end -- Carico gli utensili sulle barre portautensili local vTcPos = EgtGetAllTcPosNames() if vTcPos then for i = 1, #vTcPos do local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) if vTools and vTools[1] and #(vTools[1]) > 0 then EgtLoadTool( vTcPos[i], 1, vTools[1]) ShowToolInTcPos( vTcPos[i], true) -- Aggiunto controllo lunghezza lama minima * 0.9 per ricavare la tolleranza del VMILL if EgtTdbSetCurrTool(vTools[1]) 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 end -- Carico gli utensili iniziali o di default sulle due teste LoadFirstTool( 1, DefTcPos1) -- se è definito il default sulla testa 2 if DefTcPos2 then LoadFirstTool( 2, DefTcPos2) end 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) if EgtGetHeadId( 'H21') then AddToCollisionCheck( 'Z2', 'COLLISION', EMT.COLLOBJ) AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ) AddToCollisionCheck( 'B2', '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 = 'TC1'}, { Grp = 'Base', Sub = 'COLLISION', Name = 'TC2'}, { Grp = 'Base', Sub = 'BELT', Name = 'COLLISION'}, { Grp = 'X1', Sub = 'COLLISION', Name = 'STM'}} if EgtGetHeadId( 'H21') then table.insert( McdData, { Grp = 'X2', Sub = 'COLLISION', Name = 'STM'}) end -- gruppo CHSAW si attiva solo se progress, one con BIT mortiser o PF if Progress or Mortiser or EgtGetHeadId( 'H21') or SecondToolChanger then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'CHSAW'}) end -- gruppo MORTISER si attiva solo se PF con BIT mortiser attivo if Mortiser and EgtGetHeadId( 'H21') then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'MORTISER'}) end -- se Progress si attiva magazzino lama sotto traversa if Progress and EgtGetHeadId( 'H21') then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'SAW1'}) end -- se non è Progress ed è una ONE, aggiungo collisioni magazzino speciale if not Progress and not EgtGetHeadId( 'H21') then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'MTC'}) end if Clamp5 then table.insert( McdData, { Grp = 'W', Sub = 'COLLISION', Name = 'STM1'}) table.insert( McdData, { Grp = 'W', Sub = 'COLLISION', Name = 'STM2'}) table.insert( McdData, { Grp = 'W', Sub = 'COLLISION', Name = 'STM3'}) table.insert( McdData, { Grp = 'QW', Sub = 'COLLISION', Name = 'STM1'}) table.insert( McdData, { Grp = 'QW', Sub = 'COLLISION', Name = 'STM2'}) end EgtOutLog( 'MCODET Objects :', 4) local nMcdNullCnt = 0 for i = 1, #McdData do local nGrpId if McdData[i].Grp == 'Base' then nGrpId = EgtGetBaseId( 'Base') else nGrpId = EgtGetAxisId( McdData[i].Grp) end local nId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nGrpId, McdData[i].Sub), McdData[i].Name) if nId then table.insert( EMT.MCODET, nId) EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' (' .. tostring( nId) .. ') is ok', 4) else nMcdNullCnt = nMcdNullCnt + 1 EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' is null', 4) end end if nMcdNullCnt > 0 then EgtOutLog( 'Warning : MCODET with one or more null Element(s) ') end -- Preparo lista collisioni vuota EMT.COLLIDE = {} end --------------------------------------------------------------------- function OnSimulEnd() EMT.Y1DELTA = nil EMT.Y2DELTA = nil ExecParkRoller() ExecStartHome() 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 -- imposto eventuale utensile corrente SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) 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 b3Bar = BBox3d() local b3Raw = BBox3d() local nPartRawId, nScrapRawId local nRawId = EgtGetFirstRawPart() while nRawId do local nNextRawId = EgtGetNextRawPart( nRawId) if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then EmtLinkRawPartToGroup( nRawId, 'Tab') local b3Tmp = EgtGetRawPartBBox( nRawId) b3Bar:Add( b3Tmp) local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') if nRawOrd == nOrd then b3Raw:Add( b3Tmp) nPartRawId = nRawId elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then b3Raw:Add( b3Tmp) nScrapRawId = nRawId end end nRawId = nNextRawId end -- indice pezzo local PartId = EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) or BBox3d() -- 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( PartId 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 -- forzo apertura rulli in caso fossero chiusi. Altrimenti all'apertura nell OnSimulMoveStart sposterebbe anche la trave ExecParkRoller( nil, nil, nil, nil, nil, nil) 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 -- Indicazione angolo rotazione pezzo EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0 local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN') EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF)) EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF)) EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF)) end --------------------------------------------------------------------- function OnSimulDispositionEnd() if EMT.UNLOADING or EMT.FALL then ExecUnloading() EMT.UNLOADING = false EMT.FALL = false EMT.TO_FALL = false EMT.Y2DELTA = nil end -- se disposizione intermedia if IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then -- se le rotazioni delle fasi corrente e precedente sono diverse if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then -- imposto stato post-rotazione EMT.POSTROT = true end -- se altrimenti disposizione intermedia speciale con eventuale rotazione elseif IsMid2Phase( EMT.PHASE) then -- se le rotazioni delle fasi corrente e precedente sono diverse if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then -- imposto stato post-rotazione EMT.POSTROT = true end end EMT.SPLIT = false EMT.SPECSPLIT = false EMT.TO_SPECSPLIT = false EMT.OPEISDISP = false end --------------------------------------------------------------------- function OnSimulToolSelect( dPosA) -- recupero dati utensile EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) EMT.TUSERNOTES = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES) local nSetHead = GetHeadSet( EMT.HEAD) -- se ho due teste, verifico che l'altra sia dalla parte opposta if EgtGetHeadId( 'H21') then if nSetHead == 1 then EgtSetAxisPos( 'X2', MinX2) else EgtSetAxisPos( 'X1', MaxX1) end end -- se sega a catena, imposto subito angolo scelto per asse virtuale A if HeadIsChainSaw( EMT.HEAD) then -- apro le paratie ExecParkRoller( nil, nil, nil, nil, false, IsStartPhase( EMT.PHASE)) -- valore dell'asse virtuale dPosA = dPosA or GetNextChainSawingVirtualAxis( EMT.MCHID) -- imposto il valore di A EgtSetAxisPos( 'A', dPosA) if nSetHead == 1 then -- imposto home dell'asse C1 (A=0 -> T101, A=-90 -> T102) local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) EmtModifyAxisHome( 'C1', MyParkCSawC1) EgtSetAxisPos( 'C1', MyParkCSawC1) EgtSetAxisPos( 'B1', ParkCSawB1) EgtSetAxisPos( 'X1', ParkCSawX1) -- l'utensile viene caricato qui, quindi setto come già cambiato EMT.PREVHEAD_H1 = EMT.HEAD else -- imposto home dell'asse C2 (A=0 -> T111, A=-90 -> T112) local MyParkCSawC2 = GetChainSawCHomeFromVirtualAxis( dPosA) EmtModifyAxisHome( 'C2', MyParkCSawC2) EgtSetAxisPos( 'C2', MyParkCSawC2) EgtSetAxisPos( 'B2', ParkCSawB2) EgtSetAxisPos( 'X2', ParkCSawX2) -- l'utensile viene caricato qui, quindi setto come già cambiato EMT.PREVHEAD_H2 = EMT.HEAD end -- Imposto visualizzazione EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) end -- carico utensile, con breve pausa EgtPause( 100) EgtOutText( '') -- lo nascondo sul portautensili ShowToolInTcPos( EMT.TCPOS, false) -- dichiaro assi ausiliari da visualizzare EMT.AuxAxes = 4 EMT.A1n = 'Y1' EMT.A2n = 'Y2' EMT.A3n = 'V1' EMT.A4n = 'V2' -- se attivo Vmill SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) -- se attivo Collision Check EMT.SAFEDIST = COLL_SAFE_DIST if EMT.COLLOBJ then local nInd = EgtIf( EMT.HEAD ~= 'H21', 1001, 1011) AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd) AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1) for i, Coll in ipairs( EMT.COLLOBJ or {}) do EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) end end -- salvataggio dati utensile rimandato a OnMachiningStart end --------------------------------------------------------------------- function OnSimulToolDeselect( dPrevA) -- se utensile corrente è sega a catena, devo depositarla if HeadIsChainSaw( EMT.PREVHEAD_H1) then -- simulo movimento SimulMoveAxis( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID) local dMyParkC = EgtGetAxisHomePos( 'C1') if dPrevA then dMyParkC = GetChainSawCHomeFromVirtualAxis( dPrevA) end SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', dMyParkC, MCH_SIM_STEP.RAPROT) -- 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) -- se non è chiamata per cambio angolo di presa della sega a catena if not dPrevA then -- cambio utensile EgtSetAxisPos( 'C1', ParkC1) EgtSetAxisPos( 'B1', ParkB1) EgtSetAxisPos( 'Z1', MaxZ1) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) LoadNextTool( 1, DefTcPos1) end elseif HeadIsChainSaw( EMT.PREVHEAD_H2) then -- simulo movimento SimulMoveAxis( 'X2', ParkCSawX2, MCH_SIM_STEP.RAPID) local dMyParkC = EgtGetAxisHomePos( 'C2') if dPrevA then dMyParkC = GetChainSawCHomeFromVirtualAxis( dPrevA) end SimulMoveAxes( 'B2', ParkCSawB2, MCH_SIM_STEP.RAPROT, 'C2', dMyParkC, MCH_SIM_STEP.RAPROT) -- 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 non è chiamata per cambio angolo di presa della sega a catena if not dPrevA then -- cambio utensile EgtSetAxisPos( 'C2', ParkC2) EgtSetAxisPos( 'B2', ParkB2) EgtSetAxisPos( 'Z2', MaxZ2) SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) LoadNextTool( 2, DefTcPos2) end end -- reset flag sega a catena già depositata EMT.CHSAW_OUT = nil -- se utensile non cambia e non è sega a catena, esco if ( EMT.NEXTTOOL == EMT.PREVTOOL_H1 or EMT.NEXTTOOL == EMT.PREVTOOL_H2) and not HeadIsChainSaw( EMT.NEXTHEAD) then return end -- deposito utensile EgtOutText( 'Tool change in progress...') -- se prossimo utensile sega a catena, devo mettere in home testa 1 e depositare l'utensile sulla testa 2 o viceversa if HeadIsChainSaw( EMT.NEXTHEAD) then -- salvo dati utensile -- se ci sono due teste if EgtGetHeadId( 'H21') then local nSetHead = GetHeadSet( EMT.NEXTHEAD) if nSetHead == 1 then -- porto in home testa 1 SimulMoveAxis( 'X1', MaxX1, MCH_SIM_STEP.RAPID) -- deposito utensile fresa if EMT.PREVHEAD_H2 == 'H21' then -- simulo movimento SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.RAPROT, 'C2', ParkC2, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) -- deposito utensile lama elseif EMT.PREVHEAD_H1 == 'H22' then -- simulo movimento SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.RAPROT, 'C2', ParkC2, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) -- deposito utensile sega a catena elseif HeadIsChainSaw( EMT.PREVHEAD_H2) then ; -- già depositata end else SimulMoveAxis( 'X2', MinX2, MCH_SIM_STEP.RAPID) -- deposito utensile fresa if EMT.PREVHEAD_H1 == 'H11' then -- simulo movimento SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) -- deposito utensile lama elseif EMT.PREVHEAD_H1 == 'H12' or EMT.PREVHEAD_H1 == 'H17' then -- simulo movimento SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) -- deposito utensile sega a catena elseif HeadIsChainSaw( EMT.PREVHEAD_H1) then ; -- già depositata end end -- altrimenti mi avvicino a CU dell'utensile che ho montato else local nSetHead = GetHeadSet( EMT.HEAD) if nSetHead == 1 then local MyParkX1 = EgtIf( GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC1', ParkX1, ParkFrnX1) SimulMoveAxis( 'X1', MyParkX1, MCH_SIM_STEP.RAPID) else SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) end end -- 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) -- breve pausa EgtPause( 100) -- se devo scaricare un utensile normale else local nSetHead = GetHeadSet( EMT.HEAD) if nSetHead == 1 and EMT.PREVHEAD_H1 then local MyParkX1 = EgtIf( GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC1', ParkX1, ParkFrnX1) SimulMoveAxis( 'X1', MyParkX1, MCH_SIM_STEP.RAPID) elseif EMT.PREVHEAD_H2 then SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) end end -- recupero il prossimo gruppo local nNextSetHead = GetHeadSet( EMT.NEXTHEAD) -- per prossima testa gruppo 2 if nNextSetHead == 2 then -- 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) -- prendo utensile fresa if 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) SimulMoveAxis( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID) -- prendo utensile lama elseif EMT.NEXTHEAD == 'H22' then -- simulo movimento SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.RAPROT, 'C2', ParkC2, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID) -- prendo utensile sega a catena elseif HeadIsChainSaw( EMT.NEXTHEAD) then -- simulo movimento SimulMoveAxes( 'B2', ParkCSawB2, MCH_SIM_STEP.RAPROT, 'C2', ParkCSawC2, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'Z2', ParkCSawZ2, MCH_SIM_STEP.RAPID) end -- per prossima testa gruppo 1 else -- 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) -- prendo utensile fresa o lama if EMT.NEXTHEAD == 'H11' or EMT.NEXTHEAD == 'H12' or EMT.NEXTHEAD == 'H17' then local MyParkX1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkX1, ParkFrnX1) local MyParkB1 = ParkB1 local MyParkC1 = ParkC1 -- se ho due teste oppure è progress, significa che ho CU verticale if EgtGetHeadId('H21') or Progress or SecondToolChanger then MyParkB1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkB1, ParkFrnB1) MyParkC1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkC1, ParkFrnC1) -- altrimenti su one CU speciale motosega-utensile lungo else MyParkB1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkB1, ParkLongToolB1) MyParkC1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkC1, ParkLongToolC1) end -- simulo movimento SimulMoveAxes( 'B1', MyParkB1, MCH_SIM_STEP.RAPROT, 'C1', MyParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', MyParkX1, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID) -- prendo utensile sega a catena elseif HeadIsChainSaw( EMT.NEXTHEAD) then -- simulo movimento SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', ParkCSawC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'Z1', ParkCSawZ1, MCH_SIM_STEP.RAPID) end end end --------------------------------------------------------------------- function OnSimulMachiningStart() -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare if HeadIsChainSaw( EMT.HEAD) then -- se anche precedente con sega a catena ma depositata, devo riprenderla if EMT.CHSAW_OUT then local dPosA = GetCurrChainSawingVirtualAxis() EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) OnSimulToolDeselect() OnSimulToolSelect( dPosA) elseif ( EMT.HEAD == EMT.PREVHEAD_H2 and EMT.TCPOS == EMT.PREVTCPOS_H2) or EMT.HEAD == EMT.PREVHEAD_H1 then local dPrevA = EgtGetAxisPos( 'A') local dPosA = GetCurrChainSawingVirtualAxis() if abs( dPosA - dPrevA) > 1 then OnSimulToolDeselect( dPrevA) EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) OnSimulToolSelect( dPosA) end end end -- salvo dati utensile local nSetHead = GetHeadSet( EMT.HEAD) -- 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 della feature lavorata local vId = EgtGetMachiningGeometry() if vId and #vId > 0 and #vId[1] > 0 then EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; else EMT.TASKID = 0 end -- gestione eventuale lavorazione in doppio local nDouType = EgtGetValInNotes( EMT.MCHUSERNOTES, 'DOUBLE', 'i') if nDouType == 2 then local sDouTool = EgtGetValInNotes( EMT.TUSERNOTES, 'DOUBLE', 's') or '' local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) if EgtTdbSetCurrTool( sDouTool) and EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) then local sDouHead = 'H21' local nDouExit = 1 -- carico l'utensile sulla testa local sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) EgtLoadTool( sDouHead, nDouExit, sDouTool) ShowToolInTcPos( sTcPos, false) -- dichiaro utensile per Vmill EmtAddToolForVmill( sDouTool, sDouHead, nDouExit, EMT.VMILL) -- dichiaro utensile per verifica collisioni local nInd = 1011 AddToolToCollisionObj( sDouTool, sDouHead, nDouExit, nInd, true) AddToolHolderToCollisionObj( sDouTool, sDouHead, nDouExit, nInd + 1) -- salvo dati EMT.DOU_TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) EMT.DOU_TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) EMT.DOU_TYPE = nDouType EMT.DOU_TOOL = sDouTool -- reset necessità movimento in sicurezza sola testa in doppio EMT.DOU_TO_ZMAX = nil else EmtSetLastError( 1211, 'Missing or not active double tool of '..sOldTool) end EgtTdbSetCurrTool( sOldTool) 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 SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID) SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID) 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 EMT.SPECSPLIT = nil EMT.TO_SPECSPLIT = nil if EMT.DOU_TYPE and not EMT.ZMAX then EMT.DOU_TO_ZMAX = true end EMT.DOU_TYPE = nil EMT.DOU_TOOL = nil -- salvo dati utensile local nSetHead = GetHeadSet( EMT.HEAD) -- se non ho già tolto la sega a catena, aggiorno valori if not EMT.CHSAW_OUT then -- per gruppo testa 1 if nSetHead == 1 then EMT.PREVTOOL_H1 = EMT.TOOL EMT.PREVHEAD_H1 = EMT.HEAD EMT.PREVTCPOS_H1 = EMT.TCPOS -- per gruppo testa 2 elseif nSetHead == 2 then EMT.PREVTOOL_H2 = EMT.TOOL EMT.PREVHEAD_H2 = EMT.HEAD EMT.PREVTCPOS_H2 = EMT.TCPOS end 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 elseif sCmd:find( 'SpecSplit', 1, true) then EMT.TO_SPECSPLIT = true end 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 and not EMT.TO_SPECSPLIT then EMT.SPLIT_Y1DELTA = EMT.Y1DELTA EMT.Y1DELTA = nil ExecMovePY1( false) end ExecMoveZmax( EMT.MCHSPLIT, false) 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_SPECSPLIT 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, false) 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 = EgtIf( EMT.W2DELTA, 5, 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, Y1Pos, 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 -- 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) or ( EMT.TOOL ~= EMT.PREVTOOL_H1 and EMT.TOOL ~= EMT.PREVTOOL_H2) then bParkV = true EMT.A3 = ParkV1 EMT.A4 = ParkV2 end end -- pinza 5 if EMT.W2DELTA then EMT.A5n = 'W' local dPosQW = EgtGetAxisPos( 'QW') or 0 if dPosQW < 1 then EMT.A5m = nil else EMT.A5m = 'T' end EMT.A5 = EMT.L1 + EMT.W2DELTA - EMT.A4 VerifyWStroke( EMT.A5) 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') -- se la lavorazione è un taglio di separazione, se necessario, ripristino posizione di Y1DELTA prima di aprire i rulli if EMT.SPLIT_Y1DELTA and not EMT.MCHSPLIT then EMT.Y1DELTA = EMT.SPLIT_Y1DELTA end nRes = ExecParkRoller( Y1Pos, Y2Pos, V1Pos, V2Pos, false, bAgg) if EMT.SPLIT_Y1DELTA then EMT.Y1DELTA = nil end end -- se movimento in rapido ad inizio lavorazione if EMT.MOVE == 0 and EMT.MOVEIND <= 3 then -- gestione speciale per pezzi molto alti. Se il movimento successivo è più alto del precedente, allora prendo il successivo if EMT.L3s then if EMT.L3s > EMT.L3 then EMT.L3 = EMT.L3s end end -- 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') -- se testa 1 if GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC1' then -- se fresa o lama ('H11' o 'H12') if not HeadIsChainSaw( EMT.HEAD) then -- se movimento iniziale da Zmax con lama o fresa if EMT.ZMAX or EMT.FLAG == 1 or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then --EgtOutBox( 'Flag 2,1', 'Info Rapid') local bMoveZbeforeX = false local dZref = EMT.L3 if EMT.HEAD == 'H12' and ( EgtIf( BD.RIGHT_LOAD, -EMT.L2 < -LimX1RotSaw, -EMT.L2 > -LimX1RotSaw) or EMT.R2 < -91) then dZref = Z1Home + GetZExtra( EMT.HEAD, EMT.R2) - 100 end -- se la quota di lavoro è più in alta della posizione a ZHOME della testa, prima si va alla Z di lavoro e poi si approccia il pezzo if EMT.L3 > dZref then bMoveZbeforeX = true end -- se vado in posizione speciale rotazione assi, poi devo ritornare alla X vera di lavoro local dMoveXtoFinalPosition = false local dXref = EMT.L2 if EMT.HEAD == 'H12' and -EMT.L2 < -LimX1PlRotSaw then dXref = LimX1PlRotSaw SimulMoveAxis( 'X1', dXref, MCH_SIM_STEP.RAPID) dZref = max( EMT.L3, Z1Home + GetZExtra( EMT.HEAD, EMT.R2)) dMoveXtoFinalPosition = true elseif not bMoveZbeforeX then SimulMoveAxis( 'X1', dXref, MCH_SIM_STEP.RAPID) else SimulMoveAxis( 'X1', LimX1PlRotSaw, MCH_SIM_STEP.RAPID) dZref = max( EMT.L3, Z1Home + GetZExtra( EMT.HEAD, EMT.R2)) dMoveXtoFinalPosition = true end -- caso speciale per trave alta con rotazione lama pericolosa (tolto "and EMT.SB > 379") if EMT.HEAD == 'H12' and abs( C1Pos - EMT.R1) > 1 and ( abs( C1Home - EMT.R1) > 30.1 or abs(B1Home - EMT.R2) > 30.1) then SimulMoveAxis( 'B1', 0, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) -- 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', dZref, MCH_SIM_STEP.RAPID, 'B1', dBref, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) else SimulMoveAxes( 'Z1', dZref, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end if bMoveZbeforeX then SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) end if dMoveXtoFinalPosition then SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) end -- caso standard else SimulMoveAxis( 'Z1', dZref, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) end end -- altrimenti sega a catena else local dPosA = GetCurrChainSawingVirtualAxis() -- se anche precedente con sega a catena ma depositata, devo riprenderla if EMT.CHSAW_OUT then EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) OnSimulToolDeselect() EgtLoadTool( EMT.HEAD, 1, EMT.TOOL) ShowToolInTcPos( EMT.TCPOS, false) OnSimulToolSelect( dPosA) -- recupero i dati dato che ho scaricato motosega e preso quelli dell'utensile di default EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'B1', ParkCSawB1) B1Home = EgtGetAxisHomePos( 'B1') C1Home = EgtGetAxisHomePos( 'C1') Z1Home = EgtGetAxisHomePos( 'Z1') EMT.CHSAW_OUT = nil end -- se motosega configurata per lavorazioni di fianco o circa orizzontale if dPosA == 0 or abs( EMT.R2) < 10 then SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) -- se circa verticale else SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end end -- altrimenti testa 2 else if GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC2' then -- se movimento iniziale da Zmax con lama o fresa if EMT.HEAD == 'H11' or EMT.HEAD == 'H12' or EMT.HEAD == 'H17' then if EMT.ZMAX or EMT.FLAG == 1 or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then --EgtOutBox( 'Flag 2,1', 'Info Rapid') local bMoveZbeforeX = false local dZref = EMT.L3 if EMT.HEAD == 'H12' and ( EgtIf( BD.RIGHT_LOAD, -EMT.L2 < -LimX1RotSaw, -EMT.L2 > -LimX1RotSaw) or EMT.R2 > 91) then dZref = Z1Home + GetZExtra( EMT.HEAD, EMT.R2) - 100 end -- se la quota di lavoro è più in alta della posizione a ZHOME della testa, prima si va alla Z di lavoro e poi si approccia il pezzo if EMT.L3 > dZref then bMoveZbeforeX = true end if not bMoveZbeforeX then SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID) else SimulMoveAxis( 'X1', LimX1RotSawTC2, MCH_SIM_STEP.RAPID) end -- caso speciale per trave alta con rotazione lama pericolosa (tolto "and EMT.SB > 400") if EMT.HEAD == 'H12' and abs( C1Pos - EMT.R1) > 1 and ( abs( C1Home - EMT.R1) > 30.1 or abs(B1Home - EMT.R2) > 30.1) then SimulMoveAxis( 'B1', 0, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) -- 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', dZref, MCH_SIM_STEP.RAPID, 'B1', dBref, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) else SimulMoveAxes( 'Z1', dZref, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end if bMoveZbeforeX then SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID) end -- caso standard else SimulMoveAxis( 'Z1', dZref, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end end -- altrimenti sega a catena (H13 o H15) else local dPosA = GetCurrChainSawingVirtualAxis() -- se anche precedente con sega a catena ma depositata, devo riprenderla if EMT.CHSAW_OUT then EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) OnSimulToolDeselect() EgtLoadTool( EMT.HEAD, 1, EMT.TOOL) ShowToolInTcPos( EMT.TCPOS, false) OnSimulToolSelect( dPosA) -- recupero i dati dato che ho scaricato motosega e preso quelli dell'utensile di default EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'B1', ParkCSawB1) B1Home = EgtGetAxisHomePos( 'B1') C1Home = EgtGetAxisHomePos( 'C1') Z1Home = EgtGetAxisHomePos( 'Z1') EMT.CHSAW_OUT = nil end -- se motosega configurata per lavorazioni di fianco o circa orizzontale if dPosA == 0 or abs( EMT.R2) < 10 then SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) -- se circa verticale else SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT) end end else -- Dati local B2Pos = EgtGetAxisPos( 'B2') local B2Home = EgtGetAxisHomePos( 'B2') local C2Pos = EgtGetAxisPos( 'C2') local C2Home = EgtGetAxisHomePos( 'C2') local Z2Pos = EgtGetAxisPos( 'Z2') local Z2Home = EgtGetAxisHomePos( 'Z2') -- se fresa o lama ('H21' o 'H22') if not HeadIsChainSaw( EMT.HEAD) then -- se movimento iniziale da Zmax con lama o fresa if EMT.ZMAX or EMT.FLAG == 1 or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then --EgtOutBox( 'Flag 2,1', 'Info Rapid') local bMoveZbeforeX = false local dZref = EMT.L3 if EMT.HEAD == 'H22' and ( EgtIf( BD.RIGHT_LOAD, -EMT.L2 < -LimX1RotSaw, -EMT.L2 > -LimX1RotSaw) or EMT.R2 > 91) then dZref = Z2Home + GetZExtra( EMT.HEAD, EMT.R2) - 100 end -- se la quota di lavoro è più in alta della posizione a ZHOME della testa, prima si va alla Z di lavoro e poi si approccia il pezzo if EMT.L3 > dZref then bMoveZbeforeX = true end if not bMoveZbeforeX then SimulMoveAxis( 'X2', EMT.L2, MCH_SIM_STEP.RAPID) else SimulMoveAxis( 'X2', LimX2RotSaw, MCH_SIM_STEP.RAPID) end -- caso speciale per trave alta con rotazione lama pericolosa (tolto "and EMT.SB > 379") if abs( C2Pos - EMT.R1) > 1 and ( abs( C2Home - EMT.R1) > 30.1 or abs( B2Home - EMT.R2) > 30.1) then if EMT.HEAD == 'H22' then SimulMoveAxis( 'B2', 0, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) -- 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( 'Z2', dZref, MCH_SIM_STEP.RAPID, 'B2', dBref, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) else SimulMoveAxes( 'Z2', dZref, MCH_SIM_STEP.RAPID, 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) end if bMoveZbeforeX then SimulMoveAxis( 'Z2', EMT.L3, MCH_SIM_STEP.RAPID) end -- caso standard else SimulMoveAxis( 'Z2', dZref, MCH_SIM_STEP.RAPID) SimulMoveAxis( 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) if bMoveZbeforeX then SimulMoveAxis( 'Z2', EMT.L3, MCH_SIM_STEP.RAPID) end end end end -- altrimenti sega a catena else local dPosA = GetCurrChainSawingVirtualAxis() -- se anche precedente con sega a catena ma depositata, devo riprenderla if EMT.CHSAW_OUT then EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN) OnSimulToolDeselect() EgtLoadTool( EMT.HEAD, 1, EMT.TOOL) ShowToolInTcPos( EMT.TCPOS, false) OnSimulToolSelect( dPosA) -- recupero i dati dato che ho scaricato motosega e preso quelli dell'utensile di default EmtModifyAxisHome( 'Z2', GetChainSawZHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'C2', GetChainSawCHomeFromVirtualAxis( dPosA)) EmtModifyAxisHome( 'B2', ParkCSawB2) B2Home = EgtGetAxisHomePos( 'B2') C2Home = EgtGetAxisHomePos( 'C2') Z2Home = EgtGetAxisHomePos( 'Z2') EMT.CHSAW_OUT = nil end -- se motosega configurata per lavorazioni di fianco o circa orizzontale if dPosA == 0 or abs( EMT.R2) < 10 then SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z2', EMT.L3, MCH_SIM_STEP.RAPID, 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) -- se circa verticale else SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT) SimulMoveAxes( 'Z2', EMT.L3, MCH_SIM_STEP.RAPID, 'B2', EMT.R2, MCH_SIM_STEP.COLLROT) end end 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 EMT.DOU_TYPE == 2 and not ( EMT.MOVE == 0 and EMT.FLAG == 3) then 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 if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then Z2 = MaxZ2 end EMT.A6 = min( Z2, MaxZ2) EMT.A6m = EgtIf( ( EMT.MOVE == 2 or EMT.MOVE == 3), 'Z1', nil) EMT.A7n = 'C2' EMT.A7 = -EMT.R1 EMT.A8n = 'B2' EMT.A8 = -EMT.R2 -- controllo minimo interasse tra X1 e X2 local dDeltaX1X2 = EMT.L2 - EMT.A5 - Head2Y if dDeltaX1X2 < MinDeltaX1X2 then local sErr = 'X1 X2 charriots in collision (distance=' .. EgtNumToString( dDeltaX1X2, 1) .. ')' EmtSetLastError( 1208, sErr) end -- controllo minima distanza tra utensili di X1 e X2 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 end -- se necessario ... if EMT.MCHFIRST and bParkV 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) else 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) 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.XHOME = nil end --------------------------------------------------------------------- function OnSimulMoveEnd() -- rimozione eventuali sfridi if EMT.FLAG == 301 then ExecRemoveScraps() end -- se primo rapido della lavorazione if EMT.MCHFIRST and EMT.MOVE == 0 then -- se lavorazione split, dichiaro carro Y1 riagganciato if EMT.SPLIT_Y1DELTA then EMT.SPLIT_Y1DELTA = nil ExecMovePY1( true) end -- chiusura pinza speciale (e posizionamento iniziale) if EMT.W2DELTA then local dPosQW = EgtGetAxisPos( 'QW') or 0 if dPosQW < 1 then EgtSetAxisPos( 'W', EMT.A5) EgtSetAxisPos( 'QW', 30) EgtSetAxisPos( 'PW', EMT.HB) end 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.DOU_TYPE == 2 and EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 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) end -- se Zmax dopo fine lavorazione if EMT.MOVE == 0 and EMT.FLAG == 3 then -- eventuale rimozione sfridi ExecRemoveScraps() -- se Split o Presplit lascio agganciata solo la pinza Y2 alla fine dei movimenti local sNextTool = GetNextTool( EMT.MCHID, true) -- vado in home se è ultimo movimento ed è ultima lavorazione, se sono con motosega e devo cambiare utensile, oppure se ho la lama local bToXhome = ( IsLastPath( EMT.PATHID) and not sNextTool) or ( EMT.HEAD == 'H23' and EMT.TOOL ~= sNextTool) or ( EMT.HEAD == 'H13' and EMT.TOOL ~= sNextTool) or ( EMT.HEAD == 'H12' and EMT.TOOL ~= sNextTool ) or ( EMT.HEAD == 'H22' and EMT.TOOL ~= sNextTool) or EMT.MCHSPLIT -- eseguo ExecMoveZmax( EMT.MCHSPLIT, bToXhome) EMT.TO_ZMAX = nil end end --------------------------------------------------------------------- function OnSimulCollision() -- se prima collisione della lavorazione, la segnalo if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then local Class = '' if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then Class = 'T_'..EMT.HEAD elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then Class = 'TH_'..EMT.HEAD else Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl end table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME EMT.ERR = 11 local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID EmtSetLastError( 1221, sErr, true) EgtOutLog( 'Collision : ' .. sErr, 1) end end --------------------------------------------------------------------- function ExecAuxCmd( sCmd, bPathStart) -- analizzo il comando local Cmd = EgtSplitString( sCmd) if Cmd[1] == '0' then if Cmd[2] == 'Unloading' then EMT.UNLOADING = true elseif Cmd[2] == 'Unloading SpecSplit' then EMT.UNLOADING = true EMT.SPECUNL = true elseif Cmd[2] == 'Split' then EMT.SPLIT = true elseif Cmd[2] == 'SpecSplit' then EMT.SPECSPLIT = true elseif Cmd[2] == 'Fall' then EMT.FALL = true elseif Cmd[2] == 'SplitRot' then ; end EgtOutText( Cmd[2]) elseif Cmd[1] == '1' then if Cmd[2] ~= 'Z' then ExecOpenRoller( 1) ExecOpenRoller( 2) local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) -- se stringo i rulli e ho lama, verifico che sia in home if MoveV1 and MoveV1 < 400 and ( EMT.HEAD == 'H12' or EMT.HEAD == 'H22') and EMT.ZMAX and not EMT.XHOME then ExecMoveZmax( false, true) end 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) -- se stringo i rulli e ho lama, verifico che sia in home if MoveV1 and MoveV1 < 400 and ( EMT.HEAD == 'H12' or EMT.HEAD == 'H22') and EMT.ZMAX and not EMT.XHOME then ExecMoveZmax( false, true) end 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) -- se stringo i rulli e ho lama, verifico che sia in home if MoveV1 and MoveV1 < 400 and ( EMT.HEAD == 'H12' or EMT.HEAD == 'H22') and EMT.ZMAX and not EMT.XHOME then ExecMoveZmax( false, true) end 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] == '23' then local nW2Delta = tonumber( Cmd[2]) EMT.W2DELTA = EgtIf( nW2Delta > 0.01, nW2Delta, nil) 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) -- recupero dati per necessità aggiuntivo local bAgg = ( Cmd and #Cmd > 0 and Cmd[#Cmd] == '*') local MinDeltaY1V1 = MinDeltaYV + EgtIf( bAgg, AggLoad, 0) -- verifico se necessario muovere V1 local MoveV1 local MoveY1 = GetCmdAxMove( Cmd, 'Y1') local V1Pos = EgtGetAxisPos( 'V1') if MoveY1 and V1Pos > MoveY1 - MinDeltaY1V1 + 0.1 then MoveV1 = MoveY1 - MinDeltaY1V1 elseif MoveY1 and EMT.SPECSPLIT and MoveY1 - MinDeltaY1V1 + 0.1 > ParkV1 then MoveV1 = ParkV1 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 local HomeX1 = EgtGetAxisHomePos( 'X1') local HomeC1 = EgtGetAxisHomePos( 'C1') local HomeB1 = EgtGetAxisHomePos( 'B1') EgtSetAxisPos( 'X1', HomeX1) EgtSetAxisPos( 'C1', HomeC1) EgtSetAxisPos( 'B1', HomeB1) EgtSetAxisPos( 'Z1', MaxZ1) -- Testa 2 if EgtGetHeadId( 'H21') then local HomeX2 = EgtGetAxisHomePos( 'X2') local HomeC2 = EgtGetAxisHomePos( 'C2') local HomeB2 = EgtGetAxisHomePos( 'B2') EgtSetAxisPos( 'X2', HomeX2) EgtSetAxisPos( 'C2', HomeC2) EgtSetAxisPos( 'B2', HomeB2) EgtSetAxisPos( 'Z2', MaxZ2) end end --------------------------------------------------------------------- function ExecMoveHome( bNearV, bMchSplit) -- risalita a Zmax ExecMoveZmax( bMchSplit, true) EMT.TO_ZMAX = nil -- se richiesto, avvicino i rulli if bNearV then -- se sega a catena su testa 1 devo prima depositarla if HeadIsChainSaw( EMT.PREVHEAD_H1) 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) -- cambio utensile EgtSetAxisPos( 'C1', ParkC1) EgtSetAxisPos( 'B1', ParkB1) EgtSetAxisPos( 'Z1', MaxZ1) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) LoadNextTool( 1, DefTcPos1) -- dichiaro sega a catena depositata EMT.CHSAW_OUT = true -- se sega a catena su testa 2 devo prima depositarla elseif HeadIsChainSaw( EMT.PREVHEAD_H2) then -- 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) -- cambio utensile EgtSetAxisPos( 'C2', ParkC2) EgtSetAxisPos( 'B2', ParkB2) EgtSetAxisPos( 'Z2', MaxZ2) SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) LoadNextTool( 2, DefTcPos2) -- dichiaro sega a catena depositata EMT.CHSAW_OUT = true end -- porto le teste in home if EgtGetHeadId( 'H21') then SimulMoveAxes( 'X1', ParkX1, MCH_SIM_STEP.RAPID, 'X2', ParkX2, MCH_SIM_STEP.RAPID) else if GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC1' then SimulMoveAxes( 'X1', ParkX1, MCH_SIM_STEP.RAPID) else SimulMoveAxes( 'X1', ParkFrnX1, MCH_SIM_STEP.RAPID) end end -- sistemo i rulli 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, btoXHome) -- set della testa local nSetHead = GetHeadSet( EMT.HEAD) if nSetHead == 0 then return end -- posizioni correnti degli assi testa local CurrX = EgtGetAxisPos( EgtIf( nSetHead == 1, 'X1', 'X2')) local CurrZ = EgtGetAxisPos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) local CurrC = EgtGetAxisPos( EgtIf( nSetHead == 1, 'C1', 'C2')) local CurrB = EgtGetAxisPos( EgtIf( nSetHead == 1, 'B1', 'B2')) -- posizioni home degli assi testa local HomeX = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'X1', 'X2')) local HomeZ = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) local HomeC = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'C1', 'C2')) local HomeB = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'B1', 'B2')) -- verifico se necessario ruotare la testa local bRot = ( abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1) -- se necessario ruotare la testa, allargo i carrelli if RollerParkingNeeded( EMT.HEAD, CurrC, CurrB, HomeC, HomeB) then ExecOpenRoller( 1) ExecOpenRoller( 2) local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT') ExecParkRoller( nil, nil, nil, nil, bMchSplit, bAgg) end -- se testa 1 if nSetHead == 1 then -- se fresa o lama if GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC1' then if not HeadIsChainSaw( EMT.HEAD) then if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then local dZref = HomeZ + GetZExtra( EMT.HEAD, EgtClamp( CurrB, -90, 90)) if EgtIf( BD.RIGHT_LOAD, -CurrX < -LimX1RotSaw, -CurrX > -LimX1RotSaw) then dZref = dZref - EgtIf( not Mortiser, 100, 370) end SimulMoveAxes( 'Z1', EgtIf( dZref > CurrZ, dZref, CurrZ), MCH_SIM_STEP.RAPID, 'B1', EgtClamp( CurrB, -90, 90), MCH_SIM_STEP.COLLROT) if EMT.HEAD == 'H12' and ( abs( HomeC - CurrC) > 30.1 or abs( HomeB - CurrB) > 30.1) then SimulMoveAxes( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'C1', HomeC, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', HomeB, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID) if btoXHome then EMT.XHOME = true SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) end -- se lavorazione in doppio if EMT.DOU_TYPE == 2 then local CurrZ2 = EgtGetAxisPos( 'Z2') if CurrZ2 < ParkZ2 then SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID) end SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID) if bToXHome then EMT.XHOME = true SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) end EMT.DOU_TO_ZMAX = nil end -- altrimenti sega a catena else SimulMoveAxes( 'Z1', HomeZ, MCH_SIM_STEP.RAPID, 'B1', HomeB, MCH_SIM_STEP.COLLROT) if EMT.R3 and abs( EMT.R3) < 0.1 then SimulMoveAxis( 'Z1', ParkCSawZ1, MCH_SIM_STEP.RAPID) end SimulMoveAxes( 'X1', HomeX, MCH_SIM_STEP.RAPID, 'C1', HomeC, MCH_SIM_STEP.COLLROT) end else -- se fresa o lama if not HeadIsChainSaw( EMT.HEAD) 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) SimulMoveAxes( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'C1', HomeC, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B1', HomeB, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID) if btoXHome then EMT.XHOME = true SimulMoveAxis( 'X1', HomeX, MCH_SIM_STEP.RAPID) end -- altrimenti sega a catena else -- controlla che l'ingombro della sega a catena non possa collidere durante il suo riposizionamento local dChSawEncumbrance = sqrt( pow( EgtTdbGetCurrToolParam( MCH_TP.TOTLEN), 2) + pow( ChSawLen + MillOffs, 2)) if EMT.ADIR and EMT.TDIR then -- direzione versore sega a catena X- (copre anche eventuali inclinazioni in Y) if EMT.TDIR[1] <= 0 then -- ingombro massimo di quota Z (senza pivot) + ingombro massimo sega + altezza pezzo + altezza sicurezza local dEncumbranceTot = EMT.L3p + MillOffs - dChSawEncumbrance - EMT.SB - 30 -- nuova quota Z intermedia local dZUp = EMT.L3p + ( DeltaTabZ - dEncumbranceTot) -- se la nuova quota è minore della quota di parcheggio if dZUp <= ParkCSawZ1 then -- se B è oltre il punto di massimo ingombro (con l'inclinazione attuale non ha il massimo ingombro) if asin( EMT.TDIR[3] / 1) > asin( EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) / dChSawEncumbrance) and ( dEncumbranceTot < DeltaTabZ) then SimulMoveAxis( 'Z1', dZUp, MCH_SIM_STEP.RAPID) end end end end SimulMoveAxes( 'Z1', HomeZ, MCH_SIM_STEP.RAPID, 'B1', HomeB, MCH_SIM_STEP.COLLROT) if EMT.R3 and abs( EMT.R3) < 0.1 then SimulMoveAxis( 'Z1', ParkCSawZ1, MCH_SIM_STEP.RAPID) end if btoXHome then EgtUnloadTool( EMT.HEAD, 1) ShowToolInTcPos( EMT.TCPOS, true) -- nascondo l'utensile sulla testa EgtSetMode( EgtGetHeadId( EMT.HEAD or '') or GDB_ID.NULL, GDB_MD.HIDDEN) EMT.PREVTOOL_H1 = nil EMT.PREVHEAD_H1 = nil EMT.PREVTCPOS_H1 = nil EMT.CHSAW_OUT = true EMT.XHOME = true end SimulMoveAxes( 'X1', HomeX, MCH_SIM_STEP.RAPID, 'C1', HomeC, MCH_SIM_STEP.COLLROT) end end -- altrimenti testa 2 else -- se fresa o lama if not HeadIsChainSaw( EMT.HEAD) then if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then local dZref = HomeZ + GetZExtra( EMT.HEAD, CurrB) SimulMoveAxes( 'Z2', EgtIf( dZref > CurrZ, dZref, CurrZ), MCH_SIM_STEP.RAPID, 'B2', EgtClamp( CurrB, -90, 90), MCH_SIM_STEP.COLLROT) if EMT.HEAD == 'H22' and ( abs( HomeC - CurrC) > 30.1 or abs( HomeB - CurrB) > 30.1) then SimulMoveAxes( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID, 'B2', 0, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'C2', HomeC, MCH_SIM_STEP.COLLROT) SimulMoveAxis( 'B2', HomeB, MCH_SIM_STEP.COLLROT) end SimulMoveAxis( 'Z2', MaxZ2, MCH_SIM_STEP.RAPID) if btoXHome then EMT.XHOME = true SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID) end -- altrimenti sega a catena else -- controlla che l'ingombro della sega a catena non possa collidere durante il suo riposizionamento local dChSawEncumbrance = sqrt( pow( EgtTdbGetCurrToolParam( MCH_TP.TOTLEN), 2) + pow( ChSawLen + Mill2Offs, 2)) if EMT.ADIR and EMT.TDIR then -- direzione versore sega a catena X- (copre anche eventuali inclinazioni in Y) if EMT.TDIR[1] <= 0 then -- ingombro massimo di quota Z (senza pivot) + ingombro massimo sega + altezza pezzo + altezza sicurezza local dEncumbranceTot = EMT.L3p + Mill2Offs - dChSawEncumbrance - EMT.SB - 30 -- nuova quota Z intermedia local dZUp = EMT.L3p + ( DeltaTabZ - dEncumbranceTot) -- se la nuova quota è minore della quota di parcheggio if dZUp <= ParkCSawZ2 then -- se B è oltre il punto di massimo ingombro (con l'inclinazione attuale non ha il massimo ingombro) if asin( EMT.TDIR[3] / 1) > asin( EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) / dChSawEncumbrance) and ( dEncumbranceTot < DeltaTabZ) then SimulMoveAxis( 'Z2', dZUp, MCH_SIM_STEP.RAPID) end end end end SimulMoveAxes( 'Z2', HomeZ, MCH_SIM_STEP.RAPID, 'B2', HomeB, MCH_SIM_STEP.COLLROT) if EMT.R3 and abs( EMT.R3) < 0.1 then SimulMoveAxis( 'Z2', ParkCSawZ2, MCH_SIM_STEP.RAPID) end SimulMoveAxes( 'X2', ParkCSawX2, MCH_SIM_STEP.RAPID, 'C2', HomeC, MCH_SIM_STEP.COLLROT) 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, 2000, -2000), -475) elseif EMT.SPECUNL then EMT.SPECUNL = nil EMT.W2DELTA = nil vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 2000, -2000), -475) EgtSetAxisPos( 'W', ParkW) EgtSetAxisPos( 'QW', 0) EgtSetAxisPos( 'PW', MaxWOpen) 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 else if EMT.SPECUNL then EMT.SPECUNL = nil EMT.W2DELTA = nil EgtSetAxisPos( 'W', ParkW) EgtSetAxisPos( 'QW', 0) EgtSetAxisPos( 'PW', MaxWOpen) 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) SimulMoveAxis( 'PY1', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID) SetPY1Light( bClose) if bClose then CheckClamping( 'PY1') end end --------------------------------------------------------------------- function ExecMovePY2( bClose) SimulMoveAxis( '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') -- se entrambe già parcheggiate, non devo fare alcunché if ( PosV1 - ParkV1) > -0.1 and ( PosV2 - ParkV2) < 0.1 then return end -- 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 local dAddMove -- se entrambe le morse si spostano vado in posizione calcolata if DiffY1 > 0.1 and DiffY2 < -0.1 then dAddMove = 0 -- se almeno una è rimasta ferma in posizione, allontano comunque di 30mm ulteriori else dAddMove = 30 end local MoveY1 = max( DiffY1, 0.0) local MoveY2 = min( DiffY2, 0.0) MoveY1 = MoveY1 + dAddMove MoveY2 = MoveY2 - dAddMove -- aggancio i pezzi rimanenti all'asse Y1 LinkRemainingPartsToY1() -- eseguo i movimenti if not SimulMoveAxes( 'T', PosT + MoveY2, MCH_SIM_STEP.RAPID, 'V1', ParkV1, MCH_SIM_STEP.RAPID, 'V2', ParkV2, MCH_SIM_STEP.RAPID, 'Y1', PosY1 + MoveY1, MCH_SIM_STEP.RAPID, 'Y2', PosY2 + MoveY2, 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) - EMT.HOVM, MaxY1 - PosY1 - 10) if ( PosT > ParkV2 - ExtraParkV and PosT < ParkV1 and PosY1 + TryMoveY1 < MaxY1 and not EMT.W2DELTA) then MoveY1 = max( MoveY1, TryMoveY1) end -- 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, 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', EgtIf( PosY1 > MyParkY1, PosY1, 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) local dPV = EgtIf( EMT.ROT == -1, EMT.SB, EMT.HB) local dQV = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), dPV) EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), dQV) 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 - EMT.HOVM 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 VerifyWStroke( dW) if dW < MinW then EmtSetOutstrokeInfo( 'W', 'W', true, dW - MinW, ' (L1-)') EMT.ERR = 1 local sErr = 'W axis outstroke ' .. EgtNumToString( dW - MinW, 3) EgtOutLog( sErr) return false elseif dW > MaxW then EmtSetOutstrokeInfo( 'W', 'W', true, dW - MaxW, ' (L1+)') EMT.ERR = 1 local sErr = 'W axis outstroke ' .. EgtNumToString( dW - MaxW, 3) EgtOutLog( sErr) return false end return true 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 ( not EMT.W2DELTA and 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 -- recupero il gruppo dell'utensile local TcExitId = EgtGetFirstNameInGroup( TcPosId or GDB_ID.NULL, 'T1') if not TcExitId then return end -- imposto lo stato di visualizzazione EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) -- 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) return LoadNextTool( nHSet, sTcPosDef, true) end --------------------------------------------------------------------- function LoadNextTool( nHSet, sTcPosDef, bFirst) -- recupero gruppo della testa (1 o 2) if nHSet ~= 1 and nHSet ~= 2 then return end -- recupero il prossimo utensile attrezzabile senza problemi local sTool, sHead, sTcPos = FindNextToolOnHeadSet( nHSet, bFirst) if HeadIsChainSaw( sHead) then sTool = nil end -- se non trovato, cerco l'utensile di default if not sTool and GetHeadSetFromTcPos( sTcPosDef) == nHSet then local vTools = EgtGetToolsInCurrSetupPos( sTcPosDef) if vTools and vTools[1] and #(vTools[1]) > 0 then sTool = vTools[1] sTcPos = sTcPosDef if Progress or SecondToolChanger then sHead = EgtIf( sTcPos == 'T11', 'H12', 'H11') elseif nHSet == 1 then sHead = EgtIf( sTcPos == 'T1', 'H12', 'H11') else sHead = EgtIf( sTcPos == 'T11', 'H22', 'H21') end end end -- se non trovato, lascio la testa vuota if not sTool then sTool = '' sHead = EgtIf( nHSet == 1, 'H11', 'H21') sTcPos = '' EgtUnloadTool( sHead, 1) end -- imposto correttamente i dati di testa local OrigEMC = EMC EMC = { HEAD = sHead, TOOL = sTool, TCPOS = sTcPos, TOTDIAM = 0} OnSetHead() EMC = OrigEMC -- carico l'utensile EgtLoadTool( sHead, 1, sTool) ShowToolInTcPos( sTcPos, false) -- aggiorno dati utensile corrente sulla testa if nHSet == 1 then EMT.PREVTOOL_H1 = sTool EMT.PREVHEAD_H1 = sHead EMT.PREVTCPOS_H1 = sTcPos else EMT.PREVTOOL_H2 = sTool EMT.PREVHEAD_H2 = sHead EMT.PREVTCPOS_H2 = sTcPos 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 102000, 20000, 102000) -- feed massima pinze EMT.MAXACC = MaxAcc or ( EMT.FMAXPINZE / ( 60 * 0.3)) -- accelerazione massima pinze EMT.MINACC = MinAcc or ( EMT.FMAXPINZE / ( 60 * 4)) -- accelerazione minima pinze 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 o finale dopo separazione e rotazione, eventuale rotazione elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then -- recupero le rotazioni delle fasi corrente e precedente local nRot = GetPhaseRot( EMT.PHASE) local nPrevRot = GetPhaseRot( EMT.PHASE - 1) -- verifico se sono diverse if nRot ~= nPrevRot then -- imposto stato post-rotazione EMT.POSTROT = true end -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni else ; end -- emetto dati in sospeso if EMT.TLE_NAME then EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') EMT.TLE_NAME = nil EMT.TLE_TIME = nil end -- termine disposizione EMT.OPEISDISP = false end --------------------------------------------------------------------- function 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 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 GetHeadSetFromTcPos( sTcPos) local TCPOS_1A = {} local TCPOS_1B = {} local TCPOS_1C = {} local TCPOS_2A = {} local TCPOS_2B = {} if EgtGetHeadId( 'H21') then TCPOS_1A = { 'T1', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10'} TCPOS_1B = { 'T101'} TCPOS_2A = { 'T11', 'T12', 'T13', 'T14', 'T15', 'T16', 'T17', 'T18', 'T19', 'T20'} TCPOS_2B = { 'T111'} else TCPOS_1A = { 'T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10'} TCPOS_1B = { 'T101', 'T201'} TCPOS_1C = { 'T301'} TCPOS_2A = { 'T11', 'T12', 'T13', 'T14', 'T15', 'T16', 'T17', 'T18', 'T19', 'T20'} end for _, sVal in ipairs( TCPOS_1A) do if sVal == sTcPos then return 1, 1 end end for _, sVal in ipairs( TCPOS_1B) do if sVal == sTcPos then return 1, 2 end end for _, sVal in ipairs( TCPOS_1C) do if sVal == sTcPos then return 1, 3 end end for _, sVal in ipairs( TCPOS_2A) do -- se esiste testa 2 if EgtGetHeadId( 'H21') then if sVal == sTcPos then return 2, 1 end -- altrimenti è un CU della testa 1 else if sVal == sTcPos then return 1, 4 end end end for _, sVal in ipairs( TCPOS_2B) do if sVal == sTcPos then return 2, 2 end end return 0, 0 end --------------------------------------------------------------------- function FindFirstToolOnHeadSet( nHSet) return FindNextToolOnHeadSet( nHSet, true) end --------------------------------------------------------------------- function FindNextToolOnHeadSet( nHSet, bFirst) -- salvo stato iniziale local CurrMachId = EgtGetCurrMachining() local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) -- cerco lavorazione con utensile su gruppo testa indicato local sTool, sHead, sTcPos local OpId if bFirst then OpId = EgtGetFirstActiveOperation() else OpId = EgtGetNextActiveOperation( CurrMachId or EMT.MCHID) end 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 sTool = sTest sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) 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 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 GetCurrChainSawingVirtualAxis() -- recupero il valore dell'asse virtuale bloccato A local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A=0' local dPosA = tonumber( sVal:sub( 3)) or 0 return dPosA 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 not NextMchId or 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 GetNextTool( nMchId, bResetOnStart) -- inizializzo prossimo utensile local sNextTool -- recupero lavorazione successiva local nNextMchId = EgtGetNextActiveOperation( nMchId) while nNextMchId do -- se la prossima lavorazione è lo start di un altro pezzo, faccio finta che cambia utensile in modo che vada in parcheggio con utensili speciali if EgtGetOperationType( nNextMchId) == MCH_OY.DISP then if IsStartOrRestPhase( EMT.PHASE+1) and bResetOnStart then return nil end else break end nNextMchId = EgtGetNextActiveOperation( nNextMchId) end -- se trovata if nNextMchId and EgtSetCurrMachining( nNextMchId) then sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) end -- ripristino stato corrente EgtSetCurrMachining( EMT.MCHID) EgtTdbSetCurrTool( EMT.TOOL) return sNextTool end --------------------------------------------------------------------- function IsLastPath( nPathId) return not EgtGetNext( nPathId) end --------------------------------------------------------------------- function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2) if sHead == 'H11' or sHead == 'H12' or sHead == 'H17' or HeadIsChainSaw( sHead) then return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1) % 180.0 > 1)) elseif sHead == 'H21' or sHead == 'H22' or HeadIsChainSaw( sHead) then return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1) % 180.0 > 1)) end end --------------------------------------------------------------------- function GetCmdAxMove( Cmd, sAx) if #Cmd >= 3 and Cmd[2] == sAx then return tonumber( Cmd[3]) elseif #Cmd >= 5 and Cmd[4] == sAx then return tonumber( Cmd[5]) elseif #Cmd >= 7 and Cmd[6] == sAx then return tonumber( Cmd[7]) end end --------------------------------------------------------------------- function CalcDinamicaPinze( dH, dS, dL) local KgMtCubo= WoodDensity or 550 -- densità legno [Kg / metro cubo] local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg] local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min] local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N] local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito) / 1000) local AccMaxPinze = EMT.MAXACC local AccPinze = EgtClamp( FMaxPinze / ( 60 * TempoAcc), EMT.MINACC, EMT.MAXACC) local RidFeed = 100 / Massa * 100 if RidFeed > 100 then RidFeed = 100 elseif RidFeed < 10 then RidFeed = 10 end return AccPinze, AccMaxPinze, RidFeed end --------------------------------------------------------------------- function CalcMoveTime( dPathLen, dFeed, bIsSplitted) local dTime local dFeedInSec = dFeed / 60 local dAcc, _, _ = CalcDinamicaPinze( EMT.HB, EMT.SB, EgtIf( bIsSplitted, EMT.LT, EMT.LB)) -- Caso 1: dFeed raggiunta if dPathLen >= ( dFeedInSec ^ 2) / dAcc then dTime = ( dFeedInSec / dAcc) + ( dPathLen / dFeedInSec) -- Caso 2: dFeed non raggiunta else dTime = 2 * sqrt( dPathLen / dAcc) end return dTime end --------------------------------------------------------------------- -- *** END GENERAL ***