82f0eab4ae
- Cambio versione per rilascio a cliente
1981 lines
75 KiB
Plaintext
1981 lines
75 KiB
Plaintext
-- Processore macchina Essetre-FAST by EgalWare s.r.l. 2024/03/09
|
|
|
|
-- Intestazioni
|
|
require( 'EmtGenerator')
|
|
EgtEnableDebug( false)
|
|
|
|
-- carico librerie
|
|
local BD = require( 'BeamData')
|
|
|
|
---------------------------------------------------------------------
|
|
-- *** GENERATION ***
|
|
---------------------------------------------------------------------
|
|
local sBaseDir = EgtGetCurrMachineDir()
|
|
if NumericalControl == 'NUM' then
|
|
dofile( sBaseDir .. '\\Common_FAST.NUM.mlpe')
|
|
elseif NumericalControl == 'TPA' then
|
|
dofile( sBaseDir .. '\\Common_FAST.TPA.mlpe')
|
|
elseif NumericalControl == 'NUM_PLUS' then
|
|
dofile( sBaseDir .. '\\Common_FAST.NUM_PLUS.mlpe')
|
|
else
|
|
EmtSetLastError( 1201, '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
|
|
-- 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( 'Z', 'COLLISION', EMT.COLLOBJ)
|
|
AddToCollisionCheck( 'B', 'COLLISION', EMT.COLLOBJ)
|
|
AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ)
|
|
AddToCollisionCheck( 'H5', 'COLLISION', EMT.COLLOBJ)
|
|
AddToCollisionCheck( 'H6', 'COLLISION', EMT.COLLOBJ)
|
|
AddToolToCollisionCheck( 'H2', 1, EMT.COLLOBJ)
|
|
AddToolHolderToCollisionCheck( 'H2', 1, 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 = {}
|
|
local McdData = { { Grp = 'Y', Sub = 'COLLISION', Name = 'VOL1'},
|
|
{ Grp = 'Y', Sub = 'COLLISION', Name = 'VOL2'},
|
|
{ Grp = 'PY', Sub = 'COLLISION', Name = 'VOL'},
|
|
{ Grp = 'V', Sub = 'COLLISION', Name = 'VOL1'},
|
|
{ Grp = 'V', Sub = 'COLLISION', Name = 'VOL2'},
|
|
{ Grp = 'PV', Sub = 'COLLISION', Name = 'VOL'},
|
|
{ Grp = 'Base', Sub = 'COLLISION', Name = 'SIDE1'},
|
|
{ Grp = 'Base', Sub = 'COLLISION', Name = 'SIDE2'},
|
|
{ Grp = 'C', Sub = 'COLLISION2', Name = 'C_TOP'}}
|
|
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 or GDB_ID.NULL, McdData[i].Sub) or GDB_ID.NULL, 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()
|
|
--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 dimensioni del grezzo
|
|
local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL
|
|
local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD)
|
|
EMT.LT = 0
|
|
EMT.ST = 0
|
|
EMT.HT = 0
|
|
if b3Sol then
|
|
EMT.LT = b3Sol:getDimX()
|
|
EMT.ST = b3Sol:getDimY()
|
|
EMT.HT = b3Sol:getDimZ()
|
|
end
|
|
-- Carico primo utensile sulla testa 1
|
|
local sTool, nTlen = FindFirstToolOnHead( 'H1')
|
|
if sTool and nTlen < LONG_TOOL_MINLEN 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 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
|
|
-- 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 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 = EgtGetRawPartBBox( nRawId)
|
|
b3Raw:Add( b3Tmp)
|
|
b3Part:Add( b3Tmp)
|
|
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
|
|
EMT.LB = b3Bar:getDimX()
|
|
EMT.LR = b3Raw:getDimX()
|
|
EMT.LT = b3Part:getDimX()
|
|
-- recupero CutId del pezzo in lavorazione
|
|
EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0
|
|
EMT.YSPEC = 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
|
|
-- 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
|
|
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, 'Y')
|
|
end
|
|
end
|
|
nRawId = nNextRawId
|
|
end
|
|
EMT.LB = b3Bar:getDimX()
|
|
end
|
|
-- Indicazione angolo rotazione pezzo
|
|
EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0
|
|
local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN')
|
|
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF))
|
|
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF))
|
|
EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnSimulDispositionEnd()
|
|
if EMT.UNLOADING or EMT.FALL then
|
|
ExecUnloading()
|
|
EMT.UNLOADING = false
|
|
EMT.FALL = false
|
|
end
|
|
-- se disposizione intermedia
|
|
if IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
|
|
-- se le rotazioni delle fasi corrente e precedente sono diverse
|
|
if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then
|
|
-- imposto stato post-rotazione
|
|
EMT.POSTROT = true
|
|
end
|
|
-- se altrimenti disposizione intermedia speciale con eventuale rotazione
|
|
elseif IsMid2Phase( EMT.PHASE) then
|
|
-- se le rotazioni delle fasi corrente e precedente sono diverse
|
|
if GetPhaseRot( EMT.PHASE) ~= GetPhaseRot( EMT.PHASE - 1) then
|
|
-- imposto stato post-rotazione
|
|
EMT.POSTROT = true
|
|
end
|
|
end
|
|
EMT.SPLIT = false
|
|
EMT.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.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN)
|
|
EMT.TOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM)
|
|
-- se non è chiamato da altro script (non c'è parametro)
|
|
if not dPosA then
|
|
-- 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
|
|
for i, Coll in ipairs( EMT.COLLOBJ) do
|
|
EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3)
|
|
end
|
|
if EMT.HEAD ~= 'H2' then
|
|
AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001)
|
|
AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002)
|
|
else
|
|
AddToolToCollisionObj( nil, 'H1', 1, 1001)
|
|
AddToolHolderToCollisionObj( nil, 'H1', 1, 1002)
|
|
end
|
|
end
|
|
-- dichiaro assi ausiliari da visualizzare
|
|
EMT.AuxAxes = 2
|
|
EMT.A1n = 'Y'
|
|
EMT.A2n = 'V'
|
|
end
|
|
-- carico utensile se non lama
|
|
if EMT.HEAD ~= 'H2' then
|
|
-- se sega a catena, imposto subito angolo scelto per asse virtuale A
|
|
if EMT.HEAD == 'H3' then
|
|
if not dPosA 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 A
|
|
dPosA = GetCurrChainSawingVirtualAxis()
|
|
else
|
|
-- imposto visualizzazione
|
|
EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD)
|
|
end
|
|
-- imposto il valore di A
|
|
EgtSetAxisPos( 'A', dPosA)
|
|
local dHomeC = GetChainSawCHomeFromVirtualAxis( dPosA)
|
|
EgtSetAxisPos( 'C', dHomeC)
|
|
EgtSetAxisPos( 'B', 0)
|
|
-- se aggregato per fresa tipo blockhaus
|
|
elseif EMT.HEAD == 'H7' then
|
|
EgtSetAxisPos( 'C', EgtIf( BD.RIGHT_LOAD, 180, 0))
|
|
end
|
|
-- se TC 1
|
|
if GetTCSet( EMT.TCPOS) == 1 then
|
|
EgtSetAxisPos( 'B', 90)
|
|
else
|
|
if EMT.HEAD ~= 'H3' then
|
|
EgtSetAxisPos( 'B', -90)
|
|
end
|
|
end
|
|
-- se punta lunga
|
|
if EMT.TOTLEN > LONG_TOOL_MINLEN then
|
|
-- se su cambio utensile T111
|
|
if EMT.TCPOS == 'T111' then
|
|
EgtSetAxisPos( 'B', 0)
|
|
end
|
|
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
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnSimulToolDeselect()
|
|
-- se prossimo utensile non definito, è disposizione ed esco
|
|
if EMT.NEXTTOOL == '' then return end
|
|
-- se cambia uscita su rinvio non devo fare alcunché
|
|
if ( EMT.HEAD == 'H5' and EMT.NEXTHEAD == 'H5') or ( EMT.HEAD == 'H6' and EMT.NEXTHEAD == 'H6') then return end
|
|
-- se sega a catena o rinvio o punta lunga o utensile di grosso diametro, devo cambiare
|
|
if EMT.HEAD == 'H3' or EMT.HEAD == 'H5' or EMT.HEAD == 'H6' or EMT.HEAD == 'H7' 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
|
|
-- se avevo motosega, torno in zona sicura senza ruotare assi rotanti
|
|
SimulMoveAxis( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID)
|
|
-- raddrizzo asse B prima di ruotare il C
|
|
SimulMoveAxis( 'B', 0, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'C', 0, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
-- movimento scarico rinvio
|
|
elseif EMT.HEAD == 'H5' or EMT.HEAD == 'H6' then
|
|
SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
-- movimento scarico aggregato BlockHaus
|
|
elseif EMT.HEAD == 'H7' then
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
SimulMoveAxes( 'B', 90, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT)
|
|
-- movimento scarico punta lunga su T111
|
|
elseif EMT.TOTLEN > LONG_TOOL_MINLEN then
|
|
-- se su cambio utensile T111
|
|
if EMT.TCPOS == 'T111' then
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
SimulMoveAxes( 'B', 0, MCH_SIM_STEP.COLLROT, 'C', 0, MCH_SIM_STEP.COLLROT)
|
|
-- altrimenti posizioni standard rastrelliera
|
|
else
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
if GetTCSet( EMT.TCPOS) == 1 then
|
|
SimulMoveAxes( 'B', 90, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT)
|
|
else
|
|
SimulMoveAxes( 'B', -90, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT)
|
|
end
|
|
end
|
|
-- movimento scarico utensile di grosso diametro (su T111)
|
|
else
|
|
local dPosB = EgtGetAxisPos( 'B')
|
|
local dNewB = EgtIf( dPosB < 0, -90, 90)
|
|
SimulMoveAxes( 'B', dNewB, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 180, 0), MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'X', 0, 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
|
|
if EMT.NEXTHEAD ~= 'H3' and EMT.NEXTHEAD ~= 'H5' and EMT.NEXTHEAD ~= 'H6' then
|
|
SimulMoveAxes( 'B', EgtIf( GetTCSet( EMT.TCPOS) == 1, 90, -90), MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT)
|
|
else
|
|
if EMT.NEXTHEAD == 'H3' then
|
|
SimulMoveAxes( 'B', 0, MCH_SIM_STEP.RAPROT, 'C', 0, MCH_SIM_STEP.RAPROT)
|
|
else
|
|
SimulMoveAxes( 'B', 0, MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT)
|
|
end
|
|
end
|
|
-- se segue lama, carico utensile di default
|
|
if EMT.NEXTHEAD == 'H2' then
|
|
local sDefTool = GetDefaultToolName()
|
|
EMT.TOOL_1 = sDefTool
|
|
EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1)
|
|
-- se TC 1
|
|
if GetTCSet( EMT.TCPOS_1) == 1 then
|
|
EgtSetAxisPos( 'B', 90)
|
|
else
|
|
EgtSetAxisPos( 'B', -90)
|
|
end
|
|
EgtLoadTool( 'H1', 1, sDefTool)
|
|
-- lo nascondo sul portautensili
|
|
ShowToolInTcPos( EMT.TCPOS_1, false)
|
|
end
|
|
EgtOutText( '')
|
|
-- deposito utensile se prossimo non lama su sua testa
|
|
elseif EMT.NEXTHEAD ~= 'H2' then
|
|
if EMT.NEXTTOOL ~= EMT.TOOL_1 then
|
|
EgtOutText( 'Tool change in progress...')
|
|
-- simulo movimento
|
|
SimulMoveAxes( 'B', 90, MCH_SIM_STEP.COLLROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'X', 0, MCH_SIM_STEP.RAPID)
|
|
-- breve pausa
|
|
EgtPause( 100)
|
|
ShowToolInTcPos( EMT.TCPOS_1, true)
|
|
-- se segue sega a catena
|
|
if EMT.NEXTHEAD == 'H3' or EMT.NEXTHEAD == 'H5' or EMT.NEXTHEAD == 'H6' then
|
|
-- se non lama, nascondo l'utensile corrente
|
|
if EMT.HEAD ~= 'H2' then
|
|
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF)
|
|
end
|
|
-- eseguo movimento opportuno
|
|
SimulMoveAxes( 'B', 0, MCH_SIM_STEP.RAPROT, 'C', EgtIf( BD.RIGHT_LOAD, 90, -90), MCH_SIM_STEP.RAPROT)
|
|
-- se altrimenti lama su cambio utensile
|
|
elseif EMT.NEXTHEAD == 'H1' and SpecialBH and EMT.NEXTTCPOS == 'T111' then
|
|
-- se non lama, nascondo l'utensile corrente
|
|
if EMT.HEAD ~= 'H2' then
|
|
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF)
|
|
end
|
|
-- eseguo movimento opportuno
|
|
SimulMoveAxes( 'B', -90, MCH_SIM_STEP.RAPROT, 'C', 0, MCH_SIM_STEP.RAPROT)
|
|
end
|
|
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 A diverso, devo scaricare e ricaricare
|
|
if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then
|
|
local dPrevA = EgtGetAxisPos( 'A')
|
|
local dPosA = GetCurrChainSawingVirtualAxis()
|
|
if abs( dPosA - dPrevA) > 1 then
|
|
OnSimulToolDeselect()
|
|
EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON)
|
|
OnSimulToolSelect( dPosA)
|
|
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.SPLIT = nil
|
|
EMT.PREVHEAD = EMT.HEAD
|
|
EMT.PREVTOOL = EMT.TOOL
|
|
EMT.PREVEXIT = EMT.EXIT
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
--function OnSimulPathStart()
|
|
--end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnSimulPathEnd()
|
|
-- rimozione eventuali sfridi
|
|
ExecRemoveScraps()
|
|
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 Yp = EgtGetAxisPos( 'Y')
|
|
local Vp = EgtGetAxisPos( 'V')
|
|
-- Imposto movimento carrelli insieme con la tavola :
|
|
-- entrambe le pinze
|
|
if EMT.YDELTA and EMT.VDELTA then
|
|
EMT.AuxAxes = 2
|
|
EMT.A1n = 'Y'
|
|
EMT.A1m = 'T'
|
|
EMT.A1 = EMT.L1 + EMT.YDELTA
|
|
EMT.A2n = 'V'
|
|
EMT.A2m = 'T'
|
|
EMT.A2 = EMT.L1 + EMT.VDELTA
|
|
-- solo pinza Y
|
|
elseif EMT.YDELTA then
|
|
EMT.AuxAxes = 2
|
|
EMT.A1n = 'Y'
|
|
EMT.A1m = 'T'
|
|
EMT.A1 = EMT.L1 + EMT.YDELTA
|
|
EMT.A2n = 'V'
|
|
EMT.A2m = nil
|
|
EMT.A2 = ParkV
|
|
-- solo pinza V
|
|
elseif EMT.VDELTA then
|
|
EMT.AuxAxes = 2
|
|
EMT.A1n = 'Y'
|
|
EMT.A1m = nil
|
|
EMT.A1 = EgtIf( EMT.YSPEC, Yp, ParkY)
|
|
EMT.A2n = 'V'
|
|
EMT.A2m = 'T'
|
|
EMT.A2 = EMT.L1 + EMT.VDELTA
|
|
end
|
|
-- Controllo scorrimento pinze chiuse Y e V
|
|
if EMT.YDELTA then
|
|
local dYDeltaP = Yp - EMT.L1p
|
|
if abs( EMT.YDELTA - dYDeltaP) > 0.1 then
|
|
EMT.ERR = 2
|
|
local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.YDELTA, 3)
|
|
EmtSetLastError( 1202, sErr)
|
|
end
|
|
end
|
|
if EMT.VDELTA then
|
|
local dVDeltaP = Vp - EMT.L1p
|
|
if abs( EMT.VDELTA - dVDeltaP) > 0.1 then
|
|
EMT.ERR = 2
|
|
local sErr = 'V slide : ' .. EgtNumToString( dVDeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.VDELTA, 3)
|
|
EmtSetLastError( 1202, sErr)
|
|
end
|
|
end
|
|
-- Controllo corse assi Y e V
|
|
VerifyYStroke( EMT.A1)
|
|
VerifyVStroke( EMT.A2)
|
|
-- se inizio lavorazione
|
|
if EMT.MCHFIRST then
|
|
|
|
local bGoToHome = false
|
|
-- se gli assi rotanti cambiano parecchio, con motosega si va in parcheggio
|
|
if EMT.PREVHEAD == 'H3' and EMT.HEAD == 'H3' and EMT.TOOL == EMT.PREVTOOL and abs( EMT.R3p - EMT.R3) < 100 * GEO.EPS_SMALL and ( abs( EMT.R2p - EMT.R2) > 25 or abs( EMT.R1p - EMT.R1) > 25) then
|
|
bGoToHome = true
|
|
end
|
|
|
|
EgtOutText( '')
|
|
EMT.MCHFIRST = false
|
|
local bZmax = ( EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1)
|
|
-- con pezzi alti aggiorno gli assi rotanti prima di muovermi sopra il pezzo
|
|
if EMT.HEAD == 'H3' and EMT.PREVHEAD ~= 'H3' then
|
|
SimulMoveAxis( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID)
|
|
SimulMoveAxis( 'B', 0, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'C', EMT.R1, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'B', EMT.R2, MCH_SIM_STEP.COLLROT)
|
|
elseif not EMT.LOAD and EMT.MOVE == 0 and ( EMT.HEAD == 'H3' or ( bZmax and EMT.TOTLEN > 200)) and
|
|
( EMT.HT > BeamHeightForFixRot or ( EMT.HEAD == 'H1' and EMT.TOTLEN > 350) or bGoToHome) and EMT.FLAG2 == 1 then
|
|
-- se motosega mi muovo a X di sicurezza per ruotare, prima si raddrizza B e poi C in posizione
|
|
if EMT.HEAD == 'H3' and bGoToHome then
|
|
SimulMoveAxis( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID)
|
|
SimulMoveAxis( 'B', 0, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'C', EMT.R1, MCH_SIM_STEP.COLLROT)
|
|
SimulMoveAxis( 'B', EMT.R2, MCH_SIM_STEP.COLLROT)
|
|
elseif ( bZmax and EMT.TOTLEN > 200) then
|
|
SimulMoveAxes( 'X', SafeXRotAxes, MCH_SIM_STEP.RAPID, 'C', EMT.R1, MCH_SIM_STEP.COLLROT, 'B', EMT.R2, MCH_SIM_STEP.COLLROT)
|
|
end
|
|
end
|
|
EMT.POSTROT = nil
|
|
end
|
|
-- 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()
|
|
-- se termine di passata con lama
|
|
if EMT.FLAG == 301 then
|
|
-- rimozione eventuali sfridi
|
|
ExecRemoveScraps()
|
|
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
|
|
-- standard
|
|
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] == 'Split' then
|
|
EMT.SPLIT = 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 VerifyYVStroke( Cmd[2], tonumber( Cmd[3])) == nil then
|
|
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
|
|
end
|
|
end
|
|
elseif Cmd[1] == '2' then
|
|
if Cmd[2] == 'Y' 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 VerifyYVStroke( 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 VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then
|
|
EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd)
|
|
end
|
|
end
|
|
elseif Cmd[1] == '11' then
|
|
ExecMovePY( Cmd[2] ~= '0')
|
|
elseif Cmd[1] == '12' then
|
|
ExecMovePV( Cmd[2] ~= '0')
|
|
elseif Cmd[1] == '21' then
|
|
local nYDelta = tonumber( Cmd[2])
|
|
local nVDelta = tonumber( Cmd[3])
|
|
if nYDelta > 0.01 and nVDelta > 0.01 then
|
|
EMT.YDELTA = nYDelta
|
|
EMT.VDELTA = nVDelta
|
|
elseif nYDelta > 0.01 then
|
|
EMT.YDELTA = nYDelta
|
|
EMT.VDELTA = nil
|
|
elseif nVDelta > 0.01 then
|
|
EMT.YDELTA = nil
|
|
EMT.VDELTA = nVDelta
|
|
end
|
|
elseif Cmd[1] == '31' then
|
|
local nRawId = tonumber( Cmd[2])
|
|
EmtUnlinkRawPartFromGroup( nRawId)
|
|
EmtLinkRawPartToGroup( nRawId, Cmd[3])
|
|
EMT.YSPEC = true
|
|
end
|
|
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
|
|
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() < 1250 then
|
|
EgtRemoveVolZmapPart( vMillId, i - 1)
|
|
end
|
|
end
|
|
end
|
|
-- aggiorno visualizzazione
|
|
EgtDraw()
|
|
end
|
|
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, EgtIf( BD.RIGHT_LOAD, ( EMT.ST + 50.0), -( EMT.ST + 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, 450, -450), 0)
|
|
if EMT.FALL then vtMove = Vector3d( 0, EgtIf( BD.RIGHT_LOAD, 500, -500), -750) 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)
|
|
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 CheckClamping( sClampName)
|
|
|
|
local nClampId = EgtGetAxisId( sClampName) or GDB_ID.NULL
|
|
local nClampPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nClampId, 'CLAMP_CHECK') or GDB_ID.NULL)
|
|
local b3ClampingArea = EgtGetBBoxGlob( nClampPathId or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- se non trovo percorso area di clamping, esco subito
|
|
if not nClampPathId or not EMT.VMILL or not ClampingCoeffMin then
|
|
return
|
|
end
|
|
|
|
local function GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth)
|
|
local vCurveListId = {}
|
|
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 nLoopId, nLoopCnt = EgtPlaneVolZmapInters( ptPosIntersPlane, vtIntersPlane, EMT.VMILL[i], CLAMP_CHECK_INTERS, GDB_RT.GLOB)
|
|
vCurveListId = EgtTableAdd( vCurveListId, nLoopId, nLoopCnt)
|
|
end
|
|
|
|
return vCurveListId
|
|
end
|
|
|
|
local function CalculateIntersectionArea( sPosIntersPlane, sIntersPlane, dDepth)
|
|
-- test piano frontale
|
|
local vCurveListId = GetCurveListFromIntersection( sPosIntersPlane, sIntersPlane, dDepth)
|
|
-- si copia curva intersezione e curva pinza in gruppo di confronto
|
|
local nFlatSurfId, nFlatSurfCnt = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, vCurveListId)
|
|
local vFlatSurfId = EgtTableFill( nFlatSurfId, nFlatSurfCnt) or {}
|
|
local nClampSurfId = EgtSurfFlatRegion( CLAMP_CHECK_GROUP, nClampPathId)
|
|
|
|
local dTotalArea = 0
|
|
local dTotalXLenght = 0
|
|
for i = 1, #vFlatSurfId do
|
|
local nTempSurfId = vFlatSurfId[i]
|
|
EgtSurfFrIntersect( nTempSurfId, nClampSurfId)
|
|
if nTempSurfId then
|
|
dTotalArea = dTotalArea + ceil( EgtSurfArea( nTempSurfId) or 0)
|
|
local b3BoxIntersectionBox = EgtGetBBoxGlob( nTempSurfId, GDB_BB.STANDARD)
|
|
if b3BoxIntersectionBox then
|
|
dTotalXLenght = dTotalXLenght + ceil( b3BoxIntersectionBox:getDimX()) -- somma lunghezze (x) delle aree pinzate
|
|
end
|
|
end
|
|
end
|
|
return dTotalArea, dTotalXLenght
|
|
end
|
|
|
|
-- minima area considerata per un corretto pinzaggio
|
|
DistZClampToTable = DistZClampToTable or 0
|
|
--local MinJoin = BD.GetMinJoin( EMT.ST, EMT.HT, EgtIf( EMT.SPLIT, EMT.LT, EMT.LB))
|
|
UpdateMinJoinDeltaTol( EMT.ST, EMT.HT, EgtIf( EMT.SPLIT, EMT.LT, EMT.LB))
|
|
local MinZClamping = min( b3ClampingArea:getDimZ() + DistZClampToTable, EMT.HT) - DistZClampToTable
|
|
local dMinClamping = ( MinJoin * MinZClamping)
|
|
-- si moltiplica per un coefficiente minimo sotto al quale si da l'errore di pinzaggio
|
|
ClampingCoeffMin = EgtClamp( ClampingCoeffMin, 0.01, 1)
|
|
if MinZClamping > 116 then
|
|
dMinClamping = MinJoin * 116 + ( pow( MinJoin, 2) / 2)
|
|
if MinJoin > 280 then
|
|
dMinClamping = MinJoin * 116 + ( pow( 280, 2) / 2) + ( pow( MinJoin - 280, 2))
|
|
end
|
|
end
|
|
|
|
local dMinClampingAreaWarn = dMinClamping * ClampingCoeffMin
|
|
local dMinClampingAreaErr = dMinClamping * ( 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, dXClampedLenght = 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 ExecMovePY( bClose)
|
|
--SimulMoveAxes( 'PY', EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID)
|
|
local dPY = MaxOpen
|
|
if bClose then
|
|
dPY = EgtIf( EMT.ROT == -1, EMT.HT, EMT.ST)
|
|
end
|
|
SimulMoveAxis( 'PY', dPY, MCH_SIM_STEP.RAPID)
|
|
SetPYLight( bClose)
|
|
if bClose then
|
|
CheckClamping( 'PY')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function ExecMovePV( bClose)
|
|
--EgtIf( not bClose, MaxHoOpen, EMT.HB), MCH_SIM_STEP.RAPID)
|
|
local dPV = MaxOpen
|
|
if bClose then
|
|
dPV = EgtIf( EMT.ROT == -1, EMT.HT, EMT.ST)
|
|
end
|
|
SimulMoveAxis( 'PV', dPV, MCH_SIM_STEP.RAPID)
|
|
SetPVLight( bClose)
|
|
if bClose then
|
|
CheckClamping( 'PV')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function VerifyYSlide( sName1, dVal1, sName2, dVal2)
|
|
-- Se movimento trave agganciata con carrello Y
|
|
if sName1 == 'T' and sName2 == 'Y' and GetPYLight() then
|
|
local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'Y')
|
|
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 == 'V' and GetPVLight() then
|
|
local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'V')
|
|
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 == 'Y' then
|
|
return VerifyYSlide( sName1, dVal1, sName2, dVal2)
|
|
elseif sName2 == 'V' 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 == 'Y' then
|
|
return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3)
|
|
elseif sName2 == 'V' then
|
|
return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3)
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function VerifyYStroke( dY)
|
|
if dY < MinY then
|
|
EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MinY, ' (L1-)')
|
|
EMT.ERR = 1
|
|
local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MinY, 3)
|
|
EgtOutLog( sErr)
|
|
return false
|
|
elseif dY > MaxY then
|
|
EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MaxY, ' (L1+)')
|
|
EMT.ERR = 1
|
|
local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MaxY, 3)
|
|
EgtOutLog( sErr)
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function VerifyVStroke( dV)
|
|
if dV > MaxV then
|
|
EmtSetOutstrokeInfo( 'V', 'V', true, dV - MaxV, ' (L1+)')
|
|
EMT.ERR = 1
|
|
local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MaxV, 3)
|
|
EgtOutLog( sErr)
|
|
return false
|
|
elseif dV < MinV then
|
|
EmtSetOutstrokeInfo( 'V', 'V', true, dV - MinV, ' (L1-)')
|
|
EMT.ERR = 1
|
|
local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MinV, 3)
|
|
EgtOutLog( sErr)
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function VerifyYVStroke( sName, dVal)
|
|
if sName == 'Y' then
|
|
return VerifyYStroke( dVal)
|
|
elseif sName == 'V' then
|
|
return VerifyVStroke( dVal)
|
|
else
|
|
return nil
|
|
end
|
|
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 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 ESTIMATION_RAPID_COEFF = EstimationRapidMultiplier or 1
|
|
local RAPID_X_FEED = 100000 / ESTIMATION_RAPID_COEFF -- mm/min
|
|
local RAPID_Y_FEED = 100000 / ESTIMATION_RAPID_COEFF -- mm/min
|
|
local RAPID_Z_FEED = 100000 / ESTIMATION_RAPID_COEFF -- mm/min
|
|
local RAPID_C_FEED = 12000 / ESTIMATION_RAPID_COEFF -- deg/min
|
|
local RAPID_B_FEED = 12000 / 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
|
|
|
|
-- TPA
|
|
if NumericalControl == 'TPA' then
|
|
EMT.FMAXPINZE = EgtClamp( MaxFeedPinze or 154000, 20000, 160000) -- feed massima pinze
|
|
EMT.MAXACC = MaxAcc or 4000 -- accelerazione massima pinze. In realtà è il tempo in millisecondi, quindi MAXACC corrisponde al tempo massimo per raggiungere la velocità desiderata
|
|
EMT.MINACC = MinAcc or 300 -- accelerazione minima pinze. In realtà è il tempo in millisecondi, quindi MINACC corrisponde al tempo massimo per raggiungere la velocità desiderata
|
|
-- NUM_PLUS e NUM
|
|
else
|
|
EMT.FMAXPINZE = EgtClamp( MaxFeedPinze or 154000, 20000, 160000) -- feed massima pinze
|
|
EMT.MAXACC = MaxAcc or ( EMT.FMAXPINZE / ( 60 * 0.3)) -- accelerazione massima pinze
|
|
EMT.MINACC = MinAcc or ( EMT.FMAXPINZE / ( 60 * 4)) -- accelerazione minima pinze
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimEnd()
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimProgramStart()
|
|
-- imposto inizio movimenti da Home
|
|
EMT.L1 = EgtGetAxisHomePos( 'T')
|
|
EMT.L2 = EgtGetAxisHomePos( 'X')
|
|
EMT.L3 = EgtGetAxisHomePos( 'Z')
|
|
EMT.R1 = EgtGetAxisHomePos( 'C')
|
|
EMT.R2 = EgtGetAxisHomePos( 'B')
|
|
-- aggiorno valori come precedenti
|
|
EmtUpdatePrev()
|
|
-- totalizzatori tempi e lunghezze
|
|
EMT.TOTCUTLEN = 0
|
|
EMT.TOTCUTTIME = 0
|
|
EMT.TOTEXTLEN = 0
|
|
EMT.TOTEXTTIME = 0
|
|
-- variabile per lunghezza taglio utensili
|
|
EMT.TOOLCUTLEN = {}
|
|
-- intestazioni
|
|
EmtTleStart( EMT.INFO)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimProgramEnd()
|
|
-- stampa dei totali delle lavorazioni
|
|
EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN))
|
|
-- stampa dei totali degli utensili
|
|
for i = 1, #EMT.TOOLCUTLEN do
|
|
local TCL = EMT.TOOLCUTLEN[i]
|
|
EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len))
|
|
end
|
|
-- completo il file
|
|
local _, _, sExt = EgtSplitPath( EMT.FILE)
|
|
EmtTleEnd( sExt:sub( 2))
|
|
-- salvo i dati principali nel progetto
|
|
EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0))
|
|
EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimDispositionStart()
|
|
-- inizio disposizione
|
|
EMT.OPEISDISP = true
|
|
-- sulla prima fase dichiaro carico barra
|
|
if EMT.PHASE == 1 then
|
|
EMT.LOAD = true
|
|
else
|
|
EMT.LOAD = false
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimDispositionEnd()
|
|
-- Se disposizione inizio o rimanenza
|
|
if IsStartOrRestPhase( EMT.PHASE) then
|
|
;
|
|
-- se altrimenti disposizione intermedia o finale dopo separazione e rotazione, eventuale rotazione
|
|
elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then
|
|
-- recupero le rotazioni delle fasi corrente e precedente
|
|
local nRot = GetPhaseRot( EMT.PHASE)
|
|
local nPrevRot = GetPhaseRot( EMT.PHASE - 1)
|
|
-- verifico se sono diverse
|
|
if nRot ~= nPrevRot then
|
|
-- imposto stato post-rotazione
|
|
EMT.POSTROT = true
|
|
end
|
|
-- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni
|
|
else
|
|
;
|
|
end
|
|
-- emetto dati in sospeso
|
|
if EMT.TLE_NAME then
|
|
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
|
|
EMT.TLE_NAME = nil
|
|
EMT.TLE_TIME = nil
|
|
end
|
|
-- termine disposizione
|
|
EMT.OPEISDISP = false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimRawMoveData()
|
|
-- se start del pezzo
|
|
if IsStartOrRestPhase( EMT.PHASE) then
|
|
EMT.SPLIT = false
|
|
end
|
|
OnRawMoveData()
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimToolSelect()
|
|
-- reset indice utensile in tabella lunghezze
|
|
EMT.TCLIND = 0
|
|
-- verifico che l'utensile sia definito
|
|
if #EMT.TOOL == 0 then return end
|
|
-- cerco l'utensile nella tabella
|
|
for i = 1, #EMT.TOOLCUTLEN do
|
|
if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then
|
|
EMT.TCLIND = i
|
|
break
|
|
end
|
|
end
|
|
-- se non trovato, lo aggiungo
|
|
if EMT.TCLIND == 0 then
|
|
table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0})
|
|
EMT.TCLIND = #EMT.TOOLCUTLEN
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimToolDeselect()
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimMachiningStart()
|
|
EMT.MCHNAME = EgtGetOperationName( EMT.MCHID)
|
|
EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE)
|
|
EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5)
|
|
-- reset contatori di lavorazione
|
|
EMT.MCHCUTLEN = 0
|
|
EMT.MCHCUTTIME = 0
|
|
EMT.MCHEXTLEN = 0
|
|
EMT.MCHEXTTIME = 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimMachiningEnd()
|
|
-- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita
|
|
if EMT.MCHTYPE == MCH_MY.DRILLING then
|
|
EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2
|
|
end
|
|
local sName = EgtGetName( EMT.MCHID)
|
|
EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL)
|
|
-- aggiorno totali e utensili
|
|
EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN
|
|
EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME
|
|
EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN
|
|
EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME
|
|
EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN
|
|
-- emetto dati in sospeso
|
|
if EMT.TLE_NAME then
|
|
EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ')
|
|
EMT.TLE_NAME = nil
|
|
EMT.TLE_TIME = nil
|
|
end
|
|
|
|
EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
|
|
EMT.MCHSPLIT = ( EMT.MCHUSERNOTES:find( 'Split;', 1, true) ~= nil)
|
|
if EMT.MCHSPLIT then
|
|
EMT.SPLIT = true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnEstimPathStart()
|
|
EMT.AUXTYPE = nil
|
|
EMT.MCHMOVEFIRST = true
|
|
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 = CalcMoveTime( abs( dL1), EMT.FMAXPINZE, EMT.SPLIT)
|
|
if dT1 > dTime then dTime = dT1 end
|
|
local dT2 = abs( dL2) / ( RAPID_X_FEED / 60) -- CalcMoveTime( abs( dL2), RAPID_X_FEED, EMT.SPLIT)
|
|
if dT2 > dTime then dTime = dT2 end
|
|
local dT3 = abs( dL3) / ( RAPID_Z_FEED * 60) -- 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 = dLen / ( EMT.F / 60) -- 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 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 IsEndPhase( nPhase)
|
|
local sVal = GetPhaseType( nPhase)
|
|
return ( sVal == 'END')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function IsMidPhase( nPhase)
|
|
local sVal = GetPhaseType( nPhase)
|
|
return ( sVal == 'MID')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function IsMid2Phase( nPhase)
|
|
local sVal = GetPhaseType( nPhase)
|
|
return ( sVal == 'MID2')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function IsEnd2Phase( nPhase)
|
|
local sVal = GetPhaseType( nPhase)
|
|
return ( sVal == 'END2')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetPhaseType( nPhase)
|
|
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetPhaseOrd( nPhase)
|
|
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetPhaseRot( nPhase)
|
|
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetParkT()
|
|
local dTmp = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EgtGetInfo( EMT.DISPID, 'TPARK', 'd')
|
|
if dTmp then
|
|
return dTmp
|
|
else
|
|
return LoadT
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetCurrChainSawingVirtualAxis()
|
|
-- recupero il valore dell'asse virtuale bloccato A
|
|
local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A=0'
|
|
local dPosA = tonumber( sVal:sub( 3)) or 0
|
|
return dPosA
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function CalcDinamicaPinze_TPA( dH, dS, dL)
|
|
local MinTempoAcc = EMT.MINACC -- [ms] ~300
|
|
local MaxTempoAcc = EMT.MAXACC -- [ms] ~4000
|
|
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 CalcDinamicaPinze_NUM( dH, dS, dL)
|
|
local KgMtCubo= WoodDensity or 550 -- densità legno [Kg / metro cubo]
|
|
local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg]
|
|
local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min]
|
|
local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N]
|
|
local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito) / 1000)
|
|
local AccMaxPinze = EMT.MAXACC
|
|
local AccPinze = EgtClamp( FMaxPinze / ( 60 * TempoAcc), EMT.MINACC, EMT.MAXACC)
|
|
local RidFeed = 100 / Massa * 100
|
|
if RidFeed > 100 then
|
|
RidFeed = 100
|
|
elseif RidFeed < 10 then
|
|
RidFeed = 10
|
|
end
|
|
return AccPinze, AccMaxPinze, RidFeed, TempoAcc
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function CalcMoveTime( dPathLen, dFeed, bIsSplitted)
|
|
local dTime
|
|
local dFeedInSec = dFeed / 60
|
|
|
|
if NumericalControl == 'TPA' then
|
|
local dTempoAcc, _, _ = CalcDinamicaPinze_TPA( EMT.HT, EMT.ST, 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
|
|
else
|
|
local dAcc, _, _, _ = CalcDinamicaPinze_NUM( EMT.HT, EMT.ST, EgtIf( bIsSplitted, EMT.LT, EMT.LB))
|
|
-- Caso 1: dFeed raggiunta
|
|
if dPathLen >= ( dFeedInSec ^ 2) / dAcc then
|
|
dTime = ( dFeedInSec / dAcc) + ( dPathLen / dFeedInSec)
|
|
-- Caso 2: dFeed non raggiunta
|
|
else
|
|
dTime = 2 * sqrt( dPathLen / dAcc)
|
|
end
|
|
end
|
|
|
|
return dTime
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- *** END GENERAL ***
|
|
---------------------------------------------------------------------
|