Files
saomad-kairos-mk2/Saomad-KAIROS.mlpe
T
2024-06-27 12:46:19 +02:00

1431 lines
52 KiB
Plaintext

-- Processore macchina Saomad-KAIROS by EgalWare s.r.l. 2023/12/03
-- Funzioni generiche indipendenti dal controllo
-- Intestazioni
require( 'EmtGenerator')
EgtEnableDebug( false)
LONG_TOOL_MINLEN = 221
BIG_TOOL_DIAM = 300
---------------------------------------------------------------------
-- *** GENERATION ***
---------------------------------------------------------------------
local sBaseDir = EgtGetSourceDir()
if NumericalControl == 'SIEMENS' then
dofile( sBaseDir .. 'Saomad-KAIROS.SIEMENS.mlpe')
else
EmtSetLastError( 1201, 'Numerical Control error : unkwnown type')
end
---------------------------------------------------------------------
-- *** SIMULATION ***
---------------------------------------------------------------------
local COLL_SAFE_DIST = 4
---------------------------------------------------------------------
function OnSimulStart()
-- Carico gli utensili sulle barre portautensili
local vTcPos = EgtGetAllTcPosNames()
if vTcPos then
for i = 1, #vTcPos do
local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i])
if vTools and vTools[1] then
EgtLoadTool( vTcPos[i], 1, vTools[1])
ShowToolInTcPos( vTcPos[i], true)
end
end
end
-- Se reset o home, esco
if EMT.SIM1ST then return end
-- Muovo i supporti nella posizione intermedia
SimulMoveAxes( 'RX1', MidRX, MCH_SIM_STEP.RAPID, 'RX2',MidRX, MCH_SIM_STEP.RAPID)
-- Creo o svuoto gruppo per copia finale degli oggetti virtual milling
local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill')
if nVmGrpId then
EgtSetStatus( nVmGrpId, GDB_ST.ON)
EgtEmptyGroup( nVmGrpId)
else
nVmGrpId = EgtGroup( GDB_ID.ROOT)
EgtSetName( nVmGrpId, 'VMill')
EgtSetLevel( nVmGrpId, GDB_LV.TEMP)
end
-- Preparo lista oggetti da verificare per collisioni
EMT.COLLOBJ = {}
AddToCollisionCheck( 'Z', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'A', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ)
DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4)
-- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill)
EMT.MCODET = {}
EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X1'), 'COLLISION'), 'STM3') or GDB_ID.NULL
EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX1'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX1'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[10] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'X2'), 'COLLISION'), 'STM3') or GDB_ID.NULL
EMT.MCODET[11] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[12] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PX2'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[13] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[14] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'QX2'), 'COLLISION'), 'STM2') or GDB_ID.NULL
EMT.MCODET[15] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE1') or GDB_ID.NULL
EMT.MCODET[16] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE2') or GDB_ID.NULL
EMT.MCODET[17] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'BACK') or GDB_ID.NULL
EMT.MCODET[18] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'BELT') or GDB_ID.NULL
EMT.MCODET[19] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'RX1'), 'COLLISION'), 'STM1') or GDB_ID.NULL
EMT.MCODET[20] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'RX2'), 'COLLISION'), 'STM1') or GDB_ID.NULL
for i = #EMT.MCODET, 1, -1 do
if not EMT.MCODET[i] or EMT.MCODET[i] == GDB_ID.NULL then
table.remove( EMT.MCODET, i)
EgtOutLog( ' Warning : MCODET element (' .. tostring( i) .. ') is null')
elseif EgtGetDebugLevel() >= 4 then
EgtOutLog( ' MCODET element (' .. tostring( i) .. ') is ok')
end
end
-- Preparo lista collisioni vuota
EMT.COLLIDE = {}
end
---------------------------------------------------------------------
function OnSimulEnd()
-- Muovo i supporti nella posizione home
SimulMoveAxes( 'RX1', MinRX, MCH_SIM_STEP.RAPID, 'RX2',MinRX, MCH_SIM_STEP.RAPID)
end
---------------------------------------------------------------------
function OnSimulDispositionStarting()
EmtUnlinkAllRawPartsFromGroups()
if EMT.PHASE > 1 then
if IsStartOrRestPhase( EMT.PHASE) then
EgtSetAxisPos( 'T', LoadT)
end
end
end
---------------------------------------------------------------------
function OnSimulDispositionStart()
EMT.OPEISDISP = true
-- Se prima disposizione
if EMT.PHASE == 1 then
-- Determino dimensioni del grezzo
local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL
local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
EMT.LB = 0
EMT.SB = 0
EMT.HB = 0
if b3Sol then
EMT.LB = b3Sol:getDimX()
EMT.SB = b3Sol:getDimY()
EMT.HB = b3Sol:getDimZ()
end
-- Carico primo utensile sulla testa 1
local sTool, nTlen = FindFirstToolOnHead( 'H1')
if sTool then
EMT.TOOL_1 = sTool
else
EMT.TOOL_1 = GetDefaultToolName()
end
EgtLoadTool( 'H1', 1, EMT.TOOL_1)
EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1)
ShowToolInTcPos( EMT.TCPOS_1, false)
EMT.LOAD = true
-- Se vero inizio e abilitato creo gli Zmap
EMT.VMILL = {}
if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then
local nLastOrd = GetPhaseOrd( EgtGetPhaseCount())
local nPartRawId = EgtGetFirstRawPart()
while nPartRawId do
-- se è lo scarto finale tagliato a pezzi, esco
local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i')
if nRawOrd == nLastOrd + 1 then break end
-- elimino eventuale vecchio Zmap
EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL)
-- recupero il solido
local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid')
local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
-- aggiungo eventuale scrap successivo
if nRawOrd == nLastOrd then
local nScrapId = EgtGetNextRawPart( nPartRawId)
if nScrapId then
local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid')
local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD)
if b3ScrapRaw then
b3Raw:Add( b3ScrapRaw)
end
end
end
-- determino la risoluzione dello Zmap
local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ()
local dTol = 4.71
if dArea < CoeffVM * 0.15e6 then
dTol = 0.71
elseif dArea < CoeffVM * 0.3e6 then
dTol = 1.01
elseif dArea < CoeffVM * 0.6e6 then
dTol = 1.51
elseif dArea < CoeffVM * 1.2e6 then
dTol = 1.97
elseif dArea < CoeffVM * 2.4e6 then
dTol = 2.81
elseif dArea < CoeffVM * 4.8e6 then
dTol = 3.77
end
-- creo lo Zmap
local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB)
if VMillId then
EgtSetName( VMillId, 'VMill')
EgtSetLevel( VMillId, GDB_LV.TEMP)
EgtSetColor( VMillId, EgtGetColor( nSolId), false)
-- nascondo le altre geometrie
local nId = EgtGetFirstInGroup( nPartRawId)
while nId do
if nId ~= VMillId then
EgtSetStatus( nId, GDB_ST.OFF)
end
nId = EgtGetNext( nId)
end
table.insert( EMT.VMILL, VMillId)
end
nPartRawId = EgtGetNextRawPart( nPartRawId)
end
end
-- fasi successive
else
EMT.LOAD = false
end
-- recupero sovramateriale di testa del pezzo corrente
local nCurrRawId = EgtGetFirstRawPart()
while nCurrRawId do
if EgtVerifyRawPartPhase( nCurrRawId, EMT.PHASE) then
break
end
nCurrRawId = EgtGetNextRawPart( nCurrRawId)
end
EMT.HOVM = EgtGetInfo( nCurrRawId or GDB_ID.NULL, 'HOVM', 'd') or 0
-- Nascondo tutte le lavorazioni
local nMchId = EgtGetFirstOperation()
while nMchId do
if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then
EgtSetOperationStatus( nMchId, false)
end
nMchId = EgtGetNextOperation( nMchId)
end
-- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola
if IsStartOrRestPhase( EMT.PHASE) then
-- se fase inizio, segnalo giacitura del grezzo
if IsStartPhase( EMT.PHASE) then
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= 0 then
EgtOutText( tostring( -90 * nRot) .. '° rotated bar')
else
EgtOutText( 'Not rotated bar')
end
end
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1
local b3Raw = BBox3d()
local nPartRawId, nScrapRawId
local nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
EmtLinkRawPartToGroup( nRawId, 'Tab')
local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i')
if nRawOrd == nOrd then
b3Raw = EgtGetRawPartBBox( nRawId)
nPartRawId = nRawId
elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then
local b3Tmp = EgtGetRawPartBBox( nRawId) or BBox3d()
b3Raw:Add( b3Tmp)
nScrapRawId = nRawId
end
end
nRawId = nNextRawId
end
-- gestione eventuale scarto affettato successivo
if EMT.VMILL and #EMT.VMILL > 0 then
EMT.SCRAP = nScrapRawId
EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF)
else
EMT.SCRAP = nil
end
-- recupero CutId del pezzo in lavorazione
EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0
EMT.X1SPEC = nil
-- se vero inizio, assegno solidi per verifica collisione
if not EMT.SIM1ST then
EMT.CODET = {}
for i = 1, #( EMT.MCODET or {}) do
EMT.CODET[i] = EMT.MCODET[i]
end
for i = 1, #( EMT.VMILL or {}) do
table.insert( EMT.CODET, EMT.VMILL[i])
end
end
-- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola
elseif IsMidPhase( EMT.PHASE) then
-- se cambiata giacitura, lo segnalo
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= nPrevRot then
if nRot ~= 0 then
EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°')
else
EgtOutText( 'Barra non ruotata')
end
end
-- eseguo aggancio
local nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
EmtLinkRawPartToGroup( nRawId, 'Tab')
end
nRawId = nNextRawId
end
-- se Vmill, nascondo eventuale scrap
if EMT.VMILL then
EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF)
end
-- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico
elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
-- se cambiata giacitura, lo segnalo
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
local nRot = GetPhaseRot( EMT.PHASE)
if nRot ~= nPrevRot then
if nRot ~= 0 then
EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°')
else
EgtOutText( 'Barra non ruotata')
end
end
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
-- ricerco vettore movimento per i successivi
local vtMove = Vector3d()
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then
vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
-- eseguo
nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then
EmtLinkRawPartToGroup( nRawId, 'Tab')
else
EgtMove( nRawId, vtMove, GDB_RT.GLOB)
EgtSetStatus( nRawId, GDB_ST.OFF)
end
end
nRawId = nNextRawId
end
-- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y
else
-- indice primo grezzo della fase
local nOrd = GetPhaseOrd( EMT.PHASE)
-- ricerco vettore movimento per i successivi
local vtMove = Vector3d()
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then
vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
-- eseguo
nRawId = EgtGetFirstRawPart()
while nRawId do
local nNextRawId = EgtGetNextRawPart( nRawId)
if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then
if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then
EmtLinkRawPartToGroup( nRawId, 'Tab')
else
EgtMove( nRawId, vtMove, GDB_RT.GLOB)
EmtLinkRawPartToGroup( nRawId, 'X1')
end
end
nRawId = nNextRawId
end
end
-- Indicazione angolo rotazione pezzo
EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0
local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN')
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF))
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF))
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF))
end
---------------------------------------------------------------------
function OnSimulDispositionEnd()
if EMT.UNLOADING or EMT.FALL then
ExecUnloading()
EMT.UNLOADING = false
EMT.FALL = false
end
-- se disposizione intermedia
if IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
-- se le rotazioni delle fasi corrente e precedente sono diverse
if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then
-- imposto stato post-rotazione
EMT.POSTROT = true
end
-- se altrimenti disposizione intermedia speciale con eventuale rotazione
elseif IsMid2Phase( EMT.PHASE) then
-- se le rotazioni delle fasi corrente e precedente sono diverse
if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then
-- imposto stato post-rotazione
EMT.POSTROT = true
end
end
EMT.OPEISDISP = false
end
---------------------------------------------------------------------
function OnSimulToolSelect( dPosCS)
-- se utensile non definito, è disposizione ed esco
if EMT.TOOL == '' then return end
-- recupero dati utensile
EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
EMT.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
EMT.TOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM)
-- se non è chiamato da altro script (non c'è parametro)
if not dPosCS then
-- se attivo Vmill
SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL)
-- se attivo Collision Check
EMT.SAFEDIST = COLL_SAFE_DIST
if EMT.COLLOBJ then
for i, Coll in ipairs( EMT.COLLOBJ) do
EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3)
end
AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001)
AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002)
end
-- dichiaro assi ausiliari da visualizzare
EMT.AuxAxes = 2
EMT.A1n = 'X1'
EMT.A2n = 'X2'
end
-- se sega a catena, imposto subito angolo scelto per asse virtuale CS
if EMT.HEAD == 'H3' then
if not dPosCS then
-- recupero la lavorazione successiva
local NextMchId
if EMT.MCHID then
NextMchId = EgtGetNextActiveOperation( EMT.MCHID)
else
NextMchId = EgtGetFirstActiveOperation()
end
while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do
NextMchId = EgtGetNextActiveOperation( NextMchId)
end
EgtSetCurrMachining( NextMchId)
-- recupero il valore dell'asse virtuale bloccato CS
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
dPosCS = tonumber( sVal:sub( 4))
else
-- imposto visualizzazione
EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD)
end
-- imposto il valore di CS
EgtSetAxisPos( 'CS', dPosCS)
EgtSetAxisPos( 'C', GetChainSawCHomeFromVirtualAxis( dPosCS))
EgtSetAxisPos( 'A', 0)
end
-- breve pausa
EgtPause( 100)
EgtOutText( '')
EMT.TOOL_1 = EMT.TOOL
EMT.TCPOS_1 = EMT.TCPOS
-- lo nascondo sul portautensili
ShowToolInTcPos( EMT.TCPOS, false)
end
---------------------------------------------------------------------
function OnSimulToolDeselect()
-- se prossimo utensile non definito, è disposizione ed esco
if EMT.NEXTTOOL == '' then return end
-- se sega a catena o punta lunga o utensile di grosso diametro, devo cambiare
if EMT.HEAD == 'H3' or ( EMT.HEAD == 'H1' and ( EMT.TOTLEN > LONG_TOOL_MINLEN or EMT.TOTDIAM > BIG_TOOL_DIAM)) then
EgtOutText( 'Tool change in progress...')
-- movimento scarico sega a catena
if EMT.HEAD == 'H3' then
local dPosCS = EgtGetAxisPos( 'CS')
SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.COLLROT, 'C', GetChainSawCHomeFromVirtualAxis( dPosCS), MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'Y', ParkY, MCH_SIM_STEP.RAPID)
end
-- breve pausa
EgtPause( 100)
-- nascondo utensile su testa e lo visualizzo su TcPos
EgtSetMode( EgtGetHeadId( EMT.HEAD), GDB_MD.HIDDEN)
ShowToolInTcPos( EMT.TCPOS_1, true)
-- movimento per carico utensile
SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.RAPROT, 'C', ParkC, MCH_SIM_STEP.RAPROT)
EgtOutText( '')
-- deposito utensile
else
if EMT.NEXTTOOL ~= EMT.TOOL_1 then
EgtOutText( 'Tool change in progress...')
-- simulo movimento
SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.COLLROT, 'C', ParkC, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'Y', ParkY, MCH_SIM_STEP.RAPID)
-- breve pausa
EgtPause( 100)
ShowToolInTcPos( EMT.TCPOS_1, true)
-- nascondo l'utensile corrente
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF)
-- eseguo movimento opportuno
SimulMoveAxes( 'A', ParkA, MCH_SIM_STEP.RAPROT, 'C', ParkC, MCH_SIM_STEP.RAPROT)
else
EMT.TOOL_1 = nil
EMT.TCPOS_1 = nil
end
end
end
---------------------------------------------------------------------
function OnSimulMachiningStart()
-- se lavorazione attuale e precedente con sega a catena con angolo CS diverso, devo scaricare e ricaricare
if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then
local dPrevCS = EgtGetAxisPos( 'CS')
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
local dPosCS = tonumber( sVal:sub( 3))
if abs( dPosCS - dPrevCS) > 1 then
OnSimulToolDeselect()
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON)
OnSimulToolSelect( dPosCS)
end
end
-- recupero alcuni dati della lavorazione
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true)))
-- recupero TASKID della feature lavorata
local vId = EgtGetMachiningGeometry()
if vId and #vId > 0 and #vId[1] > 0 then
EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ;
else
EMT.TASKID = 0
end
-- non ancora iniziata la lavorazione
EMT.MCHFIRST = true
end
---------------------------------------------------------------------
function OnSimulMachiningEnd()
if EMT.LOAD then
EMT.LOAD = false
elseif EMT.UNLOADING or EMT.FALL then
ExecUnloading()
EMT.UNLOADING = false
EMT.FALL = false
end
EMT.PREVHEAD = EMT.HEAD
EMT.PREVEXIT = EMT.EXIT
end
---------------------------------------------------------------------
--function OnSimulPathStart()
--end
---------------------------------------------------------------------
function OnSimulPathEnd()
-- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi
if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then
EgtOutLog( 'OnSimulPathEnd', 5)
local vMillId = EMT.VMILL[1]
local nPart = EgtVolZmapPartCount( vMillId)
if nPart > 1 then
-- ricerca del pezzo con massimo volume
local nPartMax = 0
local dVolMax = 0
for i = 1, nPart do
local dVol = EgtVolZmapPartVolume( vMillId, i - 1)
if dVol > dVolMax then
dVolMax = dVol
nPartMax = i
end
end
-- eliminazione di tutti i pezzi piccoli
for i = nPart, 1, -1 do
if i ~= nPartMax then
local b3Vmill = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD)
if b3Vmill:getDimX() < 1200 then
EgtRemoveVolZmapPart( vMillId, i - 1)
end
end
end
-- aggiorno visualizzazione
EgtDraw()
end
end
end
---------------------------------------------------------------------
function OnSimulPathStartAux()
--EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX)
EgtOutLog( 'OnSimulPathStartAux', 5)
-- eseguo il comando
ExecAuxCmd( EMT.AUX)
end
---------------------------------------------------------------------
function OnSimulPathEndAux()
--EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX)
EgtOutLog( 'OnSimulPathEndAux', 5)
-- eseguo il comando
ExecAuxCmd( EMT.AUX)
end
---------------------------------------------------------------------
function OnSimulMoveStart()
-- Recupero la posizione corrente dei carrelli
local X1p = EgtGetAxisPos( 'X1')
local X2p = EgtGetAxisPos( 'X2')
-- Imposto movimento carrelli insieme con la tavola :
-- entrambe le pinze
if EMT.X1DELTA and EMT.X2DELTA then
EMT.AuxAxes = 2
EMT.A1n = 'X1'
EMT.A1m = 'T'
EMT.A1 = EMT.L1 + EMT.X1DELTA
EMT.A2n = 'X2'
EMT.A2m = 'T'
EMT.A2 = EMT.L1 + EMT.X2DELTA
-- solo pinza Y
elseif EMT.X1DELTA then
EMT.AuxAxes = 2
EMT.A1n = 'X1'
EMT.A1m = 'T'
EMT.A1 = EMT.L1 + EMT.X1DELTA
EMT.A2n = 'X2'
EMT.A2m = nil
EMT.A2 = ParkX2
-- solo pinza V
elseif EMT.X2DELTA then
EMT.AuxAxes = 2
EMT.A1n = 'X1'
EMT.A1m = nil
EMT.A1 = EgtIf( EMT.X1SPEC, X1p, ParkX1)
EMT.A2n = 'X2'
EMT.A2m = 'T'
EMT.A2 = EMT.L1 + EMT.X2DELTA
end
-- Controllo scorrimento pinze chiuse X1 e X2
if EMT.X1DELTA then
local dX1DeltaP = X1p - EMT.L1p
if abs( EMT.X1DELTA - dX1DeltaP) > 0.1 then
EMT.ERR = 2
local sErr = 'X1 slide : ' .. EmtLenToString( dX1DeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.X1DELTA, 3)
EmtSetLastError( 1202, sErr)
end
end
if EMT.X2DELTA then
local dX2DeltaP = X2p - EMT.L1p
if abs( EMT.X2DELTA - dX2DeltaP) > 0.1 then
EMT.ERR = 2
local sErr = 'X2 slide : ' .. EgtNumToString( dX2DeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.X2DELTA, 3)
EmtSetLastError( 1202, sErr)
end
end
-- Controllo corse assi X1 e X2
VerifyX1Stroke( EMT.A1)
VerifyX2Stroke( EMT.A2)
-- se inizio lavorazione
if EMT.MCHFIRST then
EgtOutText( '')
EMT.MCHFIRST = false
EMT.POSTROT = nil
end
end
---------------------------------------------------------------------
--function OnSimulMoveEnd()
--end
---------------------------------------------------------------------
function OnSimulCollision()
-- se prima collisione della lavorazione, la segnalo
if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then
local Class = ''
if EMT.SIMCOBIND == 1001 then
Class = 'T_H1'
elseif EMT.SIMCOBIND == 1002 then
Class = 'TH_H1'
else
Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl
end
table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID})
EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME
EMT.ERR = 1
local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID
EmtSetLastError( 1221, sErr, true)
EgtOutLog( 'Collision : ' .. sErr, 1)
end
end
---------------------------------------------------------------------
function ExecAuxCmd( sCmd)
local Cmd = EgtSplitString( sCmd)
if Cmd[1] == '0' then
if Cmd[2] == 'Unloading' then
EMT.UNLOADING = true
elseif Cmd[2] == 'Fall' then
EMT.FALL = true
end
EgtOutText( EgtIf( Cmd[3], Cmd[3], Cmd[2]))
elseif Cmd[1] == '1' then
if not SimulMoveAxis( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID) then
if VerifyX12Stroke( Cmd[2], tonumber( Cmd[3])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
end
elseif Cmd[1] == '2' then
if Cmd[2] == 'X1' and EMT.POSTROT then
local dPosY = tonumber( Cmd[3]) - EMT.HOVM
Cmd[3] = EgtNumToString( dPosY, 3)
EMT.HOVM = 0
end
-- Verifico movimento carrello con trave agganciata
VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5])
-- Eseguo il movimento
local _, bOk, bOk2 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID,
Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID)
if not ( bOk and bOk2) then
local nI = EgtIf( not bOk, 2, 4)
if VerifyX12Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
end
elseif Cmd[1] == '3' then
-- Verifico movimento carrelli con trave agganciata
VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7])
-- Eseguo il movimento
local _, bOk, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), MCH_SIM_STEP.RAPID,
Cmd[4], tonumber( Cmd[5]), MCH_SIM_STEP.RAPID,
Cmd[6], tonumber( Cmd[7]), MCH_SIM_STEP.RAPID)
if not ( bOk and bOk2 and bOk3) then
local nI = EgtIf( not bOk, 2, EgtIf( not bOk2, 4, 6))
if VerifyX12Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
end
end
elseif Cmd[1] == '11' then
local dPX1 = MaxHOpen
if Cmd[2] ~= '0' then
dPX1 = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB)
end
SimulMoveAxis( 'PX1', dPX1, MCH_SIM_STEP.RAPID)
local dQX1 = MaxVOpen
if Cmd[2] == '2' then
dQX1 = EgtIf( EMT.ROT == -1, EMT.SB, EMT.HB)
end
SimulMoveAxis( 'QX1', dQX1, MCH_SIM_STEP.RAPID)
SetPX1Light( Cmd[2] ~= '0')
elseif Cmd[1] == '12' then
local dPX2 = MaxHOpen
if Cmd[2] ~= '0' then
dPX2 = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB)
end
SimulMoveAxis( 'PX2', dPX2, MCH_SIM_STEP.RAPID)
local dQX2 = MaxVOpen
if Cmd[2] == '2' then
dQX2 = EgtIf( EMT.ROT == -1, EMT.SB, EMT.HB)
end
SimulMoveAxis( 'QX2', dQX2, MCH_SIM_STEP.RAPID)
SetPX2Light( Cmd[2] ~= '0')
elseif Cmd[1] == '21' then
local nX1Delta = tonumber( Cmd[2])
local nX2Delta = tonumber( Cmd[3])
if nX1Delta > 0.01 and nX2Delta > 0.01 then
EMT.X1DELTA = nX1Delta
EMT.X2DELTA = nX2Delta
elseif nX1Delta > 0.01 then
EMT.X1DELTA = nX1Delta
EMT.X2DELTA = nil
elseif nX2Delta > 0.01 then
EMT.X1DELTA = nil
EMT.X2DELTA = nX2Delta
end
elseif Cmd[1] == '31' then
local nRawId = tonumber( Cmd[2])
EmtUnlinkRawPartFromGroup( nRawId)
EmtLinkRawPartToGroup( nRawId, Cmd[3])
EMT.X1SPEC = true
end
end
---------------------------------------------------------------------
function ExecUnloading()
if EMT.VMILL and #EMT.VMILL > 0 then
local vMillId = EMT.VMILL[1]
-- gruppo dei Vmill
local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill')
-- li sposto per lasciare spazio al nuovo pezzo
local nId = EgtGetFirstInGroup( nVmGrpId)
while nId do
EgtMove( nId, Vector3d( 0, -( EMT.SB + 50.0), 0), GDB_RT.GLOB)
nId = EgtGetNext( nId)
end
-- creo un nuovo layer e vi inserisco il nuovo pezzo
local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId))
EgtRelocate( vMillId, nLayId)
local vtMove = Vector3d( 0, -800, 0)
if EMT.FALL then vtMove = Vector3d( -300, -800, -600) end
EgtMove( nLayId, vtMove, GDB_RT.GLOB)
EgtSetLevel( vMillId, GDB_LV.USER)
-- aggiungo gli spigoli
local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId)
if nFirstId then
for nId = nFirstId, nFirstId + nCount - 1 do
EgtSetColor( nId, Color3d( 96, 96, 96))
end
end
-- rilascio Vmill
table.remove( EMT.VMILL, 1)
-- aggiorno la visualizzazione
EgtDraw()
-- se finito
if EMT.PHASE == EgtGetPhaseCount() then
-- se impostato di salvare i Vmill, lo faccio
local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini'
if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then
local sFile = EgtGetCurrFilePath()
if sFile then
local sDir, sName, sExt = EgtSplitPath( sFile)
if sExt and sExt:lower() == ".nge" then
sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup())
EgtSetLevel( nVmGrpId, GDB_LV.USER)
EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge')
EgtSetLevel( nVmGrpId, GDB_LV.TEMP)
end
end
end
end
end
end
---------------------------------------------------------------------
function VerifyYSlide( sName1, dVal1, sName2, dVal2)
-- Se movimento trave agganciata con carrello Y
if sName1 == 'T' and sName2 == 'X1' and GetPX1Light() then
local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'X1')
local dYDeltaA = tonumber( dVal1) - tonumber( dVal2)
EgtOutLog( string.format( 'YDeltaP=%.3f YDeltaA=%.3f', dYDeltaP, dYDeltaA), 5)
if abs( dYDeltaA - dYDeltaP) > 0.5 then
EMT.ERR = 2
local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( dYDeltaA, 3)
EmtSetLastError( 1202, sErr)
end
end
-- Tutto bene
return true
end
---------------------------------------------------------------------
function VerifyVSlide( sName1, dVal1, sName2, dVal2)
-- Se movimento trave agganciata con carrello V
if sName1 == 'T' and sName2 == 'X2' and GetPX2Light() then
local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'X2')
local dVDeltaA = tonumber( dVal1) - tonumber( dVal2)
EgtOutLog( string.format( 'VDeltaP=%.3f VDeltaA=%.3f', dVDeltaP, dVDeltaA), 5)
if abs( dVDeltaA - dVDeltaP) > 0.5 then
EMT.ERR = 2
local sErr = 'V slide : ' .. EmtLenToString( dVDeltaP, 3) .. ' -> ' .. EmtLenToString( dVDeltaA, 3)
EmtSetLastError( 1202, sErr)
end
end
return true
end
---------------------------------------------------------------------
function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2)
-- Metto in prima posizione la trave
if sName2 == 'T' then
sName1, sName2 = sName2, sName1
dVal1, dVal2 = dVal2, dVal1
end
-- Eseguo verifica
if sName2 == 'X1' then
return VerifyYSlide( sName1, dVal1, sName2, dVal2)
elseif sName2 == 'X2' then
return VerifyVSlide( sName1, dVal1, sName2, dVal2)
end
return true
end
---------------------------------------------------------------------
function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3)
-- Metto in prima posizione la trave
if sName2 == 'T' then
sName1, sName2 = sName2, sName1
dVal1, dVal2 = dVal2, dVal1
elseif sName3 == 'T' then
sName1, sName3 = sName3, sName1
dVal1, dVal3 = dVal3, dVal1
end
-- Eseguo verifica
if sName2 == 'X1' then
return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3)
elseif sName2 == 'X2' then
return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3)
end
return true
end
---------------------------------------------------------------------
function VerifyX1Stroke( dX1)
if dX1 < MinX1 then
EmtSetOutstrokeInfo( 'X1', 'X1', true, dX1 - MinX1, ' (L1-)')
EMT.ERR = 1
local sErr = 'X1 axis outstroke ' .. EgtNumToString( dX1 - MinX1, 3)
EgtOutLog( sErr)
return false
elseif dX1 > MaxX1 then
EmtSetOutstrokeInfo( 'X1', 'X1', true, dX1 - MaxX1, ' (L1+)')
EMT.ERR = 1
local sErr = 'X1 axis outstroke ' .. EgtNumToString( dX1 - MaxX1, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyX2Stroke( dX2)
if dX2 > MaxX2 then
EmtSetOutstrokeInfo( 'X2', 'X2', true, dX2 - MaxX2, ' (L1+)')
EMT.ERR = 1
local sErr = 'X2 axis outstroke ' .. EgtNumToString( dX2 - MaxX2, 3)
EgtOutLog( sErr)
return false
elseif dX2 < MinX2 then
EmtSetOutstrokeInfo( 'X2', 'X2', true, dX2 - MinX2, ' (L1-)')
EMT.ERR = 1
local sErr = 'X2 axis outstroke ' .. EgtNumToString( dX2 - MinX2, 3)
EgtOutLog( sErr)
return false
end
return true
end
---------------------------------------------------------------------
function VerifyX12Stroke( sName, dVal)
if sName == 'X1' then
return VerifyX1Stroke( dVal)
elseif sName == 'X2' then
return VerifyX2Stroke( dVal)
else
return nil
end
end
---------------------------------------------------------------------
function ShowToolInTcPos( sTcPos, bShow)
-- recupero il gruppo dell'utensile
local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1')
if not TcExitId then return end
-- imposto lo stato di visualizzazione
EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF))
end
---------------------------------------------------------------------
function GetToolTcPos( sTool)
-- salvo stato iniziale
local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- recupero la posizione di cambio utensile dell'utensile indicato
local sTcPos
if EgtTdbSetCurrTool( sTool) then
sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS)
end
-- ripristino stato iniziale
if CurrTool then
EgtTdbSetCurrTool( CurrTool)
else
EgtTdbSetCurrTool( '')
end
-- restituisco risultato
return sTcPos
end
---------------------------------------------------------------------
-- *** ESTIMATION T&L ***
---------------------------------------------------------------------
local RAPID_X_FEED = 75000 -- mm/min
local RAPID_Y_FEED = 100000 -- mm/min
local RAPID_Z_FEED = 50000 -- mm/min
local RAPID_C_FEED = 15000 -- deg/min
local RAPID_B_FEED = 15000 -- deg/min
local RAPID_MIN_T = 0.1 -- s
local LOAD_T = 6 -- s
local CHAR_ONE_MOVE_T = 1 -- s
local ROTATION_T = 40 -- s
local SPLIT_T = 6 -- s
local UNLOAD_T = 6 -- s
local FALL_T = 2 -- s
---------------------------------------------------------------------
function OnEstimStart()
EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches
end
---------------------------------------------------------------------
function OnEstimEnd()
end
---------------------------------------------------------------------
function OnEstimProgramStart()
-- imposto inizio movimenti da Home
EMT.L1 = EgtGetAxisHomePos( 'T')
EMT.L2 = EgtGetAxisHomePos( 'Y')
EMT.L3 = EgtGetAxisHomePos( 'Z')
EMT.R1 = EgtGetAxisHomePos( 'C')
EMT.R2 = EgtGetAxisHomePos( 'A')
-- aggiorno valori come precedenti
EmtUpdatePrev()
-- totalizzatori tempi e lunghezze
EMT.TOTCUTLEN = 0
EMT.TOTCUTTIME = 0
EMT.TOTEXTLEN = 0
EMT.TOTEXTTIME = 0
-- variabile per lunghezza taglio utensili
EMT.TOOLCUTLEN = {}
-- intestazioni
EmtTleStart( EMT.INFO)
end
---------------------------------------------------------------------
function OnEstimProgramEnd()
-- stampa dei totali delle lavorazioni
EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN))
-- stampa dei totali degli utensili
for i = 1, #EMT.TOOLCUTLEN do
local TCL = EMT.TOOLCUTLEN[i]
EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len))
end
-- completo il file
local _, _, sExt = EgtSplitPath( EMT.FILE)
EmtTleEnd( sExt:sub( 2))
-- salvo i dati principali nel progetto
EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0))
EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0))
end
---------------------------------------------------------------------
function OnEstimDispositionStart()
-- inizio disposizione
EMT.OPEISDISP = true
-- sulla prima fase dichiaro carico barra
if EMT.PHASE == 1 then
EMT.LOAD = true
else
EMT.LOAD = false
end
end
---------------------------------------------------------------------
function OnEstimDispositionEnd()
-- Se disposizione inizio o rimanenza
if IsStartOrRestPhase( EMT.PHASE) then
;
-- se altrimenti disposizione intermedia o finale dopo separazione e rotazione, eventuale rotazione
elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
-- recupero le rotazioni delle fasi corrente e precedente
local nRot = GetPhaseRot( EMT.PHASE)
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
-- verifico se sono diverse
if nRot ~= nPrevRot then
-- imposto stato post-rotazione
EMT.POSTROT = true
end
-- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni
else
;
end
-- emetto dati in sospeso
if EMT.TLE_NAME then
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
EMT.TLE_NAME = nil
EMT.TLE_TIME = nil
end
-- termine disposizione
EMT.OPEISDISP = false
end
---------------------------------------------------------------------
function OnEstimToolSelect()
-- reset indice utensile in tabella lunghezze
EMT.TCLIND = 0
-- verifico che l'utensile sia definito
if #EMT.TOOL == 0 then return end
-- cerco l'utensile nella tabella
for i = 1, #EMT.TOOLCUTLEN do
if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then
EMT.TCLIND = i
break
end
end
-- se non trovato, lo aggiungo
if EMT.TCLIND == 0 then
table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0})
EMT.TCLIND = #EMT.TOOLCUTLEN
end
end
---------------------------------------------------------------------
function OnEstimToolDeselect()
end
---------------------------------------------------------------------
function OnEstimMachiningStart()
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5)
-- reset contatori di lavorazione
EMT.MCHCUTLEN = 0
EMT.MCHCUTTIME = 0
EMT.MCHEXTLEN = 0
EMT.MCHEXTTIME = 0
end
---------------------------------------------------------------------
function OnEstimMachiningEnd()
-- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita
if EMT.MCHTYPE == MCH_MY.DRILLING then
EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2
end
local sName = EgtGetName( EMT.MCHID)
EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL)
-- aggiorno totali e utensili
EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN
EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME
EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN
EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME
EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN
-- emetto dati in sospeso
if EMT.TLE_NAME then
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
EMT.TLE_NAME = nil
EMT.TLE_TIME = nil
end
end
---------------------------------------------------------------------
function OnEstimPathStart()
EMT.AUXTYPE = nil
EMT.MCHMOVEFIRST = true
EMT.CHARMOVE = nil
end
---------------------------------------------------------------------
function OnEstimPathEnd()
EMT.AUXTYPE = nil
end
---------------------------------------------------------------------
function OnEstimPathStartAux()
-- se richiesto, preparo il carico barra
if EMT.LOAD then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = LOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ')
EMT.LOAD = false
end
-- se altrimenti carico dopo rotazione
elseif EMT.POSTROT then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = ROTATION_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ')
EMT.POSTROT = false
end
-- altrimenti, spostamento carrelli
else
local Cmd = EgtSplitString( EMT.AUX)
if ( Cmd[1] == '1' and Cmd[2] ~= 'Z') or Cmd[1] == '2' or Cmd[1] == '3' then
EMT.CHARMOVE = true
end
if EMT.AUXIND == EMT.AUXTOT and EMT.CHARMOVE then
local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ')
end
end
end
---------------------------------------------------------------------
function OnEstimPathEndAux()
-- verifico tipo di emissione
if EMT.OPEISDISP then
if not EMT.AUXTYPE then
local Cmd = EgtSplitString( EMT.AUX)
if Cmd[1] == '0' and Cmd[2] == 'Unloading' then
EMT.AUXTYPE = 'U'
else
EMT.AUXTYPE = 'R'
end
end
else
if not EMT.AUXTYPE then
local Cmd = EgtSplitString( EMT.AUX)
if Cmd[1] == '0' and Cmd[2] == 'Split' then
EMT.AUXTYPE = 'S'
elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then
EMT.AUXTYPE = 'U'
elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then
EMT.AUXTYPE = 'F'
else
EMT.AUXTYPE = 'P'
end
end
end
-- per lo scarico della rimanenza
if EMT.AUXTYPE == 'R' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = LOAD_T + UNLOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Remnant unloading'
EMT.TLE_TIME = dTime
end
-- per lo split
elseif EMT.AUXTYPE == 'S' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = SPLIT_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Splitting'
EMT.TLE_TIME = dTime
end
-- per lo scarico
elseif EMT.AUXTYPE == 'U' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = UNLOAD_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Unloading'
EMT.TLE_TIME = dTime
end
-- per lo scarico a caduta
elseif EMT.AUXTYPE == 'F' then
if EMT.AUXIND == EMT.AUXTOT then
local dTime = FALL_T
EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime
EMT.TLE_NAME = 'Fall'
EMT.TLE_TIME = dTime
end
-- per la pre-rotazione
elseif EMT.AUXTYPE == 'P' then
; -- calcolato come parte della rotazione
end
end
---------------------------------------------------------------------
function OnEstimRapid()
-- dati movimento
local dL1 = EMT.L1 - EMT.L1p
local dL2 = EMT.L2 - EMT.L2p
local dL3 = EMT.L3 - EMT.L3p
local dR1 = 0
if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end
local dR2 = 0
if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end
-- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli
if EMT.MCHMOVEFIRST then
EMT.MCHMOVEFIRST = false
dL1 = 0
end
-- calcolo lunghezza
local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3)
EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen
-- calcolo tempo
local dTime = RAPID_MIN_T
local dT1 = abs( dL1) / RAPID_X_FEED * 60
if dT1 > dTime then dTime = dT1 end
local dT2 = abs( dL2) / RAPID_Y_FEED * 60
if dT2 > dTime then dTime = dT2 end
local dT3 = abs( dL3) / RAPID_Z_FEED * 60
if dT3 > dTime then dTime = dT3 end
local dT4 = abs( dR1) / RAPID_C_FEED * 60
if dT4 > dTime then dTime = dT4 end
local dT5 = abs( dR2) / RAPID_B_FEED * 60
if dT5 > dTime then dTime = dT5 end
EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime
EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
function OnEstimLinear()
-- dati movimento
local dL1 = EMT.L1 - EMT.L1p
local dL2 = EMT.L2 - EMT.L2p
local dL3 = EMT.L3 - EMT.L3p
-- calcolo lunghezza
local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3)
EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen
-- calcolo tempo
local dTime = dLen / EMT.F * 60
EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime
EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
function OnEstimArc()
-- dati movimento
local dLxy = EMT.RR * abs( EMT.AC) * pi / 180
local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR))
-- calcolo lunghezza
local dLen = sqrt( dLxy * dLxy + dLz * dLz)
EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen
-- calcolo tempo
local dTime = dLen / EMT.F * 60
EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime
EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5)
-- aggiorno valori come precedenti
EmtUpdatePrev()
end
---------------------------------------------------------------------
-- *** GENERAL ***
---------------------------------------------------------------------
function FindFirstToolOnHead( sH1)
-- salvo stato iniziale
local CurrMachId = EgtGetCurrMachining()
local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- cerco lavorazione con utensile su testa indicata
local sTool, nTlen
local OpId = EgtGetFirstActiveOperation()
while OpId do
local nType = EgtGetOperationType( OpId)
if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then
if EgtSetCurrMachining( OpId) then
local sTest = EgtGetMachiningParam( MCH_MP.TOOL)
if EgtTdbSetCurrTool( sTest) then
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
if sHead and ( sHead == sH1) then
sTool = sTest
nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
break
end
end
end
end
OpId = EgtGetNextActiveOperation( OpId)
end
-- ripristino stato iniziale
if CurrMachId then
EgtSetCurrMachining( CurrMachId)
else
EgtResetCurrMachining()
end
if CurrTool then
EgtTdbSetCurrTool( CurrTool)
else
EgtTdbSetCurrTool( '')
end
-- restituisco risultato
return sTool, nTlen
end
---------------------------------------------------------------------
function GetDefaultToolName()
local vTools = EgtGetToolsInCurrSetupPos( DefTcPos)
if vTools and vTools[1] and #vTools[1] > 0 then
return vTools[1]
else
local sErr = 'Missing tool in Default Position ' .. DefTcPos
EgtOutLog( 'Error : ' .. sErr)
if EMT.VER and EMT.VER >= '2.3a2' and EMT.SIM1ST then
EgtOutBox( sErr, 'ERROR', 'ERROR')
end
return ''
end
end
---------------------------------------------------------------------
function IsStartPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'START')
end
---------------------------------------------------------------------
function IsRestPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'REST')
end
---------------------------------------------------------------------
function IsStartOrRestPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'START' or sVal == 'REST')
end
---------------------------------------------------------------------
function IsMidPhase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'MID')
end
---------------------------------------------------------------------
function IsMid2Phase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'MID2')
end
---------------------------------------------------------------------
function IsEnd2Phase( nPhase)
local sVal = GetPhaseType( nPhase)
return ( sVal == 'END2')
end
---------------------------------------------------------------------
function GetPhaseType( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '')
end
---------------------------------------------------------------------
function GetPhaseOrd( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0)
end
---------------------------------------------------------------------
function GetPhaseRot( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0)
end
---------------------------------------------------------------------
function IsLastMachining( nMchId)
local nOpeId = EgtGetNextActiveOperation( nMchId)
while nOpeId do
local nType = EgtGetOperationType( nOpeId)
if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then
return false
end
nOpeId = EgtGetNextActiveOperation( nOpeId)
end
return true
end
---------------------------------------------------------------------
-- *** END GENERAL ***
---------------------------------------------------------------------