Files
Essetre-90480029/Essetre-WALL.mlpe
T
luca.mazzoleni 7d767e4bd4 - aggiunto YAML per compilazione e comunicazione versioni a LiMan
- in mlde aggiunta PP_NVER, versione in formato numerico
- tutte le chiamate a EgtGetSourceDir() sostituite con EgtGetCurrMachineDir()
2024-09-23 12:25:12 +02:00

1011 lines
37 KiB
Plaintext

-- Processore macchina Essetre-WALL by EgalTech s.r.l. 2022/06/14
-- Funzioni generiche indipendenti dal controllo
-- Intestazioni
require( 'EmtGenerator')
EgtEnableDebug( false)
---------------------------------------------------------------------
-- *** GENERATION ***
---------------------------------------------------------------------
local sBaseDir = EgtGetCurrMachineDir()
if NumericalControl == 'NUM' then
dofile( sBaseDir .. '\\Essetre-WALL.NUM.mlpe')
elseif NumericalControl == 'TPA' then
error( 'Numerical Control error : TPA not yet managed')
--dofile( sBaseDir .. 'Essetre-WALL.TPA.mlpe')
else
error( 'Numerical Control error : unkwnown type')
end
---------------------------------------------------------------------
-- *** SIMULATION ***
---------------------------------------------------------------------
---------------------------------------------------------------------
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
-- Non effettuate lavorazioni con sega a catena sul fianco
EMT.CSAWFIRST = true
-- Non effettuata pausa per rimozione sfridi
EMT.SCRAPFIRST = true
-- 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( 'B1', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ)
AddToCollisionCheck( 'C2', '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( 'Y'), 'COLLISION'), 'TRAV')
EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'COL1')
EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'COL2')
EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'TC1')
EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'TC2')
EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'CHSAW')
EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'STM')
EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF1')
EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF2')
EMT.MCODET[10] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF3')
EMT.MCODET[11] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF4')
EMT.MCODET[12] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF5')
for i = #EMT.MCODET, 1, -1 do
if not EMT.MCODET[i] then
table.remove( EMT.MCODET, i)
EgtOutLog( 'Warning : MCODET element (' .. tostring( i) .. ') is null')
end
end
-- Preparo lista collisioni vuota
EMT.COLLIDE = {}
end
---------------------------------------------------------------------
function OnSimulEnd()
if EMT.SCRAPFIRST then
EMT.SCRAPFIRST = false
ExecScrapRemove()
end
ExecUnloading()
end
---------------------------------------------------------------------
--function OnSimulDispositionStarting()
--end
---------------------------------------------------------------------
function OnSimulDispositionStart()
EMT.OPEISDISP = true
-- Se prima disposizione (dovrebbe essere l'unica)
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 = FindFirstToolOnHead( 'H1')
if sTool then
EMT.TOOL_1 = sTool
EgtLoadTool( 'H1', 1, EMT.TOOL_1)
EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1)
ShowToolInTcPos( EMT.TCPOS_1, false)
else
EgtUnloadTool( 'H1', 1)
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
-- dati del grezzo
local nRawId = EgtGetFirstRawPart()
local b3Raw = EgtGetRawPartBBox( nRawId or GDB_ID.NULL)
-- Se abilitato e trovato grezzo, creazione Zmap
if EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') and nRawId then
-- Se vero inizio, creo Zmap
if not EMT.SIM1ST then
-- elimino eventuale vecchio Zmap
EgtErase( EgtGetFirstNameInGroup( nRawId, 'VMill') or GDB_ID.NULL)
-- recupero il solido
local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid')
-- determino la risoluzione dello Zmap
local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
local dArea = b3Sol:getDimX() * b3Sol:getDimY() + b3Sol:getDimX() * b3Sol:getDimZ() + b3Sol:getDimY() * b3Sol:getDimZ()
local dTol = 4.33
if dArea < CoeffVM * 6.0e6 then
dTol = 2.29
elseif dArea < CoeffVM * 12.0e6 then
dTol = 3.07
elseif dArea < CoeffVM * 24.0e6 then
dTol = 3.73
end
-- creo lo Zmap
EMT.VMILL = EgtVolZmapBox( nRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB)
if EMT.VMILL then
EgtSetName( EMT.VMILL, 'VMill')
EgtSetLevel( EMT.VMILL, GDB_LV.TEMP)
EgtSetColor( EMT.VMILL, EgtGetColor( nSolId), false)
-- nascondo le altre geometrie
local nId = EgtGetFirstInGroup( nRawId)
while nId do
if nId ~= EMT.VMILL then
EgtSetStatus( nId, GDB_ST.OFF)
end
nId = EgtGetNext( nId)
end
EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF)
-- imposto eventuale utensile corrente
SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL)
end
end
end
-- 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
if EMT.VMILL then
table.insert( EMT.CODET, EMT.VMILL)
end
end
end
---------------------------------------------------------------------
function OnSimulDispositionEnd()
if EMT.UNLOADING or EMT.FALL then
EMT.UNLOADING = false
EMT.FALL = false
end
EMT.OPEISDISP = false
end
---------------------------------------------------------------------
function OnSimulToolSelect()
-- se utensile non definito, è disposizione ed esco
if EMT.TOOL == '' then return end
-- recupero dati utensile
EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
EMT.TOOLTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
-- se lama su sua testa, verifico che l'altra sia dalla parte opposta
if EMT.HEAD == 'H2' then
EgtSetAxisPos( 'X1', MaxX1)
-- se altrimenti utensile su testa 1, lo carico
elseif EMT.HEAD == 'H1' or EMT.HEAD == 'H3' then
-- se sega a catena, imposto subito angolo scelto per asse virtuale A
if EMT.HEAD == 'H3' then
-- recupero la lavorazione successiva
local NextMchId
if EMT.MCHID then
NextMchId = EgtGetNextActiveOperation( EMT.MCHID)
else
NextMchId = EgtGetFirstActiveOperation()
end
if EgtGetOperationType( NextMchId) == MCH_OY.DISP then
NextMchId = EgtGetNextActiveOperation( NextMchId)
end
EgtSetCurrMachining( NextMchId)
-- leggo e imposto il valore di A1
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
local CSawPosA = EgtGetVal( sVal, 'A1', 'd') or 0
EgtSetAxisPos( 'A1', CSawPosA)
EmtModifyAxisHome( 'A1', CSawPosA)
EgtSetAxisPos( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA))
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
-- se attivo Vmill
SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL)
-- se attivo Collision Check
EMT.SAFEDIST = COLL_SAFE_DIST
if EMT.COLLOBJ then
local nInd = EgtIf( EMT.HEAD ~= 'H2', 1001, 1011)
AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd)
AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1)
for i, Coll in ipairs( EMT.COLLOBJ) do
EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3)
end
end
end
---------------------------------------------------------------------
function OnSimulToolDeselect()
-- porto la testa in home
if EMT.HEAD == 'H2' then
SimulMoveAxes( 'X2', MinX2, MCH_SIM_STEP.RAPID, 'C2', EgtGetAxisHomePos( 'C2'), MCH_SIM_STEP.COLLROT, 'B2', EgtGetAxisHomePos( 'B2'), MCH_SIM_STEP.COLLROT)
elseif EMT.NEXTHEAD == 'H2' then
local ParkX1 = EgtIf( EMT.HEAD == 'H3', ( MinX1 + MaxX1) / 2, MaxX1)
SimulMoveAxes( 'X1', ParkX1, MCH_SIM_STEP.RAPID, 'C1', EgtGetAxisHomePos( 'C1'), MCH_SIM_STEP.COLLROT, 'B1', EgtGetAxisHomePos( 'B1'), MCH_SIM_STEP.COLLROT)
end
-- se testa attuale è sega a catena devo depositarla
if EMT.HEAD == 'H3' then
ShowToolInTcPos( EMT.TCPOS_1, true)
EgtUnloadTool( 'H3', 1)
EMT.TOOL_1 = nil
EMT.TCPOS_1 = nil
end
-- deposito utensile se non lama su sua testa o foratori lunghi
if EMT.NEXTHEAD ~= 'H2' and EMT.NEXTHEAD ~= 'H5' and EMT.NEXTHEAD ~= 'H6' then
if EMT.NEXTTOOL ~= EMT.TOOL_1 then
EgtOutText( 'Tool change in progress...')
-- simulo movimento
SimulMoveAxes( 'B1', 0, MCH_SIM_STEP.COLLROT, 'C1', 0, MCH_SIM_STEP.COLLROT)
SimulMoveAxis( 'X1', MaxX1, MCH_SIM_STEP.RAPID)
-- breve pausa
EgtPause( 100)
ShowToolInTcPos( EMT.TCPOS_1, true)
-- se segue sega a catena
if EMT.NEXTHEAD == 'H3' then
-- nascondo l'utensile corrente
EgtSetStatus( EgtGetHeadId( 'H1'), GDB_ST.OFF)
-- eseguo movimenti opportuni
SimulMoveAxis( 'X1', ( MinX1 + MaxX1) / 2, MCH_SIM_STEP.RAPID)
SimulMoveAxes( 'B1', 0, MCH_SIM_STEP.COLLROT, 'C1', 90, MCH_SIM_STEP.COLLROT)
end
else
EMT.TOOL_1 = nil
EMT.TCPOS_1 = nil
end
end
end
---------------------------------------------------------------------
function OnSimulMachiningStart()
-- recupero alcuni dati della lavorazione
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES)
EMT.VMRS = false
-- recupero CUTID e TASKID della feature lavorata
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
-- eventuale pausa per rimozione sfridi
local bSystemSR = ( EMT.SCRAPFIRST and (( EMT.HEAD == 'H3' and string.sub( EMT.MCHNAME, 1, 5) == 'Csaw_') or EgtExistsInfo( EMT.MCHID, 'MOVE_AFTER')))
local bUserSR = ( EgtGetValInNotes( EMT.MCHUSERNOTES, 'ScrapRemove', 'i') == 1)
if bSystemSR or bUserSR then
if bSystemSR then EMT.SCRAPFIRST = false end
EgtOutText( 'Pause for Scrap Remove')
ParkForScrapRemove()
ExecScrapRemove()
EgtPause( 500)
EgtOutText( '')
end
-- non ancora iniziata la lavorazione
EMT.MCHFIRST = true
end
---------------------------------------------------------------------
function OnSimulMachiningEnd()
if EMT.UNLOADING or EMT.FALL then
EMT.UNLOADING = false
EMT.FALL = false
end
end
---------------------------------------------------------------------
--function OnSimulPathStart()
--end
---------------------------------------------------------------------
function OnSimulPathEnd()
-- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi
if EMT.VMILL and not EMT.OPEISDISP and EMT.VMRS then
EgtOutLog( 'OnSimulPathEnd', 5)
local nPart = EgtVolZmapPartCount( EMT.VMILL)
if nPart > 1 then
-- ricerca del pezzo con massimo volume
local nPartMax = 0
local dVolMax = 0
for i = 1, nPart do
local dVol = EgtVolZmapPartVolume( EMT.VMILL, 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( EMT.VMILL, i - 1, GDB_BB.STANDARD)
if b3Vmill:getDimX() < 1200 then
EgtRemoveVolZmapPart( EMT.VMILL, 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()
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 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
-- se foratura verticale ammetto discesa nel piano fino a 15 mm
if EMT.TOOLTYPE == MCH_TY.DRILL_STD and abs( EgtGetAxisPos( 'B1')) < 60.1 then
local PosZ = EgtGetAxisPos( 'Z1') + MillOffs - ( MillOffs + EMT.TOOLTOTLEN) * EMT.TDIR[3]
local DownZ = PosZ - DeltaTabZ
if DownZ > -15 then
EgtOutLog( 'Top Drill down table '..EgtNumToString( DownZ, 1), 1)
return
end
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 ParkForScrapRemove()
-- Quota di parcheggio
local b3Raw = EgtGetRawPartBBox( EgtGetFirstRawPart() or GDB_ID.NULL)
local ParkY = max( ( b3Raw:getMin():getX() - 2000), MinY)
--Eseguo
SimulMoveAxis( 'Z1', EgtGetAxisHomePos( 'Z1'), MCH_SIM_STEP.RAPID)
SimulMoveAxis( 'Y', ParkY, MCH_SIM_STEP.RAPID)
end
---------------------------------------------------------------------
function ExecScrapRemove()
-- Se non c'è virtual milling attivo, esco
if not EMT.VMILL then return end
-- Se non ci sono almeno due parti nel virtual milling, esco
local nVmPart = EgtVolZmapPartCount( EMT.VMILL)
if nVmPart < 2 then return end
-- Recupero box e area dei pezzi
local vPart = {}
local nPartId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL)
while nPartId do
-- box e area
local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
local dPartArea = b3Part:getDimX() * b3Part:getDimY()
-- box espanso
local b3PartExp = BBox3d( b3Part)
b3PartExp:Add( b3PartExp:getMin() - Vector3d( 10, 10, 0))
b3PartExp:Add( b3PartExp:getMax() + Vector3d( 10, 10, 0))
-- salvo i dati
table.insert( vPart, { Box = b3Part, BoxExp = b3PartExp, Area = dPartArea})
-- passo al successivo
nPartId = EgtGetNextPartInRawPart( nPartId)
end
-- Recupero box e area delle parti di Vmill
local vVmPart = {}
for i = 1, nVmPart do
-- recupero il box e calcolo l'area della parte come Vmill
local b3VmPart = EgtVolZmapGetPartBBoxGlob( EMT.VMILL, i - 1, GDB_BB.STANDARD)
local dVmPartArea = EgtVolZmapPartVolume( EMT.VMILL, i - 1) / b3VmPart:getDimZ()
-- box espanso
local b3VmPartExp = BBox3d( b3VmPart)
b3VmPartExp:Add( b3VmPart:getMin() - Vector3d( 100, 100, 0))
b3VmPartExp:Add( b3VmPart:getMax() + Vector3d( 100, 100, 0))
-- salvo i dati
table.insert( vVmPart, { Box = b3VmPart, BoxExp = b3VmPartExp, Area = dVmPartArea})
end
-- Tengo solo le parti del Vmill che contengono almeno un box di un pezzo o che interferiscono e sono abbastanza grandi
local nValidCnt = 0
for i = #vVmPart, 1, -1 do
-- verifiche per parte da eliminare
local bToRemove = true
-- se area abbastanza grande, allora da verificare
if vVmPart[i].Area > 1e4 then
-- verifico se sono sicuramente valide (i due box si equivalgono entro la tolleranza)
for j = 1, #vPart do
if EnclosesXY( vVmPart[i].BoxExp, vPart[j].Box) and EnclosesXY( vPart[j].BoxExp, vVmPart[i].Box) then
bToRemove = false
vVmPart[i].Part = j
nValidCnt = nValidCnt + 1
break
end
end
-- verifico se sono molto probabilmente valide
for j = 1, #vPart do
if bToRemove and ( OverlapsXY( vVmPart[i].Box, vPart[j].Box) and vVmPart[i].Area > 0.30 * vPart[j].Area) then
bToRemove = false
break
end
end
end
-- se richiesta eliminazione, la eseguo
if bToRemove then
EgtRemoveVolZmapPart( EMT.VMILL, i - 1)
table.remove( vVmPart, i)
end
end
-- Se il numero delle parti sicuramente valide uguaglia il numero dei pezzi, elimino le altre ed ho finito
if nValidCnt == #vPart then
for i = #vVmPart, 1, -1 do
if not vVmPart[i].Part then
EgtRemoveVolZmapPart( EMT.VMILL, i - 1)
table.remove( vVmPart, i)
end
end
return
end
-- Calcolo punti interni alle parti di Vmill non già dichiarate valide
for i = 1, #vVmPart do
if not vVmPart[i].Part then
local vtDir = VectorFromRotated( X_AX(), Z_AX(), 45)
local ptP = vVmPart[i].Box:getCenter() - vtDir * ( vVmPart[i].Box:getRadius() + 10)
local bOk, vIntType, vIntDist = EgtLineVolZmapInters( ptP, vtDir, EMT.VMILL, GDB_RT.GLOB)
if bOk then
for j = 1, #vIntType do
-- se la corrente entra ed esiste la successiva che esce
if vIntType[j] == GDB_SLT.IN and j + 1 <= #vIntType and vIntType[j + 1] == GDB_SLT.OUT then
local ptC = ptP + vtDir * (( vIntDist[j] + vIntDist[j + 1]) / 2)
local nPart = EgtVolZmapGetPartMinDist( EMT.VMILL, ptC, GDB_RT.GLOB)
if nPart == i - 1 then
if not vVmPart[i].Cen then
vVmPart[i].Cen = ptC
elseif not vVmPart[i].Cen2 then
vVmPart[i].Cen2 = ptC
else
vVmPart[i].Cen3 = ptC
break
end
end
end
end
end
end
end
-- Verifico le parti di Vmill non già dichiarate valide
for i = #vVmPart, 1, -1 do
if not vVmPart[i].Part then
local bToRemove = true
if vVmPart[i].Cen then
for j = 1, #vPart do
if EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen) then
bToRemove = false
break
elseif vVmPart[i].Cen2 and EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen2) then
bToRemove = false
break
elseif vVmPart[i].Cen3 and EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen3) then
bToRemove = false
break
end
end
for k = 1, #vVmPart do
if k ~= i then
local vExpBox = BBox3d( vVmPart[k].Box)
-- lo espando in XY per sicurezza
vExpBox:Add( vExpBox:getMin() - Vector3d( 100, 100, 0))
vExpBox:Add( vExpBox:getMax() + Vector3d( 100, 100, 0))
-- verifico contenimento
if EnclosesXY( vExpBox, vVmPart[i].Box) then
bToRemove = true
break
end
end
end
end
-- se richiesta eliminazione, la eseguo
if bToRemove then
EgtRemoveVolZmapPart( EMT.VMILL, i - 1)
table.remove( vVmPart, i)
end
end
end
end
---------------------------------------------------------------------
function ExecUnloading()
if EMT.VMILL then
-- gruppo dei Vmill
local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill')
-- creo un nuovo layer e vi inserisco il nuovo pezzo
local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( EMT.VMILL))
EgtRelocate( EMT.VMILL, nLayId)
EgtSetLevel( EMT.VMILL, GDB_LV.USER)
-- aggiungo gli spigoli
local nFirstId, nCount = EgtVolZmapGetEdges( EMT.VMILL, nLayId)
if nFirstId then
for nId = nFirstId, nFirstId + nCount - 1 do
EgtSetColor( nId, Color3d( 96, 96, 96))
end
end
-- rilascio Vmill
EMT.VMILL = nil
-- 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 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 = 2 -- s
local CHAR_ONE_MOVE_T = 1 -- s
local ROTATION_T = 40 -- s
local SPLIT_T = 6 -- s
local UNLOAD_T = 4 -- s
local FALL_T = 2 -- s
---------------------------------------------------------------------
function OnEstimStart()
EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches
end
---------------------------------------------------------------------
function OnEstimEnd()
end
---------------------------------------------------------------------
function OnEstimProgramStart()
-- imposto inizio movimenti da Home
EMT.L1 = EgtGetAxisHomePos( 'Y')
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()
-- 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
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 > 2 and EMT.AUXIND == EMT.AUXTOT 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 or 0)
local dL2 = EMT.L2 - ( EMT.L2p or 0)
local dL3 = EMT.L3 - ( EMT.L3p or 0)
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
---------------------------------------------------------------------
-- *** END GENERAL ***
---------------------------------------------------------------------