Files
essetre-pfmaxrl/Common_ONE-PF.mlse
2026-03-17 15:21:34 +01:00

2967 lines
124 KiB
Plaintext

-- Special Operations macchine standard ONE e PF by EgalWare s.r.l. 2023/11/24
-- Intestazioni
require( 'EmtGenerator')
EgtEnableDebug( false)
-- Carico libreria
local BD = require( 'BeamData')
---------------------------------------------------------------------
-- *** Generic Machinings ***
---------------------------------------------------------------------
require( 'EmtGenMachining')
---------------------------------------------------------------------
-- *** Special GetPrevMachiningOffset ***
---------------------------------------------------------------------
-----------------------------------------------------------------------------------------
function OnSpecialGetPrevMachiningOffset()
-- Aggiorno posizione della testa della trave a seguito di movimenti delle pinze non previsti tra le fasi
local function TPosUpdate()
local nClId = EgtGetFirstNameInGroup( EMC.CURRMCHID, 'CL') -- recupero Id del gruppo CL della lavorazione corrente
local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) -- Id del primo gruppo nella lavorazione (P1)
if not nPathId then
EMC.ERR = 12
EMC.MSG = ' Error : CL group path not found'
return
end
local dAuxMoveCount = EgtGetInfo( nPathId, 'AS#', 'd') or 0 -- numero di movimenti ausiliari
local dTRepos = nil
-- controlla ogni gruppo di movimenti ausiliari
for i = 1, dAuxMoveCount do
local aAuxMove = EgtGetInfo( nPathId, 'AS' .. tostring( i), 'vs') or {} -- array contenete i parametri di ogni gruppo
-- controlla solo i movimenti della testa trave e salva l'ultimo
if aAuxMove[1] == '2' or aAuxMove[1] == '3' then
for j = 2, #aAuxMove do
if aAuxMove[j] == 'T' then
dTRepos = aAuxMove[j+1]
break
end
end
end
end
return dTRepos
end
-- default
EMC.ERR = 0
EMC.PREVOFFSX = 0
-- se c'è cambio di fase tra le lavorazioni (quindi la precedente è l'ultima della sua fase e la corrente la prima)
if EMC.PREVPHASE ~= EMC.CURRPHASE then
-- se la fase corrente è di inizio lavorazione di nuova trave
if IsStartOrRestPhase( EMC.CURRPHASE) then
-- recupero la posizione finale della lavorazione precedente
local vPrevAx = EmtGetFinalAxesPos( EMC.PREVMCHID)
-- ricava se e quanto la trave viene spostata tra le due fasi dai movimenti ausiliari e corregge l'offset di fine fase
local dNewTPos = TPosUpdate()
-- se ci sono dei movimenti della testa trave tra le due fasi ricava il delta tra la vecchia e la nuova posizione
if dNewTPos then
EMC.PREVOFFSX = dNewTPos - vPrevAx[1]
-- oppure la X (L1) di questa corrisponde alla posizione iniziale della nuova trave, se ne deduce l'offset
else
EMC.PREVOFFSX = ParkV1 - vPrevAx[1]
end
end
end
end
---------------------- 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 su utesta 1
if EMC.HEAD == 'H13' or EMC.HEAD == 'H15' then
EMC.MAXZ = EgtGetAxisHomePos( 'Z1')
return
-- Gestione speciale per sega a catena su testa 2
elseif EMC.HEAD == 'H23' then
EMC.MAXZ = EgtGetAxisHomePos( 'Z2')
return
end
-- Sistemazione dati di input
local vtTp = Vector3d( EMC.TDIRp)
local sHead_TC = GetHeadTCSet( EMC.HEAD, EMC.TCPOS)
local bFromZmax = false
if vtTp:isSmall() then
vtTp = X_AX()
bFromZmax = true
if sHead_TC == 'Head1_TC1' then
EMC.R1p = ParkC1
EMC.R2p = ParkB1
elseif sHead_TC == 'Head2_TC2' then
EMC.R1p = ParkC2
EMC.R2p = ParkB2
elseif sHead_TC == 'Head1_TC2' then
EMC.R1p = ParkFrnC1
EMC.R2p = ParkFrnB1
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}, { Tz=-0.5, Ez=1}, { Tz=-0.61, Ez=1}}
EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ)
end
elseif ( EMC.HEAD == 'H12' or EMC.HEAD == 'H17') and sHead_TC == 'Head1_TC1' then
if vtTp:getX() > 0.4 and vtT:getX() > 0.4 then
if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then
EMC.MAXZ = MaxZ1 - 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
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) or
( EMC.R1p > 179.9 and EMC.R1p < 330.1 and EMC.R1 > 179.9 and EMC.R1 < 330.1 and EMC.R2p < 10 and EMC.R2 < 10)) then
EMC.MAXZ = MaxZ1 - 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) or
( EMC.R1p > 179.9 and EMC.R1p < 360.1 and EMC.R1 > 179.9 and EMC.R1 < 360.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 == 'H12' and sHead_TC == 'Head1_TC2' then
if vtTp:getX() > 0.4 and vtT:getX() > 0.4 then
if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then
EMC.MAXZ = MaxZ1 - 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
else
EMC.MAXZ = ParkZ1 + 1
end
elseif bBSameSign and
(( EMC.R1p > -180.1 and EMC.R1p < -29.9 and EMC.R1 > -180.1 and EMC.R1 < -29.9 and EMC.R2p < 10 and EMC.R2 < 10) or
( EMC.R1p > -330.1 and EMC.R1p < -179.9 and EMC.R1 > -330.1 and EMC.R1 < -179.9 and EMC.R2p > -10 and EMC.R2 > -10)) then
EMC.MAXZ = MaxZ1 - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
elseif bBSameSign and
(( EMC.R1p > -180.1 and EMC.R1p < 0.1 and EMC.R1 > -180.1 and EMC.R1 < 0.1 and EMC.R2p < 10 and EMC.R2 < 10) or
( EMC.R1p > -360.1 and EMC.R1p < -179.9 and EMC.R1 > -360.1 and EMC.R1 < -179.9 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=380}, { Tz=0.7, Ez=280}, { Tz=0.5, Ez=180}, { Tz=0.15, Ez=60}, { 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}, { Tz=-0.5, Ez=1}, { Tz=-0.61, Ez=1}}
EMC.MAXZ = ParkZ2 + CalcExtraZ( vtTpZm, vtT, vMZ)
end
elseif EMC.HEAD == 'H22' then
if vtTp:getX() > 0.4 and vtT:getX() > 0.4 then
if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then
EMC.MAXZ = MaxZ2 - 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 = ParkZ2 + 200
else
EMC.MAXZ = ParkZ2 + 1
end
elseif bBSameSign and
(( EMC.R1p > -180.1 and EMC.R1p < -29.9 and EMC.R1 > -180.1 and EMC.R1 < -29.9 and EMC.R2p < 10 and EMC.R2 < 10) or
( EMC.R1p > -330.1 and EMC.R1p < -179.9 and EMC.R1 > -330.1 and EMC.R1 < -179.9 and EMC.R2p > -10 and EMC.R2 > -10)) then
EMC.MAXZ = MaxZ2 - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130)
elseif bBSameSign and
(( EMC.R1p > -180.1 and EMC.R1p < 0.1 and EMC.R1 > -180.1 and EMC.R1 < 0.1 and EMC.R2p < 10 and EMC.R2 < 10) or
( EMC.R1p > -360.1 and EMC.R1p < -179.9 and EMC.R1 > -360.1 and EMC.R1 < -179.9 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 = ParkZ2 + 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 = ParkZ2 + CalcExtraZ( vtTpZm, vtT, vMZ)
end
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)
-- Posizione nel TC
local sHead_TC = GetHeadTCSet( EMC.HEAD, EMC.TCPOS)
-- recupero Z1 home
local nHeadSet = GetHeadSet( EMC.HEAD)
local dZmax = EgtGetAxisHomePos( EgtIf( nHeadSet ~= 2, 'Z1', 'Z2'))
-- se fresa su testa1 o su testa 2
if EMC.HEAD == 'H11' or EMC.HEAD == 'H21' then
;
-- se lama posizionata su CU prossimo a testa 1
elseif ( EMC.HEAD == 'H12' or EMC.HEAD == 'H17') and sHead_TC == 'Head1_TC1' then
-- se inclinata oltre 90 gradi e interferisce con la trave
if ( EMC.R2 > 87.9 and ( EMC.R1 < 15.0 or EMC.R1 > 180.0)) or ( EMC.R2 < -87.9 and ( EMC.R1 > -15.0 and EMC.R1 < 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 lama posizionata su CU prossimo a testa 2
elseif ( EMC.HEAD == 'H12' and sHead_TC == 'Head1_TC2') or ( EMC.HEAD == 'H22' and sHead_TC == 'Head2_TC2') then
-- se inclinata oltre 90 gradi e interferisce con la trave
if ( EMC.R2 < -87.9 and ( EMC.R1 < -180.0 or EMC.R1 > -15.0)) or ( EMC.R2 > 87.9 and ( EMC.R1 < 15.0 and EMC.R1 > 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
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_FRONT_ENG_V = 152 -- ingombro asse Z con cremagliera a destra
local MIN_BACK_ENG_V = 115 -- ingombro asse Z a sinistra
local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza
local MIN_CLAMP_5 = 150 -- minima presa con la pinza speciale (pinza 5)
local SIC_CLAMP_5 = 50 -- sicurezza testa da pinza speciale
local MAX_BACK_CLAMP_5 = EgtClamp( MaxBackClamp5 or 320, 200, 380) -- massima sporgenza posteriore del pezzo da pinza speciale
----------------------- 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 IsMid2Phase( nPhase)
local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE')
return ( sVal == 'MID2')
end
---------------------------------------------------------------------
local function IsEnd2Phase( nPhase)
local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE')
return ( sVal == 'END2')
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 GetPhaseRot( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0)
end
---------------------------------------------------------------------
local function IsLastOperationBeforeRotation( nMchId)
-- se ultima fase o ultima fase del pezzo, ritorno risultato negativo
if EMC.PHASE == EgtGetPhaseCount() or IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then
return false
end
-- recupero la successiva operazione attiva
local nNextOperId = EgtGetNextActiveOperation( nMchId)
-- se non esiste o non è una disposizione, ritorno risultato negativo
if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then
return false
end
-- recupero le rotazioni della fase corrente e della prossima fase
local nRot = GetPhaseRot( EMC.PHASE)
local nNextRot = GetPhaseRot( EMC.PHASE + 1)
-- ritorno se sono diverse
return ( nRot ~= nNextRot)
end
---------------------------------------------------------------------
local function IsFirstMachiningAfterRotation( nMchId)
-- se prima fase o prima fase del pezzo, ritorno risultato negativo
if EMC.PHASE == 1 or 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
-- recupero le rotazioni della fase corrente e della fase precedente
local nRot = GetPhaseRot( EMC.PHASE)
local nPrevRot = GetPhaseRot( EMC.PHASE - 1)
-- ritorno se sono diverse
return ( nRot ~= nPrevRot)
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 GetPartId()
-- recupero Id del pezzo in lavoro
local nOrd = GetPhaseOrd( EMC.PHASE)
local nPartId
local nRawId = EgtGetFirstRawPart()
while nRawId do
local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i')
if nRawOrd == nOrd then
nPartId = EgtGetFirstPartInRawPart( nRawId)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
return nPartId
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, nInd)
-- 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
if not nInd then
table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)})
else
table.insert( vCmd, nInd, { 4, EgtIf( bCloseV, 1, 0)})
end
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) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( 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 l'operazione successiva è una disposizione con rotazione, devo preparare il pezzo alla rotazione
if IsLastOperationBeforeRotation( EMC.DISPID) then
-- aggiornamento posizioni
if IsStartPhase( EMC.PHASE) then
-- carico le posizioni
local dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd')
local dPosY = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd')
EMC.TPOS = dPosT
EMC.Y1DELTA = dPosY - dPosT
EMC.Y2DELTA = nil
EMC.W2DELTA = nil
EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') or ParkV1
EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') or ParkV2
EMC.CNT = 1
else
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.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', 'd')
EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1
EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2
EMC.CNT = SpecGetCNT( EMC.DISPID)
end
-- Determinazione delle dimensioni del grezzo in lavoro
local b3Raw = BBox3d()
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then
b3Raw = EgtGetRawPartBBox( nRawId)
break
end
nRawId = EgtGetNextRawPart( nRawId)
end
EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL
-- Assegno sovramateriale di testa e ingombro tagli di testa e di coda
EMC.HOVM = EgtGetInfo( nRawId, 'HOVM', 'd') or 0
EMC.HCING = 0
EMC.TCING = EgtGetInfo( nRawId, 'TCING', 'd') or 0
-- Eseguo preparazione alla rotazione
local vCmd = SpecCalcPreRot()
SpecOutputCmds( vCmd, true)
return
end
-- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo
if nNextOpeType == MCH_OY.DISP and SPLIT and not IsEnd2Phase( EMC.PHASE) 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.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', '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 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 o dopo rotazione eseguo carico con carrello Y
local vCmd = {}
if EMC.PHASE == 1 or IsEnd2Phase( EMC.PHASE) then
dPosT = LoadT
if IsEnd2Phase( EMC.PHASE) then dPosT = dPosT + TurnerOffs end
vCmd = SpecCalcLoad( dPosT, 0, max( MinJoin + EgtIf( SPLIT, EMC.TCING, 0), EMC.LB - ( MaxY1 - MinY1) + 6))
-- 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')
-- se carrello agganciato
if dPosY1 then
-- 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 è grezzo scaricato al carico e devo ricaricarlo
else
vCmd = SpecCalcLoad( dPosT, 0, max( MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6))
end
-- altrimenti fase successiva pari
else
EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd')
EMC.W2DELTA = nil
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) or IsEnd2Phase( 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 - UnloadT
vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL)
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()
-- Inizializzo codice di errore
EMC.ERR = 0
-- Verifico se ultima lavorazione della fase
local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID)
local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) -- Agisco sui diversi percorsi della lavorazione
local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL)
while nPathId do
-- 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
end
end
---------------------------------------------------------------------
function OnSpecialApplyMachining()
EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 1)
-- 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 or IsFirstMachiningAfterRotation( EMC.MCHID) then
-- posizioni home
EMC.TPOS = nil
EMC.Y1DELTA = nil
EMC.Y2DELTA = nil
EMC.W2DELTA = 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')
-- se carrello agganciato
if dPosY then
EMC.TPOS = dPosT
EMC.Y1DELTA = dPosY - dPosT
EMC.Y2DELTA = nil
EMC.W2DELTA = nil
EMC.V1POS = ParkV1
EMC.V2POS = ParkV2
EMC.CNT = SpecGetCNT( EMC.MCHID)
-- altrimenti è grezzo scaricato al carico e devo ricaricarlo
else
EMC.TPOS = nil
EMC.Y1DELTA = nil
EMC.Y2DELTA = nil
EMC.W2DELTA = nil
EMC.V1POS = ParkV1
EMC.V2POS = ParkV2
EMC.CNT = 1
end
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.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', '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.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', '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 se ultima lavorazione prima di una rotazione
local bPreRotMch = IsLastOperationBeforeRotation( EMC.MCHID)
-- Verifico flag di separazione e fase di scarico
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
local bPreSplit = ( false and 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) or IsEnd2Phase( 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 OriW2Delta = EMC.W2DELTA
local OriV1Pos = EMC.V1POS
local OriV2Pos = EMC.V2POS
local OriCnt = EMC.CNT
-- eseguo le elaborazioni
SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch)
-- 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.W2DELTA = OriW2Delta
EMC.V1POS = OriV1Pos
EMC.V2POS = OriV2Pos
EMC.CNT = OriCnt
-- eseguo le elaborazioni
SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch)
-- 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, bPreRotMch)
-- 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) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( 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)
-- Se split prima di rotazione, devo lasciare dietro spazio per scambio carrelli
if bSplitting and IsMid2Phase( EMC.PHASE + 1) then
dDistFront = min( dDistFront, EMC.LT - MinOther)
end
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
-- Eventuale aggiuntivo al carico su distanza Back (finchè non c'è un riposizionamento carrelli)
if EMC.CNT == 1 or not EMC.TPOS then
dDistBack = dDistBack - AggLoad
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 or IsEnd2Phase( EMC.PHASE) then
dY2DeltaMinUL = EMC.LT + MinY2 - UnloadT
end
local vSaveCmd
-- Se inizio o appena dopo rotazione, eseguo il carico
if not EMC.TPOS then
local dPosT = LoadT
if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end
local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin + EgtIf( SPLIT, EMC.TCING, 0), EMC.LB - ( MaxY1 - MinY1) + 6))
local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach)
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)
vSaveCmd = vCmd
-- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli
elseif not IsEndPhase( EMC.PHASE) 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)
vSaveCmd = 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)
vSaveCmd = 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 che la barra sia agganciata al secondo carrello
if not EMC.Y2DELTA then
local dTLen = EMC.LT - EMC.HOVM - BD.OVM_MID
local dRefIng = EgtIf( dTLen < 350, 120, EgtIf( dTLen < 550, 150, 200))
local dClampLen = dTLen - min( EMC.HCING + EMC.TCING, dRefIng)
-- se pinza 5, presa ammissibile e pezzo con dimensioni nei limiti
if Clamp5 and dClampLen > MIN_CLAMP_5 + SIC_CLAMP_5 - 10 * GEO.EPS_SMALL and
EMC.SB > MinWOpen - 10 * GEO.EPS_SMALL and EMC.SB < MaxWOpen + 10 * GEO.EPS_SMALL and EMC.HB < MaxWHeight + 10 * GEO.EPS_SMALL then
EgtOutLog( ' Warning SPLITTING -> separazione con uso pinza speciale')
SpecOutputCNT()
-- reset errore
EMC.ERR = 0
local dDeltaW = EgtGetValInNotes( EgtGetInfo( GetPartId() or GDB_ID.NULL, 'COMMENT') or '', 'DeltaW') or 0
local dDeltaP5 = EMC.LT - BD.OVM_MID - min( EMC.TCING, 0.5 * dRefIng) - SIC_CLAMP_5 - 0.4 * max( dClampLen - MIN_CLAMP_5 - SIC_CLAMP_5, 0)
dDeltaP5 = max( dDeltaP5, EMC.LT- BD.OVM_MID - MAX_BACK_CLAMP_5) + dDeltaW
local vCmd = vSaveCmd
table.insert( vCmd, { 23, dDeltaP5})
SpecOutputCmds( vCmd)
EgtOutLog( ' DeltaP5='..EgtNumToString( dDeltaP5, 1)..' DeltaW = '..EgtNumToString( dDeltaW, 1), 1)
-- imposto risalita a Zmax se lavorazione successiva è ancora una fresatura con la stessa lama (per essere sicuro di evitare collisioni)
local NextMachId = EgtGetNextActiveOperation( EgtGetNextActiveOperation( EMC.MCHID) or GDB_ID.NULL)
if NextMachId and EgtGetOperationType( NextMachId) == MCH_OY.MILLING then
-- salvo lavorazione e utensile correnti, per ripristinarli alla fine
local nOrigMchId = EgtGetCurrMachining()
local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- imposto lavorazione e utensile correnti
EgtSetCurrMachining( NextMachId)
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
-- se utensile non cambiato
if sTool and EgtTdbSetCurrTool( sTool) and sTool == sOrigTool then
-- imposto risalita a Zmax
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 2)
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
-- ripristino lavorazione e utensile correnti
if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end
if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end
end
-- altrimenti separazione con caduta
else
EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo')
SpecOutputCNT()
-- forzo errore 18
EMC.ERR = 18
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
end
-- 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)
if not IsMid2Phase( EMC.PHASE + 1) then
vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft)
else
vCmd = SpecCalcSplitRot( b3Raw:getDimX(), dMaxLenLeft)
end
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
-- Se ritorno al carico per rotazione
if bPreRotMch then
-- determino posizione testa trave
local nLastEntId = EgtGetLastInGroup( EMC.PATHID)
local vAxes = EmtGetAxesPos( nLastEntId)
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
-- eseguo movimento prima di rotazione
local vCmdTmp = SpecCalcPreRot()
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 valore assi macchina
local nSecId = EgtGetNext( EgtGetFirstInGroup( nPathId))
local vAxes = EmtGetAxesPos( nSecId)
if not vAxes or #vAxes < 5 or (( sHead == 'H13' or sHead == 'H15' or sHead == 'H23') and #vAxes < 6) then
EMC.ERR = 15
EMC.MSG = ' Error : machine axes values not found'
return
end
-- Calcolo dell'ingombro della testa rispetto allo Zero Macchina
local b3Enc
if sHead ~= 'H21' and sHead ~= 'H22' and sHead ~= 'H23' then
EgtSetAxisPos( 'C1', vAxes[4])
EgtSetAxisPos( 'B1', vAxes[5])
if sHead == 'H13' or sHead == 'H15' then
EgtSetAxisPos( 'A', vAxes[6])
end
b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE)
else
EgtSetAxisPos( 'C2', vAxes[4])
EgtSetAxisPos( 'B2', vAxes[5])
if sHead == 'H23' then
EgtSetAxisPos( 'A', vAxes[6])
end
b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), 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 dRollFront = max( b3Enc:getMax():getX(), MIN_FRONT_ENG_V) + nSecRollerDist
local dRollBack = max( -b3Enc:getMin():getX(), MIN_BACK_ENG_V) + 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, vAxes[4], vAxes[5], vAxes[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 - EgtIf( SPLIT, EMC.TCING, 0))
if dNewY1min > dNewY1max then return nil end
local dNewY1Delta = dNewY1max
local dNewY2Delta = nil
local dNewY1 = dPosT + dNewY1Delta
local vCmd = {}
EgtOutLog( ' *[L]', 1)
-- [L-1]
if dNewY1 + TurnerOffs - MaxY1 > 0 then
dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs)
EgtOutLog( ' *[L1]', 1)
end --[L-2]
if EMC.LB - dNewY1Delta < MinJoin then
dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs)
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.W2DELTA = 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 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( dDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit ..
' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3)
local bBackOk = ( dDistBack > MinJoin + EgtIf( SPLIT, EMC.TCING, 0) - 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 - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM)
WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0), 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 - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING)
WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0), MaxY1 + dDistFront + dRollFront + AGG_V)
WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dDistBack - 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 - dDistBack - 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( dDistBack) ..
' 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 or EMC.W2DELTA ~= nil)
local ParkT = ParkV1
if bSplit then
if dMaxLenLeft + 100 > LoadT then
ParkT = dMaxLenLeft + 300
elseif dMaxLenLeft + 100 > ParkV1 then
ParkT = LoadT
end
end
local sType = EgtIf( EMC.Y2DELTA, 'Split', EgtIf( EMC.W2DELTA, 'SpecSplit', 'Fall'))
table.insert( vCmd, { 0, sType})
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 or EMC.W2DELTA 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 SpecCalcSplitRot( dLenRaw, dMaxLenLeft)
local vCmd = {}
EgtOutLog( ' *[SR]', 1)
local bSplit = ( EMC.Y2DELTA ~= nil)
local ParkT = LoadT
table.insert( vCmd, { 0, 'SplitRot'})
-- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari)
local vRaw = {}
local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE)
local nRawId = EgtGetFirstRawPart()
while nRawId do
if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then
table.insert( vRaw, nRawId)
end
nRawId = EgtGetNextRawPart( nRawId)
end
for _, nId in ipairs( vRaw) do
table.insert( vCmd, { 31, nId, 'Y1'})
end
-- riporto il carrello Y1 al carico con il resto della trave
local dLDelta = EMC.Y1DELTA - dLenRaw
table.insert( vCmd, { 1, 'Y1', ParkT + TurnerOffs + dLDelta})
table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0})
-- imposto subito Y non più attaccato alla trave in lavoro
EMC.Y1DELTA = nil
-- apro il carrello Y
table.insert( vCmd, { 11, 0})
-- sgancio i grezzi dal carrello Y
for _, nId in ipairs( vRaw) do
table.insert( vCmd, { 31, nId, ''})
end
-- lo porto in parcheggio
table.insert( vCmd, { 1, 'Y1', ParkY1})
-- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari)
local NextDispId = EgtGetPhaseDisposition( nNextOddPhase)
if NextDispId then
EgtSetInfo( NextDispId, 'TPOS', ParkT)
end
return vCmd
end
---------------------------------------------------------------------
function SpecCalcUnload()
local vCmdPre = {}
EgtOutLog( ' *[U]', 1)
if EMC.W2DELTA then
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'Unloading SpecSplit'})
EgtOutLog( ' *[U2]', 1)
return vCmd
elseif 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 - 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 = {}
-- Tipo di scarico
local bStdUl = ( not MaxUnloadLen or MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1)
-- Commento
table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual 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
-- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico
if bStdUl then
local dFinT = UnloadT - EMC.LB
local dFinY2 = dFinT + EMC.Y2DELTA
table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2})
EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2), 1)
else
table.insert( vCmd, { 1, 'Y2', MaxY2})
end
-- 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
---------------------------------------------------------------------
function SpecCalcPreRot()
local vCmdPre = {}
EgtOutLog( ' *[PR]', 1)
-- Se pinza Y2 chiusa, devo effettuare uno scambio
local dY1DeltaMaxSP = MaxY1 - LoadT - TurnerOffs - 10 * GEO.EPS_SMALL
if EMC.Y2DELTA or EMC.Y1DELTA > dY1DeltaMaxSP then
-- imposto quote aggancio per avere solo pinza Y
local dDistFront = 0
local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL
-- effettuo scambio
vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, dY1DeltaMaxSP)
-- recupero nuova posizione carrelli
SpecSetCarrPosFromCmds( vCmdPre)
EgtOutLog( ' [PR1]', 1)
end
-- porto il pezzo alla zona di rotazione con il carro Y1
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'Pre-Rotation'})
-- posizionamento sicuro teste e rulli
if #vCmdPre > 0 then
EnsureZmax( true, vCmdPre, 2)
else
EnsureZmax( true, vCmd)
end
-- Se pinza V chiusa, la apro
if EMC.Y2DELTA then
table.insert( vCmd, { 12, 0})
end
-- riporto la trave al carico
local RotT = LoadT + TurnerOffs
table.insert( vCmd, { 2, 'Y1', RotT + EMC.Y1DELTA, 'T', RotT})
-- apro la morsa
table.insert( vCmd, { 11, 0})
EMC.CNT = nil
-- riporto il carrello in home
table.insert( vCmd, { 1, 'Y1', ParkY1})
-- eventuale unione tabelle
if #vCmdPre > 0 then
vCmd = EgtJoinTables( vCmdPre, vCmd)
end
return vCmd
end
---------------------------------------------------------------------
local function ChangedTool( nMchId)
local bChanged = true
-- Salvo lavorazione e utensile correnti, per ripristinarli alla fine
local nOrigMchId = EgtGetCurrMachining()
local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
-- Recupero l'utensile della lavorazione precedente
local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL)
while nPrevMchId and EgtGetOperationType( nPrevMchId) == MCH_OY.DISP do
nPrevMchId = EgtGetPrevActiveOperation( nPrevMchId or GDB_ID.NULL)
end
if nPrevMchId then
EgtSetCurrMachining( nPrevMchId)
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
bChanged = ( sTool ~= sOrigTool)
end
-- Ripristino lavorazione e utensile correnti
if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end
if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end
return bChanged
end
--------------------------------------------------------------------------------------------------------
-- **CHIAMATA DELLE FUNZIONI Spec**
--------------------------------------------------------------------------------------------------------
function SpecAdjustCarriages( WorkTab)
--EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_'))
-- Aggiorno la posizione dei rulli per eventuale cambio utensile
local bChangedTool = ChangedTool( EMC.DISPID or EMC.MCHID)
if bChangedTool then
WorkTab.dV1PosI = ParkV1
WorkTab.dV2PosI = ParkV2
end
-- Verifico se compattare i rulli
local bCloseV = false
if WorkTab.dY1DeltaI then
if WorkTab.dY1DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0) then
bCloseV = true
end
end
if WorkTab.dY2DeltaI then
if EMC.LB - WorkTab.dY2DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EgtIf( SPLIT, EMC.TCING, 0) + EgtIf( EMC.CNT == 1, AggLoad, 0) then
bCloseV = true
end
end
if WorkTab.dY2DeltaMinF then
if EMC.LB - WorkTab.dY2DeltaMinF <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EgtIf( SPLIT, EMC.TCING, 0) + EgtIf( EMC.CNT == 1, AggLoad, 0) then
bCloseV = true
end
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
EgtOutLog( ' Tool : '..( EgtIf( bChangedTool, 'CHANGED', 'same')).. ' CloseV : '..( EgtIf( bCloseV, 'TRUE', 'false')), 1)
-- |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]
else
EMC.Y1DELTA = nil
EMC.Y2DELTA = nil
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]
-- impostazione pinza speciale di uscita per pezzi corti (pinza 5)
elseif Cmd[1] == 23 then
local sInfo = '23,'..EgtNumToString( Cmd[2],3)
EgtSetInfo( EMC.PATHID, sKey, sInfo)
EMC.W2DELTA = Cmd[2]
-- 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
if EMC.W2DELTA then
EgtSetInfo( EMC.PATHID, 'W2DELTA', EMC.W2DELTA)
else
EgtRemoveInfo( EMC.PATHID, 'W2DELTA')
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]
elseif Cmd[1] == 23 then
EMC.W2DELTA = Cmd[2]
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