2573 lines
106 KiB
Plaintext
2573 lines
106 KiB
Plaintext
-- Special Operations macchina Essetre-PF1250 by Egalware s.r.l. 2024/04/09
|
|
-- Intestazioni
|
|
|
|
require( 'EmtGenerator')
|
|
EgtEnableDebug( false)
|
|
|
|
-- Carico libreria
|
|
local BD = require( 'BeamData')
|
|
|
|
---------------------------------------------------------------------
|
|
-- *** Special Z moves ***
|
|
---------------------------------------------------------------------
|
|
---------------------- OnSpecialGetMaxZ -----------------------------
|
|
local function CalcExtraZ( vtTp, vtT, vMZ)
|
|
-- la tabella deve esistere ed essere non vuota
|
|
if not vMZ or #vMZ == 0 then return 0 end
|
|
-- componente Z di riferimento è la minima
|
|
local vtTz = min( vtTp:getZ(), vtT:getZ())
|
|
-- se oltre il massimo
|
|
if vtTz > vMZ[1].Tz then return vMZ[1].Ez end
|
|
-- interpolo
|
|
for i = 2, #vMZ do
|
|
if vtTz > vMZ[i].Tz then
|
|
local dCoeff = ( vtTz - vMZ[i-1].Tz) / ( vMZ[i].Tz - vMZ[i-1].Tz)
|
|
return (( 1 - dCoeff) * vMZ[i-1].Ez + dCoeff * vMZ[i].Ez)
|
|
end
|
|
end
|
|
-- sotto il minimo
|
|
return 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnSpecialGetMaxZ()
|
|
-- Inizializzazioni
|
|
EMC.ERR = 0
|
|
|
|
-- Gestione speciale per sega a catena
|
|
if EMC.HEAD == 'H13' then
|
|
EMC.MAXZ = EgtGetAxisHomePos( 'Z1')
|
|
return
|
|
end
|
|
|
|
-- Sistemazione dati di input
|
|
local vtTp = Vector3d( EMC.TDIRp)
|
|
local bFromZmax = false
|
|
-- recupero il gruppo
|
|
local nSetHead = GetHeadSet( EMC.HEAD)
|
|
if vtTp:isSmall() then
|
|
vtTp = X_AX()
|
|
bFromZmax = true
|
|
if nSetHead == 1 then
|
|
EMC.R1p = ParkC1
|
|
EMC.R2p = ParkB1
|
|
elseif nSetHead == 2 then
|
|
EMC.R1p = ParkC2
|
|
EMC.R2p = ParkB2
|
|
elseif nSetHead == 3 then
|
|
EMC.R1p = ParkC3
|
|
EMC.R2p = ParkB3
|
|
end
|
|
end
|
|
local vtT = Vector3d( EMC.TDIR)
|
|
local vtTpZm = EgtIf( bFromZmax, vtT, vtTp)
|
|
local bBSameSign = (( EMC.R2p < 10 and EMC.R2 < 10) or ( EMC.R2p > -10 and EMC.R2 > -10))
|
|
|
|
-- Calcolo in funzione della testa e dei parametri
|
|
if EMC.HEAD == 'H11' then
|
|
if bBSameSign and vtTp:getX() > -0.1 and vtT:getX() > -0.1 then
|
|
EMC.MAXZ = MaxZ1
|
|
else
|
|
local vMZ = {{ Tz=0.85, Ez=390}, { Tz=0.5, Ez=280}, { Tz=-0.01, Ez=160}}
|
|
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
end
|
|
elseif EMC.HEAD == 'H12' then
|
|
if vtTp:getX() > 0.3 and vtT:getX() > 0.3 then
|
|
if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then
|
|
EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
|
|
elseif vtTp:getZ() > 0.707 or vtT:getZ() > 0.707 then
|
|
EMC.MAXZ = ParkZ1 + 200
|
|
elseif vtTp:getZ() > 0.5 or vtT:getZ() > 0.5 then
|
|
EMC.MAXZ = ParkZ1 + 100
|
|
else
|
|
EMC.MAXZ = ParkZ1 + 1
|
|
end
|
|
elseif bBSameSign and EMC.R1p > 29.9 and EMC.R1p < 180.1 and EMC.R1 > 29.9 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then
|
|
EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
|
|
elseif bBSameSign and EMC.R1p > -0.1 and EMC.R1p < 180.1 and EMC.R1 > -0.1 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then
|
|
local vMZ = {{ Tz=0.85, Ez=440}, { Tz=0.5, Ez=200}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}}
|
|
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
else
|
|
local vMZ = {{ Tz=0.85, Ez=400}, { Tz=0.7, Ez=300}, { Tz=0.5, Ez=195}, { Tz=0.15, Ez=70}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}}
|
|
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
end
|
|
elseif EMC.HEAD == 'H16' then
|
|
if vtTp:getX() > 0.3 and vtT:getX() > 0.3 then
|
|
if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then
|
|
EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
|
|
elseif vtTp:getZ() > 0.707 or vtT:getZ() > 0.707 then
|
|
EMC.MAXZ = ParkZ1 + 200
|
|
elseif vtTp:getZ() > 0.5 or vtT:getZ() > 0.5 then
|
|
EMC.MAXZ = ParkZ1 + 100
|
|
else
|
|
EMC.MAXZ = ParkZ1 + 1
|
|
end
|
|
elseif bBSameSign and EMC.R1p > 29.9 and EMC.R1p < 180.1 and EMC.R1 > 29.9 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then
|
|
EMC.MAXZ = MaxZ1Blade - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
|
|
elseif bBSameSign and EMC.R1p > -0.1 and EMC.R1p < 180.1 and EMC.R1 > -0.1 and EMC.R1 < 180.1 and EMC.R2p > -10 and EMC.R2 > -10 then
|
|
local vMZ = {{ Tz=0.85, Ez=440}, { Tz=0.5, Ez=200}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}}
|
|
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
else
|
|
local vMZ = {{ Tz=0.85, Ez=400}, { Tz=0.7, Ez=300}, { Tz=0.5, Ez=195}, { Tz=0.15, Ez=70}, { Tz=-0.01, Ez=5}, { Tz=-0.5, Ez=1}}
|
|
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
end
|
|
elseif EMC.HEAD == 'H21' then
|
|
if bBSameSign and vtTp:getX() > -0.1 and vtT:getX() > -0.1 then
|
|
EMC.MAXZ = MaxZ2
|
|
else
|
|
local vMZ = {{ Tz=0.85, Ez=390}, { Tz=0.5, Ez=280}, { Tz=-0.01, Ez=160}}
|
|
EMC.MAXZ = ParkZ2 + CalcExtraZ( vtTpZm, vtT, vMZ)
|
|
end
|
|
elseif EMC.HEAD == 'H38' then
|
|
EMC.MAXZ = SafeZ3RotAxis
|
|
end
|
|
end
|
|
|
|
---------------------- OnSpecialMoveZup -----------------------------
|
|
function OnSpecialMoveZup()
|
|
|
|
--EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT))
|
|
|
|
-- Inizializzazioni
|
|
EMC.ERR = 0
|
|
EMC.MODIF = false
|
|
|
|
-- Direzione utensile
|
|
local vtT = Vector3d( EMC.TDIR)
|
|
|
|
-- recupero Z1 home
|
|
local nHeadSet = GetHeadSet( EMC.HEAD)
|
|
local dZmax = EgtGetAxisHomePos( EgtIf( nHeadSet ~= 2, 'Z1', 'Z2'))
|
|
|
|
|
|
-- se fresa su testa1 o testa 2
|
|
if EMC.HEAD == 'H11' or EMC.HEAD == 'H21' or EMC.HEAD == 'H22' then
|
|
;
|
|
-- se lama
|
|
elseif EMC.HEAD == 'H12' or EMC.HEAD == 'H16' then
|
|
-- riporto i valori tra -179 e + 180
|
|
local dCheckAxR1 = EMC.R1
|
|
if dCheckAxR1 < -180 then
|
|
dCheckAxR1 = dCheckAxR1 + 360
|
|
elseif dCheckAxR1 > 180 then
|
|
dCheckAxR1 = dCheckAxR1 - 360
|
|
end
|
|
-- se lama su testa1
|
|
if EMC.HEAD == 'H12' then
|
|
-- se inclinata oltre 90 gradi e interferisce con la trave
|
|
if ( EMC.R2 > 87.9 and ( dCheckAxR1 < 15.0 or dCheckAxR1 > 180.0)) or ( EMC.R2 < -87.9 and ( dCheckAxR1 > -15.0 and dCheckAxR1 < 180.0)) then
|
|
local dZref = dZmax + min( 330 * vtT:getZ(), 0) + 260 * ( 1 - sqrt( 1- vtT:getZ() * vtT:getZ()))
|
|
-- se troppo in alto
|
|
if EMC.L3 > dZref + 1 then
|
|
---- sistemo asse rotante
|
|
--EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90)
|
|
---- ricalcolo versore utensile
|
|
--EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2)
|
|
---- porto alla giusta quota
|
|
--EMC.L3 = dZmax
|
|
EMC.L3 = dZref
|
|
-- dichiaro modificato
|
|
EMC.MODIF = true
|
|
end
|
|
end
|
|
-- se seconda lama su testa1
|
|
elseif EMC.HEAD == 'H16' then
|
|
-- se inclinata oltre 90 gradi e interferisce con la trave
|
|
if ( EMC.R2 > 87.9 and ( dCheckAxR1 < 15.0 or dCheckAxR1 > 180.0)) or ( EMC.R2 < -87.9 and ( dCheckAxR1 > -15.0 and dCheckAxR1< 180.0)) then
|
|
local dZref = dZmax + min( 330 * vtT:getZ(), 0) + 260 * ( 1 - sqrt( 1- vtT:getZ() * vtT:getZ()))
|
|
-- se troppo in alto
|
|
if EMC.L3 > dZref + 1 then
|
|
---- sistemo asse rotante
|
|
--EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90)
|
|
---- ricalcolo versore utensile
|
|
--EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2)
|
|
---- porto alla giusta quota
|
|
--EMC.L3 = dZmax
|
|
EMC.L3 = dZref
|
|
-- dichiaro modificato
|
|
EMC.MODIF = true
|
|
end
|
|
end
|
|
end
|
|
elseif EMC.HEAD == 'H38' then
|
|
EMC.L3 = SafeZ3RotAxis
|
|
-- dichiaro modificato
|
|
EMC.MODIF = true
|
|
else
|
|
; -- non si fa nulla
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- *** OnSpecialApplyDisposition & OnPostApplyMachining ***
|
|
---------------------------------------------------------------------
|
|
----------------------- Costanti ------------------------------------
|
|
local DELTA_SIC = 1
|
|
local MinJoin = BD.MIN_JOIN_S
|
|
local MinOther = abs( MinY1) + abs( MaxY2) + MinJoin
|
|
local SIC_V = 50 -- sicurezza da testa
|
|
local MIN_ENG_V = 115 -- ingombro asse Z
|
|
local MIN_ENG_RACK_V = 161 -- ingombro asse Z con cremagliera
|
|
local MIN_ENG_XZ2_V = 180 -- ingombro assi XZ sotto
|
|
local MIN_Z2_FOR_ENG_XZ2_V = 270 -- quota Z2 da cui considerare ingombro assi XZ sotto
|
|
local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza
|
|
local MaxLenSmT = 1500 -- massima lunghezza pezzo scaricato con nastri verdi
|
|
local DIST_Y1MAX_LOAD = 100 -- distanza carrello Y1 da massimo asse al carico
|
|
|
|
----------------------- Variabili -----------------------------------
|
|
local Test = false
|
|
local SPLIT
|
|
|
|
---------------------------------------------------------------------
|
|
local function PrepareClGroup( nParentId)
|
|
|
|
local nClId = EgtGetFirstNameInGroup( nParentId, 'CL')
|
|
-- se non c'è, lo aggiungo
|
|
if not nClId then
|
|
nClId = EgtGroup( EMC.DISPID)
|
|
if not nClId then
|
|
return nil
|
|
end
|
|
EgtSetName( nClId, 'CL')
|
|
-- altrimenti lo svuoto
|
|
else
|
|
EgtEmptyGroup( nClId)
|
|
end
|
|
|
|
return nClId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsStartOrRestPhase( nPhase)
|
|
local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE')
|
|
return ( sVal == 'START' or sVal == 'REST')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsMidPhase( nPhase)
|
|
local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE')
|
|
return ( sVal == 'MID')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsEndPhase( nPhase)
|
|
local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE')
|
|
return ( sVal == 'END')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetNextStartOrRestPhase( nPhase)
|
|
local nNextPhase = nPhase + 1
|
|
while nNextPhase <= EgtGetPhaseCount() do
|
|
if IsStartOrRestPhase( nNextPhase) then
|
|
break ;
|
|
end
|
|
nNextPhase = nNextPhase + 1
|
|
end
|
|
return nNextPhase
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsFirstMachiningOfStart( nMchId)
|
|
-- se non è fase inizio di pezzo, ritorno risultato negativo
|
|
if not IsStartOrRestPhase( EMC.PHASE) then
|
|
return false
|
|
end
|
|
-- recupero la precedente operazione attiva
|
|
local nPrevOperId = EgtGetPrevActiveOperation( nMchId)
|
|
-- se non esiste o non è una disposizione, ritorno risultato negativo
|
|
if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then
|
|
return false
|
|
end
|
|
-- è la prima
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function UpdateMinJoin()
|
|
MinJoin = BD.GetMinJoin( EMC.SB, EMC.HB, EMC.LB)
|
|
MinOther = abs( MinY1) + abs( MaxY2) + MinJoin
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetCUTID()
|
|
-- recupero CUTID del pezzo in lavoro
|
|
local nOrd = GetPhaseOrd( EMC.PHASE)
|
|
local nPartRawId
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i')
|
|
if nRawOrd == nOrd then
|
|
nPartRawId = nRawId
|
|
break
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0
|
|
return CutID
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetNextRawInOrd( nCurrRawId)
|
|
local nCurrOrd = EgtGetInfo( nCurrRawId, 'ORD', 'i')
|
|
if not nCurrOrd then return end
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i')
|
|
if nRawOrd == nCurrOrd + 1 then
|
|
return nRawId
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
local function EnsureZmax( bCloseV, vCmd)
|
|
-- verifico non sia già inserito nella lista dei comandi
|
|
for i = 1, #vCmd do
|
|
if vCmd[i][1] == 4 then
|
|
-- se richiesta chiusura, eventuale inserimento se non già presente
|
|
if bCloseV and vCmd[i][2] == 0 then
|
|
vCmd[i][2] = 1
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
-- posizionamento sicuro teste e rulli
|
|
table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)})
|
|
return true
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
local function EmitComment( vCmd, sOut)
|
|
EgtOutLog( ' ' .. sOut, 1)
|
|
if Test then
|
|
table.insert( vCmd, { 0, sOut})
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnSpecialApplyDisposition()
|
|
|
|
EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***', 1)
|
|
|
|
-- Inizializzo codice di errore
|
|
EMC.ERR = 0
|
|
|
|
-- Campi obbligatori ma non usati
|
|
EMC.HEAD = ""
|
|
EMC.EXIT = 1
|
|
EMC.TCPOS = ""
|
|
EMC.SHIFTS = 0
|
|
EMC.SBH = false
|
|
|
|
-- Se disposizione da saltare non devo fare alcunché
|
|
if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end
|
|
|
|
-- Assegno flag di pezzo separato dal resto del grezzo
|
|
SPLIT = IsEndPhase( EMC.PHASE)
|
|
|
|
-- Recupero il tipo dell'operazione successiva
|
|
local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL)
|
|
|
|
-- Se ci sono lavorazioni successive non devo fare alcunché
|
|
if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end
|
|
|
|
-- Imposto gruppo e path di movimento
|
|
local nClId = PrepareClGroup( EMC.DISPID)
|
|
if not nClId then
|
|
EMC.ERR = 3
|
|
EMC.MSG = ' Error : creation CL group failed'
|
|
return
|
|
end
|
|
local nPathId = EgtGroup( nClId)
|
|
if not nPathId then
|
|
EMC.ERR = 6
|
|
EMC.MSG = ' Error : creation path in CL group failed'
|
|
return
|
|
end
|
|
EgtSetName( nPathId, 'Empty')
|
|
EMC.PATHID = nPathId
|
|
EMC.SHIFTS = -1
|
|
|
|
-- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo
|
|
if nNextOpeType == MCH_OY.DISP and SPLIT then
|
|
-- aggiornamento posizioni
|
|
local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID)
|
|
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL)
|
|
local nLastEntId = EgtGetLastInGroup( nLastPathId)
|
|
local vAxes = EmtGetAxesPos( nLastEntId)
|
|
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
|
|
EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd')
|
|
EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd')
|
|
EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1
|
|
EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2
|
|
EMC.CNT = SpecGetCNT( EMC.DISPID)
|
|
-- Determinazione delle dimensioni del grezzo in lavoro
|
|
local b3Raw = BBox3d()
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then
|
|
b3Raw = EgtGetRawPartBBox( nRawId)
|
|
break
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
EMC.LB = b3Raw:getDimX()
|
|
EMC.HOVM = EgtGetInfo( nRawId or GDB_ID.NULL, 'HOVM', 'd') or 0
|
|
-- Eseguo scarico
|
|
local vCmd = SpecCalcUnload()
|
|
SpecOutputCmds( vCmd, true)
|
|
return
|
|
end
|
|
|
|
-- Verifico ci sia un solo grezzo nella fase corrente
|
|
local nRawCount = 0
|
|
local nCurrRawId = GDB_ID.NULL
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then
|
|
nRawCount = nRawCount + 1
|
|
nCurrRawId = nRawId
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
if nRawCount > 1 then
|
|
EMC.ERR = 10
|
|
EMC.MSG = ' Error : too many Raw Parts in current Phase'
|
|
return
|
|
end
|
|
|
|
-- Determinazione delle sue dimensioni
|
|
local b3Raw = EgtGetRawPartBBox( nCurrRawId)
|
|
if not b3Raw or b3Raw:isEmpty() then
|
|
EMC.ERR = 11
|
|
EMC.MSG = ' Error : null Raw Part'
|
|
return
|
|
end
|
|
EMC.LB = b3Raw:getDimX()
|
|
EMC.SB = b3Raw:getDimY()
|
|
EMC.HB = b3Raw:getDimZ()
|
|
|
|
-- Aggiorno limiti di presa
|
|
UpdateMinJoin()
|
|
|
|
-- Assegno sovramateriale di testa e ingombro tagli di testa e di coda
|
|
EMC.HOVM = 0
|
|
EMC.HCING = 0
|
|
EMC.TCING = 0
|
|
|
|
-- Devo scaricare il grezzo rimasto (deve essere unico)
|
|
-- Posizione trave
|
|
local dPosT
|
|
|
|
-- Se fase 1 eseguo carico con carrello Y
|
|
local vCmd = {}
|
|
if EMC.PHASE == 1 then
|
|
dPosT = LoadT
|
|
vCmd = SpecCalcLoad( dPosT, 0, 0)
|
|
-- se altrimenti fase successiva alla prima di tipo inizio o rimanenza
|
|
elseif IsStartOrRestPhase( EMC.PHASE) then
|
|
-- recupero posizione trave e quota di aggancio carrello
|
|
dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd')
|
|
local dPosY1 = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd')
|
|
if not dPosY1 then
|
|
EMC.ERR = 14
|
|
EMC.MSG = ' Error : Y1 non clamped (start or rest)'
|
|
return
|
|
end
|
|
-- confermo i nuovi parametri di aggancio
|
|
table.insert( vCmd, { 21, dPosY1 - dPosT, 0})
|
|
-- recupero posizione rulli
|
|
EMC.V1POS = ParkV1
|
|
EMC.V2POS = ParkV2
|
|
-- recupero contatore pinza 1
|
|
EMC.CNT = SpecGetCNT( EMC.DISPID)
|
|
-- altrimenti fase successiva pari
|
|
else
|
|
EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd')
|
|
EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd')
|
|
EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd')
|
|
-- recupero contatore pinza 1
|
|
EMC.CNT = SpecGetCNT( EMC.DISPID)
|
|
end
|
|
-- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V
|
|
local vCmd2 = {}
|
|
if IsStartOrRestPhase( EMC.PHASE) then
|
|
EMC.TPOS = dPosT
|
|
SpecSetCarrPosFromCmds( vCmd)
|
|
local dDistFront = EMC.LB - MinJoin + 10 * GEO.EPS_SMALL
|
|
local dDistBack = 0
|
|
local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT)
|
|
if EMC.PHASE == 1 then EMC.LOAD = true end
|
|
vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL)
|
|
EMC.LOAD = nil
|
|
if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then
|
|
table.insert( vCmd, { 0, 'CARR_MOVE'})
|
|
end
|
|
end
|
|
-- eseguo scarico
|
|
SpecSetCarrPosFromCmds( vCmd2)
|
|
local vCmd3 = SpecCalcUnload()
|
|
-- unisco ed emetto i comandi
|
|
vCmd = EgtJoinTables( vCmd, vCmd2)
|
|
vCmd = EgtJoinTables( vCmd, vCmd3)
|
|
SpecOutputCmds( vCmd, true)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function OnPostApplyMachining()
|
|
|
|
EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID) .. ' (' .. tostring( EMC.MCHID) .. ')')
|
|
|
|
-- Inizializzo codice di errore
|
|
EMC.ERR = 0
|
|
|
|
-- Recupero la posizione della trave e dei carrelli al termine della precedente operazione
|
|
local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID)
|
|
-- se precedente operazione non esiste, errore
|
|
if not nPrevOpeId then
|
|
EMC.ERR = 1
|
|
EMC.MSG = ' Error : previous Disposition not found'
|
|
return
|
|
-- se precedente operazione è disposizione
|
|
elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then
|
|
if EMC.PHASE == 1 then
|
|
-- posizioni home
|
|
EMC.TPOS = nil
|
|
EMC.Y1DELTA = nil
|
|
EMC.Y2DELTA = nil
|
|
EMC.V1POS = ParkV1
|
|
EMC.V2POS = ParkV2
|
|
EMC.CNT = nil
|
|
elseif IsStartOrRestPhase( EMC.PHASE) then
|
|
-- carico le posizioni
|
|
local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd')
|
|
local dPosY = EgtGetInfo( nPrevOpeId, 'Y1POS', 'd')
|
|
EMC.TPOS = dPosT
|
|
EMC.Y1DELTA = dPosY - dPosT
|
|
EMC.Y2DELTA = nil
|
|
EMC.V1POS = ParkV1
|
|
EMC.V2POS = ParkV2
|
|
EMC.CNT = SpecGetCNT( EMC.MCHID)
|
|
else
|
|
-- aggiornamento posizioni (da lavorazione precedente a disposizione)
|
|
local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId)
|
|
if not nPrev2OpeId then
|
|
EMC.ERR = 1
|
|
EMC.MSG = ' Error : previous Disposition not found'
|
|
return
|
|
end
|
|
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL)
|
|
local nLastEntId = EgtGetLastInGroup( nLastPathId)
|
|
local vAxes = EmtGetAxesPos( nLastEntId)
|
|
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
|
|
EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd')
|
|
EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd')
|
|
EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1
|
|
EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2
|
|
EMC.CNT = SpecGetCNT( EMC.MCHID)
|
|
end
|
|
-- altrimenti precedente operazione è lavorazione
|
|
else
|
|
-- aggiornamento posizioni
|
|
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL)
|
|
local nLastEntId = EgtGetLastInGroup( nLastPathId)
|
|
local bAtZMax = ( EgtGetClEntMove( nLastEntId) == 0 and EgtGetClEntFlag( nLastEntId) == 3)
|
|
local vAxes = EmtGetAxesPos( nLastEntId)
|
|
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
|
|
EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd')
|
|
EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd')
|
|
EMC.V1POS = EgtIf( bAtZMax, ParkV1, EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1)
|
|
EMC.V2POS = EgtIf( bAtZMax, ParkV2, EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2)
|
|
EMC.CNT = SpecGetCNT( EMC.MCHID)
|
|
end
|
|
|
|
-- Verifico se ultima lavorazione della fase
|
|
local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID)
|
|
local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE)
|
|
|
|
-- Verifico flag di separazione e fase di scarico
|
|
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
|
|
-- bPreSplit sempre a falso per obbligare a pinzare il pezzo con 1 morsa anche se iniziato il taglio che dividerà grezzo e finito (in genere per sezioni grandi con 2 tagli di lama)
|
|
-- Tra un taglio e l'altro infatti c'e' inversione del braccio e quindi un'apertura delle rulliere. Se pinzano entrambe le pinze, potrebbero esserci problemi di collisone rulli-morse
|
|
local bPreSplit = false --( sNotes:find( 'Presplit', 1, true) ~= nil)
|
|
|
|
local bSplitting = ( sNotes:find( 'Split', 1, true) ~= nil)
|
|
local bPreCut = ( sNotes:find( 'Precut', 1, true) ~= nil)
|
|
local bCutting = ( sNotes:find( 'Cut', 1, true) ~= nil)
|
|
local bUnload = IsEndPhase( EMC.PHASE)
|
|
|
|
-- Agisco sui diversi percorsi della lavorazione
|
|
local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL)
|
|
while nPathId do
|
|
-- assegno id percorso da elaborare
|
|
EMC.PATHID = nPathId
|
|
-- recupero id del successivo
|
|
nPathId = EgtGetNext( nPathId)
|
|
-- verifico se ultimo percorso di ultima lavorazione della fase
|
|
local bLast = ( bMchLast and ( not nPathId))
|
|
-- se ultimo, elimino ritorno in home
|
|
if bLast then EgtRemoveOperationHome( EMC.MCHID) end
|
|
-- salvo lo stato dei carrelli
|
|
local OriTPos = EMC.TPOS
|
|
local OriY1Delta = EMC.Y1DELTA
|
|
local OriY2Delta = EMC.Y2DELTA
|
|
local OriV1Pos = EMC.V1POS
|
|
local OriV2Pos = EMC.V2POS
|
|
local OriCnt = EMC.CNT
|
|
-- eseguo le elaborazioni
|
|
SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload)
|
|
-- se separazione, verifico il risultato
|
|
if bSplitting then
|
|
-- recupero CUTID del pezzo in lavoro
|
|
local CutID = GetCUTID()
|
|
-- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali
|
|
if EMC.ERR == 18 then
|
|
-- segnalazione warning
|
|
EMC.ERR = -101
|
|
EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')'
|
|
-- ripristino lo stato originale dei carrelli
|
|
EMC.TPOS = OriTPos
|
|
EMC.Y1DELTA = OriY1Delta
|
|
EMC.Y2DELTA = OriY2Delta
|
|
EMC.V1POS = OriV1Pos
|
|
EMC.V2POS = OriV2Pos
|
|
EMC.CNT = OriCnt
|
|
-- eseguo le elaborazioni
|
|
SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload)
|
|
-- pinzaggio ancora impossibile, pezzo a caduta
|
|
if EMC.ERR == 18 then
|
|
-- segnalazione warning
|
|
EMC.ERR = -102
|
|
EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')'
|
|
end
|
|
-- scarico standard
|
|
elseif EMC.ERR == 0 then
|
|
-- segnalazione warning
|
|
EMC.ERR = -100
|
|
EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')'
|
|
end
|
|
-- se taglio del residuo finale, scarico standard
|
|
elseif bCutting then
|
|
-- recupero CUTID del pezzo in lavoro
|
|
local CutID = GetCUTID()
|
|
-- se non ci sono errori, segnalazione warning
|
|
if EMC.ERR == 0 then
|
|
EMC.ERR = -100
|
|
EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')'
|
|
end
|
|
end
|
|
if EMC.ERR > 0 then return end
|
|
-- determino la posizione finale della trave
|
|
local nLastEntId = EgtGetLastInGroup( EMC.PATHID)
|
|
local vAxes = EmtGetAxesPos( nLastEntId)
|
|
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
|
|
end
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload)
|
|
|
|
-- Verifico se lavorazione pareti
|
|
local bWall = ( EgtGetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', 'd') == 1)
|
|
|
|
-- mi salvo info lavorazione su una lista
|
|
local AuxInfoMach = {}
|
|
AuxInfoMach.bPreSplit = bPreSplit
|
|
AuxInfoMach.bSplitting = bSplitting
|
|
AuxInfoMach.bPreCut = bPreCut
|
|
AuxInfoMach.bCutting = bCutting
|
|
AuxInfoMach.bUnload = bUnload
|
|
|
|
-- Assegno flag di pezzo separato dal resto del grezzo
|
|
SPLIT = IsEndPhase( EMC.PHASE)
|
|
|
|
-- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro
|
|
local b3Tot = BBox3d()
|
|
local b3Raw = BBox3d()
|
|
local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE)
|
|
local nRawId = EgtGetFirstRawPart()
|
|
local nCurrRawId = GDB_ID.NULL
|
|
while nRawId do
|
|
if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then
|
|
local b3Tmp = EgtGetRawPartBBox( nRawId)
|
|
b3Tot:Add( b3Tmp)
|
|
if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then
|
|
b3Raw = b3Tmp
|
|
nCurrRawId = nRawId
|
|
end
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
if b3Tot:isEmpty() then
|
|
EMC.ERR = 11
|
|
EMC.MSG = ' Error : null Raw Parts'
|
|
return
|
|
end
|
|
EMC.LB = EgtIf( SPLIT, b3Raw:getDimX(), b3Tot:getDimX())
|
|
EMC.SB = b3Tot:getDimY()
|
|
EMC.HB = b3Tot:getDimZ()
|
|
EMC.LT = b3Raw:getDimX()
|
|
EgtOutLog( ' BarLen='..EgtNumToString( EMC.LB, 1), 3)
|
|
|
|
-- Aggiorno limiti di presa
|
|
UpdateMinJoin()
|
|
|
|
-- Recupero sovramateriale di testa e ingombro tagli di testa e di coda
|
|
EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0
|
|
EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0
|
|
EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0
|
|
-- Recupero ingombro dei tagli di testa del prossimo pezzo (se esiste)
|
|
EMC.NEXT_HCING = 0
|
|
local nNextRawId = GetNextRawInOrd( nCurrRawId)
|
|
if nNextRawId then
|
|
EMC.NEXT_HCING = EgtGetInfo( nNextRawId, 'HCING', 'd') or 0
|
|
end
|
|
|
|
-- Calcolo dell'ingombro della lavorazione
|
|
local dDistFront, dDistBack, dRollFront, dRollBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut)
|
|
if not dDistFront then return end
|
|
local dMaxLenLeft = 0
|
|
if bPreSplit or bSplitting then
|
|
local dDistF, dDistB, dRollF, dRollB, dMaxLF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1)
|
|
dDistFront = min( dDistFront, dDistF)
|
|
dDistBack = dDistBack
|
|
if bSplitting then dMaxLenLeft = dMaxLF end
|
|
elseif bPreCut or bCutting then
|
|
local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1)
|
|
dDistFront = min( dDistFront, dDistF)
|
|
dDistBack = min( dDistBack, dDistB)
|
|
end
|
|
|
|
-- Verifico lunghezza pezzo
|
|
if not SPLIT and not VerifyPartLength() then
|
|
return
|
|
end
|
|
|
|
-- Calcolo quali carrelli sono necessari
|
|
local nChar
|
|
if bPreSplit or bSplitting then
|
|
nChar = 2
|
|
elseif bPreCut or bCutting then
|
|
nChar = 3
|
|
end
|
|
local dY1DeltaMaxSP
|
|
if nChar == 2 then
|
|
dY1DeltaMaxSP = MaxY1 - LoadT + EMC.LT
|
|
end
|
|
local dY2DeltaMinUL
|
|
if ( nChar == 2 or nChar == 3) and not bWall then
|
|
dY2DeltaMinUL = EMC.LT + MinY2 - EgtIf( EMC.LT < MaxLenSmT, UnloadSmT, UnloadT)
|
|
end
|
|
|
|
-- Se inizio o appena dopo rotazione, eseguo il carico
|
|
if not EMC.TPOS then
|
|
local dPosT = LoadT
|
|
local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6))
|
|
EMC.LOAD = true
|
|
local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach)
|
|
EMC.LOAD = nil
|
|
if bSplitting and EMC.ERR == 18 then
|
|
table.insert( vCmd, { 22, dRollBack, -dRollFront})
|
|
end
|
|
if vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then
|
|
table.insert( vCmd, { 0, 'CARR_MOVE'})
|
|
end
|
|
EgtJoinTables( vCmd, vCmd2)
|
|
SpecOutputCmds( vCmd)
|
|
|
|
-- Se altrimenti non eseguito SPLIT, eseguo calcoli per carrelli
|
|
elseif not SPLIT then
|
|
local vCmd = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach)
|
|
-- Se non ci sono spostamenti, confermo i parametri di aggancio e di posizione roller
|
|
if SpecTestOnlyRemarkInCmds( vCmd) then
|
|
table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)})
|
|
table.insert( vCmd, { 22, dRollBack, -dRollFront})
|
|
end
|
|
SpecOutputCmds( vCmd)
|
|
|
|
-- Altrimenti, non muovo i carrelli rispetto alla trave ma impongo la posizione dei rulli
|
|
else
|
|
SpecOutputCNT()
|
|
local vCmd = {}
|
|
table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)})
|
|
table.insert( vCmd, { 22, dRollBack, -dRollFront})
|
|
SpecOutputCmds( vCmd)
|
|
end
|
|
|
|
-- Se taglio di separazione
|
|
local vCmd = {}
|
|
if bSplitting then
|
|
-- rimuovo eventuale vecchia info di Skip
|
|
local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL
|
|
EgtRemoveInfo( NextDispId, 'SKIP')
|
|
-- verifico se separazione con caduta
|
|
if not EMC.Y2DELTA then
|
|
EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo')
|
|
SpecOutputCNT()
|
|
if IsEndPhase( EMC.PHASE + 1) then
|
|
EgtSetInfo( NextDispId, 'SKIP', '1')
|
|
local NextOpeId = EgtGetNextOperation( NextDispId)
|
|
while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do
|
|
EgtSetOperationMode( NextOpeId, false)
|
|
NextOpeId = EgtGetNextOperation( NextOpeId)
|
|
end
|
|
end
|
|
-- forzo l'errore 18
|
|
EMC.ERR = 18
|
|
-- verifico che la barra sia agganciata anche al primo carrello
|
|
elseif not EMC.Y1DELTA then
|
|
EMC.ERR = 19
|
|
EMC.MSG = ' Error SPLIT : Y1 or Y2 not clamped'
|
|
return false
|
|
end
|
|
-- eseguo la separazione
|
|
EgtOutLog( 'MaxLenLeft=' .. EgtNumToString( dMaxLenLeft, 1), 1)
|
|
vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft)
|
|
end
|
|
-- Se taglio finale di grezzo a perdere
|
|
if bCutting then
|
|
-- salvo distanza carrello Y2 da inizio grezzo rimasto nella disposizione della prossima fase
|
|
local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1)
|
|
if NextDispId then
|
|
EgtSetInfo( NextDispId, 'Y2POS', EMC.Y2DELTA)
|
|
EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS)
|
|
EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS)
|
|
end
|
|
end
|
|
|
|
-- Se previsto scarico, lo eseguo
|
|
if bUnload then
|
|
EMC.LB = b3Raw:getDimX()
|
|
local vCmdTmp = SpecCalcUnload()
|
|
vCmd = EgtJoinTables( vCmd, vCmdTmp)
|
|
end
|
|
|
|
-- Emetto eventuali comandi di separazione e/o scarico
|
|
if #vCmd > 0 then
|
|
SpecOutputCmds( vCmd, true)
|
|
end
|
|
|
|
end --SpecApplyPath( bLast)
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecialCalcMachiningEncumbrance( nMchId, bPreCut)
|
|
-- gruppi della lavorazione
|
|
local nClId = EgtGetFirstNameInGroup( nMchId, 'CL')
|
|
local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL)
|
|
if not nPathId then
|
|
EMC.ERR = 12
|
|
EMC.MSG = ' Error : CL group path not found'
|
|
return
|
|
end
|
|
-- Recupero ptMin ptMax della lavorazione
|
|
local ptMin = EgtGetInfo( nClId, 'MMIN', 'p')
|
|
local ptMax = EgtGetInfo( nClId, 'MMAX', 'p')
|
|
if not ptMin or not ptMax then
|
|
EMC.ERR = 13
|
|
EMC.MSG = ' Error : machining Min or Max not found'
|
|
return
|
|
end
|
|
-- se pre-taglio, aggiorno ptMax con quello del taglio finale
|
|
if bPreCut then
|
|
local ptFinMax = GetFinalCutPmax( nMchId)
|
|
if ptFinMax then
|
|
ptMax = ptFinMax
|
|
end
|
|
end
|
|
-- Recupero testa
|
|
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
-- Recupero minimi e massimi degli assi macchina della lavorazione
|
|
local vAxMin = EgtGetInfo( nClId, 'MAXMIN', 'vd')
|
|
local vAxMax = EgtGetInfo( nClId, 'MAXMAX', 'vd')
|
|
if not vAxMin or not vAxMax or #vAxMin < 5 or ( sHead == 'H13' and #vAxMin < 6) then
|
|
EMC.ERR = 15
|
|
EMC.MSG = ' Error : machine axes Min or Max not found'
|
|
return
|
|
end
|
|
local vAxMid = {}
|
|
for i = 1, #vAxMin do
|
|
vAxMid[i] = ( vAxMin[i] + vAxMax[i]) / 2
|
|
end
|
|
-- recupero il gruppo
|
|
local nSetHead = GetHeadSet( sHead)
|
|
-- Calcolo dell'ingombro della testa rispetto allo Zero Macchina (assi rotanti fissi, C=4, B=5, A=6)
|
|
local b3Enc
|
|
if nSetHead == 1 then
|
|
EgtSetAxisPos( 'C1', vAxMid[4])
|
|
EgtSetAxisPos( 'B1', vAxMid[5])
|
|
if sHead == 'H13' then
|
|
EgtSetAxisPos( 'A1', vAxMid[6])
|
|
end
|
|
b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE)
|
|
elseif nSetHead == 2 then
|
|
EgtSetAxisPos( 'C2', vAxMid[4])
|
|
EgtSetAxisPos( 'B2', vAxMid[5])
|
|
if sHead == 'H22' then
|
|
EgtSetAxisPos( 'A2', vAxMid[6])
|
|
end
|
|
b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), GDB_BB.ONLY_VISIBLE)
|
|
else -- testa 3
|
|
EgtSetAxisPos( 'C3', vAxMid[4])
|
|
EgtSetAxisPos( 'B3', vAxMid[5])
|
|
b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C3'), GDB_BB.ONLY_VISIBLE)
|
|
end
|
|
|
|
-- Forzo la distanza di sicurezza da utensile
|
|
local nSecRollerDist = EgtGetValInNotes( EgtTdbGetCurrToolParam( MCH_TP.USERNOTES), 'SECDIST', 'i') or SIC_V
|
|
|
|
local dMinFrontEng = EgtIf( nSetHead ~= 2, MIN_ENG_RACK_V, EgtIf( vAxMax[3] < MIN_Z2_FOR_ENG_XZ2_V, MIN_ENG_V, MIN_ENG_XZ2_V))
|
|
local dRollFront = max( b3Enc:getMax():getX(), dMinFrontEng) + nSecRollerDist
|
|
local dMinBackEng = EgtIf( nSetHead ~= 2, MIN_ENG_V, EgtIf( vAxMax[3] < MIN_Z2_FOR_ENG_XZ2_V, MIN_ENG_V, MIN_ENG_XZ2_V))
|
|
local dRollBack = max( -b3Enc:getMin():getX(), dMinBackEng) + nSecRollerDist
|
|
EgtOutLog( ' RollFront = ' .. EgtNumToString( dRollFront, 1) .. ' RollBack = ' .. EgtNumToString( dRollBack, 1), 3)
|
|
-- Calcolo della posizione della Punta Utensile rispetto allo Zero Macchina
|
|
local ptTip
|
|
ptTip = EgtGetCalcTipFromPositions( 0, 0, 0, vAxMid[4], vAxMid[5], vAxMid[6] or 0, false)
|
|
EgtOutLog( ' ToolTip = ' .. tostring( ptTip), 5)
|
|
-- Calcolo dell'ingombro della testa rispetto alla Punta Utensile
|
|
local dHeadFront = dRollFront + AGG_V - ptTip:getX()
|
|
local dHeadBack = dRollBack + AGG_V + ptTip:getX()
|
|
EgtOutLog( ' HeadFront = ' .. EgtNumToString( dHeadFront, 1) .. ' HeadBack = ' .. EgtNumToString( dHeadBack, 1), 5)
|
|
-- Distanze limiti della pinza di destra da testa trave e della pinza di sinistra da coda trave
|
|
local dDistFront = - ptMax:getX() - LoadT - dHeadFront
|
|
local dDistBack = ptMin:getX() + LoadT + EMC.LB - dHeadBack
|
|
EgtOutLog( ' DistFront = ' .. EgtNumToString( dDistFront, 1) .. ' DistBack = ' .. EgtNumToString( dDistBack, 1), 3)
|
|
return dDistFront, dDistBack, dRollFront, dRollBack
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecialCalcPhaseEncumbrance( nPhase)
|
|
-- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave)
|
|
local dDistFront = EMC.LB
|
|
local dDistBack = EMC.LB
|
|
local dRollFront = 0
|
|
local dRollBack = 0
|
|
local dMaxLenLeft = 0
|
|
-- Salvo lavorazione e utensile correnti, per ripristinarli alla fine
|
|
local nOrigMchId = EgtGetCurrMachining()
|
|
local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
|
|
local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
-- Ciclo sulle lavorazioni
|
|
local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL)
|
|
while nMchId and EgtGetOperationPhase( nMchId) == nPhase do
|
|
-- imposto lavorazione e utensile correnti
|
|
EgtSetCurrMachining( nMchId)
|
|
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
|
|
if not sTool or not EgtTdbSetCurrTool( sTool) then
|
|
local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID)
|
|
sTool = EgtTdbGetToolFromUUID( sTuuid) or ''
|
|
EgtTdbSetCurrTool( sTool)
|
|
end
|
|
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
EgtSetCalcTool( sTool, sHead, 1)
|
|
-- calcolo ingombri
|
|
local dDistF, dDistB, dRollF, dRollB = SpecialCalcMachiningEncumbrance( nMchId)
|
|
if dDistF and dDistB then
|
|
dDistFront = min( dDistFront, dDistF)
|
|
dDistBack = min( dDistBack, dDistB)
|
|
dRollFront = max( dRollFront, dRollF)
|
|
dRollBack = max( dRollBack, dRollB)
|
|
local dMaxLenL = EMC.LT - dDistF - AGG_V - dRollF
|
|
EgtOutLog( ' MaxLenLeft = ' .. EgtNumToString( dMaxLenL, 1), 3)
|
|
dMaxLenLeft = max( dMaxLenLeft, dMaxLenL)
|
|
end
|
|
nMchId = EgtGetNextActiveOperation( nMchId)
|
|
end
|
|
-- Ripristino lavorazione e utensile correnti
|
|
if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end
|
|
if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end
|
|
if sOrigTool and sOrigHead then EgtSetCalcTool( sOrigTool, sOrigHead, 1) end
|
|
-- Restituisco gli ingombri trovati
|
|
return dDistFront, dDistBack, dRollFront, dRollBack, dMaxLenLeft
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function GetFinalCutPmax( nMchId)
|
|
local nFinalCutId
|
|
local nId = EgtGetNextActiveOperation( nMchId)
|
|
while nId and EgtGetOperationPhase( nId) == EMC.PHASE do
|
|
nFinalCutId = nId
|
|
nId = EgtGetNextActiveOperation( nId)
|
|
end
|
|
if not nFinalCutId then return end
|
|
local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL')
|
|
if not nCLId then return end
|
|
return EgtGetInfo( nCLId, 'MMAX', 'p')
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function VerifyPartLength()
|
|
|
|
-- Verifico lunghezza pezzo
|
|
if EMC.LB < MinJoin + MinOther + AggLoad + EMC.HCING + EMC.HOVM then
|
|
EMC.ERR = 17
|
|
EMC.MSG = ' Error CLAMP : part too short'
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecCalcLoad( dPosT, dDistFront, dDistBack)
|
|
--[L]
|
|
local dNewY1min = max( EMC.LB - dDistBack, MinOther + AggLoad + EMC.HCING + EMC.HOVM)
|
|
local dNewY1max = min( ( MaxY1 - MinY1) - 5, EMC.LB - MinJoin)
|
|
if dNewY1min > dNewY1max then return nil end
|
|
-- minimo posizionamento pinza 1 per permettere scarico del restante
|
|
local dMinLengthRestToUnload = abs( MinY1) + abs( MinV1) + abs( MaxV2) + abs( MaxY2) + MinJoin + AggLoad + EMC.LT + 10
|
|
-- calcolo posizionamento con i coefficienti, ma verifico che sia tra il minimo e il massimo pinzabile
|
|
local dNewY1DeltaMax = EgtClamp( 0.25 * dNewY1min + 0.75 * dNewY1max, dMinLengthRestToUnload, dNewY1max)
|
|
local dNewY1Delta = EgtClamp( BD.CHAR_LOAD_DIST or 3000, 0.75 * dNewY1min + 0.25 * dNewY1max, dNewY1DeltaMax)
|
|
local dNewY2Delta = nil
|
|
local dNewY1 = dPosT + dNewY1Delta
|
|
local vCmd = {}
|
|
EgtOutLog( ' *[L]', 1)
|
|
-- [L-1]
|
|
if dNewY1 + TurnerOffs + DIST_Y1MAX_LOAD - MaxY1 > 0 then
|
|
dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD)
|
|
EgtOutLog( ' *[L1]', 1)
|
|
end --[L-2]
|
|
if EMC.LB - dNewY1Delta < MinJoin then
|
|
dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD)
|
|
EgtOutLog( ' *[L2]', 1)
|
|
end
|
|
-- Commento
|
|
table.insert( vCmd, { 0, 'Loading'})
|
|
-- posizionamento sicuro teste e rulli
|
|
EnsureZmax( false, vCmd)
|
|
-- Apro entrambe le morse
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
table.insert( vCmd, { 12, 0})
|
|
-- Sposto il carrello Y per il carico
|
|
table.insert( vCmd, { 2, 'Y1', dPosT + dNewY1Delta, 'Y2', ParkY2})
|
|
-- Chiudo morsa Y
|
|
table.insert( vCmd, { 11, 1})
|
|
-- Sposto il carrello Y con la testa trave al parcheggio V1
|
|
table.insert( vCmd, { 2, 'T', ParkV1, 'Y1', ParkV1 + dNewY1Delta})
|
|
-- confermo i nuovi parametri di aggancio
|
|
table.insert( vCmd, { 21, dNewY1Delta, 0})
|
|
-- Inizializzo contatore globale
|
|
EMC.CNT = 1
|
|
SpecOutputCNT()
|
|
-- Assegno stato corrente
|
|
EMC.TPOS = ParkV1
|
|
EMC.Y1DELTA = dNewY1Delta
|
|
EMC.Y2DELTA = nil
|
|
EMC.V1POS = ParkV1
|
|
EMC.V2POS = ParkV2
|
|
-- Restituisco i comandi
|
|
return vCmd
|
|
end -- SpecAdjustLoad [L]
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach)
|
|
|
|
local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM
|
|
local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AggLoad, 0)
|
|
local dMyDistBack = dDistBack - EgtIf( EMC.CNT == 1, AggLoad, 0)
|
|
|
|
local sMaxSplit = ''
|
|
if dY1DeltaMaxSP then sMaxSplit = '/'..EgtNumToString( dY1DeltaMaxSP, 1)..'(MaxSplit)' end
|
|
local sMinUnload = ''
|
|
if dY2DeltaMinUL then sMinUnload = '/'..EgtNumToString( dY2DeltaMinUL, 1)..'(MinUnload)' end
|
|
EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dMyDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit ..
|
|
' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3)
|
|
|
|
local bBackOk = ( dMyDistBack > MinJoin - GEO.EPS_SMALL)
|
|
local bFrontOk = ( dDistFront > MinFrontJoin - GEO.EPS_SMALL)
|
|
|
|
-- [A] se non richiesto solo carrello Y2 e posso mettere solo carrello Y1
|
|
if ( nChar ~= 2 and nChar ~= 3 and bBackOk) or
|
|
( nChar == 2 and bBackOk and not bFrontOk) then
|
|
|
|
local WorkTab = {}
|
|
WorkTab.dTPosI = EMC.TPOS
|
|
WorkTab.dY1DeltaI = EMC.Y1DELTA
|
|
WorkTab.dY2DeltaI = EMC.Y2DELTA
|
|
WorkTab.dV1PosI = EMC.V1POS
|
|
WorkTab.bV1CloseI = false
|
|
WorkTab.dV2PosI = EMC.V2POS
|
|
WorkTab.bV2CloseI = false
|
|
|
|
WorkTab.dTPosF = nil
|
|
WorkTab.dY1DeltaMinF = max( EMC.LB - dMyDistBack, MyMinOther + EMC.HCING + EMC.HOVM)
|
|
WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V)
|
|
WorkTab.dY2DeltaMinF = nil
|
|
WorkTab.dY2DeltaMaxF = nil
|
|
if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end
|
|
WorkTab.dV1PosF = dRollBack
|
|
WorkTab.bV1CloseF = false
|
|
WorkTab.dV2PosF = -dRollFront
|
|
WorkTab.bV2CloseF = false
|
|
|
|
-- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare
|
|
if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then
|
|
if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then
|
|
WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF)
|
|
end
|
|
end
|
|
|
|
-- verifico validità intervallo ammesso per Y1
|
|
if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then
|
|
EMC.ERR = 18
|
|
EMC.MSG = ' Error : CLAMP Y1 impossible'
|
|
return {}
|
|
end
|
|
|
|
-- al carico o con prima lavorazione di un pezzo si deve ignorare l'ingombro delle lavorazioni di testa per il pinzaggio
|
|
if EMC.LOAD or IsFirstMachiningOfStart( EMC.MCHID) then EMC.HCING = 0 end
|
|
|
|
return SpecAdjustCarriages( WorkTab)
|
|
|
|
-- [B] se richiesti entrambi e posso metterli
|
|
elseif nChar == 2 and bBackOk and bFrontOk then
|
|
|
|
local WorkTab = {}
|
|
WorkTab.dTPosI = EMC.TPOS
|
|
WorkTab.dY1DeltaI = EMC.Y1DELTA
|
|
WorkTab.dY2DeltaI = EMC.Y2DELTA
|
|
WorkTab.dV1PosI = EMC.V1POS
|
|
WorkTab.bV1CloseI = false
|
|
WorkTab.dV2PosI = EMC.V2POS
|
|
WorkTab.bV2CloseI = false
|
|
|
|
WorkTab.dTPosF = nil
|
|
WorkTab.dY1DeltaMinF = max( EMC.LB - dMyDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING)
|
|
WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V)
|
|
WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dMyDistBack - AGG_V - dRollBack)
|
|
WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther) -- - EMC.TCING
|
|
if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end
|
|
if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end
|
|
WorkTab.dV1PosF = dRollBack
|
|
WorkTab.bV1CloseF = false
|
|
WorkTab.dV2PosF = -dRollFront
|
|
WorkTab.bV2CloseF = false
|
|
|
|
-- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare
|
|
if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then
|
|
if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then
|
|
WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF)
|
|
end
|
|
end
|
|
|
|
-- verifico validità intervallo ammesso per Y1
|
|
if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then
|
|
EMC.ERR = 18
|
|
EMC.MSG = ' Error : CLAMP Y1 impossible'
|
|
return {}
|
|
end
|
|
|
|
-- verifico validità intervallo ammesso per Y2
|
|
if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then
|
|
EMC.ERR = 18
|
|
EMC.MSG = ' Error : CLAMP Y2 impossible'
|
|
return {}
|
|
end
|
|
|
|
return SpecAdjustCarriages( WorkTab)
|
|
|
|
-- [C] se non richiesti entrambi e posso mettere carrello Y2
|
|
elseif bFrontOk then
|
|
|
|
local WorkTab = {}
|
|
WorkTab.dTPosI = EMC.TPOS
|
|
WorkTab.dY1DeltaI = EMC.Y1DELTA
|
|
WorkTab.dY2DeltaI = EMC.Y2DELTA
|
|
WorkTab.dV1PosI = EMC.V1POS
|
|
WorkTab.bV1CloseI = false
|
|
WorkTab.dV2PosI = EMC.V2POS
|
|
WorkTab.bV2CloseI = false
|
|
|
|
WorkTab.dTPosF = nil
|
|
WorkTab.dY1DeltaMinF = nil
|
|
WorkTab.dY1DeltaMaxF = nil
|
|
WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dMyDistBack - AGG_V - dRollBack)
|
|
WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther) -- - EMC.TCING
|
|
if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end
|
|
WorkTab.dV1PosF = dRollBack
|
|
WorkTab.bV1CloseF = false
|
|
WorkTab.dV2PosF = -dRollFront
|
|
WorkTab.bV2CloseF = false
|
|
|
|
-- verifico validità intervallo ammesso per Y2
|
|
if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then
|
|
EMC.ERR = 18
|
|
EMC.MSG = ' Error : CLAMP Y2 impossible'
|
|
return {}
|
|
end
|
|
|
|
return SpecAdjustCarriages( WorkTab)
|
|
|
|
-- altrimenti errore
|
|
else
|
|
if EgtGetDebugLevel() < 3 then
|
|
EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dMyDistBack) ..
|
|
' MinJoin=' .. EgtNumToString( MinJoin) .. ' MinFrontJoin=' .. EgtNumToString( MinFrontJoin))
|
|
end
|
|
EMC.ERR = 18
|
|
EMC.MSG = ' Error : CLAMP impossible'
|
|
return {}
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecCalcSplit( dLenRaw, dMaxLenLeft)
|
|
local vCmd = {}
|
|
EgtOutLog( ' *[S]', 1)
|
|
local bSplit = ( EMC.Y2DELTA ~= nil)
|
|
local ParkT = ParkV1
|
|
if bSplit then
|
|
if dMaxLenLeft + 100 > LoadT then
|
|
ParkT = dMaxLenLeft + 300
|
|
elseif dMaxLenLeft + 100 > ParkV1 then
|
|
ParkT = LoadT
|
|
end
|
|
end
|
|
table.insert( vCmd, { 0, EgtIf( bSplit, 'Split', 'Fall')})
|
|
if not bSplit then EnsureZmax( false, vCmd) end
|
|
-- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari)
|
|
local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE)
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then
|
|
table.insert( vCmd, { 31, nRawId, 'Y1'})
|
|
end
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
-- riporto il carrello Y al carico con il resto della trave
|
|
local dLDelta = EMC.Y1DELTA - dLenRaw
|
|
table.insert( vCmd, { 1, 'Y1', ParkT + dLDelta})
|
|
table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0})
|
|
-- imposto subito Y non più attaccato alla trave in lavoro
|
|
EMC.Y1DELTA = nil
|
|
-- salvo posizione carrello Y in disposizione del pezzo dopo split
|
|
local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1)
|
|
if PostDispId then
|
|
if not bSplit then
|
|
EgtSetInfo( PostDispId, 'TPOS', ParkT)
|
|
else
|
|
EgtRemoveInfo( PostDispId, 'TPOS')
|
|
EgtSetInfo( PostDispId, 'TPARK', ParkT)
|
|
end
|
|
EgtSetInfo( PostDispId, 'Y1POS', ParkT + dLDelta)
|
|
end
|
|
-- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari)
|
|
local NextDispId = EgtGetPhaseDisposition( nNextOddPhase)
|
|
if NextDispId then
|
|
EgtSetInfo( NextDispId, 'TPOS', ParkT)
|
|
EgtSetInfo( NextDispId, 'Y1POS', ParkT + dLDelta)
|
|
end
|
|
|
|
return vCmd
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecCalcUnload()
|
|
local vCmdPre = {}
|
|
EgtOutLog( ' *[U]', 1)
|
|
if not EMC.Y1DELTA and not EMC.Y2DELTA then
|
|
EMC.ERR = 21
|
|
EMC.MSG = ' Error : Y1 and Y2 not clamped for unloading'
|
|
return {}
|
|
end
|
|
local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT)
|
|
-- Se pinza Y1 chiusa o Y2 troppo a destra, devo effettuare uno scambio
|
|
if EMC.Y1DELTA or EMC.Y2DELTA < dY2DeltaMinUL then
|
|
-- determino posizione testa trave
|
|
local nLastEntId = EgtGetLastInGroup( EMC.PATHID)
|
|
if not nLastEntId then
|
|
local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID)
|
|
local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL'))
|
|
nLastEntId = EgtGetLastInGroup( nPathId)
|
|
end
|
|
local vAxes = EmtGetAxesPos( nLastEntId)
|
|
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
|
|
-- imposto quote aggancio per avere solo pinza V
|
|
local dDistFront = EMC.LB - MinJoin - EMC.HOVM + 10 * GEO.EPS_SMALL
|
|
local dDistBack = 0
|
|
-- imposto rulli aperti (in ogni caso pezzo sicuramente grande)
|
|
EMC.V1POS = ParkV1
|
|
EMC.V2POS = ParkV2
|
|
-- effettuo scambio
|
|
vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, nil, dY2DeltaMinUL)
|
|
-- recupero nuova posizione carrelli
|
|
SpecSetCarrPosFromCmds( vCmdPre)
|
|
EgtOutLog( ' *[U1]', 1)
|
|
end
|
|
local vCmd = {}
|
|
-- Commento
|
|
table.insert( vCmd, { 0, 'Unloading'})
|
|
-- posizionamento sicuro teste e rulli (non serve ?)
|
|
--table.insert( vCmd, { 4, 0})
|
|
-- Se pinza Y chiusa, la apro
|
|
if EMC.Y1DELTA then
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
end
|
|
-- Sposto il pezzo in posizione di scarico
|
|
local dFinT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) - EMC.LB
|
|
local dFinY2 = dFinT + EMC.Y2DELTA
|
|
table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2})
|
|
EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2), 1)
|
|
-- apro la morsa
|
|
table.insert( vCmd, { 12, 0})
|
|
-- riporto il carrello in home
|
|
table.insert( vCmd, { 1, 'Y2', ParkY2})
|
|
|
|
-- eventuale unione tabelle
|
|
if #vCmdPre > 0 then
|
|
vCmd = EgtJoinTables( vCmdPre, vCmd)
|
|
end
|
|
|
|
return vCmd
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ChangedTool( nMchId)
|
|
local nChanged = 0
|
|
-- Salvo lavorazione e utensile correnti, per ripristinarli alla fine
|
|
local nOrigMchId = EgtGetCurrMachining()
|
|
local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
|
|
local sOrigBlockedAx = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
|
|
-- Recupero l'utensile della lavorazione precedente
|
|
local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL)
|
|
if nPrevMchId and EgtGetOperationType( nPrevMchId) ~= MCH_OY.DISP then
|
|
EgtSetCurrMachining( nPrevMchId)
|
|
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
|
|
nChanged = EgtIf( sTool ~= sOrigTool, 1 , 0)
|
|
local sBlockedAx = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS)
|
|
-- se stesso utensile, ma modo caricamento diverso, è come se fosse un cambio utensile. Vale solo se aggregato su lama da sotto.
|
|
if sTool == sOrigTool then
|
|
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
if sHead == 'H22' and sOrigBlockedAx ~= sBlockedAx then
|
|
nChanged = 2
|
|
end
|
|
end
|
|
end
|
|
-- Ripristino lavorazione e utensile correnti
|
|
if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end
|
|
if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end
|
|
return nChanged
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **CHIAMATA DELLE FUNZIONI Spec**
|
|
--------------------------------------------------------------------------------------------------------
|
|
function SpecAdjustCarriages( WorkTab)
|
|
|
|
--EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_'))
|
|
local bChangedTool = ChangedTool( EMC.MCHID)
|
|
-- Aggiorno la posizione dei rulli per eventuale cambio utensile
|
|
if bChangedTool ~= 0 then
|
|
WorkTab.dV1PosI = ParkV1
|
|
WorkTab.dV2PosI = ParkV2
|
|
end
|
|
-- Verifico se compattare i rulli
|
|
local bCloseV = false
|
|
if WorkTab.dY1DeltaI then
|
|
local dY1DeltaLim = MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0)
|
|
if WorkTab.dY1DeltaI <= dY1DeltaLim or ( WorkTab.dY1DeltaMaxF and WorkTab.dY1DeltaMaxF <= dY1DeltaLim) then
|
|
bCloseV = true
|
|
end
|
|
end
|
|
if WorkTab.dY2DeltaI then
|
|
local dY2DeltaLim = MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V
|
|
if EMC.LB - WorkTab.dY2DeltaI <= dY2DeltaLim or ( WorkTab.dY2DeltaMinF and EMC.LB - WorkTab.dY2DeltaMinF <= dY2DeltaLim) then
|
|
bCloseV = true
|
|
end
|
|
end
|
|
-- se ho cambiato modo di prendere utensile, forzo chiusura
|
|
if bChangedTool == 2 then
|
|
bCloseV = true
|
|
end
|
|
-- se i pezzi del cliente sono molto storti, si forza la chiusura per evitare che vada a sbattere. Se parametro non presente, si chiude solo se necessario
|
|
if ForceToCloseRollersGate then
|
|
bCloseV = true
|
|
end
|
|
|
|
WorkTab.bCloseV = bCloseV
|
|
|
|
-- |POSIZIONO Y1| **[A]**
|
|
if WorkTab.dY1DeltaMinF and ( not WorkTab.dY2DeltaMinF) then
|
|
-- [A1]/[A2] continuazione da morsa Y1 ( Y1 -> Y1 ) scambio Y2 (Y2 -> Y1)
|
|
if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then
|
|
WorkTab.bY1Parked = not WorkTab.dY1DeltaI
|
|
WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI)
|
|
WorkTab.bY2Parked = not WorkTab.dY2DeltaI
|
|
WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI)
|
|
return SpecAdjustCarrA( WorkTab)
|
|
else
|
|
EgtOutLog( ' Error CLAMP NULL-> Y1 impossibile')
|
|
error( 'Error CLAMP NULL-> Y1 impossibile')
|
|
end
|
|
|
|
-- |POSIZIONO Y1Y2| **[B]**
|
|
elseif WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then
|
|
-- [B1] passo da carrello Y1 a entrambi
|
|
if WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI) then
|
|
WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI)
|
|
return SpecAdjustCarrB1( WorkTab)
|
|
-- [B2] passo da carrello Y2 a entrambi
|
|
elseif WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI) then
|
|
WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI)
|
|
return SpecAdjustCarrB2(WorkTab)
|
|
-- [B3] rimango con due carrelli ( per ora accetto solo il caso in cui le posizioni sono già valide)
|
|
elseif WorkTab.dY1DeltaI > WorkTab.dY1DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY1DeltaI < WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and
|
|
WorkTab.dY2DeltaI > WorkTab.dY2DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI < WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then
|
|
EgtOutLog( '*[B3]', 1)
|
|
return {}
|
|
else
|
|
EgtOutLog( ' Error CLAMP NULL-> Y1+Y2 impossibile')
|
|
error( 'Error CLAMP NULL-> Y1+Y2 impossibile')
|
|
end
|
|
|
|
-- |POSIZIONO Y2| **[C]**
|
|
elseif not WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then
|
|
-- [C1]/[C2] continuazione da morsa Y2 ( Y2 -> Y2 ) sacmbio Y1 (Y1 -> Y2)
|
|
if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then
|
|
WorkTab.bY1Parked = not WorkTab.dY1DeltaI
|
|
WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI)
|
|
WorkTab.bY2Parked = not WorkTab.dY2DeltaI
|
|
WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI)
|
|
return SpecAdjustCarrC( WorkTab)
|
|
else
|
|
EgtOutLog( ' Error CLAMP NULL-> Y2 impossibile')
|
|
error( 'Error CLAMP NULL-> Y2 impossibile')
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **accentramento**
|
|
local function PosForCent1FY1( dY1a, dY2a, dTa, dExtraY1, dCorsaY1c, dCorsaY2Tc)
|
|
local dY2Delta = dY2a - dTa
|
|
local dDispl = dCorsaY1c - dExtraY1
|
|
if dDispl / 2 <= dCorsaY2Tc then
|
|
if dDispl / 2 <= dCorsaY1c then
|
|
dY1a = dY1a - dDispl / 2
|
|
dY2a = dY2a + dDispl / 2
|
|
else
|
|
dY1a = dY1a - dCorsaY1c
|
|
dY2a = dY2a + dDispl - dCorsaY1c
|
|
end
|
|
else
|
|
dY2a = dY2a + dCorsaY2Tc
|
|
dY1a = dY1a - (dDispl - dCorsaY2Tc)
|
|
end
|
|
dTa = dY2a - dY2Delta
|
|
return dY1a, dY2a, dTa
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **accentramento**
|
|
local function PosForCent1FY2( dY1a, dY2a, dTa, dExtraY2, dCorsaY1Tc, dCorsaY2c)
|
|
local dY1Delta = dY1a - dTa
|
|
local dDispl = dCorsaY2c + dExtraY2
|
|
if dDispl / 2 <= dCorsaY1Tc then
|
|
if dDispl / 2 <= dCorsaY2c then
|
|
dY1a = dY1a - dDispl / 2
|
|
dY2a = dY2a + dDispl / 2
|
|
else
|
|
dY2a = dY2a + dCorsaY2c
|
|
dY1a = dY1a - min( dDispl - dCorsaY2c, dCorsaY1Tc)
|
|
end
|
|
else
|
|
dY1a = dY1a - dCorsaY1Tc
|
|
dY2a = dY2a + min( dDispl - dCorsaY1Tc, dCorsaY2c)
|
|
end
|
|
dTa = dY1a - dY1Delta
|
|
return dY1a, dY2a, dTa
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **allontanamento**
|
|
local function PosForEnl1FY1( dY1a, dY2a, dTa, dExtra, dCorsaY1e, dCorsaY2Te)
|
|
local dDispl = MaxY1 - dY1a + dExtra
|
|
-- eseguo il posizionamento di Y1 allontanando Y1 e (Y2+T)
|
|
if dDispl/2 <= dCorsaY2Te then
|
|
if dDispl/2 <= dCorsaY1e then
|
|
dY1a = dY1a + dDispl / 2
|
|
dY2a = dY2a - dDispl / 2
|
|
dTa = dTa - dDispl / 2
|
|
else
|
|
dY1a = dY1a + dCorsaY1e
|
|
dY2a = dY2a - (dDispl - dCorsaY1e)
|
|
dTa = dTa - (dDispl - dCorsaY1e)
|
|
end
|
|
else
|
|
dY2a = dY2a - dCorsaY2Te
|
|
dTa = dTa - dCorsaY2Te
|
|
dY1a = dY1a + (dDispl - dCorsaY2Te)
|
|
end
|
|
return dY1a, dY2a, dTa
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **allontanamento**
|
|
local function PosForEnl1FY2( dY1a, dY2a, dTa, dExtra, dCorsaY1Te, dCorsaY2e)
|
|
local dDispl = dY2a - MinY2 - dExtra
|
|
-- eseguo il posizionamento di Y2 allontanando (Y1+T) e Y2
|
|
if dDispl/2 <= dCorsaY1Te then
|
|
if dDispl/2 <= dCorsaY2e then
|
|
dY1a = dY1a + dDispl / 2
|
|
dTa = dTa + dDispl / 2
|
|
dY2a = dY2a - dDispl / 2
|
|
else
|
|
dY2a = dY2a - dCorsaY2e
|
|
dY1a = dY1a + (dDispl - dCorsaY2e)
|
|
dTa = dTa + (dDispl - dCorsaY2e)
|
|
end
|
|
else
|
|
dY1a = dY1a + dCorsaY1Te
|
|
dTa = dTa + dCorsaY1Te
|
|
dY2a = dY2a - (dDispl - dCorsaY1Te)
|
|
end
|
|
return dY1a, dY2a, dTa
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
local function MaxDispl( TabI, vCmd, sType)
|
|
local dY1a, dY2a
|
|
local dTa = TabI.dTPosI
|
|
-- **[M1]** = allontanamento dei trascinatori con Y1 in presa
|
|
if sType == 'M1' then
|
|
EmitComment( vCmd, '[M1]')
|
|
-- ev' chiudo Y1, apro Y2
|
|
table.insert( vCmd, { 11, 1})
|
|
table.insert( vCmd, { 12, 0})
|
|
-- allontano (Y1+T) e (Y2)
|
|
dY1a = MaxY1
|
|
dY2a = MinY2
|
|
dTa = ( dY1a - TabI.dY1PosI) + dTa
|
|
-- **[M2]** = allontanamento dei trascinatori con Y2 in presa
|
|
elseif sType == 'M2' then
|
|
EmitComment( vCmd, '[M2]')
|
|
-- ev' chiudo Y2, apro Y1
|
|
table.insert( vCmd, { 12, 1})
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
-- allontano (Y2+T) e (Y1)
|
|
dY1a = MaxY1
|
|
dY2a = MinY2
|
|
dTa = ( dY2a - TabI.dY2PosI) + dTa
|
|
-- **[M3]** = accentramento dei trascinatori con Y1 in presa
|
|
elseif sType == 'M3' then
|
|
EmitComment( vCmd, '[M3]')
|
|
-- ev' chiudo Y1, apro Y2
|
|
table.insert( vCmd, { 11, 1})
|
|
table.insert( vCmd, { 12, 0})
|
|
-- accentro (Y1+T) e (Y2)
|
|
dY1a = TabI.MyMinY1V1
|
|
dY2a = TabI.MaxY2V2
|
|
dTa = ( dY1a - TabI.dY1PosI) + dTa
|
|
-- **[M4]** = accentramento dei trascinatori con Y2 in presa
|
|
elseif sType == 'M4' then
|
|
EmitComment( vCmd, '[M4]')
|
|
-- ev' chiudo Y2, apro Y1
|
|
table.insert( vCmd, { 12, 1})
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
-- accentro (Y2+T) e (Y1)
|
|
dY1a = TabI.MyMinY1V1
|
|
dY2a = TabI.MaxY2V2
|
|
dTa = ( dY2a - TabI.dY2PosI) + dTa
|
|
end
|
|
--
|
|
table.insert( vCmd, { 3, 'Y1', dY1a, 'Y2', dY2a, 'T', dTa, EMC.CNT})
|
|
TabI.dY1PosI = dY1a
|
|
TabI.dY2PosI = dY2a
|
|
TabI.dTPosI = dTa
|
|
end -- MaxDisplForRiXw
|
|
|
|
-----------------------------------------------------------------------------------------------------------
|
|
-- **ALLONTANAMENTO di Y1**
|
|
------------------------------------------------------------------------------------------------------------------
|
|
local function PosY1FromY2A( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY1FromY2A]')
|
|
local t = {}
|
|
-- **calcolo i delta dai dati iniziali**
|
|
t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2
|
|
-- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali
|
|
t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - MaxY1 --se > 0, la posizione non è raggiunginile
|
|
-- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per Y1 e (Y2+T)
|
|
t.dCorsaY1eI = MaxY1 - TabI.dY1PosI
|
|
t.dCorsaY2TeI= TabI.dY2PosI - MinY2
|
|
-- |RICONOSCO I CASI|
|
|
-- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere
|
|
t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI
|
|
if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '[Y1(0)] ')
|
|
--return t.dY1DeltaI
|
|
-- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa
|
|
elseif t.dExtraY1New > t.dCorsaY2TeI then
|
|
EmitComment( vCmd, '[Y1A-ri]')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI})
|
|
end
|
|
-- questo movimento serve solo a gestire (in modo complesso) il caso [ri]
|
|
MaxDispl( TabI, vCmd, 'M2')
|
|
--t.bXW = true
|
|
else
|
|
-- **[rp]** = raggiungo il punto medio Y1New dell'intervallo
|
|
EmitComment( vCmd, '[Y1A-rp] ')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- **1:** calcolo pos. di allontanamento per (Y1) e (Y2+T) (da posizioni iniziali)
|
|
TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1eI, t.dCorsaY2TeI)
|
|
-- aggiornamento posizioni e dY1Delta dopo <end>
|
|
-- chiusura di Y1, apertura e parcheggio di Y2 a fine funzione
|
|
-- ev' chiudo Y2 e apro Y1 ed eseguo allontanamento
|
|
table.insert( vCmd, { 12, 1})
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI
|
|
-- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti
|
|
return t.dY1DeltaA
|
|
end -- PosY1FromY2A
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ALLONTANAMENTO di Y2**
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY2FromY1A( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY2FromY1A]')
|
|
local t = {}
|
|
-- **calcolo i delta dai dati iniziali**
|
|
t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2
|
|
-- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali
|
|
t.dExtraY2New = ( TabI.dTPosI + t.dY2NewDelta) - MinY2 --se < 0, la posizione non è raggiunginile
|
|
-- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per (Y1+T) e Y2
|
|
t.dCorsaY1Te = MaxY1 - TabI.dY1PosI
|
|
t.dCorsaY2e = TabI.dY2PosI - MinY2
|
|
--
|
|
-- |RICONOSCO I CASI|
|
|
-- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere
|
|
t.dY2DeltaI = TabI.dY2PosI- TabI.dTPosI
|
|
if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '[Y2(0)] ')
|
|
-- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa
|
|
elseif -t.dExtraY2New > t.dCorsaY1Te then
|
|
EmitComment( vCmd, '[Y2A-ri]' )
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- questo movimento serve solo a gestire (in modo complesso) il caso [ri]
|
|
MaxDispl( TabI, vCmd, 'M1')
|
|
else
|
|
-- **[rp]** = raggiungo il punto medio Y2New dell'intervallo
|
|
EmitComment( vCmd, '[Y2A-rp] ')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- **1:** calcolo pos. di allontanamento per (Y1+T) e (Y2) (da posizioni iniziali)
|
|
TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1Te, t.dCorsaY2e)
|
|
-- chiudo Y1 e apro Y2 ed eseguo allontanamento (finale)
|
|
table.insert( vCmd, { 11, 1})
|
|
table.insert( vCmd, { 12, 0})
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI
|
|
-- chiusura di Y2, ev' apertura e parcheggio di Y1 : in funzioni chiamanti
|
|
return t.dY2DeltaA
|
|
end -- PosY2FromY1A
|
|
|
|
------------------------------------------------------------------------------------------------------------
|
|
-- **ACCENTRAMENTO di Y1**
|
|
------------------------------------------------------------------------------------------------------------
|
|
local function PosY1FromY2B( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY1FromY2B]')
|
|
local t = {}
|
|
-- **calcolo i delta dai dati iniziali**
|
|
t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2
|
|
-- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali
|
|
t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - TabI.MyMinY1V1 -- se < 0, la posizione non è raggiunginile
|
|
-- corse in accentramento disponibili per Y1 e (Y2+T) dalle posizioni iniziali
|
|
t.dCorsaY1cI = TabI.dY1PosI - TabI.MyMinY1V1
|
|
t.dCorsaY2TcI = TabI.MaxY2V2 - TabI.dY2PosI
|
|
--
|
|
-- |RICONOSCO I CASI|
|
|
-- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere
|
|
t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI
|
|
if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '[Y1(0)] ')
|
|
-- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa
|
|
elseif -t.dExtraY1New > t.dCorsaY2TcI then
|
|
EmitComment( vCmd, '[Y1B-ri]')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- questo movimento serve solo a gestire (in modo complesso) il caso [ri]
|
|
MaxDispl( TabI, vCmd, 'M4')
|
|
else
|
|
-- **[rp]** = raggiungo il punto medio Y1New dell'intervallo
|
|
EmitComment( vCmd, '[Y1B-rp] ')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- **1: calcolo accentramento di (Y1) e (Y2+T)**
|
|
TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1cI, t.dCorsaY2TcI)
|
|
-- posizionamento efettivo e aggiornamento di vCmd e dY1Delta dopo <end>
|
|
-- ch. di Y1 e ap. e parcheggio di Y2 a fine funzione chiamante
|
|
-- chiudo Y2 e apro Y1 ed eseguo accentramento (finale)
|
|
table.insert( vCmd, { 12, 1})
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI
|
|
-- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti
|
|
return t.dY1DeltaA
|
|
end -- PosY1FromY2B
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ACCENTRAMENTO di Y2**
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY2FromY1B( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY2FromY1B]')
|
|
local t = {}
|
|
-- **calcolo i delta dai dati iniziali**
|
|
t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2
|
|
-- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali
|
|
t.dExtraY2New = (TabI.dTPosI + t.dY2NewDelta) - TabI.MaxY2V2 -- se > 0 la posizione non è raggiunginile
|
|
-- corse in accentramento disponibili per (Y1+T) e (Y2) dalle posizioni iniziali
|
|
t.dCorsaY1TcI = TabI.dY1PosI - TabI.MyMinY1V1
|
|
t.dCorsaY2cI = TabI.MaxY2V2 - TabI.dY2PosI
|
|
-- |RICONOSCO I CASI|
|
|
-- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere
|
|
t.dY2DeltaI = TabI.dY2PosI-TabI.dTPosI
|
|
if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '[Y2(0)] ')
|
|
-- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa
|
|
elseif t.dExtraY2New > t.dCorsaY1TcI then
|
|
EmitComment( vCmd, '[Y2B-ri]' )
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- questo movimento serve solo a gestire (in modo complesso) il caso [ri]
|
|
MaxDispl( TabI, vCmd, 'M3')
|
|
else
|
|
-- **[rp]** = raggiungo il punto medio Y2New dell'intervallo
|
|
EmitComment( vCmd, '[Y2B-rp] ')
|
|
if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
-- Y1 chiuso, Y2 aperto
|
|
-- **1: calcolo accentramento di (Y1+T) e (Y2)**
|
|
TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1TcI, t.dCorsaY2cI)
|
|
-- ev' chiudo Y1 e apro Y2 ed eseguo movimento accentramento
|
|
table.insert( vCmd, { 11, 1})
|
|
table.insert( vCmd, { 12, 0})
|
|
table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT})
|
|
end
|
|
t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI
|
|
-- chiusura di Y2, apertura e parcheggio di Y1 : in funzioni chiamanti
|
|
return t.dY2DeltaA
|
|
end -- PosY2FromY1B
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ALLONTANAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C]
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY1Y2A( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY1Y2A]')
|
|
-- |RICONOSCO I CASI|
|
|
repeat
|
|
local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2
|
|
local bXW = true
|
|
-- se intervallo per Y1 raggiungibile in una sola fase
|
|
-- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc)
|
|
-- e Y2 è in posizione per aggancio su T
|
|
if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and
|
|
TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then
|
|
-- |POSIZIONO MORSA 1| in **allontanamento**
|
|
PosY1FromY2A( TabI, vCmd)
|
|
-- |POSIZIONO MORSA 2|
|
|
if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then
|
|
-- in **allontanamento**
|
|
PosY2FromY1A( TabI, vCmd)
|
|
else
|
|
-- in **accentramento**
|
|
PosY2FromY1B( TabI, vCmd)
|
|
end
|
|
bXW = false
|
|
else
|
|
-- |POSIZIONO MORSA 2| e poi MORSA 1
|
|
-- in **allontanamento**
|
|
if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then
|
|
-- se intervallo per Y2 raggiungibile in una sola fase
|
|
if - (( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI then
|
|
PosY2FromY1A( TabI, vCmd)
|
|
PosY1FromY2A( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
else
|
|
-- in **accentramento**
|
|
-- sempre se intervallo per Y2 raggiungibile in una sola fase
|
|
if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 then
|
|
PosY2FromY1B( TabI, vCmd)
|
|
PosY1FromY2A( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
end
|
|
end
|
|
if bXW then
|
|
-- Massimo trascinamento della trave in direzione negativa ( casi **[xw]**)
|
|
EmitComment( vCmd, '[Y1A-xw]')
|
|
if TabI.dY1PosI ~= TabI.MyMinY1V1 then
|
|
-- accentramento morse, trascinamento trave con Y1
|
|
MaxDispl( TabI, vCmd, 'M3')
|
|
else
|
|
-- allontanamento morse, trascinamento trave con Y2
|
|
MaxDispl( TabI, vCmd, 'M2')
|
|
end
|
|
end
|
|
until ( not bXW)
|
|
-- chiusura/parcheggio dei trascinatori in funzioni chiamanti
|
|
local dY1Delta = TabI.dY1PosI - TabI.dTPosI
|
|
local dY2Delta = TabI.dY2PosI - TabI.dTPosI
|
|
return dY1Delta, dY2Delta
|
|
end -- PosY1Y2A
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ACCENTRAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C]
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY1Y2B( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY1Y2B]')
|
|
-- |RICONOSCO I CASI|
|
|
local nCnt = 0
|
|
repeat
|
|
local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF) / 2
|
|
local bXW = true
|
|
-- se intervallo per Y1 raggiungibile in una sola fase
|
|
-- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc)
|
|
-- e Y2 è in posizione per aggancio su T
|
|
if -(( TabI.dTPosI + TabI.dY1DeltaMaxF) - TabI.MyMinY1V1) < TabI.MaxY2V2 - TabI.dY2PosI and
|
|
TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then
|
|
-- |POSIZIONO MORSA 1| in **accentramento**
|
|
PosY1FromY2B( TabI, vCmd)
|
|
-- |POSIZIONO MORSA 2|
|
|
local dY2DeltaI = TabI.dY2PosI - TabI.dTPosI
|
|
-- Se il trascinatore 2 non è già nell'intervallo richiesto
|
|
if dY2DeltaI > TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL or dY2DeltaI < TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then
|
|
-- in **allontanamento**
|
|
PosY2FromY1A( TabI, vCmd)
|
|
else
|
|
-- in **accentramento**
|
|
PosY2FromY1B( TabI, vCmd)
|
|
end
|
|
end
|
|
bXW = false
|
|
-- se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 (casi [rp] o [ri])
|
|
else
|
|
-- |POSIZIONO MORSA 2| e poi MORSA 1
|
|
-- in **allontanamento**
|
|
if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then
|
|
-- se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T
|
|
if -(( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI and
|
|
TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then
|
|
PosY2FromY1A( TabI, vCmd)
|
|
PosY1FromY2B( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
-- in **accentramento**
|
|
else
|
|
-- sempre se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T
|
|
if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and
|
|
TabI.dY1PosI <= TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then
|
|
PosY2FromY1B( TabI, vCmd)
|
|
PosY1FromY2B( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
end
|
|
end
|
|
if bXW then
|
|
-- Massimo trascinamento della trave in direzione positiva (casi **[xw]** )
|
|
-- se Y1 non è a f.c. e se Y1 può afferrare la trave
|
|
EmitComment( vCmd, '[Y1B-xw]')
|
|
if TabI.dY1PosI ~= MaxY1 and
|
|
TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then
|
|
-- allontanamento morse, trascinamento trave con Y1
|
|
MaxDispl( TabI, vCmd, 'M1')
|
|
else
|
|
-- accentramento morse, trascinamento trave con Y2
|
|
MaxDispl( TabI, vCmd, 'M4')
|
|
end
|
|
end
|
|
nCnt = nCnt + 1
|
|
if nCnt > 10 then return end
|
|
until ( not bXW)
|
|
-- chiusura/parcheggio dei trascinatori in funzioni chiamanti
|
|
local dY1Delta = TabI.dY1PosI - TabI.dTPosI
|
|
local dY2Delta = TabI.dY2PosI - TabI.dTPosI
|
|
return dY1Delta, dY2Delta
|
|
end -- PosY1Y2B
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ALLONTANAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1]
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY2Y1A( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY2Y1A]')
|
|
-- |RICONOSCO I CASI|
|
|
repeat
|
|
local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2
|
|
local bXW = true
|
|
-- se intervallo per Y2 raggiungibile in una sola fase
|
|
-- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo <=> ( -ExtraI2MaxF < Corsa Y1Te and)
|
|
-- e Y1 è in posizione per aggancio su T
|
|
if MinY2 - ( TabI.dTPosI + TabI.dY2DeltaMaxF) < MaxY1 - TabI.dY1PosI and
|
|
TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then
|
|
-- |POSIZIONO MORSA 2| in **allontanamento**
|
|
PosY2FromY1A( TabI, vCmd)
|
|
-- |POSIZIONO MORSA 1|
|
|
if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then
|
|
-- in **allontanamento**
|
|
PosY1FromY2A( TabI, vCmd)
|
|
else
|
|
-- in **accentramento**
|
|
PosY1FromY2B( TabI, vCmd)
|
|
end
|
|
bXW = false
|
|
else
|
|
-- |POSIZIONO MORSA 1| e poi MORSA 2
|
|
-- caso di allontanamento
|
|
if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then
|
|
-- se l'intervallo per Y1 è raggiungibile in una sola fase
|
|
if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 then
|
|
PosY1FromY2A( TabI, vCmd)
|
|
PosY2FromY1A( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
-- in **accentramento**
|
|
else
|
|
-- sempre se l'intervallo per Y1 è raggiungibile in una sola fase
|
|
if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI then
|
|
PosY1FromY2B( TabI, vCmd)
|
|
PosY2FromY1A( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
end
|
|
end
|
|
if bXW then
|
|
-- Massimo trascinamento della trave in direzione positiva (casi **[xw]**)
|
|
EmitComment( vCmd, '[Y2A-xw]')
|
|
-- accentramento morse, trascinamento trave con Y2
|
|
if TabI.dY2PosI ~= TabI.MaxY2V2 then
|
|
MaxDispl( TabI, vCmd, 'M4')
|
|
-- allontanamento morse, trascinamento trave con Y1
|
|
else
|
|
MaxDispl( TabI, vCmd, 'M1')
|
|
end
|
|
end
|
|
until ( not bXW)
|
|
-- chiusura/parcheggio dei trascinatori in funzioni chiamanti
|
|
local dY1Delta = TabI.dY1PosI - TabI.dTPosI
|
|
local dY2Delta = TabI.dY2PosI - TabI.dTPosI
|
|
return dY1Delta, dY2Delta
|
|
end -- PosY2Y1A
|
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
-- **ACCENTRAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1]
|
|
--------------------------------------------------------------------------------------------------------
|
|
local function PosY2Y1B( TabI, vCmd)
|
|
EmitComment( vCmd, '[PosY2Y1B]')
|
|
-- |RICONOSCO I CASI|
|
|
local nCnt = 0
|
|
repeat
|
|
local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF) / 2
|
|
local bXW = true
|
|
-- se intervallo per Y2 raggiungibile in una sola fase
|
|
-- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 <=> (-ExtraI2MinF < Corsa Y1Tc)
|
|
-- e Y1 è in posizione per aggancio su T
|
|
if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and
|
|
TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then
|
|
-- |POSIZIONO MORSA 2| in **accentramento**
|
|
PosY2FromY1B( TabI, vCmd)
|
|
-- |POSIZIONO MORSA 1|
|
|
local dY1DeltaI = TabI.dY1PosI - TabI.dTPosI
|
|
-- Se il trascinatore 1 non è già nell'intervallo richiesto
|
|
if dY1DeltaI > TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL or dY1DeltaI < TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then
|
|
if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then
|
|
-- in **allontanamento**
|
|
PosY1FromY2A( TabI, vCmd)
|
|
else
|
|
-- in **accentramento**
|
|
PosY1FromY2B( TabI, vCmd)
|
|
end
|
|
end
|
|
bXW = false
|
|
-- se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 (casi [rp] o [ri])
|
|
else
|
|
-- |POSIZIONO MORSA 1| e poi MORSA 2
|
|
-- in **allontanamento**
|
|
if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then
|
|
-- se intervallo per Y1 è raggiungibile in una sola fase e Y2 è in posizione per aggancio su T
|
|
if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and
|
|
TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then
|
|
PosY1FromY2A( TabI, vCmd)
|
|
PosY2FromY1B( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
-- in **accentramento**
|
|
else
|
|
-- se (-ExtraI1MaxF < Corsa Y2Tc) e (Y2 è in posizione per aggancio su T)
|
|
if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI and
|
|
TabI.dY2PosI >= TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then
|
|
PosY1FromY2B( TabI, vCmd)
|
|
PosY2FromY1B( TabI, vCmd)
|
|
bXW = false
|
|
end
|
|
end
|
|
end
|
|
if bXW then
|
|
-- Massimo trascinamento della trave in direzione negativa (casi x[w])
|
|
EmitComment( vCmd, '[Y2B-xw]')
|
|
-- se Y2 non è a f.c. e se Y2 può afferrare la trave
|
|
if TabI.dY2PosI > MinY2 and
|
|
TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HOVM + EMC.HCING - 10 * GEO.EPS_SMALL then
|
|
-- allontanamento morse, trascinamento trave con Y2
|
|
MaxDispl( TabI, vCmd, 'M2')
|
|
else
|
|
-- accentramento morse, trascinamento trave con Y1
|
|
MaxDispl( TabI, vCmd, 'M3')
|
|
end
|
|
end
|
|
nCnt = nCnt + 1
|
|
if nCnt > 10 then return end
|
|
until ( not bXW)
|
|
-- la chiusura delle morse è fatta sopra
|
|
local dY1Delta = TabI.dY1PosI - TabI.dTPosI
|
|
local dY2Delta = TabI.dY2PosI - TabI.dTPosI
|
|
return dY1Delta, dY2Delta
|
|
end -- PosY2Y1FromY1B
|
|
|
|
---------------------------------------------------------------------
|
|
-- **[A] Posizionamento trascinatore Y1 da (Y1 o Y2) <=> Y1/Y2 -> Y1**
|
|
---------------------------------------------------------------------
|
|
function SpecAdjustCarrA( WorkTab)
|
|
-- Elenco comandi
|
|
local vCmd = {}
|
|
table.insert( vCmd, { 0, 'Y1/Y2 -> Y1'})
|
|
EmitComment( vCmd, '*[A]')
|
|
|
|
local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1)
|
|
local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2)
|
|
-- se primo scambio
|
|
local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1)
|
|
-- recupero le posizioni correnti
|
|
local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI
|
|
local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI
|
|
local dY1DeltaF
|
|
-- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità
|
|
EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1)
|
|
EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1)
|
|
|
|
-- [A(1)] - Se il trascinatore Y1 non è nell'intervallo valido, devo posizionarlo
|
|
if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF - GEO.EPS_SMALL or WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF + GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '*[A(1)]')
|
|
-- -----------------------------------------
|
|
-- |VERIFICO POSIZIONE RULLI|
|
|
-- ------------------------------------------
|
|
-- eseguo eventuale posizionamento sicuro di teste e rulli
|
|
if WorkTab.bCloseV then
|
|
EnsureZmax( true, vCmd)
|
|
MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1)
|
|
MaxY2V2 = MaxY2
|
|
end
|
|
-- ------------------------------------------
|
|
-- |DEFINISCO INTERVALLO 2|
|
|
-- ------------------------------------------
|
|
WorkTab.dY2DeltaMaxF = WorkTab.dY1DeltaMinF - ( MyMinY1V1 - MaxY2V2) + ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF)
|
|
WorkTab.dY2DeltaMinF = WorkTab.dY1DeltaMaxF - ( MaxY1 - MinY2) - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF)
|
|
-- se Y2 deve allontanarsi assegno il primo punto valido (altrimenti mantengo tutto l'intervallo valido)
|
|
if WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF then
|
|
WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF), MinJoin + EMC.HCING + EMC.HOVM)
|
|
end
|
|
-- se la trave è più 'corta' dell'intervallo per Y2 aggiorno l'intervallo (potrei essere comunque in un punto valido)
|
|
if WorkTab.dY2DeltaMinF < MinJoin + EMC.HCING + EMC.HOVM then
|
|
WorkTab.dY2DeltaMinF = MinJoin + EMC.HCING + EMC.HOVM
|
|
-- se Y2 deve accentrarsi
|
|
if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF then
|
|
WorkTab.dY2DeltaMaxF = 2 * MinJoin + EMC.HCING + EMC.HOVM
|
|
end
|
|
end
|
|
-- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità
|
|
local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2
|
|
local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2
|
|
--------------------------------------------
|
|
-- |RICONOSCO I CASI|
|
|
--------------------------------------------
|
|
TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF,
|
|
dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF }
|
|
if WorkTab.dY1DeltaI > dY1NewDelta then
|
|
--[A(1)B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y1
|
|
EmitComment( vCmd, '[A-Y1B]')
|
|
dY1DeltaF = PosY1Y2B( TabValI, vCmd)
|
|
else
|
|
--[A(1)A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y1
|
|
EmitComment( vCmd, '[A-Y1A]')
|
|
dY1DeltaF = PosY1Y2A( TabValI, vCmd)
|
|
end
|
|
-- chiudo Y1
|
|
table.insert( vCmd, { 11, 1})
|
|
-- dichiaro Y2 da parcheggiare
|
|
WorkTab.bY2Parked = false
|
|
|
|
-- [A(0)] - Se Y1 è già nell'intervallo valido, si lascia dove è
|
|
else
|
|
EmitComment( vCmd, '*[A(0)]')
|
|
if not WorkTab.bY2Parked then
|
|
-- dichiaro posizione di Y2 e T
|
|
table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y2', dY2PosI})
|
|
end
|
|
if WorkTab.bY1Parked then
|
|
-- chiudo Y1
|
|
table.insert( vCmd, { 11, 1})
|
|
end
|
|
dY1DeltaF = WorkTab.dY1DeltaI
|
|
end
|
|
|
|
if not WorkTab.bY2Parked then
|
|
-- apro e parcheggio Y2
|
|
table.insert( vCmd, { 12, 0})
|
|
table.insert( vCmd, { 1, 'Y2', ParkY2})
|
|
end
|
|
|
|
-- aggiorno e segnalo la posizione finale Y1Delta
|
|
table.insert( vCmd, { 21, dY1DeltaF, 0})
|
|
EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF), 1)
|
|
-- segnalo la posizione dei rulli
|
|
table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF})
|
|
|
|
SpecOutputCNT()
|
|
return vCmd
|
|
end
|
|
-- SpecAdjustCarrAA
|
|
|
|
--------------------------------------------------------------------
|
|
-- **[B1] da trascinatore Y1 a entrambi <=> Y1 -> Y1+Y2**
|
|
--------------------------------------------------------------------
|
|
function SpecAdjustCarrB1( WorkTab)
|
|
-- Elenco comandi
|
|
local vCmd = {}
|
|
table.insert( vCmd, { 0, 'Y1 -> Y1+Y2'})
|
|
EmitComment( vCmd, '*[B1]')
|
|
|
|
local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1)
|
|
local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2)
|
|
-- se primo scambio
|
|
local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1)
|
|
|
|
-- recupero le posizioni correnti
|
|
local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI
|
|
local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI
|
|
local dY1DeltaF, dY2DeltaF
|
|
-- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità
|
|
local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2
|
|
local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2
|
|
--
|
|
EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1)
|
|
EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1)
|
|
EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1)
|
|
|
|
-- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle
|
|
-- -----------------------------------------
|
|
-- |VERIFICO POSIZIONE RULLI|
|
|
-- ------------------------------------------
|
|
if WorkTab.bCloseV then
|
|
EnsureZmax( true, vCmd)
|
|
MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1)
|
|
MaxY2V2 = MaxY2
|
|
end
|
|
|
|
-- -----------------------------------------
|
|
-- |RICONOSCO I CASI|
|
|
-- ------------------------------------------
|
|
-- definisco la tabella delle posizioni iniziali
|
|
TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF,
|
|
dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF }
|
|
-- [B1-Y2A] **ALLONTANAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1
|
|
if WorkTab.dY2DeltaI > dY2NewDelta then
|
|
EmitComment( vCmd, '[B1-Y2A]')
|
|
dY1DeltaF, dY2DeltaF = PosY2Y1A( TabValI, vCmd)
|
|
else
|
|
-- [B1-Y2B] **ACCENTRAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1
|
|
EmitComment( vCmd, '[B1-Y2B] ')
|
|
dY1DeltaF, dY2DeltaF = PosY2Y1B( TabValI, vCmd)
|
|
end
|
|
-- -----------------------------------------
|
|
-- |CHIUSURA MORSE|
|
|
-- ------------------------------------------
|
|
if not SpecTestSomeMoveInCmds( vCmd) then
|
|
table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT})
|
|
end
|
|
table.insert( vCmd, { 12, 1}) -- Chiudo Y2
|
|
table.insert( vCmd, { 11, 1}) -- chiudo Y1
|
|
-- imposto i nuovi parametri di aggancio
|
|
table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF})
|
|
EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1)
|
|
-- segnalo la posizione dei rulli
|
|
table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF})
|
|
|
|
SpecOutputCNT()
|
|
return vCmd
|
|
end
|
|
-- SpecAdjustCarrB1
|
|
|
|
---------------------------------------------------------------------
|
|
-- **[B2] da trascinatore Y2 a entrambi <=> Y2 -> Y1+Y2**
|
|
--------------------------------------------------------------------
|
|
function SpecAdjustCarrB2( WorkTab)
|
|
-- Elenco comandi
|
|
local vCmd = {}
|
|
table.insert( vCmd, { 0, 'Y2 -> Y1+Y2'})
|
|
EmitComment( vCmd, '*[B2]')
|
|
|
|
local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1)
|
|
local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2)
|
|
-- se primo scambio
|
|
local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1)
|
|
|
|
-- definisco le posizioni **Iniziali** (= recupero le posizioni correnti)
|
|
local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI
|
|
local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI
|
|
local dY2DeltaF, dY1DeltaF
|
|
-- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità
|
|
local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2
|
|
local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2
|
|
--
|
|
EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI)..' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1)
|
|
EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1)
|
|
EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1)
|
|
|
|
-- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle
|
|
-- -----------------------------------------
|
|
-- |VERIFICO POSIZIONE RULLI|
|
|
-- ------------------------------------------
|
|
-- eseguo eventuale posizionamento sicuro di teste e rulli
|
|
if WorkTab.bCloseV then
|
|
EnsureZmax( true, vCmd)
|
|
MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1)
|
|
MaxY2V2 = MaxY2
|
|
end
|
|
|
|
-- -----------------------------------------
|
|
-- |RICONOSCO I CASI|
|
|
-- ------------------------------------------
|
|
-- definisco la tabella delle posizioni iniziali
|
|
TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF,
|
|
dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF }
|
|
-- [B2-Y1A] **ALLONTANAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2
|
|
if WorkTab.dY1DeltaI < dY1NewDelta then
|
|
EmitComment( vCmd, '[B2-Y1A]')
|
|
dY1DeltaF, dY2DeltaF = PosY1Y2A( TabValI, vCmd)
|
|
else
|
|
-- [B2-Y1B] **ACCENTRAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2
|
|
EmitComment( vCmd, '[B2-Y1B]')
|
|
dY1DeltaF, dY2DeltaF = PosY1Y2B( TabValI, vCmd)
|
|
end
|
|
|
|
-- -----------------------------------------
|
|
-- |CHIUSURA MORSE|
|
|
-- ------------------------------------------
|
|
if not SpecTestSomeMoveInCmds( vCmd) then
|
|
table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT})
|
|
end
|
|
table.insert( vCmd, { 12, 1}) -- Chiudo Y2
|
|
table.insert( vCmd, { 11, 1}) -- chiudo Y1
|
|
-- imposto i nuovi parametri di aggancio
|
|
table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF})
|
|
EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1)
|
|
-- segnalo la posizione dei rulli
|
|
table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF})
|
|
|
|
SpecOutputCNT()
|
|
return vCmd
|
|
end
|
|
-- SpecAdjustCarrB2
|
|
|
|
---------------------------------------------------------------------
|
|
-- **[C] ex[C1]/[C2] Posizionamento trascinatore Y2 da (Y1 o Y2) <=> Y1/Y2 -> Y2**
|
|
---------------------------------------------------------------------
|
|
function SpecAdjustCarrC( WorkTab)
|
|
-- Elenco comandi
|
|
local vCmd = {}
|
|
table.insert( vCmd, { 0, 'Y1/Y2 -> Y2'})
|
|
EmitComment( vCmd, '*[C]')
|
|
|
|
local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1)
|
|
local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2)
|
|
local MyTCING = EgtIf( SPLIT, EMC.TCING, 0)
|
|
-- se primo scambio
|
|
local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1)
|
|
-- recupero le posizioni correnti
|
|
local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI
|
|
local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI
|
|
local dY2DeltaF
|
|
--
|
|
EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1)
|
|
EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1)
|
|
|
|
-- [C(1)] - Se il trascinatore Y2 non è nell'intervallo valido, devo posizionarlo
|
|
if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF - GEO.EPS_SMALL or WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF + GEO.EPS_SMALL then
|
|
EmitComment( vCmd, '*[C(1)]')
|
|
-- -----------------------------------------
|
|
-- |VERIFICO POSIZIONE RULLI|
|
|
-- ------------------------------------------
|
|
-- eseguo eventuale posizionamento sicuro di teste e rulli
|
|
if WorkTab.bCloseV then
|
|
EnsureZmax( true, vCmd)
|
|
MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1)
|
|
MaxY2V2 = MaxY2
|
|
end
|
|
-- ------------------------------------------
|
|
-- |DEFINISCO INTERVALLO 1|
|
|
-- ------------------------------------------
|
|
WorkTab.dY1DeltaMaxF = WorkTab.dY2DeltaMinF + (MaxY1 - MinY2) + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF)
|
|
WorkTab.dY1DeltaMinF = WorkTab.dY2DeltaMaxF + (MyMinY1V1 - MaxY2V2) - (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF)
|
|
-- se Y1 deve allontanarsi assegno il primo punto valido (altrimenti lascio l'intervallo)
|
|
if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF then
|
|
WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF), EMC.LB - MinJoin - MyTCING)
|
|
end
|
|
-- se la trave è più 'corta' dell'intervallo per Y1 aggiorno l'intervallo (potrei essere comunque in un punto valido)
|
|
if WorkTab.dY1DeltaMaxF > EMC.LB - ( MinJoin + MyTCING) then
|
|
WorkTab.dY1DeltaMaxF = EMC.LB - ( MinJoin + MyTCING)
|
|
-- se Y1 deve accentrarsi
|
|
if WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF then
|
|
WorkTab.dY1DeltaMinF = EMC.LB - 2 * MinJoin - MyTCING
|
|
end
|
|
end
|
|
-- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità
|
|
local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2
|
|
local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2
|
|
|
|
-- ------------------------------------------
|
|
-- |RICONOSCO I CASI|
|
|
-- ------------------------------------------
|
|
TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF,
|
|
dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF}
|
|
if WorkTab.dY2DeltaI < dY2NewDelta then
|
|
-- [C-Y2B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y2
|
|
EmitComment( vCmd, '[C-Y2B]')
|
|
_, dY2DeltaF = PosY2Y1B( TabValI, vCmd)
|
|
else
|
|
-- [C-Y2A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y2
|
|
EmitComment( vCmd, '[C-Y2A]')
|
|
_, dY2DeltaF = PosY2Y1A( TabValI, vCmd)
|
|
end
|
|
-- chiudo Y2
|
|
table.insert( vCmd, { 12, 1})
|
|
-- dichiaro Y1 da parcheggiare
|
|
WorkTab.bY1Parked = false
|
|
|
|
-- [C(0)] - Se Y2 è già nell'intervallo valido, si lascia dove è
|
|
else
|
|
EmitComment( vCmd, '*[C(0)]')
|
|
if not WorkTab.bY1Parked then
|
|
-- dichiaro posizione di Y1 e T
|
|
table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y1', dY1PosI, EMC.CNT})
|
|
end
|
|
if WorkTab.bY2Parked then
|
|
-- chiudo Y2
|
|
table.insert( vCmd, { 12, 1})
|
|
end
|
|
dY2DeltaF = WorkTab.dY2DeltaI
|
|
end
|
|
|
|
if not WorkTab.bY1Parked then
|
|
-- apro e parcheggio Y1
|
|
table.insert( vCmd, { 11, 0})
|
|
EMC.CNT = nil
|
|
table.insert( vCmd, { 1, 'Y1', ParkY1})
|
|
end
|
|
|
|
-- aggiorno e segnalo la posizione finale Y2Delta
|
|
table.insert( vCmd, { 21, 0, dY2DeltaF})
|
|
EgtOutLog( ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1)
|
|
-- segnalo la posizione dei rulli
|
|
table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF})
|
|
|
|
SpecOutputCNT()
|
|
return vCmd
|
|
end -- SpecAdjustCarrC2
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecOutputCNT()
|
|
if EMC.CNT == 1 then
|
|
EgtSetInfo( EMC.PATHID, 'CNT', 1)
|
|
else
|
|
EgtRemoveInfo( EMC.PATHID, 'CNT')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecGetCNT( CurrOpeId)
|
|
while CurrOpeId do
|
|
local nPrevOpeId = EgtGetPrevActiveOperation( CurrOpeId)
|
|
if not nPrevOpeId then
|
|
return nil
|
|
end
|
|
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL)
|
|
if nLastPathId then
|
|
return EgtGetInfo( nLastPathId, 'CNT', 'i')
|
|
end
|
|
CurrOpeId = nPrevOpeId
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecOutputCmds( vCmd, bEnd)
|
|
local sRoot = EgtIf( not bEnd, 'AS', 'AE')
|
|
-- Registro il numero di comandi
|
|
if vCmd and #vCmd > 0 then
|
|
EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd)
|
|
else
|
|
EgtRemoveInfo( EMC.PATHID, sRoot..'#')
|
|
end
|
|
-- Registro i comandi
|
|
for i = 1, #(vCmd or {}) do
|
|
local Cmd = vCmd[i]
|
|
local sKey = sRoot .. tostring( i)
|
|
-- commento
|
|
if Cmd[1] == 0 then
|
|
local sInfo = '0,'..Cmd[2]
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- movimento di 1 asse
|
|
elseif Cmd[1] == 1 then
|
|
local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..EgtIf( Cmd[4], ',*', '')
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- movimento di 2 assi
|
|
elseif Cmd[1] == 2 then
|
|
local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..EgtIf( Cmd[6], ',*', '')
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- movimento di 3 assi
|
|
elseif Cmd[1] == 3 then
|
|
local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','..
|
|
Cmd[6]..','..EgtNumToString( Cmd[7],3)..EgtIf( Cmd[8], ',*', '')
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- posizione sicura per movimento carrelli
|
|
elseif Cmd[1] == 4 then
|
|
local sInfo = '4,'..EgtNumToString( Cmd[2],0)
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- apertura/chiusura morsa Y
|
|
elseif Cmd[1] == 11 then
|
|
local sInfo = '11,'..EgtNumToString( Cmd[2],0)
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- apertura/chiusura morsa V
|
|
elseif Cmd[1] == 12 then
|
|
local sInfo = '12,'..EgtNumToString( Cmd[2],0)
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- impostazione nuovo stato dei carrelli
|
|
elseif Cmd[1] == 21 then
|
|
local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3)
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
if Cmd[2] > 0 and Cmd[3] > 0 then
|
|
EMC.Y1DELTA = Cmd[2]
|
|
EMC.Y2DELTA = Cmd[3]
|
|
elseif Cmd[2] > 0 then
|
|
EMC.Y1DELTA = Cmd[2]
|
|
EMC.Y2DELTA = nil
|
|
elseif Cmd[3] > 0 then
|
|
EMC.Y1DELTA = nil
|
|
EMC.Y2DELTA = Cmd[3]
|
|
end
|
|
-- impostazione nuova posizione dei rulli
|
|
elseif Cmd[1] == 22 then
|
|
local sInfo = '22,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3)
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
EMC.V1POS = Cmd[2]
|
|
EMC.V2POS = Cmd[3]
|
|
-- aggancio grezzo a carrello
|
|
elseif Cmd[1] == 31 then
|
|
local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3]
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
-- segnalazione errore
|
|
elseif Cmd[1] == 99 then
|
|
local sInfo = '99,' .. Cmd[2] .. ',' .. Cmd[3]
|
|
EgtSetInfo( EMC.PATHID, sKey, sInfo)
|
|
end
|
|
end
|
|
|
|
-- Salvo i nuovi delta dei carrelli
|
|
if EMC.Y1DELTA then
|
|
EgtSetInfo( EMC.PATHID, 'Y1DELTA', EMC.Y1DELTA)
|
|
else
|
|
EgtRemoveInfo( EMC.PATHID, 'Y1DELTA')
|
|
end
|
|
if EMC.Y2DELTA then
|
|
EgtSetInfo( EMC.PATHID, 'Y2DELTA', EMC.Y2DELTA)
|
|
else
|
|
EgtRemoveInfo( EMC.PATHID, 'Y2DELTA')
|
|
end
|
|
|
|
--Salvo le nuove posizioni dei rulli
|
|
EgtSetInfo( EMC.PATHID, 'V1POS', EMC.V1POS)
|
|
EgtSetInfo( EMC.PATHID, 'V2POS', EMC.V2POS)
|
|
-- Se comandi finali
|
|
if bEnd then
|
|
-- Se operazione successiva è disposizione, salvo anche lì le posizioni dei rulli
|
|
local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1)
|
|
if NextDispId and NextDispId == EgtGetNextActiveOperation( EMC.DISPID or EMC.MCHID) then
|
|
EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS)
|
|
EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecSetCarrPosFromCmds( vCmd)
|
|
-- recupero nuova posizione carrelli
|
|
for i = 1, #(vCmd or {}) do
|
|
local Cmd = vCmd[i]
|
|
if Cmd[1] == 21 then
|
|
if Cmd[2] > 0 and Cmd[3] > 0 then
|
|
EMC.Y1DELTA = Cmd[2]
|
|
EMC.Y2DELTA = Cmd[3]
|
|
elseif Cmd[2] > 0 then
|
|
EMC.Y1DELTA = Cmd[2]
|
|
EMC.Y2DELTA = nil
|
|
elseif Cmd[3] > 0 then
|
|
EMC.Y1DELTA = nil
|
|
EMC.Y2DELTA = Cmd[3]
|
|
end
|
|
elseif Cmd[1] == 22 then
|
|
EMC.V1POS = Cmd[2]
|
|
EMC.V2POS = Cmd[3]
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecTestOnlyRemarkInCmds( vCmd)
|
|
if not vCmd then return true end
|
|
-- verifico se nella lista dei comandi ci sono solo commenti
|
|
for i = 1, #vCmd do
|
|
if vCmd[i][1] ~= 0 then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function SpecTestSomeMoveInCmds( vCmd)
|
|
if not vCmd then return false end
|
|
-- verifico se nella lista dei comandi c'è almeno un movimento
|
|
for i = 1, #vCmd do
|
|
if vCmd[i][1] == 1 or vCmd[i][1] == 2 or vCmd[i][1] == 3 then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|