Files
essetre-pf1500maxrl-3t/Common_PF1250.mlpe
T
andrea.villa fc2608def7 - Allineamento a common ver. 2.7l1
- Aggiunto parametro MAX_ANGLE_DRILL_CUT a BeamData
- Recupero nome macchina da funzione EGT
2025-12-18 12:33:32 +01:00

3011 lines
119 KiB
Plaintext

-- Processore standard macchine tipo PF1250 by EgalWare s.r.l. 2024/01/22
-- Funzioni generiche indipendenti dal controllo
-- Intestazioni
require( 'EmtGenerator')
EgtEnableDebug( false)
-- Carico libreria
local BD = require( 'BeamData')
---------------------------------------------------------------------
-- *** GENERATION ***
---------------------------------------------------------------------
local sBaseDir = EgtGetCurrMachineDir()
if NumericalControl == 'NUM' then
error( 'Numerical Control error : NUM not yet managed')
elseif NumericalControl == 'TPA' then
dofile( sBaseDir .. '\\Common_PF1250.TPA.mlpe')
else
error( 'Numerical Control error : unkwnown type')
end
---------------------------------------------------------------------
-- *** SIMULATION ***
---------------------------------------------------------------------
local COLL_SAFE_DIST = 3
---------------------------------------------------------------------
function OnSimulInit()
-- se macchina con carico destro, imposto offset direzioni di vista standard
if BD.RIGHT_LOAD then
local nOrigViewOffs = EgtGetViewOrizzOffsStep()
local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView()
if nOrigViewOffs ~= 2 then
EgtSetViewOrizzOffsStep( 2)
if dOrigViewAngV < 0.1 then
EgtSetView( SCE_VD.TOP, false)
elseif dOrigViewAngV > 179.9 then
EgtSetView( SCE_VD.BOTTOM, false)
else
local dViewAngH = dOrigViewAngH + EgtIf( dOrigViewAngH > 180, 2 * 90, 0)
EgtSetGenericView( dOrigViewAngV, dViewAngH, false)
end
end
end
end
---------------------------------------------------------------------
function OnSimulExit()
-- se macchina con carico destro, annullo offset direzioni di vista standard
if BD.RIGHT_LOAD then
local nOrigViewOffs = EgtGetViewOrizzOffsStep()
local dOrigViewAngV, dOrigViewAngH = EgtGetGenericView()
if nOrigViewOffs == 2 then
EgtSetViewOrizzOffsStep( 0)
if dOrigViewAngV < 0.1 then
EgtSetView( SCE_VD.TOP, false)
elseif dOrigViewAngV > 179.9 then
EgtSetView( SCE_VD.BOTTOM, false)
else
EgtSetGenericView( dOrigViewAngV, dOrigViewAngH - 2 * 90, false)
end
end
end
end
---------------------------------------------------------------------
function OnSimulStart()
-- controllo versione programma
if not EMT.VER or EMT.VER < MIN_MACH_VER then
EmtSetLastError( 1200, 'A newer version of the program is required (minimum EgtMachKernel '..MIN_MACH_VER..')')
end
-- Carico gli utensili sulle barre portautensili
local vTcPos = EgtGetAllTcPosNames()
if vTcPos then
for i = 1, #vTcPos do
local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i])
for j = 1, #( vTools or {}) do
if vTools[j] ~= '' then
EgtLoadTool( vTcPos[i], j, vTools[j])
-- Aggiunto controllo lunghezza lama minima * 0.9 per ricavare la tolleranza del VMILL
if EgtTdbSetCurrTool(vTools[j]) then -- set utensile corrente
if EgtTdbGetCurrToolParam( MCH_TP.TYPE) == MCH_TY.SAW_STD or EgtTdbGetCurrToolParam( MCH_TP.TYPE) == MCH_TY.SAW_FLAT then -- controllo tipo utensile sega
local dCurrSawLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) * 0.9
-- se non definito o minore del valore precedente aggiorna la tolleranza
EMT.VMILLTOL = EgtIf( not EMT.VMILLTOL or dCurrSawLen < EMT.VMILLTOL, dCurrSawLen, EMT.VMILLTOL)
end
end
end
end
ShowToolInTcPos( vTcPos[i], true)
end
end
-- Carico gli utensili iniziali o di default sulle due teste
LoadFirstTool( 1, DefTcPos1)
LoadFirstTool( 2, DefTcPos2)
ExecStartHome()
-- Se reset o home, esco
if EMT.SIM1ST then return end
-- Creo o svuoto gruppo per copia finale degli oggetti virtual milling
local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill')
if nVmGrpId then
EgtSetStatus( nVmGrpId, GDB_ST.ON)
EgtEmptyGroup( nVmGrpId)
else
nVmGrpId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nVmGrpId, 'VMill')
EgtSetLevel( nVmGrpId, GDB_LV.TEMP)
end
-- Preparo lista oggetti da verificare per collisioni
EMT.COLLOBJ = {}
AddToCollisionCheck( 'Z1', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'B1', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'X2', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ)
if IsHeadExisting( 3) then
AddToCollisionCheck( 'Z3', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C3', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'B3', 'COLLISION', EMT.COLLOBJ)
end
DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4)
-- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill)
EMT.MCODET = {}
local McdData = { { Grp = 'V1', Sub = 'COLLISION', Name = 'STM'},
{ Grp = 'V2', Sub = 'COLLISION', Name = 'STM'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'TRAV'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'COL1'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'COL2'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'CHSAW'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'CEIL'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'TC1'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'TC2'},
{ Grp = 'Base', Sub = 'COLLISION', Name = 'TCR'},
{ Grp = 'Z2', Sub = 'COLLISION', Name = 'COL1'},
{ Grp = 'Z2', Sub = 'COLLISION', Name = 'CHAIN'},
{ Grp = 'Z2', Sub = 'COLLISION', Name = 'COL2'},
{ Grp = 'X1', Sub = 'COLLISION', Name = 'STM'}}
if IsHeadExisting( 3) then
table.insert( McdData, { Grp = 'X3', Sub = 'COLLISION', Name = 'STM'})
end
-- inserisco gruppi opzionali
if SecondChain then table.insert( McdData, { Grp = 'Base', Sub = 'COLLISION', Name = 'CHSAW2'}) end
if TcSpecialTools then table.insert( McdData, {Grp = 'Base', Sub = 'COLLISION', Name = 'SPTOOLS'}) end
if TcAggreBladeUnder then table.insert( McdData, {Grp = 'Base', Sub = 'COLLISION', Name = 'AGGREBLADEUNDER'}) end
EgtOutLog( 'MCODET Objects :', 4)
local nMcdNullCnt = 0
for i = 1, #McdData do
local nGrpId
if McdData[i].Grp == 'Base' then
nGrpId = EgtGetBaseId( 'Base')
else
nGrpId = EgtGetAxisId( McdData[i].Grp)
end
local nId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nGrpId, McdData[i].Sub), McdData[i].Name)
if nId then
table.insert( EMT.MCODET, nId)
EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' (' .. tostring( nId) .. ') is ok', 4)
else
nMcdNullCnt = nMcdNullCnt + 1
EgtOutLog( 'Element ' .. McdData[i].Grp .. '/' .. McdData[i].Sub .. '/' .. McdData[i].Name .. ' is null', 4)
end
end
if nMcdNullCnt > 0 then
EgtOutLog( 'Warning : MCODET with one or more null Element(s) ')
end
-- Preparo lista collisioni vuota
EMT.COLLIDE = {}
-- si crea gruppo temporaneo appoggio controllo clamping
CLAMP_CHECK_GROUP = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'CLAMP_CHECK')
CLAMP_CHECK_INTERS = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'CLAMP_INTERS')
if CLAMP_CHECK_GROUP then
EgtEmptyGroup( CLAMP_CHECK_GROUP)
else
local frClampCheckGroup = Frame3d( ORIG(), GDB_FR.FRONT)
CLAMP_CHECK_GROUP = EgtGroup( GDB_ID.ROOT, frClampCheckGroup)
EgtSetName( CLAMP_CHECK_GROUP, 'CLAMP_CHECK')
EgtSetLevel( CLAMP_CHECK_GROUP, GDB_LV.TEMP)
EgtSetStatus( CLAMP_CHECK_GROUP, GDB_ST.OFF)
end
if CLAMP_CHECK_INTERS then
EgtEmptyGroup( CLAMP_CHECK_INTERS)
else
CLAMP_CHECK_INTERS = EgtGroup( GDB_ID.ROOT)
EgtSetName( CLAMP_CHECK_INTERS, 'CLAMP_INTERS')
EgtSetLevel( CLAMP_CHECK_INTERS, GDB_LV.TEMP)
EgtSetStatus( CLAMP_CHECK_INTERS, GDB_ST.OFF)
end
end
---------------------------------------------------------------------
function OnSimulEnd()
EMT.Y1DELTA = nil
EMT.Y2DELTA = nil
ExecParkRoller()
end
---------------------------------------------------------------------
function OnSimulDispositionStarting()
EmtUnlinkAllRawPartsFromGroups()
if EMT.PHASE > 1 then
if IsStartOrRestPhase( EMT.PHASE) then
local ParkT = GetParkT()
EgtSetAxisPos( 'T', ParkT)
end
end
end
---------------------------------------------------------------------
function OnSimulDispositionStart()
EMT.OPEISDISP = true
-- Se prima disposizione
if EMT.PHASE == 1 then
-- Determino sezione del grezzo
local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL
local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
EMT.HB = 0
EMT.SB = 0
if b3Sol then
EMT.HB = b3Sol:getDimY()
EMT.SB = b3Sol:getDimZ()
end
-- Se vero inizio e abilitato creo gli Zmap
EMT.VMILL = {}
if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then
local nLastOrd = GetPhaseOrd( EgtGetPhaseCount())
local nPartRawId = EgtGetFirstRawPart()
while nPartRawId do
-- se è lo scarto finale tagliato a pezzi, esco
local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i')
if nRawOrd == nLastOrd + 1 then break end
-- elimino eventuale vecchio Zmap
EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL)
-- recupero il solido
local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid')
local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
-- aggiungo eventuale scrap successivo
if nRawOrd == nLastOrd then
local nScrapId = EgtGetNextRawPart( nPartRawId)
if nScrapId then
local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid')
local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD)
if b3ScrapRaw then
b3Raw:Add( b3ScrapRaw)
end
end
end
-- determino la risoluzione dello Zmap
local dTol = 4.71
if EmtGetVMillStep then
dTol = EmtGetVMillStep( b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol)
else
local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ()
if dArea < 0.075e6 then
dTol = 0.71
elseif dArea < 0.15e6 then
dTol = 1.01
elseif dArea < 0.3e6 then
dTol = 1.51
elseif dArea < 0.6e6 then
dTol = 1.97
elseif dArea < 1.2e6 then
dTol = 2.81
elseif dArea < 2.4e6 then
dTol = 3.77
end
end
dTol = min( dTol, EMT.VMILLTOL or dTol) -- imposto dTol al valore minore tra quello per volume e quello per spessore lama
-- creo lo Zmap
local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB)
if VMillId then
EgtSetName( VMillId, 'VMill')
EgtSetLevel( VMillId, GDB_LV.TEMP)
EgtSetColor( VMillId, EgtGetColor( nSolId), false)
-- nascondo le altre geometrie
local nId = EgtGetFirstInGroup( nPartRawId)
while nId do
if nId ~= VMillId then
EgtSetStatus( nId, GDB_ST.OFF)
end
nId = EgtGetNext( nId)
end
table.insert( EMT.VMILL, VMillId)
end
nPartRawId = EgtGetNextRawPart( nPartRawId)
end
end
end
-- Nascondo tutte le lavorazioni
local nMchId = EgtGetFirstOperation()
while nMchId do
if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then
EgtSetOperationStatus( nMchId, false)
end
nMchId = EgtGetNextOperation( nMchId)
end
-- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola
if IsStartOrRestPhase( EMT.PHASE) then
-- se fase inizio, segnalo giacitura del grezzo
if IsStartPhase( EMT.PHASE) then
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= 0 then
EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°')
else
EgtOutText( 'Barra non ruotata')
end
end
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1
local b3Raw = BBox3d()
local b3Bar = BBox3d()
local b3Part = BBox3d()
local nPartRawId, nScrapRawId
local nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
EmtLinkRawPartToGroup( nRawId, 'Tab')
local b3Tmp = EgtGetRawPartBBox( nRawId)
b3Bar:Add( b3Tmp)
local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i')
if nRawOrd == nOrd then
b3Raw:Add( b3Tmp)
b3Part:Add( b3Tmp)
nPartRawId = nRawId
elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then
b3Raw:Add( b3Tmp)
nScrapRawId = nRawId
end
end
nRawId = nNextRawId
end
-- gestione eventuale scarto affettato successivo
if EMT.VMILL and #EMT.VMILL > 0 then
EMT.SCRAP = nScrapRawId
EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF)
else
EMT.SCRAP = nil
end
EMT.LB = b3Bar:getDimX()
EMT.LR = b3Raw:getDimX()
EMT.LT = b3Part:getDimX()
EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0
EMT.Y1SPEC = nil
-- se vero inizio, assegno solidi per verifica collisione
if not EMT.SIM1ST then
EMT.CODET = {}
for i = 1, #EMT.MCODET do
EMT.CODET[i] = EMT.MCODET[i]
end
for i = 1, #( EMT.VMILL or {}) do
table.insert( EMT.CODET, EMT.VMILL[i])
end
end
-- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola
elseif IsMidPhase( EMT.PHASE) then
-- se cambiata giacitura, lo segnalo
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= nPrevRot then
if nRot ~= 0 then
EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°')
else
EgtOutText( 'Barra non ruotata')
end
end
-- eseguo aggancio
local nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
EmtLinkRawPartToGroup( nRawId, 'Tab')
end
nRawId = nNextRawId
end
-- se Vmill, nascondo eventuale scrap
if EMT.VMILL and #EMT.VMILL > 0 then
EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF)
end
-- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico
elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
-- se cambiata giacitura, lo segnalo
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= nPrevRot then
if nRot ~= 0 then
EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°')
else
EgtOutText( 'Barra non ruotata')
end
end
-- verifico posizione di carico
local ParkT = GetParkT()
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
-- ricerco vettore movimento per i successivi
local vtMove = Vector3d()
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then
vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
-- eseguo
local b3Bar = BBox3d()
nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then
EmtLinkRawPartToGroup( nRawId, 'Tab')
b3Bar = EgtGetRawPartBBox( nRawId)
else
EgtMove( nRawId, vtMove, GDB_RT.GLOB)
EgtSetStatus( nRawId, GDB_ST.OFF)
end
end
nRawId = nNextRawId
end
EMT.LB = b3Bar:getDimX()
-- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y
else
-- verifico posizione di carico
local ParkT = GetParkT()
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
-- ricerco vettore movimento per i successivi
local vtMove = Vector3d()
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then
vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
-- eseguo
local b3Bar = BBox3d()
nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then
EmtLinkRawPartToGroup( nRawId, 'Tab')
b3Bar = EgtGetRawPartBBox( nRawId)
else
EgtMove( nRawId, vtMove, GDB_RT.GLOB)
EmtLinkRawPartToGroup( nRawId, 'Y1')
end
end
nRawId = nNextRawId
end
EMT.LB = b3Bar:getDimX()
end
end
---------------------------------------------------------------------
function OnSimulDispositionEnd()
if EMT.UNLOADING or EMT.FALL then
ExecUnloading()
EMT.UNLOADING = false
EMT.FALL = false
EMT.TO_FALL = false
end
EMT.SPLIT = false
EMT.OPEISDISP = false
end
---------------------------------------------------------------------
function OnSimulToolSelect( dPosA)
-- se utensile non definito, è disposizione ed esco
if EMT.TOOL == '' then return end
-- recupero dati utensile
EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN)
EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
EMT.TUSERNOTES = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES)
-- recupero il gruppo
local nSetHead = GetHeadSet( EMT.HEAD)
-- se fresa o lama su testa 1, reset assi rotanti
if nSetHead == 1 then
-- se ho la testa 3, la mando a parcheggio
if IsHeadExisting( 3) then
EgtSetAxisPos( 'X3', ParkX3)
end
if EMT.HEAD == 'H12' or EMT.HEAD == 'H16' then
EgtSetAxisPos( 'Z1', MaxZ1Blade)
elseif EMT.HEAD == 'H13' then
EgtSetAxisPos( 'Z1', ParkCSawZ1)
else
EgtSetAxisPos( 'Z1', MaxZ1)
end
EgtResetAxisPos( 'C1')
EgtResetAxisPos( 'B1')
-- se testa 3 parcheggio la 1
elseif nSetHead == 3 then
EgtSetAxisPos( 'X1', ParkX1)
end
-- se sega a catena, imposto subito angolo scelto per asse virtuale A
if EMT.HEAD == 'H13' then
-- se prima lavorazione con motosega, parto dalla sua posizione di parcheggio
EgtSetAxisPos( 'X1', ParkCSawX1)
-- valore dell'asse virtuale
dPosA = dPosA or GetNextChainSawingVirtualAxis( EMT.MCHID)
-- imposto il valore di A
EgtSetAxisPos( 'A1', dPosA)
-- imposto home dell'asse C1 (A1=0 -> T101, A1=90 -> T104)
local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA, EMT.TTOTLEN)
EmtModifyAxisHome( 'C1', MyParkCSawC1)
EgtSetAxisPos( 'C1', MyParkCSawC1)
-- Imposto visualizzazione
EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD)
end
-- se aggregato foratura multipla, imposto subito angolo scelto per asse virtuale A
if EMT.HEAD == 'H14' then
-- valore dell'asse virtuale
dPosA = dPosA or GetNextMultiDrillVirtualAxis( EMT.MCHID)
-- imposto il valore di A
EgtSetAxisPos( 'A1', dPosA)
-- imposto home dell'asse C1 (A1=0 -> T121, A1=90 -> T124)
local MyParkCSawC1 = GetMultiDrillCHomeFromVirtualAxis( dPosA, EMT.TTOTLEN)
EmtModifyAxisHome( 'C1', MyParkCSawC1)
EgtSetAxisPos( 'C1', MyParkCSawC1)
-- Imposto visualizzazione
EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD)
end
-- se lama su aggregato da sotto, imposto subito angolo scelto per asse virtuale A
if EMT.HEAD == 'H22' then
-- se c'era un altro utensile, imposto subito asse virtuale
if EMT.PREVHEAD_H2 ~= 'H22' then
dPosA = dPosA or GetNextSawingVirtualAxis( EMT.MCHID)
end
if dPosA then
-- imposto il valore di A
EgtSetAxisPos( 'A2', dPosA)
-- imposto home dell'asse C1 (A2=0 -> T201, A2=90 -> T204)
local MyParkSawC2 = GetSawCHomeFromVirtualAxis( dPosA)
EmtModifyAxisHome( 'C2', MyParkSawC2)
EgtSetAxisPos( 'C2', MyParkSawC2)
-- Imposto visualizzazione
EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD)
end
end
-- carico utensile, con breve pausa
EgtPause( 100)
EgtOutText( '')
-- lo nascondo sul portautensili
ShowToolInTcPos( EMT.TCPOS, false)
-- dichiaro assi ausiliari da visualizzare
EMT.AuxAxes = 4
EMT.A1n = 'Y1'
EMT.A2n = 'Y2'
EMT.A3n = 'V1'
EMT.A4n = 'V2'
-- se utensile non flottante, abilito per Vmill
if not EMT.TFLOAT then
EmtSetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL)
end
-- se attivo Collision Check
EMT.SAFEDIST = COLL_SAFE_DIST
if EMT.COLLOBJ then
local nInd = EgtIf( nSetHead ~= 2, 1001, 1011)
AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd, true)
AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1)
for i, Coll in ipairs( EMT.COLLOBJ or {}) do
EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3)
end
end
end
---------------------------------------------------------------------
function OnSimulToolDeselect( dPrevA)
-- se prossimo utensile non cambia e non è sega a catena o lama su rinvio da sotto, esco
if ( EMT.NEXTTOOL == EMT.PREVTOOL_H1 or EMT.NEXTTOOL == EMT.PREVTOOL_H2) and ( EMT.NEXTHEAD ~= 'H13' or EMT.NEXTHEAD ~= 'H14') and ( EMT.NEXTHEAD ~= 'H22' or not dPrevA) then return end
-- deposito utensile
EgtOutText( 'Tool change in progress...')
-- recupero il gruppo attuale e il successivo
local nNextSetHead = GetHeadSet( EMT.NEXTHEAD)
local nSetHead = GetHeadSet( EMT.HEAD)
-- se devo deselezionare testa 3, la mando a parcheggio
if nSetHead == 3 then
SimulMoveAxis( 'X3', ParkX3, MCH_SIM_STEP.RAPID)
end
-- per testa gruppo 2
if nNextSetHead == 2 then
-- deposito lama su aggregato testa sotto
if EMT.PREVHEAD_H2 == 'H22' then
-- simulo movimento
local ParkC2 = EgtGetAxisHomePos( 'C2')
if dPrevA then
ParkC2 = GetSawCHomeFromVirtualAxis( dPrevA)
end
SimulMoveAxis( 'Z2', MinZ2, MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkSawB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT)
end
-- breve pausa
EgtPause( 100)
-- visualizzo utensile su TcPos
ShowToolInTcPos( EMT.PREVTCPOS_H2, true)
-- nascondo l'utensile sulla testa
EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H2 or '') or GDB_ID.NULL, GDB_MD.HIDDEN)
-- se testa gruppo 1
elseif nNextSetHead == 1 and EMT.PREVTCPOS_H1 then
-- deposito utensile fresa
if EMT.PREVHEAD_H1 == 'H11' then
-- simulo movimento
local nPrevTc = GetTcForTopHeadTool( EMT.PREVTCPOS_H1)
if EMT.PREVTTOTLEN_H1 < LongTool then
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
local dPosX = EgtIf( nPrevTc ~= 2, ParkTc1X1, ParkTc2X1)
SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID)
else
if nPrevTc ~= 2 then
SimulMoveAxes( 'B1', ParkLongB1, MCH_SIM_STEP.RAPROT, 'C1', ParkLongTc1C1, MCH_SIM_STEP.RAPROT)
local dPosX = ParkTc1X1
SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID)
else
SimulMoveAxes( 'B1', ParkLongB1, MCH_SIM_STEP.RAPROT, 'C1', ParkLongTc2C1, MCH_SIM_STEP.RAPROT)
local dPosX = ParkTc2X1
SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID)
end
end
-- deposito utensile lama
elseif EMT.PREVHEAD_H1 == 'H12' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkTc1X1, MCH_SIM_STEP.RAPID)
-- deposito utensile sega a catena
elseif EMT.PREVHEAD_H1 == 'H13' then
-- simulo movimento
local ParkC1 = EgtGetAxisHomePos( 'C1')
if dPrevA then
ParkC1 = GetChainSawCHomeFromVirtualAxis( dPrevA, EMT.TTOTLEN)
end
SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID)
-- deposito utensile aggregato foratore multiplo
elseif EMT.PREVHEAD_H1 == 'H14' then
-- simulo movimento
local ParkC1 = EgtGetAxisHomePos( 'C1')
if dPrevA then
ParkC1 = GetMultiDrillCHomeFromVirtualAxis( dPrevA)
end
-- simulo movimento
SimulMoveAxes( 'B1', ParkMultiDrillB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkMultiDrillX1, MCH_SIM_STEP.RAPID)
-- deposito utensile seconda lama
elseif EMT.PREVHEAD_H1 == 'H16' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkTc2X1, MCH_SIM_STEP.RAPID)
end
-- breve pausa
EgtPause( 100)
-- visualizzo utensile su TcPos
ShowToolInTcPos( EMT.PREVTCPOS_H1, true)
-- nascondo l'utensile sulla testa
EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN)
end
-- se passo da testa 1 a 3 scarico aggregato
if nNextSetHead == 3 then
-- deposito utensile prelevato da posizioni speciali
if EMT.PREVTCPOS_H1 == 'T101' or EMT.PREVTCPOS_H1 == 'T111' or EMT.PREVTCPOS_H1 == 'T121' then
-- visualizzo utensile su TcPos
ShowToolInTcPos( EMT.PREVTCPOS_H1, true)
-- nascondo l'utensile sulla testa
EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN)
local sTool, sTcPos, sHead
local vTools = EgtGetToolsInCurrSetupPos( DefTcPos1)
if vTools and vTools[1] then
sTool = vTools[1]
sTcPos = DefTcPos1
sHead = GetAdjHeadFromTcPos( 1, sTcPos)
-- carico l'utensile
EgtLoadTool( sHead, 1, sTool)
ShowToolInTcPos( DefTcPos1, false)
end
EMT.PREVTOOL_H1 = sTool
EMT.PREVHEAD_H1 = sHead
EMT.PREVTCPOS_H1 = DefTcPos1
end
SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID)
end
-- movimento per prendere nuovo utensile
-- prendo utensile fresa
if EMT.NEXTHEAD == 'H11' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
local dPosX = EgtIf( GetTcForTopHeadTool( EMT.NEXTTCPOS) ~= 2, ParkTc1X1, ParkTc2X1)
SimulMoveAxis( 'X1', dPosX, MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'Z1', MaxZ1, MCH_SIM_STEP.RAPID)
-- prendo utensile lama
elseif EMT.NEXTHEAD == 'H12' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkTc1X1, MCH_SIM_STEP.RAPID)
-- prendo utensile sega a catena
elseif EMT.NEXTHEAD == 'H13' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkCSawB1, MCH_SIM_STEP.RAPROT, 'C1', EgtGetAxisHomePos( 'C1'), MCH_SIM_STEP.RAPROT)
SimulMoveAxes( 'X1', ParkCSawX1, MCH_SIM_STEP.RAPID, 'Z1', ParkCSawZ1, MCH_SIM_STEP.RAPID)
-- prendo aggregato multi drill
elseif EMT.NEXTHEAD == 'H14' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkMultiDrillB1, MCH_SIM_STEP.RAPROT, 'C1', EgtGetAxisHomePos( 'C1'), MCH_SIM_STEP.RAPROT)
SimulMoveAxes( 'X1', ParkMultiDrillX1, MCH_SIM_STEP.RAPID, 'Z1', ParkMultiDrillZ1, MCH_SIM_STEP.RAPID)
-- prendo utensile seconda lama
elseif EMT.NEXTHEAD == 'H16' then
-- simulo movimento
SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X1', ParkTc2X1, MCH_SIM_STEP.RAPID)
-- prendo utensile su CU margherita testa sotto
elseif EMT.NEXTHEAD == 'H21' then
-- simulo movimento
SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.RAPROT, 'C2', ParkC2, MCH_SIM_STEP.RAPROT)
SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID)
-- prendo utensile lama su aggregato
elseif EMT.NEXTHEAD == 'H22' then
-- aggiungo utensile per verifica collisione
AddToolToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, 1011, false)
AddToolHolderToCollisionObj( EMT.NEXTTOOL, EMT.NEXTHEAD, EMT.NEXTEXIT, 1011 + 1)
-- simulo movimento
SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkSawB2, MCH_SIM_STEP.COLLROT, 'C2', ParkSawC2, MCH_SIM_STEP.COLLROT)
end
end
---------------------------------------------------------------------
function OnSimulMachiningStart()
-- se lavorazione è con gruppo a forare, abilito le altre punte alla lavorazione del VMILL
if EMT.HEAD == 'H14' then
local OtherTools = EgtGetToolsInCurrSetupPos( 'T121')
if OtherTools and #OtherTools > 1 then
for i = 1, #OtherTools do
if OtherTools[i] ~= '' and OtherTools[i] ~= EMT.TOOL then
EmtAddToolForVmill( OtherTools[i], 'H14', i, EMT.VMILL)
-- dichiaro utensile per verifica collisioni
local nInd = 1011
AddToolToCollisionObj( OtherTools[i], 'H14', i, nInd, true)
end
end
end
end
-- se lavorazione attuale e precedente con sega a catena o aggregato foratore multiplo e con angolo A diverso, devo scaricare e ricaricare
if ( EMT.HEAD == 'H13' or EMT.HEAD == 'H14') and EMT.HEAD == EMT.PREVHEAD_H1 then
local dPrevA = EgtGetAxisPos( 'A1')
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
local dPosA = tonumber( sVal:sub( 4))
if abs( dPosA - dPrevA) > 1 then
OnSimulToolDeselect( dPrevA)
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON)
OnSimulToolSelect( dPosA)
end
end
-- se lavorazione attuale e precedente con aggregato lama da sotto con angolo A diverso, devo scaricare e ricaricare
if EMT.HEAD == 'H22' and EMT.HEAD == EMT.PREVHEAD_H2 then
local dPrevA = EgtGetAxisPos( 'A2')
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
local dPosA = tonumber( sVal:sub( 4)) or 0
if abs( dPosA - dPrevA) > 1 then
ExecParkRoller( nil, nil, nil, nil, false, bAgg)
-- setto i valori per la funzione ToolDesel
EMT.NEXTHEAD = EMT.HEAD
EMT.NEXTTOOL = EMT.TOOL
EMT.NEXTEXIT = EMT.EXIT
OnSimulToolDeselect( dPrevA)
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON)
OnSimulToolSelect( dPosA)
-- aggiorno dati utensile su testa
EMT.TCPOSREAL = 'T' .. AdjustTcPos( false, EMT.TCPOS, dPosA)
EMT.PREVTCPOSREAL_H2 = EMT.TCPOSREAL
end
end
-- recupero alcuni dati della lavorazione
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not EMT.MCHUSERNOTES:find( 'VMRS=0;', 1, true))
EMT.MCHSPLIT = ( EMT.MCHUSERNOTES:find( 'Split;', 1, true) ~= nil)
-- recupero TASKID e CUTID della feature lavorata (CUTID va recuperato qui per le pareti)
local vId = EgtGetMachiningGeometry()
if vId and #vId > 0 and #vId[1] > 0 then
local nPartId = EgtGetParent( EgtGetParent( vId[1][1]) or GDB_ID.NULL)
EMT.CUTID = EgtGetInfo( nPartId or GDB_ID.NULL, 'CUTID', 'i') or 0
EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ;
else
EMT.CUTID = 0
EMT.TASKID = 0
end
-- gestione eventuale lavorazione in doppio
local nDouType = EgtGetValInNotes( EMT.MCHUSERNOTES, 'DOUBLE', 'i')
if nDouType == 2 or nDouType == 3 then
local sDouTool = EgtGetValInNotes( EMT.TUSERNOTES, 'DOUBLE', 's') or ''
local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
if EgtTdbSetCurrTool( sDouTool) and EgtTdbGetCurrToolParam( MCH_TP.ACTIVE) then
local sDouHead = 'H21'
local nDouExit = 1
-- carico l'utensile sulla testa
local sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS)
EgtLoadTool( sDouHead, nDouExit, sDouTool)
ShowToolInTcPos( sTcPos, false)
-- dichiaro utensile per Vmill
EmtAddToolForVmill( sDouTool, sDouHead, nDouExit, EMT.VMILL)
-- dichiaro utensile per verifica collisioni
local nInd = 1011
AddToolToCollisionObj( sDouTool, sDouHead, nDouExit, nInd, true)
AddToolHolderToCollisionObj( sDouTool, sDouHead, nDouExit, nInd + 1)
-- salvo dati
EMT.DOU_TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN)
EMT.DOU_TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
EMT.DOU_TYPE = nDouType
EMT.DOU_TOOL = sDouTool
-- reset necessità movimento in sicurezza sola testa in doppio
EMT.DOU_TO_ZMAX = nil
else
EmtSetLastError( 1211, 'Missing or not active double tool of '..sOldTool)
end
EgtTdbSetCurrTool( sOldTool)
else
-- recupero il gruppo
local nSetHead = GetHeadSet( EMT.HEAD)
if nSetHead ~= 1 and ( EMT.PREVTOOL_H1 and EMT.PREVHEAD_H1) then
local nPrevExit_H1 = 1
local nInd_H1 = 1001
AddToolToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1, true)
AddToolHolderToCollisionObj( EMT.PREVTOOL_H1, EMT.PREVHEAD_H1, nPrevExit_H1, nInd_H1 + 1)
end
if nSetHead ~= 2 and ( EMT.PREVTOOL_H2 and EMT.PREVHEAD_H2) then
local nPrevExit_H2 = 1
local nInd_H2 = 1011
AddToolToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2, true)
AddToolHolderToCollisionObj( EMT.PREVTOOL_H2, EMT.PREVHEAD_H2, nPrevExit_H2, nInd_H2 + 1)
end
if nSetHead ~= 3 and IsHeadExisting( 3) then
local nPrevExit_H3 = 1
local nInd_H3 = 1001
local sHeadName
if EgtGetHeadId( 'H39') then
sHeadName = 'H39'
elseif EgtGetHeadId( 'H38') then
sHeadName = 'H38'
else
EmtSetLastError( 1212, "HEAD not managed")
end
AddToolToCollisionObj( nil, sHeadName, nPrevExit_H3, 1001)
AddToolHolderToCollisionObj( nil, sHeadName, nPrevExit_H3, 1002)
end
end
-- se precedente in doppio ma ora solo testa 1 e non in sicurezza
if EMT.DOU_TO_ZMAX then
-- parcheggio i rulli
local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT')
ExecParkRoller( nil, nil, nil, nil, false, bAgg)
-- eseguo
if EMT.DOU_TO_ZMAX == 2 then
SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID)
end
SimulMoveAxes( 'Z2', MinZ2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID)
EMT.DOU_TO_ZMAX = nil
end
-- non ancora iniziata la lavorazione
EMT.MCHFIRST = true
end
---------------------------------------------------------------------
function OnSimulMachiningEnd()
if EMT.UNLOADING or EMT.FALL then
ExecUnloading()
EMT.UNLOADING = false
EMT.FALL = false
EMT.TO_FALL = false
end
EMT.MCHSPLIT = nil
EMT.SPLIT = nil
if EMT.DOU_TYPE and not EMT.ZMAX then EMT.DOU_TO_ZMAX = EMT.DOU_TYPE end
EMT.DOU_TYPE = nil
EMT.DOU_TOOL = nil
-- salvo dati utensile
local nSetHead = GetHeadSet( EMT.HEAD)
-- per gruppo testa 1
if nSetHead == 1 then
EMT.PREVTOOL_H1 = EMT.TOOL
EMT.PREVHEAD_H1 = EMT.HEAD
EMT.PREVTCPOS_H1 = EMT.TCPOS
EMT.PREVTTOTLEN_H1 = EMT.TTOTLEN
EMT.PREVTCPOSREAL_H1 = EMT.TCPOSREAL
-- per gruppo testa 2
elseif nSetHead == 2 then
EMT.PREVTOOL_H2 = EMT.TOOL
EMT.PREVHEAD_H2 = EMT.HEAD
EMT.PREVTCPOS_H2 = EMT.TCPOS
EMT.PREVTTOTLEN_H2 = EMT.TTOTLEN
EMT.PREVTCPOSREAL_H2 = EMT.TCPOSREAL
-- per gruppo testa 3
else
EMT.PREVTOOL_H3 = EMT.TOOL
EMT.PREVHEAD_H3 = EMT.HEAD
EMT.PREVTCPOS_H3 = EMT.TCPOS
EMT.PREVTTOTLEN_H3 = EMT.TTOTLEN
end
end
---------------------------------------------------------------------
function OnSimulPathStart()
-- se taglio di separazione, verifico se ci sarà caduta
if EMT.MCHSPLIT then
local sCmd = EgtGetInfo( EMT.PATHID, 'AE1') or ''
if sCmd:find( 'Fall', 1, true) then
EMT.TO_FALL = true
end
end
end
---------------------------------------------------------------------
function OnSimulPathEnd()
-- rimozione sfridi
ExecRemoveScraps()
-- se non ci sono comandi ausiliari associati e richiesta risalita a Zmax
if EMT.AUXTOT == 0 and EMT.TO_ZMAX then
if EMT.MCHSPLIT and not EMT.TO_FALL then
EMT.SPLIT_Y1DELTA = EMT.Y1DELTA
EMT.Y1DELTA = nil
ExecMovePY1( false)
end
ExecMoveZmax( EMT.MCHSPLIT)
EMT.TO_ZMAX = nil
end
end
---------------------------------------------------------------------
function OnSimulPathStartAux()
-- eseguo il comando
ExecAuxCmd( EMT.AUX, true)
-- se ultimo comando e lavorazione di split, sgancio il carro Y1
if EMT.AUXIND == EMT.AUXTOT and EMT.MCHSPLIT and not EMT.TO_FALL then
EMT.SPLIT_Y1DELTA = EMT.Y1DELTA
EMT.Y1DELTA = nil
ExecMovePY1( false)
end
end
---------------------------------------------------------------------
function OnSimulPathEndAux()
-- eseguo il comando
ExecAuxCmd( EMT.AUX, false)
-- se ultimo comando e richiesta risalita a Zmax
if EMT.AUXIND == EMT.AUXTOT and EMT.TO_ZMAX then
ExecMoveZmax( EMT.MCHSPLIT)
EMT.TO_ZMAX = nil
end
end
---------------------------------------------------------------------
function OnSimulMoveStart()
if EMT.MCHFIRST then EgtOutText( '') end
-- set della testa
local nSetHead = GetHeadSet( EMT.HEAD)
-- Posizioni correnti
local Y1Pos = EgtGetAxisPos( 'Y1')
local Y2Pos = EgtGetAxisPos( 'Y2')
local V1Pos = EgtGetAxisPos( 'V1')
local V2Pos = EgtGetAxisPos( 'V2')
-- Imposto movimento pinze e rulli insieme con la tavola :
EMT.AuxAxes = 4
-- pinze
EMT.A1n = 'Y1'
if EMT.Y1DELTA then
EMT.A1m = 'T'
EMT.A1 = EMT.L1 + EMT.Y1DELTA
else
EMT.A1m = nil
EMT.A1 = EgtIf( EMT.Y1SPEC, EgtGetAxisPos( 'Y1'), ParkY1)
end
EMT.A2n = 'Y2'
if EMT.Y2DELTA then
EMT.A2m = 'T'
EMT.A2 = EMT.L1 + EMT.Y2DELTA
else
EMT.A2m = nil
EMT.A2 = ParkY2
end
-- Controllo scorrimento pinze chiuse Y1 e Y2
if EMT.Y1DELTA then
local dY1DeltaP = Y1Pos - EMT.L1p
if abs( EMT.Y1DELTA - dY1DeltaP) > 0.1 then
EMT.ERR = 2
local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.Y1DELTA, 3)
EmtSetLastError( 1202, sErr)
end
end
if EMT.Y2DELTA then
local dY2DeltaP = Y2Pos - EMT.L1p
if abs( EMT.Y2DELTA - dY2DeltaP) > 0.1 then
EMT.ERR = 2
local sErr = 'Y2 slide : ' .. EgtNumToString( dY2DeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.Y2DELTA, 3)
EmtSetLastError( 1202, sErr)
end
end
-- rulli
EMT.A3n = 'V1'
EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1)
EMT.A4n = 'V2'
EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2)
local bParkV = false
if EMT.MCHFIRST then
-- se rulli più chiusi del richiesto o cambio direzione utensile (tranne solo asse B con C0 o equivalenti) devo mettere i rulli in parcheggio
if V1Pos < EMT.V1NEXTPOS - 1 or V2Pos > EMT.V2NEXTPOS + 1 or RollerParkingNeeded( EMT.HEAD, EMT.R1p, EMT.R2p, EMT.R1, EMT.R2) then
bParkV = true
EMT.A3 = ParkV1
EMT.A4 = ParkV2
end
end
-- Controllo corse assi ausiliari
VerifyY1Stroke( EMT.A1)
VerifyY2Stroke( EMT.A2)
VerifyV1Stroke( EMT.A3)
VerifyV2Stroke( EMT.A4)
-- se devo subito parcheggiare i rulli
local nRes = 0
if bParkV then
local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT')
nRes = ExecParkRoller( Y1Pos, Y2Pos, V1Pos, V2Pos, false, bAgg)
end
-- se movimento in rapido
if EMT.MOVE == 0 then
-- se testa 1
if nSetHead == 1 then
-- Dati
local B1Pos = EgtGetAxisPos( 'B1')
local B1Home = EgtGetAxisHomePos( 'B1')
local C1Pos = EgtGetAxisPos( 'C1')
local C1Home = EgtGetAxisHomePos( 'C1')
local Z1Pos = EgtGetAxisPos( 'Z1')
local Z1Home = EgtGetAxisHomePos( 'Z1')
local MyMaxZ1 = EgtGetAxisMax( 'Z1')
-- se fresa o lama
if EMT.HEAD ~= 'H13' then
-- se movimento iniziale da Zmax con lama o fresa
if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then
local bXSpec = EgtIf( BD.RIGHT_LOAD, EMT.L2 < DeltaTabY, EMT.L2 > DeltaTabY)
-- in caso di rotazione della lama lontano dalla posizione di home degli assi rotanti
if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( C1Pos - EMT.R1) > 1 or abs( B1Pos - EMT.R2) > 1) and ( abs( C1Home - EMT.R1) > 30.1 or abs( B1Home - EMT.R2) > 30.1) then
SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID)
-- se movimento di B > di 90°, spezza il movimento in 2 arrivando alla quota Z con B+-90 e poi muove l'ultimo segmento
-- evita collisione con carro X
if EMT.R2 > 91 or EMT.R2 < -91 then
local dBref = EgtClamp( EMT.R2, -91, 91)
SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', dBref, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT)
else
SimulMoveAxes( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT)
end
-- caso standard
else
-- se bisogna scrivere tutti gli assi
if WriteAllCoordsOnFirstM101 then
SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), MCH_SIM_STEP.RAPID)
end
-- se ero in posizione speciale, prima ruoto poi scendo
if bXSpec then
local dZPos = max( Z1Home, EMT.L3)
SimulMoveAxis( 'Z1', dZPos, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT, 'C1', EMT.R1, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID)
if abs( dZPos - EMT.L3) > 1 then
SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID)
end
else
SimulMoveAxis( 'Z1', EMT.L3, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B1', EMT.R2, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID)
end
end
end
-- altrimenti sega a catena
else
-- Porto la Z alla giusta quota
if Z1Pos > Z1Home + 1 and abs( B1Pos) > 89.9 then
SimulMoveAxis( 'X1', EMT.L2, MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'Z1', Z1Home, MCH_SIM_STEP.RAPID)
end
-- se movimento iniziale da Zmax
if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then
SimulMoveAxes( 'Z1', Z1Home, MCH_SIM_STEP.RAPID, 'B1', EMT.R2, MCH_SIM_STEP.COLLROT)
-- se motosega molto lunga, ruoto prima di muovermi in X
if EMT.TTOTLEN >= MinLengthLongCSaw then
SimulMoveAxis( 'C1', EMT.R1, MCH_SIM_STEP.COLLROT)
end
end
end
-- se altrimenti testa 2
elseif nSetHead == 2 then
local B2Home = EgtGetAxisHomePos( 'B2')
local C2Home = EgtGetAxisHomePos( 'C2')
local Z2Home = EgtGetAxisHomePos( 'Z2')
local X2Home = EgtGetAxisHomePos( 'X2')
local X2Pos = EgtGetAxisPos( 'X2')
local B2Pos = EgtGetAxisPos( 'B2')
local C2Pos = EgtGetAxisPos( 'C2')
-- calcolo posizione reale
EMT.TCPOSREAL = 'T' .. AdjustTcPos( false, EMT.TCPOS, EMT.R3)
-- se utensile cambiato (controllo il reale perchè per aggregato dipende come è stato caricato)
if EMT.PREVTCPOSREAL_H2 ~= EMT.TCPOSREAL then
if EMT.ZMAX then
-- se bisogna scrivere tutti gli assi
if WriteAllCoordsOnFirstM101 then
if EMT.HEAD == 'H22' then
SimulMoveAxes( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID, 'B2', 0, MCH_SIM_STEP.COLLROT, 'C2', C2Home, MCH_SIM_STEP.COLLROT)
X2Pos = ParkSawX2
else
SimulMoveAxes( 'X2', SafeX2, MCH_SIM_STEP.RAPID, 'B2', B2Home, MCH_SIM_STEP.COLLROT, 'C2', C2Home, MCH_SIM_STEP.COLLROT)
X2Pos = SafeX2
end
else
if EMT.HEAD == 'H22' then
SimulMoveAxis( 'X2', ParkSawX2, MCH_SIM_STEP.RAPID)
X2Pos = ParkSawX2
else
SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID)
X2Pos = SafeX2
end
end
SimulMoveAxis( 'Z2', Z2Home, MCH_SIM_STEP.RAPID)
-- Porto la X alla giusta quota
if X2Pos > SafeX2RotAxis and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then
SimulMoveAxis( 'X2', SafeX2RotAxis, MCH_SIM_STEP.RAPID)
end
end
else
-- solo se è macchina a 3 teste con gruppo truciolatore 4 assi, devo andare prima in Z0
if EgtGetHeadId( 'H39') then
SimulMoveAxis( 'Z2', Z2Home, MCH_SIM_STEP.RAPID)
end
-- Porto la X alla giusta quota
if EMT.ZMAX and X2Pos > SafeX2RotAxis and ( B2Pos ~= EMT.R2 or C2Pos ~= EMT.R1) then
SimulMoveAxis( 'X2', SafeX2RotAxis, MCH_SIM_STEP.RAPID)
end
end
if EMT.HEAD == 'H22' then
SimulMoveAxes( 'B2', EMT.R2, MCH_SIM_STEP.COLLROT, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT)
end
-- se ero a ZMAX, mi sposto in posizione a Z home. Ultimo movimento muove in Z
if EMT.ZMAX then
SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID, 'B2', EMT.R2, MCH_SIM_STEP.COLLROT, 'C2', EMT.R1, MCH_SIM_STEP.COLLROT)
end
-- altrimenti testa 3
else
-- testa 4 assi dedicata truciolatore
if EgtGetHeadId( 'H39') then
if EMT.ZMAX then
local MaxZ3 = EgtGetAxisMax( 'Z3')
SimulMoveAxes( 'X3', EMT.L2, MCH_SIM_STEP.RAPID, 'Z3', MaxZ3, MCH_SIM_STEP.RAPID)
end
SimulMoveAxis( 'Z3', EMT.L3, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B3', EMT.R2, MCH_SIM_STEP.COLLROT, 'C3', EMT.R1, MCH_SIM_STEP.COLLROT)
-- testa 5 assi dedicata lama
elseif EgtGetHeadId( 'H38') then
if EMT.ZMAX then
local B3Home = EgtGetAxisHomePos( 'B3')
local C3Home = EgtGetAxisHomePos( 'C3')
SimulMoveAxis( 'X3', SafeX3RotAxis, MCH_SIM_STEP.RAPID)
-- se non sono esattamente in home, devo ruotare in zona sicura
if abs( C3Home - EMT.R1) > 1 or abs( B3Home - EMT.R2) > 1 then
EMT.L3 = min( EMT.L3, SafeZ3RotAxis)
SimulMoveAxis( 'Z3', SafeZ3RotAxis, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B3', EMT.R2, MCH_SIM_STEP.COLLROT, 'C3', EMT.R1, MCH_SIM_STEP.COLLROT)
if ( EMT.L3 - SafeZ3RotAxis) > 100 * GEO.EPS_SMALL then
SimulMoveAxis( 'Z3', EMT.L3, MCH_SIM_STEP.RAPID)
end
SimulMoveAxis( 'X3', EMT.L2, MCH_SIM_STEP.RAPID)
end
end
-- si muovono tutti gli assi assieme
-- altre configurazioni
else
EmtSetLastError( 1212, "HEAD not managed")
end
end
end
-- se lavorazione split, muovo per riaggancio del carro Y1
if EMT.SPLIT_Y1DELTA then
EMT.Y1DELTA = EMT.SPLIT_Y1DELTA
EMT.A1 = EMT.L1 + EMT.Y1DELTA
end
-- se Zmax dopo fine lavorazione
if EMT.MOVE == 0 and EMT.FLAG == 3 then
-- demando movimento completo a MoveEnd
EMT.EnabAxes = false
EMT.ShowAxes = true
end
-- se lavorazione in doppio
if not ( EMT.MOVE == 0 and EMT.FLAG == 3) then
-- doppio in orizzontale
if EMT.DOU_TYPE == 2 then
-- se primo movimento, eseguo movimento rotatorio preliminare
if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then
SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'C2', EMT.R1, MCH_SIM_STEP.RAPROT, 'B2', EMT.R2, MCH_SIM_STEP.RAPROT)
else
EMT.AuxAxes = 4 + 4
EMT.A5n = 'X2'
local X2 = Delta2TabY + EMT.DOU_TLEN - ( -DeltaTabY + EMT.L2 + EMT.TLEN + EgtIf( BD.RIGHT_LOAD, -EMT.HB, EMT.HB))
if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then
EMT.DOU_DRILL_END = -( EMT.L2p - EMT.L2)
X2 = X2 + 2 * EMT.DOU_DRILL_END
end
EMT.A5 = X2
EMT.A5m = nil
EMT.A6n = 'Z2'
local Z2 = -Head2Z + MillOffs + Mill2Offs + EMT.L3
EMT.A6 = EgtClamp( Z2, MinZ2, MaxZ2)
-- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post
if not( EMT.MOVE == 0 and EMT.FLAG == 2) and Z2 > MaxZ2 then
local sErr = EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( dZ2-MaxZ2, 2)
EmtSetLastError( 1220, sErr, true)
EgtOutBox( sErr, 'ERROR')
end
EMT.A6m = EgtIf( ( EMT.MOVE == 2 or EMT.MOVE == 3), 'Z1', nil)
EMT.A7n = 'C2'
EMT.A7 = EMT.R1
EMT.A8n = 'B2'
EMT.A8 = EMT.R2
-- controllo minima distanza tra utensili di X1 e X2
local dDeltaX1X2 = EMT.L2 - EMT.A5 - Head2Y
local dDistToolX1X2 = -dDeltaX1X2 - MillOffs - EMT.TTOTLEN - Mill2Offs - EMT.DOU_TTOTLEN
if dDistToolX1X2 < MinDistToolX1X2 then
local sErr = 'X1 X2 tools in collision (distance=' .. EgtNumToString( dDistToolX1X2, 1) .. ')'
EmtSetLastError( 1208, sErr)
end
-- se appena sopra inizio, sistemo subito la quota in Z
if EMT.MOVE == 0 then
SimulMoveAxes( 'Z2', EMT.A6, MCH_SIM_STEP.RAPID)
end
end
-- doppio in verticale
elseif EMT.DOU_TYPE == 3 then
EMT.AuxAxes = 4 + 4
EMT.A5n = 'X2'
local X2 = -Head2Y + EMT.L2
EMT.A5 = X2
EMT.A5m = EgtIf( ( EMT.MOVE == 2 or EMT.MOVE == 3), 'X1', nil)
EMT.A6n = 'Z2'
local Z2 = Delta2TabZ - EMT.DOU_TLEN - ( -DeltaTabZ + EMT.L3 - EMT.TLEN - EMT.SB)
if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then
EMT.DOU_DRILL_END = EMT.L3p - EMT.L3
Z2 = Z2 - 2 * EMT.DOU_DRILL_END
end
-- dato che la testa 2 è slave, bisogna controllare eventuale extra-corsa da post
if not( EMT.MOVE == 0 and EMT.FLAG == 2) and Z2 < MinZ2 then
local sErr = EMT.MCHNAME..' ==> Out of Stroke: Z2 : '.. EgtNumToString( MinZ2-Z2, 2)
EmtSetLastError( 1220, sErr, true)
EgtOutBox( sErr, 'ERROR')
end
EMT.A6 = EgtClamp( Z2, MinZ2, MaxZ2)
EMT.A6m = nil
EMT.A7n = 'C2'
EMT.A7 = EMT.R1
EMT.A8n = 'B2'
EMT.A8 = EMT.R2
-- controllo minima distanza tra utensili di X1 e X2 (lungo Z)
local dDeltaZ1Z2 = EMT.L3 - EMT.A6 - Head2Z
local dDistToolZ1Z2 = dDeltaZ1Z2 - EMT.TTOTLEN - EMT.DOU_TTOTLEN
if dDistToolZ1Z2 < MinDistToolX1X2 then
local sErr = 'Z1 Z2 tools in collision (distance=' .. EgtNumToString( dDistToolZ1Z2, 1) .. ')'
EmtSetLastError( 1208, sErr)
end
end
end
-- se necessario ...
if EMT.MCHFIRST and EMT.EnabAxes ~= false then
if nSetHead == 1 then
SimulMoveAxes( 'X1', EMT.L2, MCH_SIM_STEP.RAPID,
'Z1', EMT.L3, MCH_SIM_STEP.RAPID,
'C1', EMT.R1, MCH_SIM_STEP.COLLROT,
'B1', EMT.R2, MCH_SIM_STEP.COLLROT)
if EMT.DOU_TYPE and EMT.AuxAxes == 8 then
SimulMoveAxes( 'X2', EMT.A5, MCH_SIM_STEP.RAPID,
'Z2', EMT.A6, MCH_SIM_STEP.RAPID,
'C2', EMT.A7, MCH_SIM_STEP.COLLROT,
'B2', EMT.A8, MCH_SIM_STEP.COLLROT)
end
elseif nSetHead == 2 then
SimulMoveAxes( 'X2', EMT.L2, MCH_SIM_STEP.RAPID,
'Z2', EMT.L3, MCH_SIM_STEP.RAPID,
'C2', EMT.R1, MCH_SIM_STEP.COLLROT,
'B2', EMT.R2, MCH_SIM_STEP.COLLROT)
else
SimulMoveAxes( 'X3', EMT.L2, MCH_SIM_STEP.RAPID,
'Z3', EMT.L3, MCH_SIM_STEP.RAPID,
'C3', EMT.R1, MCH_SIM_STEP.COLLROT,
'B3', EMT.R2, MCH_SIM_STEP.COLLROT)
end
end
if nRes ~= 0 then
EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1)
EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2)
end
EMT.ZMAX = nil
EMT.TO_ZMAX = nil
-- se aggregato flottante su inizio attacco va compresso
if EMT.TFLOAT and not EMT.TFLOAT_CMP and EMT.MOVE == 1 and EgtGetName( EMT.MOVEID) == 'LI' then
-- recupero lunghezza
local dOffsL = - EgtGetMachiningParam( MCH_MP.OFFSL)
-- imposto compressione della parte flottante
SetFloatPos( EMT.HEAD, dOffsL)
-- imposto dati utensile in posizione compressa
EmtSetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL, 2, -dOffsL)
-- dichiaro che è compresso (assegnando Id entità di movimento)
EMT.TFLOAT_CMP = EMT.MOVEID
end
end
---------------------------------------------------------------------
function OnSimulMoveEnd()
-- gruppo della testa
local nHSet = GetHeadSet( EMT.HEAD)
-- rimozione eventuali sfridi
if EMT.FLAG == 301 then
ExecRemoveScraps()
end
-- se primo rapido della lavorazione
if EMT.MCHFIRST and EMT.MOVE == 0 then
-- se lavorazione split, dichiaro carro Y1 riagganciato
if EMT.SPLIT_Y1DELTA then
EMT.SPLIT_Y1DELTA = nil
ExecMovePY1( true)
end
-- chiusura o apertura rulli V1
if GetV1ToClose() then
ExecCloseRoller( 1)
else
ExecOpenRoller( 1)
end
-- chiusura o apertura rulli V2
if GetV2ToClose() then
ExecCloseRoller( 2)
else
ExecOpenRoller( 2)
end
EMT.MCHFIRST = false
EgtOutText( '')
end
-- se movimento finale di foratura in doppio in Z
if EMT.MCHTYPE == MCH_MY.DRILLING and EMT.FLAG == 101 then
if EMT.DOU_TYPE == 2 then
SimulMoveAxes( 1, 'X1', EMT.L2 - 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED,
'X2', EMT.A5 - 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED)
SimulMoveAxes( 1, 'X1', EMT.L2 - EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED,
'X2', EMT.A5 - EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED)
elseif EMT.DOU_TYPE == 3 then
SimulMoveAxes( 1, 'Z1', EMT.L3 + 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED,
'Z2', EMT.A6 + 2 * EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED)
SimulMoveAxes( 1, 'Z1', EMT.L3 + EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED,
'Z2', EMT.A6 + EMT.DOU_DRILL_END, MCH_SIM_STEP.FEED)
end
end
-- se Zmax dopo fine lavorazione
if EMT.MOVE == 0 and EMT.FLAG == 3 then
-- eventuale rimozione sfridi
ExecRemoveScraps()
-- ricavo prossimo utensile
local sNextTool = GetNextTool( EMT.MCHID)
-- vado in home se è ultimo movimento ed è ultima lavorazione
local bToXhome = ( IsLastPath( EMT.PATHID) and not sNextTool and nHSet == 3) or EMT.HEAD == 'H38' or ( nHSet == 1 and EMT.TTOTLEN > LongTool)
-- eseguo
ExecMoveZmax( EMT.MCHSPLIT, bToXhome)
EMT.TO_ZMAX = nil
end
-- se utensile flottante e movimento di compressione
if EMT.TFLOAT and EMT.MOVEID == EMT.TFLOAT_CMP then
-- verifico ci sia stata collisione tra ghiera flottante (portautensile e pezzo)
if not EMT.TFLOAT_TH_COMPR_COLL then
local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Floating Ring not compressed on approach'
EmtSetLastError( 1222, sErr)
EgtOutLog( 'Error : ' .. sErr, 1)
else
EgtOutLog( 'Floating Ring compressed on approach (MOVEID='..EgtNumToString( EMT.MOVEID)..')', 1)
end
EMT.TFLOAT_TH_COMPR_COLL = nil
end
-- se aggregato flottante su fine uscita va rilasciato
if EMT.TFLOAT and EMT.TFLOAT_CMP and EMT.MOVE == 1 and EgtGetName( EMT.MOVEID) == 'LO' and EgtGetName( EgtGetNext( EMT.MOVEID) or GDB_ID.NULL) ~= 'LO' then
-- reset compressione della parte flottante
SetFloatPos( EMT.HEAD, 0)
-- dichiaro che è rilasciato
EMT.TFLOAT_CMP = nil
end
end
---------------------------------------------------------------------
function OnSimulCollision()
-- se prima collisione della lavorazione, la segnalo
if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then
-- speciale per utensile flottante (suo holder contro il grezzo)
if EMT.TFLOAT and EMT.TFLOAT_CMP and EMT.SIMCOBIND == 1002 and EMT.SIMVMID == EMT.VMILL[1] then
if EMT.MOVEID == EMT.TFLOAT_CMP then
EMT.TFLOAT_TH_COMPR_COLL = true
end
return
end
local Class = ''
if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then
Class = 'T_'..EMT.HEAD
elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then
Class = 'TH_'..EMT.HEAD
else
Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl
end
table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID})
EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME
EMT.ERR = 11
local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID
EmtSetLastError( 1221, sErr, true)
EgtOutLog( 'Collision : ' .. sErr, 1)
end
end
---------------------------------------------------------------------
function ExecAuxCmd( sCmd, bPathStart)
-- analizzo il comando
local Cmd = EgtSplitString( sCmd)
if Cmd[1] == '0' then
if Cmd[2] == 'Unloading' then
EMT.UNLOADING = true
elseif Cmd[2] == 'Split' then
EMT.SPLIT = true
elseif Cmd[2] == 'Fall' then
EMT.FALL = true
end
EgtOutText( Cmd[2])
elseif Cmd[1] == '1' then
if Cmd[2] ~= 'Z' then
ExecOpenRoller( 1)
ExecOpenRoller( 2)
local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd)
local bOk, bOk1, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID,
sV1, MoveV1, MCH_SIM_STEP.RAPID,
sV2, MoveV2, MCH_SIM_STEP.RAPID)
if not bOk then
if not bOk1 then
if VerifyY1Y2Stroke( Cmd[2], tonumber( Cmd[3])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
elseif not bOk2 then
VerifyV1V2Stroke( sV1, MoveV1)
elseif not bOk3 then
VerifyV1V2Stroke( sV2, MoveV2)
end
end
end
elseif Cmd[1] == '2' then
-- Verifico movimento carrello con trave agganciata
VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5])
-- Eseguo i movimenti necessari
ExecOpenRoller( 1)
ExecOpenRoller( 2)
local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd)
local bOk, bOk1, bOk2, bOk3, bOk4 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID,
Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID,
sV1, MoveV1, MCH_SIM_STEP.RAPID,
sV2, MoveV2, MCH_SIM_STEP.RAPID)
if not bOk then
if not bOk1 or not bOk2 then
local nI = EgtIf( not bOk1, 2, 4)
if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
elseif not bOk3 then
VerifyV1V2Stroke( sV1, MoveV1)
elseif not bOk4 then
VerifyV1V2Stroke( sV2, MoveV2)
end
end
elseif Cmd[1] == '3' then
-- Verifico movimento carrelli con trave agganciata
VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7])
-- Eseguo i movimenti necessari
ExecOpenRoller( 1)
ExecOpenRoller( 2)
local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd)
local bOk, bOk1, bOk2, bOk3, bOk4, bOk5 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID,
Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID,
Cmd[6], tonumber( Cmd[7]), MCH_SIM_STEP.RAPID,
sV1, MoveV1, MCH_SIM_STEP.RAPID,
sV2, MoveV2, MCH_SIM_STEP.RAPID)
if not bOk then
if not bOk1 or not bOk2 or not bOk3 then
local nI = EgtIf( not bOk1, 2, EgtIf( not bOk2, 4, 6))
if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
elseif not bOk4 then
VerifyV1V2Stroke( sV1, MoveV1)
elseif not bOk5 then
VerifyV1V2Stroke( sV2, MoveV2)
end
end
elseif Cmd[1] == '4' then
ExecMoveHome( Cmd[2] == '1', EgtIf( bPathStart, false, EMT.MCHSPLIT))
elseif Cmd[1] == '11' then
local bClose = Cmd[2] ~= '0'
if bPathStart and EMT.MCHSPLIT and not ( EMT.FALL or EMT.TO_FALL) and GetPY2Light() then bClose = false end
ExecMovePY1( bClose)
elseif Cmd[1] == '12' then
ExecMovePY2( Cmd[2] ~= '0')
elseif Cmd[1] == '21' then
local nY1Delta = tonumber( Cmd[2])
local nY2Delta = tonumber( Cmd[3])
EMT.Y1DELTA = EgtIf( nY1Delta > 0.01, nY1Delta, nil)
EMT.Y2DELTA = EgtIf( nY2Delta > 0.01, nY2Delta, nil)
elseif Cmd[1] == '22' then
EMT.V1NEXTPOS = tonumber( Cmd[2])
EMT.V2NEXTPOS = tonumber( Cmd[3])
elseif Cmd[1] == '31' then
local nRawId = tonumber( Cmd[2])
EmtUnlinkRawPartFromGroup( nRawId)
EmtLinkRawPartToGroup( nRawId, Cmd[3])
EMT.Y1SPEC = true
elseif Cmd[1] == '99' then
EMT.ERR = Cmd[2]
EmtSetLastError( 1200 + EMT.ERR, Cmd[3])
end
end
---------------------------------------------------------------------
function CalcMoveV1V2ForAuxCmd( Cmd)
-- verifico se necessario muovere V1
local MoveV1
local MoveY1 = GetCmdAxMove( Cmd, 'Y1')
local V1Pos = EgtGetAxisPos( 'V1')
if MoveY1 and V1Pos > MoveY1 - MinDeltaYV + 0.1 then
MoveV1 = MoveY1 - MinDeltaYV
end
local sV1 = EgtIf( MoveV1, 'V1', nil)
-- verifico se necessario muovere V2
local MoveV2
local MoveY2 = GetCmdAxMove( Cmd, 'Y2')
local V2Pos = EgtGetAxisPos( 'V2')
if MoveY2 and V2Pos < MoveY2 + MinDeltaYV - 0.1 then
MoveV2 = MoveY2 + MinDeltaYV
end
local sV2 = EgtIf( MoveV2, 'V2', nil)
-- restituisco i risultati
if MoveV1 and MoveV2 then
return sV1, MoveV1, sV2, MoveV2
elseif MoveV1 then
return sV1, MoveV1
elseif MoveV2 then
return sV2, MoveV2
end
end
---------------------------------------------------------------------
function ExecStartHome()
-- Testa 1
EgtResetAxisPos( 'X1')
EgtSetAxisPos( 'Z1', MaxZ1)
EgtResetAxisPos( 'C1')
EgtResetAxisPos( 'B1')
-- Testa 2
local _, sHead, _, _, _, _ = FindFirstToolOnHeadSet( 2)
local PosXStart = EgtIf( sHead == 'H22', SafeX2, ParkX2)
EgtSetAxisPos( 'X2', PosXStart)
EgtSetAxisPos( 'Z2', MinZ2)
EgtResetAxisPos( 'C2')
EgtResetAxisPos( 'B2')
end
---------------------------------------------------------------------
function ExecMoveHome( bNearV, bMchSplit)
-- risalita a Zmax
ExecMoveZmax( bMchSplit, true)
-- se testa sotto e macchina a 3 teste
if GetHeadSet( EMT.HEAD) == 2 and IsHeadExisting( 3) then
if not SimulMoveAxis( 'X2', EgtIf( EMT.HEAD == 'H22', SafeX2, ParkX2), MCH_SIM_STEP.RAPID) then
EgtOutLog( 'Error on MoveHome : X2')
end
-- se gruppo truciolatore a 4 assi
if EgtGetHeadId( 'H39') then
if not SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID) then
EgtOutLog( 'Error on MoveHome : Z2')
end
end
end
EMT.TO_ZMAX = nil
-- se richiesto, avvicino i rulli
if bNearV then
ExecOpenRoller( 1)
ExecOpenRoller( 2)
if not SimulMoveAxes( 'V1', MinV1, MCH_SIM_STEP.RAPID,
'V2', MaxV2, MCH_SIM_STEP.RAPID) then
EgtOutLog( 'Error on MoveHome : NearV1V2')
end
end
end
---------------------------------------------------------------------
function ExecMoveZmax( bMchSplit, bGoToHome)
-- set della testa
local nSetHead = GetHeadSet( EMT.HEAD)
-- posizioni correnti degli assi testa
local CurrX = EgtGetAxisPos( 'X'..nSetHead)
local CurrZ = EgtGetAxisPos( 'Z'..nSetHead)
local CurrC = EgtGetAxisPos( 'C'..nSetHead)
local CurrB = EgtGetAxisPos( 'B'..nSetHead)
-- posizioni home degli assi testa
local HomeX = EgtGetAxisHomePos( 'X'..nSetHead)
local HomeZ = EgtGetAxisHomePos( 'Z'..nSetHead)
local HomeC = EgtGetAxisHomePos( 'C'..nSetHead)
local HomeB = EgtGetAxisHomePos( 'B'..nSetHead)
-- verifico se necessario ruotare la testa
local bRot = ( abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1)
-- se necessario ruotare la testa, allargo i carrelli
if RollerParkingNeeded( EMT.HEAD, CurrC, CurrB, HomeC, HomeB) then
ExecOpenRoller( 1)
ExecOpenRoller( 2)
local bAgg = EgtExistsInfo( EMT.PATHID, 'CNT')
ExecParkRoller( nil, nil, nil, nil, bMchSplit, bAgg)
end
-- se testa sopra
if nSetHead == 1 then
local MyMaxZ1 = EgtGetAxisMax( 'Z1')
-- se fresa o lama
if EMT.HEAD ~= 'H13' then
if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then
local dZref = HomeZ + GetZExtra( EMT.HEAD, CurrB)
SimulMoveAxes( 'Z1', EgtIf( dZref > CurrZ, dZref, CurrZ), MCH_SIM_STEP.RAPID, 'B1', EgtClamp( CurrB, -90, 90), MCH_SIM_STEP.COLLROT)
if ( EMT.HEAD == 'H12' or EMT.HEAD == 'H16') and ( abs( HomeC - CurrC) > 30.1 or abs( HomeB - CurrB) > 30.1) then
SimulMoveAxes( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID, 'B1', 0, MCH_SIM_STEP.COLLROT)
end
if ( not BD.RIGHT_LOAD and EMT.L2 > DeltaTabY) or ( BD.RIGHT_LOAD and EMT.L2 < DeltaTabY) then
SimulMoveAxis( 'X1', DeltaTabY, MCH_SIM_STEP.RAPID)
end
SimulMoveAxis( 'C1', HomeC, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'B1', HomeB, MCH_SIM_STEP.COLLROT)
end
SimulMoveAxis( 'Z1', MyMaxZ1, MCH_SIM_STEP.RAPID)
if bGoToHome then
SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID)
end
-- altrimenti sega a catena
else
-- salgo in Z sicurezza raddrizzando la B
local SafeZ1 = EgtIf( EMT.TTOTLEN < MinLengthLongCSaw, ParkCSawZ1, ParkLongCSawZ1)
SimulMoveAxes( 'Z1', SafeZ1, MCH_SIM_STEP.RAPID, 'B1', HomeB, MCH_SIM_STEP.COLLROT)
SimulMoveAxes( 'X1', HomeX, MCH_SIM_STEP.RAPID, 'C1', HomeC, MCH_SIM_STEP.COLLROT)
end
-- se lavorazione in doppio
if EMT.DOU_TYPE == 2 then
SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID)
EMT.DOU_TO_ZMAX = nil
elseif EMT.DOU_TYPE == 3 then
SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID)
EMT.DOU_TO_ZMAX = nil
end
-- se altrimenti testa sotto
elseif nSetHead == 2 then
SimulMoveAxis( 'Z2', ParkZ2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B2', ParkB2, MCH_SIM_STEP.COLLROT, 'C2', ParkC2, MCH_SIM_STEP.COLLROT)
if EMT.HEAD == 'H22' then
SimulMoveAxis( 'X2', SafeX2, MCH_SIM_STEP.RAPID)
else
SimulMoveAxis( 'X2', ParkX2, MCH_SIM_STEP.RAPID)
end
-- solo se è macchina a 3 teste con gruppo truciolatore 4 assi, devo stare più alto
if EgtGetHeadId( 'H39') then
SimulMoveAxis( 'Z2', ParkInLavZ2, MCH_SIM_STEP.RAPID)
end
-- altrimenti testa 3
else
if EgtGetHeadId( 'H39') then
SimulMoveAxes( 'Z3', MaxZ3, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B3', ParkB3, MCH_SIM_STEP.COLLROT)
elseif EgtGetHeadId( 'H38') then
local MyMaxZ3 = EgtGetAxisMax( 'Z3')
-- se non sono esattamente in home, ruoto dove sono
if abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1 then
-- SimulMoveAxis( 'X3', SafeX3RotAxis, MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'Z3', SafeZ3RotAxis, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'C3', HomeC, MCH_SIM_STEP.COLLROT, 'B3', HomeB, MCH_SIM_STEP.COLLROT)
end
SimulMoveAxis( 'Z3', MyMaxZ3, MCH_SIM_STEP.RAPID)
if bGoToHome then
SimulMoveAxis( 'X3', ParkX3, MCH_SIM_STEP.RAPID)
end
else
EmtSetLastError( 1212, "HEAD not managed")
end
end
EMT.ZMAX = true
end
---------------------------------------------------------------------
function ExecUnloading()
if EMT.VMILL and #EMT.VMILL > 0 then
local vMillId = EMT.VMILL[1]
-- gruppo dei Vmill
local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill')
-- li sposto per lasciare spazio al nuovo pezzo
local nId = EgtGetFirstInGroup( nVmGrpId)
while nId do
EgtMove( nId, Vector3d( 0, EgtIf( BD.RIGHT_LOAD, ( EMT.HB + 50.0), -( EMT.HB + 50.0)), 0), GDB_RT.GLOB)
nId = EgtGetNext( nId)
end
-- creo un nuovo layer e vi inserisco il nuovo pezzo
local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId))
EgtRelocate( vMillId, nLayId)
local vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 1600, -1600), 0)
if EMT.FALL then vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 3200, -2600), -1150) end
EgtMove( nLayId, vtMove, GDB_RT.GLOB)
EgtSetLevel( vMillId, GDB_LV.USER)
-- aggiungo gli spigoli
if EgtVolZmapSetShowEdges then
EgtVolZmapSetShowEdges( vMillId, true)
else
local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId)
if nFirstId then
for nId = nFirstId, nFirstId + nCount - 1 do
EgtSetColor( nId, Color3d( 96, 96, 96))
end
end
end
-- rilascio Vmill
table.remove( EMT.VMILL, 1)
-- aggiorno la visualizzazione
EgtDraw()
-- se finito
if EMT.PHASE == EgtGetPhaseCount() then
-- se impostato di salvare i Vmill, lo faccio
local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini'
if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then
local sFile = EgtGetCurrFilePath()
if sFile then
local sDir, sName, sExt = EgtSplitPath( sFile)
sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup())
EgtSetLevel( nVmGrpId, GDB_LV.USER)
EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge')
EgtSetLevel( nVmGrpId, GDB_LV.TEMP)
end
end
end
end
end
---------------------------------------------------------------------
function CheckClamping( sClampName)
nIndexClamp = EgtGetAxisId( sClampName)
local idClampPath = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nIndexClamp, 'CLAMP_CHECK') or GDB_ID.NULL)
local b3ClampingArea = EgtGetBBoxGlob( idClampPath or GDB_ID.NULL, GDB_BB.STANDARD)
-- se non trovo percorso area di clamping, esco subito
if not idClampPath or not EMT.VMILL or not ClampingCoeffMin then
return
end
local function GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth)
local idCurveList = {}
local vtIntersPlane
-- piano di interpolazione
if sIntersPlane == 'X' then
vtIntersPlane = X_AX()
elseif sIntersPlane == 'Y' then
vtIntersPlane = Y_AX()
elseif sIntersPlane == 'Z' then
vtIntersPlane = Z_AX()
end
for i = 1, #EMT.VMILL do
local b3VMill = EgtGetBBoxGlob( EMT.VMILL[i], GDB_BB.EXACT)
local ptPosIntersPlane
if sPosIntersPlane == 'MIN' then
ptPosIntersPlane = b3VMill:getMin() + dDepth * vtIntersPlane
elseif sPosIntersPlane == 'MAX' then
ptPosIntersPlane = b3VMill:getMax() - dDepth * vtIntersPlane
end
local idLoop, nLoopCnt = EgtPlaneVolZmapInters( ptPosIntersPlane, vtIntersPlane, EMT.VMILL[i], CLAMP_CHECK_INTERS, GDB_RT.GLOB)
-- se c'è almeno una curva
if idLoop then
for j = 1, nLoopCnt do
local idLoopTemp = idLoop + j - 1
table.insert( idCurveList, idLoopTemp)
end
end
end
return idCurveList
end
local function CalculateIntersectionArea( sPosIntersPlane, sIntersPlane, dDepth)
-- test piano frontale
local idCurveList = GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth)
-- si copia curva intersezione e curva pinza in gruppo di confronto
local idFlatSurf, nFlatSurfCnt = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, idCurveList)
local idClampSurf = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, idClampPath)
if idFlatSurf then
local dTotalArea = 0
local dTotalXLenght = 0
for k = 1, nFlatSurfCnt do
local idTempSurf = idFlatSurf + k - 1
EgtSurfFrIntersect( idTempSurf, idClampSurf)
if idTempSurf then
dTotalArea = dTotalArea + ceil( EgtSurfArea( idTempSurf) or 0)
local b3BoxIntersectionBox = EgtGetBBoxGlob( idTempSurf, GDB_BB.STANDARD)
if b3BoxIntersectionBox then
dTotalXLenght = dTotalXLenght + ceil( b3BoxIntersectionBox:getDimX()) -- somma lunghezze (x) delle aree pinzate
end
end
end
return dTotalArea, dTotalXLenght
end
return 0
end
-- minima area considerata per un corretto pinzaggio
DistZClampToTable = DistZClampToTable or 0
local MinJoin = BD.GetMinJoin( EMT.HB, EMT.SB, EgtIf( EMT.SPLIT, EMT.LT, EMT.LB))
local MinZClamping = min( b3ClampingArea:getDimZ() + DistZClampToTable, EMT.SB) - DistZClampToTable
-- si moltiplica per un coefficiente minimo sotto al quale si da l'errore di pinzaggio
ClampingCoeffMin = EgtClamp( ClampingCoeffMin, 0.01, 1)
local dMinClampingAreaWarn = ( MinJoin * MinZClamping) * ClampingCoeffMin
local dMinClampingAreaErr = ( MinJoin * MinZClamping) * ( ClampingCoeffMin / 3)
local bError = true
local sWrn, sErr
local bWriteWarnMessage = false
local bWriteErrMessage = false
-- controllo faccia frontale
local dArea, dXClampedLenght = CalculateIntersectionArea( 'MIN', 'Y', 3)
-- ERRORE: pinza troppo poco (meno di 1/3 del minimo richiesto)
if dArea and dArea < dMinClampingAreaErr then
-- solo se pinza almeno 1cm2, e la somma della lunghezza pinzata è maggiore della lunghezza minima pinzabile da Warning e non errore
if dXClampedLenght >= MinJoin * ClampingCoeffMin and dArea > 1000 then
bError = false
end
-- pinzaggio non fattibile, errore
if bError then
sErr = 'ERROR CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)'
bWriteErrMessage = true
end
end
-- WARNING: pinza meno del minimo richiesto
if dArea and dArea < dMinClampingAreaWarn and not bWriteErrMessage then
sWrn = 'WARNING CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)'
bWriteWarnMessage = true
end
EgtEmptyGroup( CLAMP_CHECK_GROUP)
EgtEmptyGroup( CLAMP_CHECK_INTERS)
-- controllo altro lato solo se non sono già in errore
if not bWriteErrMessage then
-- controllo faccia posteriore
dArea = CalculateIntersectionArea( 'MAX', 'Y', 3)
-- ERRORE: pinza troppo poco (meno di 1/3 del minimo richiesto)
if dArea and dArea < dMinClampingAreaErr then
-- solo se pinza almeno 1cm2, e la somma della lunghezza pinzata è maggiore della lunghezza minima pinzabile da Warning e non errore
if dXClampedLenght >= MinJoin * ClampingCoeffMin and dArea > 1000 then
bError = false
end
-- pinzaggio non fattibile, errore
if bError then
sErr = 'ERROR CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)'
bWriteErrMessage = true
end
end
-- WARNING: pinza meno del minimo richiesto
if dArea and dArea < dMinClampingAreaWarn and not bWriteWarnMessage and not bWriteErrMessage then
sWrn = 'WARNING CLAMPING ' .. sClampName .. ' : '..tostring( ceil( ( dArea / dMinClampingAreaWarn) * 100))..'% ( '.. tostring( dArea/1000)..'cm2)'
bWriteWarnMessage = true
end
EgtEmptyGroup( CLAMP_CHECK_GROUP)
EgtEmptyGroup( CLAMP_CHECK_INTERS)
end
if bWriteErrMessage then
EmtSetLastError( 1213, sErr, EgtGetEnableUI())
EgtOutBox( sErr, 'CLAMPING', 'ERROR', 'OK')
EmtSetSimulPause()
elseif bWriteWarnMessage then
EgtOutLog( sWrn)
EgtOutBox( sWrn, 'CLAMPING', 'WARNING', 'OK')
EmtSetSimulPause()
end
end
---------------------------------------------------------------------
function ExecMovePY1( bClose)
SimulMoveAxes( 'PY1', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID)
SetPY1Light( bClose)
if bClose then
CheckClamping( 'PY1')
end
end
---------------------------------------------------------------------
function ExecMovePY2( bClose)
SimulMoveAxes( 'PY2', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID)
SetPY2Light( bClose)
if bClose then
CheckClamping( 'PY2')
end
end
---------------------------------------------------------------------
local function LinkRemainingPartsToY1()
local nCurrOrd = GetPhaseOrd( EMT.PHASE)
local TabId = EgtGetTableId( 'Tab')
local RawId = EgtGetFirstInGroup( TabId)
while RawId do
local NextRawId = EgtGetNext( RawId)
if EgtGetName( RawId) == 'RawPart' then
local nRawOrd = EgtGetInfo( RawId, 'ORD', 'i')
if nRawOrd and nRawOrd ~= nCurrOrd then
local bUlOk = EmtUnlinkRawPartFromGroup( RawId)
local bLkOk = EmtLinkRawPartToGroup( RawId, 'Y1')
end
end
RawId = NextRawId
end
end
---------------------------------------------------------------------
function ExecParkRoller( PosY1, PosY2, PosV1, PosV2, bSpliCut, bAgg)
-- Posizioni
local PosT = EgtGetAxisPos( 'T')
PosY1 = PosY1 or EgtGetAxisPos( 'Y1')
PosY2 = PosY2 or EgtGetAxisPos( 'Y2')
PosV1 = PosV1 or EgtGetAxisPos( 'V1')
PosV2 = PosV2 or EgtGetAxisPos( 'V2')
-- Parcheggi pinze
local MyParkY1 = ParkY1 + EgtIf( bAgg, AggLoad, 0)
local MyParkY2 = ParkY2
-- Apro i rulli, se necessario
if abs( ParkV1 - PosV1) > 0.1 then ExecOpenRoller( 1) end
if abs( ParkV2 - PosV2) > 0.1 then ExecOpenRoller( 2) end
-- Eseguo spostamenti
if EMT.Y1DELTA and EMT.Y2DELTA then
local DiffY1 = MyParkY1 - PosY1
local DiffY2 = MyParkY2 - PosY2
-- se appena eseguito taglio di separazione
if bSpliCut then
-- aggancio i pezzi rimanenti all'asse Y1
LinkRemainingPartsToY1()
-- eseguo i movimenti
if not SimulMoveAxes( 'T', PosT + min( DiffY2, 0.0), MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', PosY1 + max( DiffY1, 0.0), MCH_SIM_STEP.RAPID,
'Y2', PosY2 + min( DiffY2, 0.0), MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12A)')
end
return 32
elseif DiffY1 > 0.1 and DiffY2 < -0.1 then
EMT.ERR = 2
EmtSetLastError( 1201, 'Error Collision in ParkRoller')
elseif DiffY1 > 0.1 then
if not SimulMoveAxes( 'T', PosT + DiffY1, MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', PosY1 + DiffY1, MCH_SIM_STEP.RAPID,
'Y2', PosY2 + DiffY1, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12B)')
end
return 12
elseif DiffY2 < -0.1 then
if not SimulMoveAxes( 'T', PosT + DiffY2, MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', PosY1 + DiffY2, MCH_SIM_STEP.RAPID,
'Y2', PosY2 + DiffY2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1203, 'Error on MoveAxes in ParkRoller (12C)')
end
return 21
else
if not SimulMoveAxes( 'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1204, 'Error on MoveAxes in MoveStart')
end
return 30
end
elseif EMT.Y1DELTA then
local MoveV1 = ParkV1 - PosV1
local DiffY1 = MyParkY1 - PosY1
local MoveY1 = EgtIf( DiffY1 > 0.1, MoveV1, 0)
local TryMoveY1 = min( ParkV1 - PosT - EgtIf( bSpliCut or EMT.FALL, EMT.LT, 0), MaxY1 - PosY1 - 10)
if ( PosT > ParkV2 - ExtraParkV and PosT < ParkV1 and PosY1 + TryMoveY1 < MaxY1) then MoveY1 = max( MoveY1, TryMoveY1) end
-- se appena eseguito taglio di separazione
if bSpliCut then
-- aggancio i pezzi rimanenti all'asse Y1
LinkRemainingPartsToY1()
-- eseguo movimenti
if not SimulMoveAxes( 'T', PosT, MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', PosY1 + MoveY1, MCH_SIM_STEP.RAPID,
'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)')
end
else
if not SimulMoveAxes( 'T', PosT + MoveY1, MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', PosY1 + MoveY1, MCH_SIM_STEP.RAPID,
'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)')
end
end
return 11
elseif EMT.Y2DELTA then
local MoveV2 = ParkV2 - PosV2
local DiffY2 = MyParkY2 - PosY2
local MoveY2 = EgtIf( DiffY2 < -0.1, MoveV2, 0)
local TryMoveY2 = max( ParkV2 - PosT - EMT.LT, MinY2 - PosY2 + 10)
if ( PosT + EMT.LT < ParkV1 + ExtraParkV and PosT + EMT.LT > ParkV2 and PosY2 + TryMoveY2 > MinY2) then MoveY2 = min( MoveY2, TryMoveY2) end
if not SimulMoveAxes( 'T', PosT + MoveY2, MCH_SIM_STEP.RAPID,
'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', EgtIf( PosY1 > MyParkY1, PosY1, MyParkY1), MCH_SIM_STEP.RAPID,
'Y2', PosY2 + MoveY2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1206, 'Error on MoveAxes in ParkRoller (2)')
end
return 22
else
if not SimulMoveAxes( 'V1', ParkV1, MCH_SIM_STEP.RAPID,
'V2', ParkV2, MCH_SIM_STEP.RAPID,
'Y1', MyParkY1, MCH_SIM_STEP.RAPID,
'Y2', MyParkY2, MCH_SIM_STEP.RAPID) then
EMT.ERR = 2
EmtSetLastError( 1207, 'Error on MoveAxes in ParkRoller (0)')
end
return 0
end
end
---------------------------------------------------------------------
function ExecCloseRoller( nInd)
EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), EMT.HB)
EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), EMT.SB)
end
---------------------------------------------------------------------
function ExecOpenRoller( nInd)
EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), MaxHoOpen)
EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), MaxVeOpen)
end
---------------------------------------------------------------------
function ExecRemoveScraps()
-- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi
if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then
local vMillId = EMT.VMILL[1]
local nPart = EgtVolZmapPartCount( vMillId)
if nPart > 1 then
-- ricerca del pezzo con massimo volume
local dTCenX = -EgtGetAxisPos( 'T') - EMT.LT / 2
local nPartMax = 0
local dVolMax = 0
for i = 1, nPart do
local dVol = EgtVolZmapPartVolume( vMillId, i - 1)
if dVol > dVolMax then
local b3VmPart = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD)
if b3VmPart and b3VmPart:getMax():getX() > dTCenX and b3VmPart:getMin():getX() < dTCenX then
dVolMax = dVol
nPartMax = i
end
end
end
-- eliminazione di tutti i pezzi piccoli
for i = nPart, 1, -1 do
if i ~= nPartMax then
EgtRemoveVolZmapPart( vMillId, i - 1)
end
end
-- aggiorno visualizzazione
EgtDraw()
end
EMT.VMRS = false
end
end
---------------------------------------------------------------------
function VerifyY1Slide( sName1, dVal1, sName2, dVal2)
-- Se movimento trave agganciata con carrello Y1
if sName1 == 'T' and sName2 == 'Y1' and GetPY1Light() then
local dY1DeltaP = EgtGetAxisPos( 'Y1') - EgtGetAxisPos( 'T')
local dY1DeltaA = tonumber( dVal2) - tonumber( dVal1)
EgtOutLog( string.format( 'Y1DeltaP=%.3f Y1DeltaA=%.3f', dY1DeltaP, dY1DeltaA), 5)
if abs( dY1DeltaA - dY1DeltaP) > 0.5 then
EMT.ERR = 2
local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( dY1DeltaA, 3)
EmtSetLastError( 1202, sErr)
end
end
-- Tutto bene
return true
end
---------------------------------------------------------------------
function VerifyY2Slide( sName1, dVal1, sName2, dVal2)
-- Se movimento trave agganciata con carrello Y2
if sName1 == 'T' and sName2 == 'Y2' and GetPY2Light() then
local dY2DeltaP = EgtGetAxisPos( 'Y2') - EgtGetAxisPos( 'T')
local dY2DeltaA = tonumber( dVal2) - tonumber( dVal1)
EgtOutLog( string.format( 'Y2VDeltaP=%.3f Y2DeltaA=%.3f', dY2DeltaP, dY2DeltaA), 5)
if abs( dY2DeltaA - dY2DeltaP) > 0.5 then
EMT.ERR = 2
local sErr = 'Y2 slide : ' .. EmtLenToString( dY2DeltaP, 3) .. ' -> ' .. EmtLenToString( dY2DeltaA, 3)
EmtSetLastError( 1202, sErr)
end
end
-- Tutto bene
return true
end
---------------------------------------------------------------------
function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2)
-- Metto in prima posizione la trave
if sName2 == 'T' then
sName1, sName2 = sName2, sName1
dVal1, dVal2 = dVal2, dVal1
end
-- Eseguo verifica
if sName2 == 'Y1' then
return VerifyY1Slide( sName1, dVal1, sName2, dVal2)
elseif sName2 == 'Y2' then
return VerifyY2Slide( sName1, dVal1, sName2, dVal2)
end
return true
end
---------------------------------------------------------------------
function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3)
-- Metto in prima posizione la trave
if sName2 == 'T' then
sName1, sName2 = sName2, sName1
dVal1, dVal2 = dVal2, dVal1
elseif sName3 == 'T' then
sName1, sName3 = sName3, sName1
dVal1, dVal3 = dVal3, dVal1
end
-- Eseguo verifica
if sName2 == 'Y1' then
return VerifyY1Slide( sName1, dVal1, sName2, dVal2) and VerifyY2Slide( sName1, dVal1, sName3, dVal3)
elseif sName2 == 'Y2' then
return VerifyY2Slide( sName1, dVal1, sName2, dVal2) and VerifyY1Slide( sName1, dVal1, sName3, dVal3)
end
return true
end
---------------------------------------------------------------------
function VerifyY1Stroke( dY1)
if dY1 < MinY1 then
EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MinY1, ' (L1-)')
EMT.ERR = 1
local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MinY1, 3)
EgtOutLog( sErr)
return false
elseif dY1 > MaxY1 then
EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MaxY1, ' (L1+)')
EMT.ERR = 1
local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MaxY1, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyY2Stroke( dY2)
if dY2 < MinY2 then
EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MinY2, ' (L1-)')
EMT.ERR = 1
local sErr = 'Y2 axis outstroke ' .. EgtNumToString( dY2 - MinY2, 3)
EgtOutLog( sErr)
return false
elseif dY2 > MaxY2 then
EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MaxY2, ' (L1+)')
EMT.ERR = 1
local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY2 - MaxY2, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyY1Y2Stroke( sName, dVal)
if sName == 'Y1' then
return VerifyY1Stroke( dVal)
elseif sName == 'Y2' then
return VerifyY2Stroke( dVal)
else
return nil
end
end
---------------------------------------------------------------------
function VerifyV1Stroke( dV1)
if dV1 < MinV1 then
EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MinV1, ' (L1-)')
EMT.ERR = 1
local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MinV1, 3)
EgtOutLog( sErr)
return false
elseif dV1 > MaxV1 then
EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MaxV1, ' (L1+)')
EMT.ERR = 1
local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MaxV1, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyV2Stroke( dV2)
if dV2 < MinV2 then
EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MinV2, ' (L1-)')
EMT.ERR = 1
local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MinV2, 3)
EgtOutLog( sErr)
return false
elseif dV2 > MaxV2 then
EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MaxV2, ' (L1+)')
EMT.ERR = 1
local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MaxV2, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyV1V2Stroke( sName, dVal)
if sName == 'V1' then
return VerifyV1Stroke( dVal)
elseif sName == 'V2' then
return VerifyV2Stroke( dVal)
else
return nil
end
end
---------------------------------------------------------------------
function GetV1ToClose()
--EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB))
--EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0))
return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax)
end
---------------------------------------------------------------------
function GetV2ToClose()
--EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB))
--EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0))
return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin)
end
---------------------------------------------------------------------
function ShowToolInTcPos( sTcPos, bShow)
-- recupero identificativo della posizione sul TC
local TcPosId = EgtGetTcPosId( sTcPos or '')
if not TcPosId then return end
-- ciclo sulle possibili uscite
for i = 1, 100 do
-- recupero il gruppo dell'utensile
local TcExitId = EgtGetFirstNameInGroup( TcPosId, 'T'..tostring( i))
if not TcExitId then break end
-- imposto lo stato di visualizzazione
EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF))
end
-- recupero eventuale gruppo ausiliario da visualizzare/nascondere
local TcHSId = EgtGetFirstNameInGroup( TcPosId, sTcPos..'_HS')
if TcHSId then EgtSetStatus( TcHSId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) end
end
---------------------------------------------------------------------
function LoadFirstTool( nHSet, sTcPosDef)
if nHSet ~= 1 and nHSet ~= 2 then return end
EgtUnloadTool( EgtIf( nHSet == 1, 'H11', 'H21'), 1)
if GetHeadSetFromTcPos( sTcPosDef) ~= nHSet then return end
local sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis = FindFirstToolOnHeadSet( nHSet)
-- se primo utensile motosega, non lo carico e visualizzo quello di default
if sHead == 'H13' then
sTool = nil
end
if not sTool then
local vTools = EgtGetToolsInCurrSetupPos( sTcPosDef)
if vTools and vTools[1] then
sTool = vTools[1]
sTcPos = sTcPosDef
sHead = GetAdjHeadFromTcPos( nHSet, sTcPos)
end
end
if sTool then
-- imposto correttamente i dati di testa
local OrigEMC = EMC
EMC = { HEAD = sHead, TOOL = sTool, TCPOS = sTcPos, TOTLEN = sTTotLen, TOTDIAM = sTotDiam, BLOCKEDAXIS = sBlockedAxis}
OnSetHead()
EMC = OrigEMC
if sBlockedAxis then
local dPosA = tonumber( sBlockedAxis:sub( 4) or '') or 0
if dPosA ~= 0 then
-- imposto il valore di A
EgtSetAxisPos( EgtIf( nHSet == 1 , 'A1', 'A2'), dPosA)
end
end
-- carico l'utensile
EgtLoadTool( sHead, 1, sTool)
ShowToolInTcPos( sTcPos, false)
-- salvo utensili caricati
if nHSet == 1 then
EMT.PREVTOOL_H1 = sTool
EMT.PREVHEAD_H1 = sHead
EMT.PREVTCPOS_H1 = sTcPos
EMT.PREVTTOTLEN_H1 = sTTotLen
-- per gruppo testa 2
elseif nHSet == 2 then
EMT.PREVTOOL_H2 = sTool
EMT.PREVHEAD_H2 = sHead
EMT.PREVTCPOS_H2 = sTcPos
EMT.PREVTTOTLEN_H2 = sTTotLen
end
end
return sTool
end
---------------------------------------------------------------------
-- *** ESTIMATION T&L ***
---------------------------------------------------------------------
local ESTIMATION_RAPID_COEFF = EstimationRapidMultiplier or 1
local RAPID_X_FEED = 70000 / ESTIMATION_RAPID_COEFF -- mm/min
local RAPID_Y_FEED = 100000 / ESTIMATION_RAPID_COEFF -- mm/min
local RAPID_Z_FEED = 32000 / ESTIMATION_RAPID_COEFF -- mm/min
local RAPID_C_FEED = 15000 / ESTIMATION_RAPID_COEFF -- deg/min
local RAPID_B_FEED = 15000 / ESTIMATION_RAPID_COEFF -- deg/min
local RAPID_MIN_T = 0.1 * ESTIMATION_RAPID_COEFF -- s
local LOAD_T = 2 * ESTIMATION_RAPID_COEFF -- s
local CHAR_ONE_MOVE_T = 1 * ESTIMATION_RAPID_COEFF -- s
local ROTATION_T = 40 * ESTIMATION_RAPID_COEFF -- s
local SPLIT_T = 6 * ESTIMATION_RAPID_COEFF -- s
local UNLOAD_T = 4 * ESTIMATION_RAPID_COEFF -- s
local FALL_T = 2 * ESTIMATION_RAPID_COEFF -- s
---------------------------------------------------------------------
function OnEstimStart()
EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches
EMT.FMAXPINZE = EgtClamp( MaxFeedPinze or 116000, 20000, 130000) -- feed massima pinze
EMT.MAXACC = MaxAcc or 6000 -- accelerazione massima pinze. In realtà è il tempo in millisecondi, quindi MAXACC corrisponde al tempo massimo per raggiungere la velocità desiderata
EMT.MINACC = MinAcc or 600 -- accelerazione minima pinze. In realtà è il tempo in millisecondi, quindi MINACC corrisponde al tempo massimo per raggiungere la velocità desiderata
end
---------------------------------------------------------------------
function OnEstimEnd()
end
---------------------------------------------------------------------
function OnEstimProgramStart()
-- imposto inizio movimenti da Home
EMT.L1 = EgtGetAxisHomePos( 'T')
EMT.L2 = EgtGetAxisHomePos( 'X1')
EMT.L3 = EgtGetAxisHomePos( 'Z1')
EMT.R1 = EgtGetAxisHomePos( 'C1')
EMT.R2 = EgtGetAxisHomePos( 'B1')
-- aggiorno valori come precedenti
EmtUpdatePrev()
-- totalizzatori tempi e lunghezze
EMT.TOTCUTLEN = 0
EMT.TOTCUTTIME = 0
EMT.TOTEXTLEN = 0
EMT.TOTEXTTIME = 0
-- variabile per lunghezza taglio utensili
EMT.TOOLCUTLEN = {}
-- intestazioni
EmtTleStart( EMT.INFO)
end
---------------------------------------------------------------------
function OnEstimProgramEnd()
-- stampa dei totali delle lavorazioni
EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN))
-- stampa dei totali degli utensili
for i = 1, #EMT.TOOLCUTLEN do
local TCL = EMT.TOOLCUTLEN[i]
EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len))
end
-- completo il file
local _, _, sExt = EgtSplitPath( EMT.FILE)
EmtTleEnd( sExt:sub( 2))
-- salvo i dati principali nel progetto
EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0))
EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0))
end
---------------------------------------------------------------------
function OnEstimDispositionStart()
-- inizio disposizione
EMT.OPEISDISP = true
-- sulla prima fase dichiaro carico barra
if EMT.PHASE == 1 then
EMT.LOAD = true
else
EMT.LOAD = false
end
end
---------------------------------------------------------------------
function OnEstimDispositionEnd()
-- Se disposizione inizio o rimanenza
if IsStartOrRestPhase( EMT.PHASE) then
;
-- se altrimenti disposizione intermedia, eventuale rotazione
elseif IsMidPhase( EMT.PHASE) then
-- recupero le rotazioni delle fasi corrente e precedente
local nRot = GetPhaseRot( EMT.PHASE)
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
-- verifico se sono diverse
if nRot ~= nPrevRot then
-- imposto stato post-rotazione
EMT.POSTROT = true
end
-- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni
else
;
end
-- emetto dati in sospeso
if EMT.TLE_NAME then
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
EMT.TLE_NAME = nil
EMT.TLE_TIME = nil
end
-- termine disposizione
EMT.OPEISDISP = false
end
---------------------------------------------------------------------
function OnEstimRawMoveData()
-- se start del pezzo
if IsStartOrRestPhase( EMT.PHASE) then
EMT.SPLIT = false
end
OnRawMoveData()
end
---------------------------------------------------------------------
function OnEstimToolSelect()
-- reset indice utensile in tabella lunghezze
EMT.TCLIND = 0
-- verifico che l'utensile sia definito
if #EMT.TOOL == 0 then return end
-- cerco l'utensile nella tabella
for i = 1, #EMT.TOOLCUTLEN do
if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then
EMT.TCLIND = i
break
end
end
-- se non trovato, lo aggiungo
if EMT.TCLIND == 0 then
table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0})
EMT.TCLIND = #EMT.TOOLCUTLEN
end
end
---------------------------------------------------------------------
function OnEstimToolDeselect()
end
---------------------------------------------------------------------
function OnEstimMachiningStart()
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5)
-- reset contatori di lavorazione
EMT.MCHCUTLEN = 0
EMT.MCHCUTTIME = 0
EMT.MCHEXTLEN = 0
EMT.MCHEXTTIME = 0
end
---------------------------------------------------------------------
function OnEstimMachiningEnd()
-- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita
if EMT.MCHTYPE == MCH_MY.DRILLING then
EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2
end
local sName = EgtGetName( EMT.MCHID)
EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL)
-- aggiorno totali e utensili
EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN
EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME
EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN
EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME
EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN
-- emetto dati in sospeso
if EMT.TLE_NAME then
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
EMT.TLE_NAME = nil
EMT.TLE_TIME = nil
end
EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
EMT.MCHSPLIT = ( EMT.MCHUSERNOTES:find( 'Split;', 1, true) ~= nil)
if EMT.MCHSPLIT then
EMT.SPLIT = true
end
end
---------------------------------------------------------------------
function OnEstimPathStart()
EMT.AUXTYPE = nil
EMT.MCHMOVEFIRST = true
end
---------------------------------------------------------------------
function OnEstimPathEnd()
EMT.AUXTYPE = nil
end
---------------------------------------------------------------------
function OnEstimPathStartAux()
-- se richiesto, preparo il carico barra
if EMT.LOAD then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = LOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ')
EMT.LOAD = false
end
-- se altrimenti carico dopo rotazione
elseif EMT.POSTROT then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = ROTATION_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ')
EMT.POSTROT = false
end
-- altrimenti, spostamento carrelli
else
if EMT.AUXTOT > 3 and EMT.AUXIND == EMT.AUXTOT then
local dTime = ( EMT.AUXTOT - 3) * CHAR_ONE_MOVE_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ')
end
end
end
---------------------------------------------------------------------
function OnEstimPathEndAux()
-- verifico tipo di emissione
if EMT.OPEISDISP then
if not EMT.AUXTYPE then
local Cmd = EgtSplitString( EMT.AUX)
if Cmd[1] == '0' and Cmd[2] == 'Unloading' then
EMT.AUXTYPE = 'U'
else
EMT.AUXTYPE = 'R'
end
end
else
if not EMT.AUXTYPE then
local Cmd = EgtSplitString( EMT.AUX)
if Cmd[1] == '0' and Cmd[2] == 'Split' then
EMT.AUXTYPE = 'S'
elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then
EMT.AUXTYPE = 'U'
elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then
EMT.AUXTYPE = 'F'
else
EMT.AUXTYPE = 'P'
end
end
end
-- per lo scarico della rimanenza
if EMT.AUXTYPE == 'R' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = LOAD_T + UNLOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Remnant unloading'
EMT.TLE_TIME = dTime
end
-- per lo split
elseif EMT.AUXTYPE == 'S' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = SPLIT_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Splitting'
EMT.TLE_TIME = dTime
end
-- per lo scarico
elseif EMT.AUXTYPE == 'U' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = UNLOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Unloading'
EMT.TLE_TIME = dTime
end
-- per lo scarico a caduta
elseif EMT.AUXTYPE == 'F' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = FALL_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Fall'
EMT.TLE_TIME = dTime
end
-- per la pre-rotazione
elseif EMT.AUXTYPE == 'P' then
; -- calcolato come parte della rotazione
end
end
---------------------------------------------------------------------
function OnEstimRapid()
-- dati movimento
local dL1 = EMT.L1 - EMT.L1p
local dL2 = EMT.L2 - EMT.L2p
local dL3 = EMT.L3 - EMT.L3p
local dR1 = 0
if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end
local dR2 = 0
if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end
-- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli
if EMT.MCHMOVEFIRST then
EMT.MCHMOVEFIRST = false
dL1 = 0
end
-- calcolo lunghezza
local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3)
EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen
-- calcolo tempo
local dTime = RAPID_MIN_T
local dT1 = CalcMoveTime( abs( dL1), RAPID_X_FEED, EMT.SPLIT)
if dT1 > dTime then dTime = dT1 end
local dT2 = CalcMoveTime( abs( dL2), EMT.FMAXPINZE, EMT.SPLIT)
if dT2 > dTime then dTime = dT2 end
local dT3 = CalcMoveTime( abs( dL3), RAPID_Z_FEED, EMT.SPLIT)
if dT3 > dTime then dTime = dT3 end
local dT4 = abs( dR1) / RAPID_C_FEED * 60
if dT4 > dTime then dTime = dT4 end
local dT5 = abs( dR2) / RAPID_B_FEED * 60
if dT5 > dTime then dTime = dT5 end
EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime
EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
function OnEstimLinear()
-- dati movimento
local dL1 = EMT.L1 - EMT.L1p
local dL2 = EMT.L2 - EMT.L2p
local dL3 = EMT.L3 - EMT.L3p
-- calcolo lunghezza
local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3)
EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen
-- calcolo tempo
local dTime = CalcMoveTime( dLen, EMT.F, EMT.SPLIT)
EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime
EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
function OnEstimArc()
-- dati movimento
local dLxy = EMT.RR * abs( EMT.AC) * pi / 180
local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR))
-- calcolo lunghezza
local dLen = sqrt( dLxy * dLxy + dLz * dLz)
EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen
-- calcolo tempo
local dTime = dLen / EMT.F * 60
EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime
EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
-- *** GENERAL ***
---------------------------------------------------------------------
function IsStartPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'START')
end
---------------------------------------------------------------------
function IsRestPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'REST')
end
---------------------------------------------------------------------
function IsStartOrRestPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'START' or sVal == 'REST')
end
---------------------------------------------------------------------
function IsMidPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'MID')
end
---------------------------------------------------------------------
function IsStartOrMidPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'START' or sVal == 'MID')
end
---------------------------------------------------------------------
function IsMid2Phase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'MID2')
end
---------------------------------------------------------------------
function IsEnd2Phase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'END2')
end
---------------------------------------------------------------------
function GetPhaseType( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '')
end
---------------------------------------------------------------------
function GetPhaseOrd( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0)
end
---------------------------------------------------------------------
function GetPhaseRot( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0)
end
---------------------------------------------------------------------
function GetParkT()
local dTmp = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EgtGetInfo( EMT.DISPID, 'TPARK', 'd')
if dTmp then
return dTmp
else
return LoadT
end
end
---------------------------------------------------------------------
function FindFirstToolOnHeadSet( nHSet)
-- salvo stato iniziale
local CurrMachId = EgtGetCurrMachining()
local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- cerco lavorazione con utensile su gruppo testa indicato
local sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis
local OpId = EgtGetFirstActiveOperation()
while OpId do
local nType = EgtGetOperationType( OpId)
if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then
if EgtSetCurrMachining( OpId) then
local sTest = EgtGetMachiningParam( MCH_MP.TOOL)
if EgtTdbSetCurrTool( sTest) then
sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
if GetHeadSet( sHead) == nHSet then
sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS)
-- aggregato lama non si può mai preselezionare e viene sempre scaricato, quindi non sarà mai già caricato
if nHSet == 2 and sTcPos == 'T201' then
sTcPos = nil
break
end
sTool = sTest
sTTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
sTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM)
sBlockedAxis = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
break
end
end
end
end
OpId = EgtGetNextActiveOperation( OpId)
end
-- ripristino stato iniziale
EgtSetCurrMachining( CurrMachId or GDB_ID.NULL)
EgtTdbSetCurrTool( CurrTool or '')
-- restituisco risultato
return sTool, sHead, sTcPos, sTTotLen, sTotDiam, sBlockedAxis
end
---------------------------------------------------------------------
function GetToolTcPos( sTool)
-- salvo stato iniziale
local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- recupero la posizione di cambio utensile dell'utensile indicato
local sTcPos
if EgtTdbSetCurrTool( sTool) then
sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS)
end
-- ripristino stato iniziale
EgtTdbSetCurrTool( CurrTool or '')
-- restituisco risultato
return sTcPos
end
---------------------------------------------------------------------
function GetNextChainSawingVirtualAxis( MchId)
-- recupero la lavorazione successiva
local NextMchId
if MchId then
NextMchId = EgtGetNextActiveOperation( MchId)
else
NextMchId = EgtGetFirstActiveOperation()
end
while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do
NextMchId = EgtGetNextActiveOperation( NextMchId)
end
-- verifico sia un taglio con sega a catena
if EgtGetOperationType( NextMchId) ~= MCH_OY.MORTISING then
return nil
end
-- la imposto come lavorazione corrente
EgtSetCurrMachining( NextMchId)
-- recupero il valore dell'asse virtuale bloccato A
local dPosA = GetCurrChainSawingVirtualAxis()
-- ripristino la lavorazione corrente
if MchId then
EgtSetCurrMachining( MchId)
end
return dPosA
end
---------------------------------------------------------------------
function GetNextMultiDrillVirtualAxis( MchId)
-- recupero la lavorazione successiva
local NextMchId
if MchId then
NextMchId = EgtGetNextActiveOperation( MchId)
else
NextMchId = EgtGetFirstActiveOperation()
end
while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do
NextMchId = EgtGetNextActiveOperation( NextMchId)
end
-- verifico sia un taglio con sega a catena
if EgtGetOperationType( NextMchId) ~= MCH_OY.DRILLING then
return nil
end
-- la imposto come lavorazione corrente
EgtSetCurrMachining( NextMchId)
-- recupero il valore dell'asse virtuale bloccato A
local dPosA = GetCurrMultiDrillVirtualAxis()
-- ripristino la lavorazione corrente
if MchId then
EgtSetCurrMachining( MchId)
end
return dPosA
end
---------------------------------------------------------------------
function GetCurrSawingVirtualAxis()
-- recupero il valore dell'asse virtuale bloccato A
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A2=0'
local dPosA = tonumber( sVal:sub( 4)) or 0
return dPosA
end
---------------------------------------------------------------------
function GetNextSawingVirtualAxis( MchId)
-- recupero la lavorazione successiva
local NextMchId
if MchId then
NextMchId = EgtGetNextActiveOperation( MchId)
else
NextMchId = EgtGetFirstActiveOperation()
end
while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do
NextMchId = EgtGetNextActiveOperation( NextMchId)
end
-- verifico sia un taglio o fresatura con lama su aggregato da sotto
if ( EgtGetOperationType( NextMchId) ~= MCH_OY.MILLING and EgtGetOperationType( NextMchId) ~= MCH_OY.SAWING) or EMT.HEAD ~= 'H22' then
return nil
end
-- la imposto come lavorazione corrente
EgtSetCurrMachining( NextMchId)
-- recupero il valore dell'asse virtuale bloccato A
local dPosA = GetCurrSawingVirtualAxis()
-- ripristino la lavorazione corrente
if MchId then
EgtSetCurrMachining( MchId)
end
return dPosA
end
---------------------------------------------------------------------
function GetStartMachiningXaxis( nMchId)
-- Recupero quota X (nostro -L2)
local nClEntId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nMchId, 'CL') or GDB_ID.NULL, 'P1') or GDB_ID.NULL)
local vAxes = EmtGetAxesPos( nClEntId or GDB_ID.NULL)
if vAxes and #vAxes >= 2 then
return -vAxes[2]
else
return nil
end
end
---------------------------------------------------------------------
function IsLastPath( nPathId)
return not EgtGetNext( nPathId)
end
---------------------------------------------------------------------
function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2)
if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H16' then
return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1) % 180.0 > 1))
elseif sHead == 'H21' or sHead == 'H22' then
return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1) % 180.0 > 1))
elseif sHead == 'H38' then
return ( abs( dAng1 - dAng1p) > 1 or abs( dAng2 - dAng2p) > 1)
end
end
---------------------------------------------------------------------
function GetCmdAxMove( Cmd, sAx)
if #Cmd >= 3 and Cmd[2] == sAx then
return tonumber( Cmd[3])
elseif #Cmd >= 5 and Cmd[4] == sAx then
return tonumber( Cmd[5])
elseif #Cmd >= 7 and Cmd[6] == sAx then
return tonumber( Cmd[7])
end
end
---------------------------------------------------------------------
function CalcDinamicaPinze( dH, dS, dL)
local MinTempoAcc = EMT.MINACC -- [ms] ~600
local MaxTempoAcc = EMT.MAXACC -- [ms] ~6000
local KgMtCubo= WoodDensity or 550 -- densità legno [Kg / metro cubo]
local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg]
local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min]
local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N]
local TempoAcc = EgtClamp( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito), MinTempoAcc, MaxTempoAcc)
local RidFeed = 100 / Massa * 100
if RidFeed > 100 then
RidFeed = 100
elseif RidFeed < 10 then
RidFeed = 10
end
return TempoAcc, MinTempoAcc, RidFeed
end
---------------------------------------------------------------------
function CalcMoveTime( dPathLen, dFeed, bIsSplitted)
local dTime
local dFeedInSec = dFeed / 60
local dTempoAcc, _, _ = CalcDinamicaPinze( EMT.HB, EMT.SB, EgtIf( bIsSplitted, EMT.LT, EMT.LB))
dTempoAcc = dTempoAcc / 1000
-- se si raggiunge la velocità massima
if dPathLen >= dFeedInSec * dTempoAcc then
dTime = dTempoAcc * 2 + ( ( dPathLen - dFeedInSec * dTempoAcc) / dFeedInSec)
else
dTime = 2 * sqrt( (dPathLen * dTempoAcc) / dFeedInSec)
end
return dTime
end
---------------------------------------------------------------------
-- *** END GENERAL ***