Files
saomad-kairos-mk2/Saomad-KAIROS.mlse
T
2025-05-20 15:39:17 +02:00

3868 lines
159 KiB
Plaintext

-- Special Operations macchina Saomad-KAIROS by EgalWare s.r.l. 2023/12/01
-- Intestazioni
require( 'EmtGenerator')
EgtEnableDebug( false)
-- Carico i dati globali
local sBaseDir = EgtGetSourceDir()
local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua')
---------------------------------------------------------------------
-- *** Generic Machinings ***
---------------------------------------------------------------------
pcall( require, 'EmtGenMachining') -- si fa una require con PCALL perchè la libreria è opzionale
---------------------- OnSpecialMoveZup -----------------------------
---------------------------------------------------------------------
function OnSpecialMoveZup()
--EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT))
-- Inizializzazioni
EMC.ERR = 0
EMC.MODIF = false
-- se sega a catena
if EMC.HEAD == 'H3' then
end
end
---------- OnSpecialApplyDisposition & OnPostApplyMachining ---------
----------------------- Costanti ------------------------------------
local DELTA_TOL_V = 110
local DELTA_TOL_S = 160
local DELTA_TOL_L = 310
local DELTA_TOL_FIXED = 50
local DeltaTol = DELTA_TOL_S
local DELTA_SIC = 1
local AGG_LOAD = 0
local MIN_JOIN_VV = 75
local MIN_JOIN_SS = 100
local MIN_JOIN_LS = 100
local MIN_JOIN_SL = 290
local MIN_JOIN_LL = 400
local MinJoin = MIN_JOIN_SS
local MinOther = abs( MinX1) + abs( MaxX2) + MinJoin
local MaxLenSmT = 1500 -- massima lunghezza pezzo scaricato con nastri verdi
----------------------- Variabili -----------------------------------
local Test = false
---------------------------------------------------------------------
local function PrepareClGroup( nParentId)
local nClId = EgtGetFirstNameInGroup( nParentId, 'CL')
-- se non c'è, lo aggiunge
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 GetPhaseRot( nPhase)
return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0)
end
---------------------------------------------------------------------
local function IsLastOperationBeforeRotation( nOperId)
-- 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( nOperId)
-- 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 UpdateMinJoinDeltaTol()
local L_SMALL = 800
local H_V = 90
local H_S = 150
local H_L = 250
local W_V = 90
local W_S = 150
local W_L = 450
if EMC.SB <= W_V and EMC.HB <= H_V then
MinJoin = MIN_JOIN_VV
DeltaTol = DELTA_TOL_V
elseif EMC.LB <= L_SMALL then
MinJoin = MIN_JOIN_SS
DeltaTol = DELTA_TOL_S
else
local dMinJoinS
local dMinJoinL
if EMC.SB <= W_S then
dMinJoinS = MIN_JOIN_SS
dMinJoinL = MIN_JOIN_LS
elseif EMC.SB <= W_L then
local Coeff = ( EMC.SB - W_S) / ( W_L - W_S)
dMinJoinS = ( 1 - Coeff) * MIN_JOIN_SS + Coeff * MIN_JOIN_SL
dMinJoinL = ( 1 - Coeff) * MIN_JOIN_LS + Coeff * MIN_JOIN_LL
else
dMinJoinS = MIN_JOIN_SL
dMinJoinL = MIN_JOIN_LL
end
if EMC.HB <= H_S then
MinJoin = dMinJoinS
DeltaTol = DELTA_TOL_S
elseif EMC.HB <= H_L then
local Coeff = ( EMC.HB - H_S) / ( H_L - H_S)
MinJoin = ( 1 - Coeff) * dMinJoinS + Coeff * dMinJoinL
DeltaTol = ( 1 - Coeff) * DELTA_TOL_S + Coeff * DELTA_TOL_L
else
MinJoin = dMinJoinL
DeltaTol = DELTA_TOL_L
end
if EMC.SB < W_V then
DeltaTol = DELTA_TOL_V
end
end
MinOther = abs( MinX1) + abs( MaxX2) + 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 EnsureZmax( bZmaxOk, vCmd)
if not bZmaxOk then table.insert( vCmd, { 1, 'Z', EgtGetAxisHomePos( 'Z')}) 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
local bSplit = 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
return
end
local nPathId = EgtGroup( nClId)
if not nPathId then
EMC.ERR = 6
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, 'YPOS', 'd')
EMC.TPOS = dPosT
EMC.YDELTA = dPosY - dPosT
EMC.VDELTA = nil
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.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd')
EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd')
EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i')
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 l'operazione successiva è ancora una disposizione, devo scaricare il pezzo
if nNextOpeType == MCH_OY.DISP and bSplit 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.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd')
EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd')
EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i')
-- 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() + 10 * GEO.EPS_SMALL
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
-- Determinazione delle sue dimensioni
local b3Raw = EgtGetRawPartBBox( nCurrRawId)
if not b3Raw or b3Raw:isEmpty() then
EMC.ERR = 11
return
end
EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL
EMC.SB = b3Raw:getDimY()
EMC.HB = b3Raw:getDimZ()
EMC.ZMIN = b3Raw:getMin():getZ()
-- Aggiorno limiti di presa e tolleranza
UpdateMinJoinDeltaTol()
-- 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, min( EMC.LB - MinOther - AGG_LOAD, MaxX1 - dPosT))
-- 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 dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd')
-- se carrello agganciato
if dPosY then
-- confermo i nuovi parametri di aggancio
table.insert( vCmd, { 21, dPosY - dPosT, 0})
-- recupero CNT
local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID)
if EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP and EgtExistsInfo( nPrevOpeId, 'SKIP') then
nPrevOpeId = EgtGetPrevActiveOperation( nPrevOpeId)
end
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL)
EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i')
-- altrimenti è grezzo scaricato al carico e devo ricaricarlo
else
vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxX1 - dPosT))
end
-- altrimenti fase successiva pari
else
local dPosV = EgtGetInfo( EMC.DISPID, 'VPOS', 'd')
EMC.VDELTA = dPosV
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 CurrUnloadT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT)
local dDistFront = EgtIf( EMC.LB < abs( MinX2 - CurrUnloadT), MinJoin, EMC.LB - abs( MinX2 - CurrUnloadT) + MinJoin + DeltaTol)
vCmd2 = SpecCalcCarriages( dDistFront, 0)
if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 then
table.insert( vCmd, { 0, 'CARR_MOVE'})
end
end
-- eseguo scarico
SpecSetCarrPosFromCmds( vCmd2)
local vCmd3 = SpecCalcUnload()
-- unisco ed emetto i comandi
vCmd = EgtJoinTables( vCmd, vCmd2)
vCmd = EgtJoinTables( vCmd, vCmd3)
SpecOutputCmds( vCmd, true)
end
---------------------------------------------------------------------
function OnPostApplyMachining()
EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 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
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.YDELTA = nil
EMC.VDELTA = nil
EMC.HCING_IGNORE = true
elseif IsStartOrRestPhase( EMC.PHASE) then
-- carico le posizioni
local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd')
local dPosY = EgtGetInfo( nPrevOpeId, 'YPOS', 'd')
-- se carrello agganciato
if dPosY then
EMC.TPOS = dPosT
EMC.YDELTA = dPosY - dPosT
EMC.VDELTA = nil
-- altrimenti è grezzo scaricato al carico e devo ricaricarlo
else
EMC.TPOS = nil
EMC.YDELTA = nil
EMC.VDELTA = nil
end
EMC.HCING_IGNORE = true
else
-- aggiornamento posizioni (da lavorazione precedente a disposizione)
local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId)
if not nPrev2OpeId then
EMC.ERR = 2
return
end
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL)
local nLastEntId = EgtGetLastInGroup( nLastPathId)
local vAxes = EmtGetAxesPos( nLastEntId or GDB_ID.NULL)
if not vAxes then
EMC.ERR = 3
return
end
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd')
EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd')
end
EMC.CNT = nil
-- altrimenti precedente operazione è lavorazione
else
-- aggiornamento posizioni
local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL)
local nLastEntId = EgtGetLastInGroup( nLastPathId)
local vAxes = EmtGetAxesPos( nLastEntId or GDB_ID.NULL)
if not vAxes then
EMC.ERR = 4
return
end
if #vAxes > 0 then EMC.TPOS = vAxes[1] end
EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd')
EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd')
EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i')
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 = ( sNotes:find( 'Presplit') ~= nil)
local bSplitting = ( sNotes:find( 'Split') ~= nil)
local bPreCut = ( sNotes:find( 'Precut') ~= nil)
local bCutting = ( sNotes:find( 'Cut') ~= nil)
local bUnload = IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE)
if bPreSplit or bPreCut then
EgtSetInfo( EMC.MCHID, 'IS_PRE', '1')
else
EgtRemoveInfo( EMC.MCHID, 'IS_PRE')
end
-- 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 di trave e carrelli
local OriTPos = EMC.TPOS
local OriYDelta = EMC.YDELTA
local OriVDelta = EMC.VDELTA
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 di trave e carrelli
EMC.TPOS = OriTPos
EMC.YDELTA = OriYDelta
EMC.VDELTA = OriVDelta
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)
-- Assegno flag di pezzo separato dal resto del grezzo
local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE)
-- Assegno flag di pezzo in separazione
local bFixedDelta = ( bPreSplit or bSplitting or bPreCut or bCutting)
-- Se separazione o taglio del grezzo finale, verifico se precedente era una preparazione
local bFixedPos = false
if bPreSplit or bSplitting or bPreCut or bCutting then
local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID)
bFixedPos = EgtExistsInfo( nPrevOpeId or GDB_ID.NULL, 'IS_PRE')
end
-- 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
return
end
EMC.LB = EgtIf( bSplit, b3Raw:getDimX(), b3Tot:getDimX()) + 10 * GEO.EPS_SMALL
EMC.SB = b3Tot:getDimY()
EMC.HB = b3Tot:getDimZ()
EMC.LR = b3Raw:getDimX() + 10 * GEO.EPS_SMALL
EMC.YMIN = b3Raw:getMin():getY()
EMC.ZMIN = b3Raw:getMin():getZ()
-- Aggiorno limiti di presa e tolleranza
UpdateMinJoinDeltaTol()
-- Recupero sovramateriale di testa e ingombro tagli di testa e di coda dal pezzo
EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0
EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0
EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0
EMC.XMAX = b3Raw:getMax():getX() - EMC.HOVM
-- correggo area non pinzabile in testa o coda in base alle info sulla disposizione, se presenti
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
local idDisp = EgtGetPhaseDisposition( EMC.PHASE)
local dHCING = EgtGetInfo( idDisp, 'HCING', 'd') or 0
if dHCING then
EMC.HCING = dHCING
end
local dTCING = EgtGetInfo( idDisp, 'TCING', 'd') or 0
if dTCING then
EMC.TCING = dTCING
end
-- Calcolo dell'ingombro della lavorazione
local dDistFront, dDistBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut)
if not dDistFront or not dDistBack then return end
if bPreSplit or bSplitting then
local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1)
dDistFront = min( dDistFront, dDistF)
local dNextHOVM = EgtGetInfo( EgtGetNextRawPart( nCurrRawId) or GDB_ID.NULL, 'HOVM', 'd') or 0
local dBackOther = b3Tot:getDimX() - b3Raw:getDimX() - MinOther - dNextHOVM
EgtOutLog( 'DistBack='..EgtNumToString( dDistBack)..' OtherBack='..EgtNumToString( dBackOther), 3)
dDistBack = min( dDistBack, dBackOther)
elseif bPreCut or bCutting then
local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1)
dDistFront = min( dDistFront, dDistF)
dDistBack = 0.0
end
-- Verifico lunghezza pezzo
if not bSplit and not VerifyPartLength() then
return
end
-- 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))
local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos)
if vCmd2 and #vCmd2 > 1 then
table.insert( vCmd, { 0, 'CARR_MOVE'})
end
EgtJoinTables( vCmd, vCmd2)
SpecOutputCmds( vCmd)
-- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli
elseif not IsEndPhase( EMC.PHASE) then
local vCmd = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos)
-- Se non ci sono spostamenti, confermo i parametri di aggancio
if SpecTestOnlyRemarkInCmds( vCmd) then
table.insert( vCmd, { 21, EgtIf( EMC.YDELTA, EMC.YDELTA, 0), EgtIf( EMC.VDELTA, EMC.VDELTA, 0)})
end
SpecOutputCmds( vCmd)
-- Altrimenti, non muovo i carrelli rispetto alla trave
else
local vCmd = {}
SpecOutputCmds( vCmd)
end
EMC.HCING_IGNORE = nil
-- Se taglio di separazione
local vCmd = {}
if bSplitting then
-- rimuovo eventuale vecchia info di Skip
local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL
EgtRemoveInfo( NextDispId, 'SKIP')
-- verifico se separazione con caduta
if not EMC.VDELTA then
EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo')
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
EMC.ERR = 18
-- verifico che la barra sia agganciata ad entrambi i carrelli
elseif not EMC.YDELTA or not EMC.VDELTA then
EMC.ERR = 19
EMC.MSG = ' Error SPLIT : Y or V not clamped'
return false
end
-- eseguo la separazione ( standard o di pezzo ruotato)
if not IsMid2Phase( EMC.PHASE + 1) then
vCmd = SpecCalcSplit( b3Raw:getDimX())
else
vCmd = SpecCalcSplitRot( b3Raw:getDimX())
end
end
-- Se taglio finale di grezzo a perdere
if bCutting then
-- salvo distanza carrello V da inizio grezzo rimasto nella disposizione della prossima fase
local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1)
if NextDispId then
EgtSetInfo( NextDispId, 'VPOS', EMC.VDELTA)
end
end
-- Se previsto scarico, lo eseguo
if bUnload then
EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL
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
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
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 del vettore estrusione (coincide con il vettore utensile)
local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v')
if not vtTool then
EMC.ERR = 14
return
end
-- Recupero testa
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
-- Calcolo del vettore ausiliario
local vAxes = EmtGetAxesPos( EgtGetFirstInGroup( nPathId))
if not vAxes or #vAxes < 5 or ( sHead == 'H3' and #vAxes < 6) then
EMC.ERR = 15
return
end
local vtAux = EgtGetCalcAuxDirFromAngles( vAxes[4], vAxes[5], vAxes[6])
if not vtAux then
EMC.ERR = 16
return
end
local vtArm = vtAux
-- Recupero dei dati dell'utensile
local nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
local bSaw = ( nToolType == MCH_TY.SAW_STD or nToolType == MCH_TY.SAW_FLAT)
local bChain = ( nToolType == MCH_TY.MORTISE_STD)
local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN)
local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
local dTDist = EgtIf( EgtTdbGetCurrToolParam( MCH_TP.DIST) > 1, EgtTdbGetCurrToolParam( MCH_TP.DIST), ChSawLen)
-- Se sega a catena, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C
if bChain then
if abs( vAxes[6] or 0) < 1 then
vtArm = vtTool
else
vtArm = vtTool ^ vtAux
end
end
-- Calcolo limiti derivanti dalla lavorazione
local dDistFront, dDistBack = SpecCalcEncumbrance( vtTool, vtArm, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dTDist)
return dDistFront, dDistBack
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
-- Salvo lavorazione e utensile correnti, per ripristinarli alla fine
local nOrigMchId = EgtGetCurrMachining()
local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME)
local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
local nOrigExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT)
-- 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 EgtTdbSetCurrTool( sTool) then
local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID)
sTool = EgtTdbGetToolFromUUID( sTuuid)
EgtTdbSetCurrTool( sTool)
end
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT)
if sTool and sHead and nExit then EgtSetCalcTool( sTool, sHead, nExit) end
-- calcolo ingombri
local dDistF, dDistB = SpecialCalcMachiningEncumbrance( nMchId)
if dDistF and dDistB then
dDistFront = min( dDistFront, dDistF)
dDistBack = min( dDistBack, dDistB)
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 and nOrigExit then EgtSetCalcTool( sOrigTool, sOrigHead, nOrigExit) end
-- Restituisco gli ingombri trovati
return dDistFront, dDistBack
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 SpecCalcEncumbrance( vtTool, vtArm, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dTDist)
-- Quota in Z dal punto di inclinazione dei carrelli
local dCompZ = sqrt( 1 - vtTool:getZ() * vtTool:getZ())
local dZup = ptMin:getZ() - 0.5 * dCompZ * dTDiam - ( EMC.ZMIN + 130)
-- Posizione min e max del naso mandrino (rispetto a testa pezzo in X e riferimento pezzo in Y e Z)
local ptHeadMin = ptMin + vtTool * dTLen - Vector3d( EMC.XMAX, EMC.YMIN + EMC.SB, EMC.ZMIN)
local ptHeadMax = ptMax + vtTool * dTLen - Vector3d( EMC.XMAX, EMC.YMIN + EMC.SB, EMC.ZMIN)
-- Ingombro a sinistra
local dDistBack = EMC.LB + ptMin:getX() + LoadT
local dHeadBack = 350
if bSaw then
if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then
dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then
dHeadBack = EgtIf( vtArm:getX() < 0, 540, 350)
elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then
if vtArm:getX() < 0 then
dHeadBack = 450
else
dHeadBack = EgtIf( vtTool:getX() > 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
end
elseif ( vtTool:getX() > 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then
if vtTool:getZ() > 0 then
dHeadBack = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()))
else
dHeadBack = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()))
end
if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then
dHeadBack = dHeadBack + BD.VICE_MINH
end
elseif ( vtTool:getX() > 0.2 and abs( vtTool:getZ()) < 0.5) then
dHeadBack = max( 90, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()))
elseif abs( vtTool:getZ()) < 0.93 then
if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then
dHeadBack = 180
elseif vtTool:getX() > -0.05 then
dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
elseif vtTool:getX() > -0.3 then
dHeadBack = 250
elseif vtTool:getX() > -0.707 then
dHeadBack = 350
elseif vtTool:getX() > -0.8667 then
dHeadBack = 450
else
dHeadBack = 650
end
else
dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
end
-- per limiti corsa asse X1
dHeadBack = max( dHeadBack, MinX1 + 1 - vtTool:getX() * ( MillOffs + dTLen))
else
if ( vtTool:getX() > -0.1 and vtArm:getX() > -0.1) or
( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then
dHeadBack = EgtIf( EMC.CNT == 1, 180, 130)
elseif ( vtTool:getX() > -0.1 and vtArm:getX() > -0.95) then
dHeadBack = 180
elseif ( vtTool:getX() < -0.8) then
dHeadBack = 675
elseif ( vtTool:getX() < -0.75) then
dHeadBack = 650
elseif ( vtTool:getX() < -0.5) then
dHeadBack = 450
end
if vtTool:getX() < -0.25 then
dHeadBack = dHeadBack + max( dTLen - 130, 0) * abs( vtTool:getX())
elseif vtTool:getX() < 0 then
dHeadBack = dHeadBack + ( dTLen + 180) * abs( vtTool:getX())
end
if vtTool:getX() > 0.866 then
dHeadBack = 50
elseif vtTool:getX() >= 0 and dZup > 0 then
dHeadBack = max( EgtIf( EMC.CNT == 1, 180, 130), dHeadBack - dZup)
end
if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then
if vtArm:getX() < -0.259 then
dHeadBack = 510
else
dHeadBack = EgtIf( vtTool:getZ() > 0.966, 160, 280)
end
end
-- per fresature longitudinali con utensile di fianco
if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() < -0.5 then
dHeadBack = 500
end
-- per sega a catena di fianco
if bChain and vtTool:getX() < 0.5 and vtTool:getZ() < 0.5 and vtArm:getX() < -0.5 then
dHeadBack = max( dHeadBack, 510)
end
-- per fresa diretta quasi esattamente come Y+/- e con la testa non troppo nel pezzo
if not bChain and abs( vtTool:getX()) < 0.017 and abs( vtTool:getZ()) < 0.017 and
(( vtTool:getY() > 0 and ptHeadMin:getY() > 80) or ( vtTool:getY() < 0 and ptHeadMax:getY() < -EMC.SB - 80)) then
dHeadBack = EgtIf( EMC.CNT == 1, 180, 130)
end
-- per limiti corsa asse X1
if not bChain then
dHeadBack = max( dHeadBack, MinX1 + 1 - vtTool:getX() * ( MillOffs + dTLen))
else
dHeadBack = max( dHeadBack, MinX1 + 1 - vtAux:getX() * ( MillOffs + dTDist) - vtTool:getX() * dTLen)
end
end
-- Ingombro a destra
local dDistFront = - ptMax:getX() - LoadT
local dHeadFront = 350
if bSaw then
if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then
dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then
dHeadFront = EgtIf( vtArm:getX() > 0, 540, 350)
elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then
if vtArm:getX() > 0 then
dHeadFront = 450
else
dHeadFront = EgtIf( vtTool:getX() < 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
end
elseif ( vtTool:getX() < - 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then
if vtTool:getZ() > 0 then
dHeadFront = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()))
else
dHeadFront = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()))
end
if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then
dHeadFront = dHeadFront + BD.VICE_MINH
end
elseif ( vtTool:getX() < -0.2 and abs( vtTool:getZ()) < 0.5) then
dHeadFront = max( 90, 40 + 0.5 * dTDiam * sqrt( vtTool:getY() * vtTool:getY() + vtTool:getZ() * vtTool:getZ()))
elseif abs( vtTool:getZ()) < 0.93 then
if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then
dHeadFront = 180
elseif vtTool:getX() < 0.05 then
dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
elseif vtTool:getX() < 0.3 then
dHeadFront = 250
elseif vtTool:getX() < 0.707 then
dHeadFront = 350
elseif vtTool:getX() < 0.8667 then
dHeadFront = 450
else
dHeadFront = 650
end
else
dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())
end
-- per limiti corsa asse X2
dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtTool:getX() * ( MillOffs + dTLen))
else
if ( vtTool:getX() < -0.5 and vtArm:getX() < 0.1) then
dHeadFront = max( 50, dTDiam / 2 * abs( vtTool:getZ()) + 20)
elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.1) or
( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then
dHeadFront = 130
elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.95) then
dHeadFront = 180
elseif ( vtTool:getX() > 0.8) then
dHeadFront = 675
elseif ( vtTool:getX() > 0.75) then
dHeadFront = 650
elseif ( vtTool:getX() > 0.5) then
dHeadFront = 450
end
if vtTool:getX() > 0.25 then
dHeadFront = dHeadFront + max( dTLen - 130, 0) * vtTool:getX()
elseif vtTool:getX() > 0 then
dHeadFront = dHeadFront + ( dTLen + 180) * vtTool:getX()
end
if vtTool:getX() < -0.866 then
dHeadFront = 50
elseif vtTool:getX() <= 0 and dZup > 0 then
dHeadFront = max( 130, dHeadFront - dZup)
end
if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then
if vtArm:getX() > 0.259 then
dHeadFront = 510
else
dHeadFront = EgtIf( vtTool:getZ() > 0.966, 160, 280)
end
end
-- per fresature longitudinali con utensile di fianco
if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() > 0.5 then
dHeadFront = 500
end
-- per sega a catena di fianco
if bChain and vtTool:getX() > -0.5 and vtTool:getZ() < 0.5 and vtArm:getX() > 0.5 then
dHeadFront = max( dHeadFront, 510)
end
-- per fresa diretta quasi esattamente come Y+/- e con la testa non troppo nel pezzo
if not bChain and abs( vtTool:getX()) < 0.017 and abs( vtTool:getZ()) < 0.017 and
(( vtTool:getY() > 0 and ptHeadMin:getY() > 80) or ( vtTool:getY() < 0 and ptHeadMax:getY() < -EMC.SB - 80)) then
dHeadFront = 130
end
-- per limiti corsa asse X2
if not bChain then
dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtTool:getX() * ( MillOffs + dTLen))
else
dHeadFront = max( dHeadFront, -MaxX2 + 1 + vtAux:getX() * ( MillOffs + dTDist) + vtTool:getX() * dTLen)
end
end
-- Stampe debug
EgtOutLog( ' Tdir=' .. tostring( vtTool) .. ' Adir=' .. tostring( vtArm) .. ' Zup=' .. EgtNumToString( dZup), 3)
EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) ..
' HeadFront=' .. EgtNumToString( dHeadFront) .. ' HeadBack=' .. EgtNumToString( dHeadBack), 3)
-- Restituisco ingombri effettivi
return ( dDistFront - dHeadFront), ( dDistBack - dHeadBack)
end
---------------------------------------------------------------------
function VerifyPartLength()
-- Verifico lunghezza pezzo
if EMC.LB < MinJoin + MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM then
EgtOutLog( ' Error CLAMP -> pezzo troppo corto')
EMC.ERR = 17
return false
end
return true
end
---------------------------------------------------------------------
function SpecCalcLoad( dPosT, dDistFront, dDistBack)
--[L]
local dMinDistBack= max( dDistBack, MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0))
local dNewYDelta = max( EMC.LB - dMinDistBack, MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM)
local dNewVDelta = nil
local dNewY = dPosT + TurnerOffs + dNewYDelta
local vCmd = {}
EgtOutLog( ' *[L]', 1)
-- [L-1]
if dNewY - MaxX1 > 0 then
dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxX1 - dPosT - TurnerOffs)
EgtOutLog( ' *[L1]', 1)
end --[L-2]
if EMC.LB - dNewYDelta < MinJoin then
dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxX1 - dPosT - TurnerOffs)
EgtOutLog( ' *[L2]', 1)
end
-- Commento
table.insert( vCmd, { 0, 'Loading'})
-- risalita testa a Zmax
local bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- Apro entrambe le morse
table.insert( vCmd, { 11, 0})
table.insert( vCmd, { 12, 0})
-- Sposto il carrello Y per il carico
table.insert( vCmd, { 2, 'X1', dPosT + dNewYDelta, 'X2', ParkX2})
-- Chiudo morsa Y
table.insert( vCmd, { 11, EgtIf( EMC.LB - dNewYDelta < LenToPress, 1, 2)})
-- confermo i nuovi parametri di aggancio
table.insert( vCmd, { 21, dNewYDelta, 0})
-- Inizializzo contatore globale
EMC.CNT = 1
SpecOutputCNT()
-- Assegno stato corrente
EMC.TPOS = dPosT
EMC.YDELTA = dNewYDelta
EMC.VDELTA = nil
-- Restituisco i comandi
return vCmd
end -- SpecAdjustLoad [L]
---------------------------------------------------------------------
function SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos)
local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM
local MinBackJoin = MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0)
local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AGG_LOAD, 0)
local dDistFrontEff = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING)
if bFixedDelta and IsMid2Phase( EMC.PHASE + 1) then
dDistFrontEff = min( dDistFrontEff, EMC.LR - MinOther - EMC.TCING)
end
local dDistBackEff = min( dDistBack, EMC.LB - MyMinOther - EMC.HCING - EMC.HOVM)
EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) ..
' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) ..
' Fixed : Delta=' .. EgtIf( bFixedDelta, 'T', 'F') .. ' Pos=' .. EgtIf( bFixedPos, 'T', 'F'), 3)
-- [A] se posso mettere solo carrello Y
if dDistFrontEff < MinFrontJoin and dDistBackEff > MinBackJoin - GEO.EPS_SMALL then
local dPosT = EMC.TPOS
local dYDelta = EMC.YDELTA
local dVDelta = EMC.VDELTA
local dNewPosT = nil
local dNewYDelta = EMC.LB - dDistBackEff
local dNewVDelta = nil
return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos)
-- [B] se altrimenti posso mettere entrambi i carrelli Y e V
elseif dDistBackEff > MinBackJoin - GEO.EPS_SMALL and
dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then
local dPosT = EMC.TPOS
local dYDelta = EMC.YDELTA
local dVDelta = EMC.VDELTA
local dNewPosT = nil
local dNewYDelta = EMC.LB - dDistBackEff
local dNewVDelta = dDistFrontEff
return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos)
-- [C] se altrimenti posso mettere solo carrello V
elseif dDistBackEff < MinBackJoin and dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then
local dPosT = EMC.TPOS
local dYDelta = EMC.YDELTA
local dVDelta = EMC.VDELTA
local dNewPosT = nil
local dNewYDelta = nil
local dNewVDelta = dDistFrontEff
return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos)
-- altrimenti errore
else
if EgtGetDebugLevel() < 3 then
EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) ..
' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1))
end
EgtOutLog( ' Error CLAMP impossible')
EMC.ERR = 18
return {}
end
end
---------------------------------------------------------------------
function SpecCalcSplit( dLenRaw)
local vCmd = {}
EgtOutLog( ' *[S]', 1)
table.insert( vCmd, { 0, EgtIf( EMC.VDELTA, 'Split', 'Fall')})
-- 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, 'X1'})
end
nRawId = EgtGetNextRawPart( nRawId)
end
-- riporto il carrello Y al carico con il resto della trave
local dLDelta = EMC.YDELTA - dLenRaw
table.insert( vCmd, { 1, 'X1', LoadT + dLDelta})
table.insert( vCmd, { 21, 0, EMC.VDELTA or 0})
-- imposto subito Y non più attaccato al trave in lavoro
EMC.YDELTA = nil
-- salvo posizione carrello Y in disposizione del pezzo dopo split
local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1)
if PostDispId then
EgtSetInfo( PostDispId, 'YPOS', LoadT + 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', LoadT)
EgtSetInfo( NextDispId, 'YPOS', LoadT + dLDelta)
end
return vCmd
end
---------------------------------------------------------------------
function SpecCalcSplitRot( dLenRaw)
local vCmd = {}
EgtOutLog( ' *[SR]', 1)
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, 'X1'})
end
-- riporto il carrello Y al carico con il resto della trave
local dLDelta = EMC.YDELTA - dLenRaw
table.insert( vCmd, { 1, 'X1', LoadT + TurnerOffs + dLDelta})
table.insert( vCmd, { 21, 0, EMC.VDELTA})
-- imposto subito Y non più attaccato alla trave in lavoro
EMC.YDELTA = 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, 'X1', ParkX1})
-- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari)
local NextDispId = EgtGetPhaseDisposition( nNextOddPhase)
if NextDispId then
EgtSetInfo( NextDispId, 'TPOS', LoadT)
end
return vCmd
end
---------------------------------------------------------------------
function SpecCalcUnload()
local vCmdPre = {}
EgtOutLog( ' *[U]', 1)
-- Se pinza Y chiusa , devo effettuare uno scambio
if EMC.YDELTA then
-- determino posizione testa trave
local nLastEntId = EgtGetLastInGroup( EMC.PATHID)
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 - MinOther - EMC.TCING - 10 * GEO.EPS_SMALL
local dDistBack = 0
-- effettuo scambio
vCmdPre = SpecCalcCarriages( dDistFront, dDistBack)
if EMC.ERR ~= 0 then
return {}
end
-- recupero nuova posizione carrelli
SpecSetCarrPosFromCmds( vCmdPre)
EgtOutLog( ' *[U1]', 1)
end
local vCmd = {}
-- Tipo di scarico
local bStdUl = ( MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1)
-- Commento
table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual Unloading')})
-- risalita testa a Zmax
local bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- Se pinza Y chiusa, la apro
if EMC.YDELTA then
table.insert( vCmd, { 11, 0})
end
-- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico
if bStdUl then
local dFinT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) - EMC.LB
local dFinV = dFinT + EMC.VDELTA
table.insert( vCmd, { 2, 'T', dFinT, 'X2', dFinV})
else
table.insert( vCmd, { 1, 'X2', MaxX2})
end
-- apro la morsa
table.insert( vCmd, { 12, 0})
-- riporto il carrello in home
table.insert( vCmd, { 1, 'X2', ParkX2})
-- eventuale unione tabelle
if #vCmdPre > 0 then
vCmd = EgtJoinTables( vCmdPre, vCmd)
end
return vCmd
end
---------------------------------------------------------------------
function SpecCalcPreRot()
local vCmdPre = {}
EgtOutLog( ' *[PR]', 1)
-- Se pinza V chiusa , devo effettuare uno scambio
if EMC.VDELTA 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)
-- recupero nuova posizione carrelli
SpecSetCarrPosFromCmds( vCmdPre)
EgtOutLog( ' *[PR1]', 1)
end
-- porto il pezzo alla zona di rotazione con il carro Y
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'Pre-Rotation'})
-- risalita testa a Zmax
local bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- Se pinza V chiusa, la apro
if EMC.VDELTA then
table.insert( vCmd, { 12, 0})
end
-- riporto la trave al carico
local RotT = LoadT + TurnerOffs - EMC.HOVM
table.insert( vCmd, { 2, 'X1', RotT + EMC.YDELTA, 'T', RotT})
-- apro la morsa
table.insert( vCmd, { 11, 0})
-- riporto il carrello in home
table.insert( vCmd, { 1, 'X1', ParkX1})
-- eventuale unione tabelle
if #vCmdPre > 0 then
vCmd = EgtJoinTables( vCmdPre, vCmd)
end
return vCmd
end
---------------------------------------------------------------------
function SpecAdjustCarriages( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos)
-- [A] richiesto solo carrello Y
if dYDeltaF and ( not dVDeltaF) then
-- [A1] rimango sul carrello Y
if dYDeltaI and ( not dVDeltaI) then
return SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
-- [A2] torno da entrambi
elseif dYDeltaI and dVDeltaI then
return SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
-- [A3] torno da carrello V
elseif dVDeltaI and (not dYDeltaI) then
return SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
else
EgtOutLog( ' Error CLAMP NULL-> Y impossibile')
error( 'Error CLAMP NULL-> Y impossibile')
end
-- (B) richiesti entrambi i carrelli
elseif dYDeltaF and dVDeltaF then
-- [B1] passo da carrello Y a entrambi
if dYDeltaI and ( not dVDeltaI) then
return SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
-- [B2] continuo con entrambi i carrelli
elseif dYDeltaI and dVDeltaI then
return SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
-- [B3] passo da carrello V a entrambi
elseif dVDeltaI and (not dYDeltaI) then
return SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
else
EgtOutLog( ' Error CLAMP NULL-> Y+V impossibile')
error( 'Error CLAMP NULL-> Y+V impossibile')
end
-- [C] richiesto solo carrello V
elseif ( not dYDeltaF) and dVDeltaF then
-- [C1] provengo da solo carrello Y
if dYDeltaI and ( not dVDeltaI) then
return SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
-- [C2] provengo da carrelli Y e V
elseif dYDeltaI and dVDeltaI then
return SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
-- [C3] rimango sul carrello V
elseif ( not dYDeltaI) and dVDeltaI then
return SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos)
else
EgtOutLog( ' Error CLAMP NULL-> V impossibile')
error( 'Error CLAMP NULL-> V impossibile')
end
end
end
---------------------------------------------------------------------
local function CalcCharStatus( sType, dDelta)
-- se per carrello Y
if sType == 'X1' then
return EgtIf( EMC.LB - dDelta < LenToPress, 1, 2)
-- altrimenti per carrello V
else
return EgtIf( dDelta < LenToPress, 1, 2)
end
end
---------------------------------------------------------------------
local function GetDeltaTol( dLenPresa, TCING, HCING, HOVM, Carr, bFixedDelta)
local dDeltaTolEff = DELTA_SIC
if Carr == 'X1' then
local dLenPreEff = dLenPresa - TCING
if dLenPreEff < MinJoin + DeltaTol then
dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL)
else
dDeltaTolEff = DeltaTol
end
elseif Carr == 'X2' then
local dLenPreEff = dLenPresa - HCING - HOVM
if dLenPreEff < MinJoin + DeltaTol then
dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL)
else
dDeltaTolEff = DeltaTol
end
end
return EgtIf( bFixedDelta, min( dDeltaTolEff, DELTA_TOL_FIXED), dDeltaTolEff)
end
---------------------------------------------------------------------
local function GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistN, sSide)
local dRecTotn = min( dDistN, dCorsaYfc+ dCorsaVfc) -- recupero possibile al netto di dCorsa..TrA)
local dCorsaYd, dCorsaYTd, dCorsaVd, dCorsaVTd
if sSide == 'Fr' then
if dRecTotn / 2 <= dCorsaYfc then
if dRecTotn / 2 <= dCorsaVfc then
dCorsaYTd = dRecTotn / 2
dCorsaVd = dRecTotn / 2
else
dCorsaVd = dCorsaVfc
dCorsaYTd = min( dCorsaYfc, dRecTotn - dCorsaVd)
end
else
dCorsaYTd = dCorsaYfc
dCorsaVd = min( dCorsaVfc, dRecTotn - dCorsaYTd)
end
dCorsaY = dCorsaYTd
dCorsaV = dCorsaVd
else
if dRecTotn / 2 <= dCorsaVfc then
if dRecTotn / 2 <= dCorsaYfc then
dCorsaVTd = dRecTotn / 2
dCorsaYd = dRecTotn / 2
else
dCorsaYd = dCorsaYfc
dCorsaVTd = min( dCorsaVfc, dRecTotn - dCorsaYd)
end
else
dCorsaVTd = dCorsaVfc
dCorsaYd = min( dCorsaYfc, dRecTotn - dCorsaVTd)
end
dCorsaY = dCorsaYd
dCorsaV = dCorsaVTd
end
return dCorsaY, dCorsaV
end
---------------------------------------------------------------------
local function PosxExtraYV( dX1PosA, dX2PosA, dTPosA, dMinX1, dMaxX2, sYV)
-- svolge la predisposizione iniziale di trave e carrelli in caso di situazione iniziale con un solo carrello chiuso
-- con un solo carrello chiuso per l'aggancio del carrello aperto
local dX1Pos, dX2Pos, dTPos
-- per aggancio del carrello X2
if sYV == 'X2' then
dTPos = min( dTPosA, dX2PosA - MinJoin - EgtIf( EMC.HCING_IGNORE, 0, EMC.HCING) - EMC.HOVM)
dX1Pos = dX1PosA + ( dTPos - dTPosA)
if dX1Pos < dMinX1 then
dX2Pos = dX2PosA + ( dMinX1 - dX1Pos)
if dX2Pos > dMaxX2 + GEO.EPS_SMALL then
EmitComment( vCmd, ' Error CLAMP X2')
error( 'Error CLAMP X2')
return
elseif dX2Pos > dMaxX2 - GEO.EPS_SMALL then
dX2Pos = dMaxX2
end
dX1Pos = dMinX1
dTPos = dTPosA + ( dX1Pos - dX1PosA)
else
--dX1Pos = dMinX1
--dX1Pos = dX1Pos!
--dTPos = dTPosA + ( dX1Pos - dX1PosA)
--dTPos = dTPos!
dX2Pos = dX2PosA
end
end
-- per aggancio del carrello X1
if sYV == 'X1' then
dTPos = max( dTPosA, dX1PosA + MinJoin + EMC.TCING - EMC.LB)
dX2Pos = dX2PosA + ( dTPos - dTPosA)
if dX2Pos > dMaxX2 then
dX1Pos = dX1PosA - ( dX2Pos - dMaxX2)
if dX1Pos < dMinX1 - GEO.EPS_SMALL then
EmitComment( vCmd, ' Error CLAMP X1')
error( 'Error CLAMP X1')
return
elseif dX1Pos < dMinX1 + GEO.EPS_SMALL then
dX1Pos = dMinX1
end
dX2Pos = dMaxX2
dTPos = dTPosA + ( dX2Pos - dX2PosA)
else
-- ++++++++++++++++++++++++++++++++
--dX2Pos = dMaxX2
--dX2Pos = dX2Pos!
--dTPos = dTPosA + ( dX2Pos - dX2PosA)
--dTpos = dTPos!!
dX1Pos = dX1PosA
end
end
return dX1Pos, dX2Pos, dTPos
end
---------------------------------------------------------------------
local function PosXs2Enl (dYa, dVa, dTa, dExtraC, dCorsaTra, dCorsaYd, dCorsaVd, sYV)
-- svolge la fase di allontanamento dei carrelli per il recupero di 'ExtraX2'/'ExtraX1'
-- richiesto alle posizioni [--.xs2] delle funzioni SpecAdjustCarr..
if sYV == 'X2' then -- caso di ExtraX2 (ed eventuale ulteriore allontanamento di X1)
local dCorsaYTrA = dCorsaTra
local dExtraX2n = dExtraC - dCorsaYTrA
-- eseguo allontanamento di Y e (V+T)
if dExtraX2n / 2 <= dCorsaYd then
if dExtraX2n / 2 <= dCorsaVd then
dYa = dYa + dExtraX2n / 2
dVa = dVa - dExtraX2n / 2
dTa = dTa - dExtraX2n / 2
else
dVa = dVa - dCorsaVd
dTa = dTa - dCorsaVd
dYa = dYa + min( dExtraX2n - dCorsaVd, dCorsaYd)
end
else
dYa = dYa + dCorsaYd
dVa = dVa - min( dExtraX2n - dCorsaYd, dCorsaVd)
dTa = dTa - min( dExtraX2n - dCorsaYd, dCorsaVd)
end
end
if sYV == 'X1' then -- caso di ExtraX1 (ed eventuale ulteriore allontanamento di X2)
local dCorsaVTrA = dCorsaTra
local dExtraX1n = -dExtraC - dCorsaVTrA
-- eseguo allontanamento di (Y+T) e V
if dExtraX1n / 2 <= dCorsaVd then
if dExtraX1n / 2 <= dCorsaYd then
dVa = dVa - dExtraX1n / 2
dYa = dYa + dExtraX1n / 2
dTa = dTa + dExtraX1n / 2
else
dYa = dYa + dCorsaYd
dTa = dTa + dCorsaYd
dVa = dVa - min( dExtraX1n - dCorsaYd, dCorsaVd)
end
else
dVa = dVa - dCorsaVd
dYa = dYa + min( dExtraX1n - dCorsaVd, dCorsaYd)
dTa = dTa + min( dExtraX1n - dCorsaVd, dCorsaYd)
end
end
return dYa, dVa, dTa
end
---------------------------------------------------------------------
-- *** [A1] da carrello X1 a X1 : X1 -> X1 ***
---------------------------------------------------------------------
function
SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
EgtOutLog( ' *[A1] = X1 -> X1', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1 -> X1'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
-- recupero le posizioni correnti dei carrelli
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = ParkX2
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dX2PosA - dTPosA
local dNewYDelta -- = dYDeltaF
local dCorsaYfc = MaxX1 - dX1PosA
local dCorsaYd = min( dCorsaYfc, EMC.LB - dYDeltaI - MinJoin)
-- tolleranza
local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1')
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 4
else
dNewYDelta = dYDeltaA
end
EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1)
EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1)
-- flag per risalita resta a Zmax
local bZmaxOk = false
-- **[A1Ys]** |pos. di Y cambia in modo significativo|
if bYDeltaS then
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- definisco 'ExtraX1' con (Y+T) e V accentrati q.b. per la presa con V
local dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2')
local dNewY = dTPos + dNewYDelta
local dExtraX1 = dNewY - MyMinX1
-- effettuo spostamenti di (Y+T) e V per predisporre all'aggancio di T con V
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dVDeltaA = dX2PosA - dTPosA
-- **[A1Ys-x]** posizione di |Y non raggiungibile| (oltre MyMinX1)
if dExtraX1 < 0 then
-- **[A1Ys-xs]** posizione di Y non raggiungibile, |con ExtraX1 'significativo'|
if -dExtraX1 > dYDeltaTol /2 then
--EmitComment( vCmd, '[A1Ys-xs]')
-- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V
local dCorsaYfc = MaxX1 - dX1Pos
local dCorsaVfc = dX2Pos - MinX2
local dDistFrN = (dX2Pos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
local dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T)
local dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos)
local dCorsaYr = dCorsaYTd
-- **[A1Ys-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr|
if -dExtraX1 > ( dCorsaVTr + dCorsaYr) and bYDeltaS then
EmitComment( vCmd, '[A1Ys-xsw]' .. 'CASO NON GESTITO')
return
end
local dCorsaVTrA = MaxX2 - dX2Pos -- !! att.ne: non dX2PosA !!
-- **[A1Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T)
-- (dalle posizione impostate sopra per l'aggancio di V)
if dCorsaVTrA >= -dExtraX1 then
EmitComment( vCmd, '[A1Ys-xs1]')
-- chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: accentro** Y e (V+T)
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = dX2PosA + (-dExtraX1)
dTPosA = dTPosA + (-dExtraX1)
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dYDeltaA = dX1PosA - dTPosA
else -- **[A1Ys-xs2]**
-- ci sarebbe un doppio movimento di Y ? => caso impossibile ?
EmitComment( vCmd, '[A1Ys-xs2]')
-- **1:** posiziono (ulteriormente!) (Y+T) e V
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1')
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dVDeltaA = dX2PosA - dTPosA
-- chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2: accentro** Y e (V+T)
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = MaxX2
dTPosA = dX2PosA - dVDeltaA
--dVDeltaA = dX2PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [A1Ys-xs1/-xs2]
-- **[A1Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')|
else --if -dExtraX1 < DeltaToll/2
EmitComment( vCmd, '[A1Ys-xn]')
-- chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1:** accentro Y
dExtraX1 = 0
dX1PosA = MyMinX1 -- (pos. finale)
table.insert( vCmd, { 1, 'X1', dX1PosA})
-- dYDeltaA = dX1PosA - dTPosA
end --[A1Ys-xs/xn]
-- **[A1Ys-r]** |posizione di Y raggiungibile| (ExtraX1 >=0)
-- (si esclude la possibilità di extra corsa oltre maxX1)
else
EmitComment( vCmd, '[A1Ys-r]')
-- chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1:** posiziono Y alla posizione richiesta
dX1PosA = dNewY
table.insert( vCmd, { 1, 'X1', dX1PosA})
end -- [A1Ys]
-- calcolo il nuovo parametro di aggancio
dYDeltaA = dX1PosA - dTPosA
-- chiudo Y e apro V
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, 0})
-- sposto il carrello V in parcheggio
table.insert( vCmd, { 1, 'X2', ParkX2})
-- imposto il nuovo parametro di aggancio
table.insert( vCmd, { 21, dYDeltaA, 0})
-- reset contatore
EMC.CNT = nil
else -- **[A1Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'|
EmitComment( vCmd, '[A1Yns]')
end --[A1Ys/ns]
EgtOutLog(' YDeltaA =' .. EgtNumToString( dYDeltaA), 1)
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrA1
---------------------------------------------------------------------
-- *** [A2] da entrambi a carrello X1 : X1+X2 -> X1 ***
---------------------------------------------------------------------
function SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
EgtOutLog( ' *[A2] = X1+X2 -> X1 ', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1+X2 -> X1'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
local dCorsaY = MaxX1 - MyMinX1
local dCorsaV = MaxX2 - MinX2
-- recupero le posizioni correnti dei carrelli
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = dTPosI + dVDeltaI
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dVDeltaI
local dNewYDelta -- = dYDeltaF
-- tolleranze
local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1')
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 4
else
dNewYDelta = dYDeltaA
end
-- definisco 'ExtraX1'
local dNewY = dTPosA + dNewYDelta
local dExtraX1 = dNewY - MyMinX1 -- < 0 = nuova pos. di Y 'non raggiungibile' (= oltre MyMinX1)
-- definisco 'ExtraX1 significativo'
local bYxs = -dExtraX1 > dYDeltaTol / 2
EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI) ..
' VDeltaI=' .. EgtNumToString( dVDeltaI), 1)
EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1)
-- flag per risalita resta a Zmax
local bZmaxOk = false
-- risalita testa a Zmax (da effettuare comunque, per il parcheggio di V)
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- calcoli preliminari in caso di spostamento richiesto per Y significativo
local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw
if bYDeltaS then
if bYxs then
-- calcolo le **corse disponibili** dei carrelli **a partire dalle posizioni attuali** (=iniziali)
-- per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd + (MaxX2 - dX2PosA)
dCorsaYr = dCorsaYTd
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaYr + dCorsaVTr
end
end
-- **[A2Ys-xsw]** posizione NewY non raggiungibile (oltre MyMinX1), con ||dExtraX1 | > CorsaYr + CorsaVTr|
while bXsw do
EmitComment( vCmd, '[A2Ys-xsw]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- chiudo eventualmente il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** allontano q.p. (Y+T) e V
dX1PosA = dX1PosA + dCorsaYTd
dTPosA = dTPosA + dCorsaYTd
dX2PosA = dX2PosA - dCorsaVd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2:** accentro Y e (V+T)
dX1PosA = MyMinX1
dX2PosA = dX2PosA + dCorsaVTr
dTPosA = dTPosA + dCorsaVTr
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto Delta attuali
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
-- aggiorno l'extra corsa residua per Y
dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr
bYxs = -dExtraX1 > dYDeltaTol/2
-- **aggiorno la valutazione delle corse disponibili**
-- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd
dCorsaYr = dCorsaYTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end -- [A2Ys-xw]
-- **[A2Ys]** se lo |spostamento| richiesto (ev' residuo) per |Y| è |'significativo'|
if bYDeltaS then
-- **[A2Ys-x]** se la |posizione per Y non è 'raggiungibile'|
if dExtraX1 < 0 then
-- **[A2Ys-xs]** se |ExtraX1 'significativo'|
if bYxs then
local dCorsaVTrA = MaxX2 - dX2PosA
-- **[A2Ys-xs1]** se posso recuperare ExtraX1 solo accentrando (V+T) e Y
if dCorsaVTrA >= -dExtraX1 then
EmitComment( vCmd, '[A2Ys-xs1]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1:** accentro (V+T) q.b. e Y
dX2PosA = dX2PosA + (-dExtraX1)
dTPosA = dTPosA + (-dExtraX1)
dX1PosA = MyMinX1 -- (pos. finale)
--dYDeltaA = dX1PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
else -- **[A2Ys-xs2]**
EmitComment( vCmd, '[A2Ys-xs2]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** allontano (Y+T) e V
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1')
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dVDeltaA = dX2PosA - dTPosA
-- chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2:** accentro Y e (V+T) q.b. per recupero di dExtraX1
dX1PosA = MyMinX1
dX2PosA = MaxX2
dTPosA = dX2PosA - dVDeltaA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end --[A2Ys-xs1/-xs2]
-- [A2Ys-xn] |ExtraX1 ancora <= 0, ma 'non significativo'|
else --if dExtraX1 <= 0 then
EmitComment( vCmd, '[A2Ys-xn]')
dExtraX1 = 0
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- 1: accentro Y
dX1PosA = MyMinX1 -- (pos. finale)
table.insert( vCmd, { 1, 'X1', dX1PosA})
end -- [A2Ys-xs/xn]
--[A2Ys-r] dExtraX2 > 0 ( |pos. Y'raggiungibile|)
else
EmitComment( vCmd, '[A2Ys-r]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- posizione Y
dX1PosA = dTPosA + dNewYDelta -- (pos. finale)
table.insert( vCmd, { 1, 'X1', dX1PosA})
end -- [A2Ys-x/r]
else -- [A2Yns] |spostamento Y| (ev' residuo) |non significativo|
EmitComment( vCmd, '[A2Yns]')
end -- [A2Ys/ns]
-- calcolo i nuovi parametri di aggancio
dYDeltaA = dX1PosA - dTPosA
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, 0})
-- sposto il carrello V in parcheggio
table.insert( vCmd, { 1, 'X2', ParkX2})
-- imposto i nuovi parametri di aggancio
table.insert( vCmd, { 21, dYDeltaA, 0})
EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrA2
---------------------------------------------------------------------
-- *** [A3] da carrello X2 a X1 : X2 -> X1 ***
---------------------------------------------------------------------
function SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF)
EgtOutLog( ' *[A3] = X2 -> X1', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X2 -> X1'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
-- recupero le posizioni correnti
local dX1PosA = ParkX1
local dTPosA = dTPosI
local dX2PosA = dTPosI + dVDeltaI
local dYDeltaA = dX1PosA - dTPosA
local dVDeltaA = dVDeltaI
local dNewYDelta -- = dVDeltaF
-- tolleranza
local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1')
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
-- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 4
else
dNewYDelta = dYDeltaA
end
--
EgtOutLog(' VDeltaI=' .. EgtNumToString( dVDeltaA) .. ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA)..
' TPosI=' .. EgtNumToString( dTPosI) , 1)
EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta) , 1)
local bZmaxOk = false
-- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli)
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- calcoli preliminari in caso di spostamento richiesto per Y significativo
local dX1Pos, dX2Pos, dTPos
local dNewY, dExtraX1, bYxs
local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw
if bYDeltaS then
-- definisco 'ExtraX1' con Y e (V+T) accentrati q.b. per la presa con Y
dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1')
dNewY = dTPos + dNewYDelta
dExtraX1 = dNewY - MyMinX1 --( <0 <=> pos. 'non raggiungibile')
bYxs = -dExtraX1 > dYDeltaTol/2
if bYxs then
-- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1Pos
dCorsaVfc = dX2Pos - MinX2
--local dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dDistFrN = (dX2Pos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos)
dCorsaYr = dCorsaYTd
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end
-- inizializzo
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
end
-- **[A3Ys-xsw]** posizione finale dNewY non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr|
while bXsw do
EmitComment( vCmd, '[A3Ys-xsw]')
-- |1:| posiziono (V+T) e Y come calcolato sopra
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo ev' il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- |2:| allontano (Y+T) e V quanto possibile
dX1PosA = dX1PosA + dCorsaYTd
dTPosA = dTPosA + dCorsaYTd
dX2PosA = dX2PosA - dCorsaVd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |3:| accentro (V+T) e Y
dX2PosA = dX2PosA + dCorsaVTr
dTPosA = dTPosA + dCorsaVTr
dX1PosA = MyMinX1
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto i Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
-- aggiorno ExtraX1
dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr
-- **aggiorno la valutazione delle corse disponibili**
-- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd
dCorsaYr = dCorsaYTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end --[A3Ys-xw]
-- **[A3Ys]** |spostamento| richiesto (ev' residuo) |di Y| |'significativo'|
if bYDeltaS then
EmitComment( vCmd, '[A3Ys]')
-- **[A3Ys-x]** posizione di |Y non raggiungibile|
if dExtraX1 < 0 then
-- **[A3Ys-xs]** |pos. NewY non raggiungibile, con ExtraX1 'significativo'|
-- ( -dExtraX1 <= (CorsaYr+CorsaVr) da ciclo precedente )
if bYxs then
local dCorsaVTrA = MaxX2 - dX2PosA
-- **[A3Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T)
-- ulteriormente rispetto a YPos e Vpos definiti c.s.
if dCorsaVTrA >= -dExtraX1 then
EmitComment( vCmd, '[A3Ys-xs1]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: accentro** Y e (V+T)
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = dX2PosA - dExtraX1
dTPosA = dTPosA - dExtraX1
dYDeltaA = dX1PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[A3Ys-xs2]**
EmitComment( vCmd, '[A3Ys-xs2]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: accentro** ev' Y e (V+T) alle posizioni impostate
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dYDeltaA = dX1PosA - dTPosA
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2: allontano** (Y+T) e V
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1')
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dVDeltaA = dX2PosA - dTPosA
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **3: accentro** Y e (V+T)
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = MaxX2
dTPosA = dX2PosA - dVDeltaA
--dYDeltaA = dX1PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [A3Ys-xs1/-xs2]
-- **[A3Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')|
else --if -dExtraX1 < DeltaToll/2
EmitComment( vCmd, '[A3Ys-xn]')
-- ev' chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1:** accentro Y e porto (V+T) alla posizione impostata
dExtraX1 = 0
dX1PosA = MyMinX1 -- (pos. finale)
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end --[A3Ys-xs/xn]
-- **[A3Ys-r]** |posizione di Y raggiungibile (ExtraX1 >=0)|
else
EmitComment( vCmd, '[A3Ys-r]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- posizione Y in posizione finale ed ev' (V+T) come impostato sopra
dX1PosA = dTPosA + dNewYDelta
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [A3Ys]
else -- **[A3Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'|
EmitComment( vCmd, '[A3Yns]')
end --[A3Ys/ns]
-- calcolo il nuovo parametro di aggancio
dYDeltaA = dX1PosA - dTPosA
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, 0})
-- sposto il carrello V in parcheggio
table.insert( vCmd, { 1, 'X2', ParkX2})
-- imposto il nuovo parametro di aggancio
table.insert( vCmd, { 21, dYDeltaA, 0})
EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrA3
---------------------------------------------------------------------
local function AdjustPositionsForB( dNewYDelta, dNewVDelta, TCING, HCING, HOVM, bFixedDelta)
local REF_DIST = 1400
local dYDelta = 0
local dVDelta = 0
-- incremento se possibile la distanza tra le due posizioni
if not bFixedDelta and ( dNewYDelta - dNewVDelta) < REF_DIST then
local dEffAddDist = ( REF_DIST - ( dNewYDelta - dNewVDelta)) / 2
dYDelta = max( min( dEffAddDist, EMC.LB - dNewYDelta - MinJoin - TCING), 0)
dVDelta = max( min( dEffAddDist, dNewVDelta - MinJoin - HOVM - HCING), 0)
end
return dYDelta, dVDelta
end
---------------------------------------------------------------------
-- *** [B1] da carrello X1 a entrambi : X1 -> X1+X2 ***
---------------------------------------------------------------------
function SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
EgtOutLog( ' *[B1] = X1 -> X1+X2', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1 -> X1+X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
local dCorsaY = MaxX1 - MyMinX1
local dCorsaV = MaxX2 - MinX2
-- recupero le posizioni correnti
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = ParkX2
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dX2PosA - dTPosA
local dNewYDelta
local dNewVDelta
-- incremento la distanza tra le due posizioni ( se abilitato e possibile)
local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta)
-- tolleranze
local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta)
local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
-- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 2
else
dNewYDelta = dYDeltaA
end
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 2
else
dNewVDelta = dVDeltaA
end
EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA) ..
' TPosI='.. EgtNumToString( dTPosI), 1)
EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1)
EgtOutLog(' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1)
-- risalita testa a Zmax
local bZmaxOk = false
-- calcoli preliminari in caso di spostamento richiesto per V significativo
local dX1Pos, dX2Pos, dTPos
local dNewV, dExtraX2, bVxs
local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw
if bVDeltaS then
-- definisco 'ExtraX2' con (Y+T) e V accentrati q.b. per la presa di V
dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2')
dNewV = dTPos + dNewVDelta
dExtraX2 = dNewV - MaxX2 -- se > 0 pos. V non direttamente 'raggiungibile'
bVxs = dExtraX2 > dVDeltaTol/2 -- ExtraX2 'significativo'
if bVxs then
-- calcolo le **corse disponibili** dei carrelli a partire da Y e V c.s.|
-- per allontanare q.p. Y e (V+T)
dCorsaYfc = MaxX1 - dX1Pos
dCorsaVfc = dX2Pos - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- valuto le **corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V
dCorsaYTr = dCorsaYd + (dX1Pos - MyMinX1)
dCorsaVr = dCorsaVTd
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr
end
-- inizializzo
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
end
-- **[B1Vs-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr|
while bXsw do
EmitComment( vCmd, '[B1Vs-xsw]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- |1:| imposto (Y+T) e V come calcolato sopra
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |2:| allontano Y e (V+T) quanto possibile
dX1PosA = dX1PosA + dCorsaYd
dX2PosA = dX2PosA - dCorsaVTd
dTPosA = dTPosA - dCorsaVTd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- |3:| accentro (Y+T) e V
dX1PosA = dX1PosA - dCorsaYTr
dTPosA = dTPosA - dCorsaYTr
dX2PosA = MaxX2
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto i Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- aggiorno l'extra corsa residuo per V
dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr
-- **aggiorno la valutazione delle corse disponibili**
-- a partire da Y e V c.s. per allontanare q.p. Y e (V+T)
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- aggiorno i prossimi recuperi disponibili
dCorsaYTr = dCorsaYd
dCorsaVr = dCorsaVTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr
end --[B1Vs-xw]
-- **[B1Vs]** se lo |spostamento| finale richiesto (ev' residuo) di |V| è |'significativo'|
if bVDeltaS then
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- **[B1Vs-x]** posizione di |V non raggiungibile|
if dExtraX2 > 0 then
-- **[B1Vs-xs]** |ExtraX2 'signfificativo'|
-- (ExtraX2 <= (CorsaYr+CorsaVr) da ciclo precedente )
if bVxs then
local dCorsaYTrA = dX1PosA - MyMinX1
local dCorsaVra = MaxX2 - dX2PosA
-- **[B1Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando V e (Y+T)
-- ulteriormente rispetto a YPos e Vpos definiti c.s.
if dCorsaYTrA >= dExtraX2 then
EmitComment( vCmd, '[B1Vs-xs1]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: accentro** (Y+T) e V
dX1PosA = dX1PosA - dExtraX2
dTPosA = dTPosA - dExtraX2
dX2PosA = MaxX2 -- (pos. finale)
dVDeltaA = dX2PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[B1Vs-xs2]**
EmitComment( vCmd, '[B1Vs-xs2]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: accentro** ev' (Y+T) e V alle posizioni impostate
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dVDeltaA = dX2PosA - dTPosA
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2: allontano** (V+T) e Y
-- tenendo conto di dover 'recuperare' ExtraX2....
local dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2')
local dYDispl1 = dX1Pos1 - dX1PosA
local dVDispl1 = dX2Pos1 - dX2PosA
--local dTDispl1 = dTPos1 - dTPosA
local dYDeltaDiff = dNewYDelta - (dX1Pos1 - dTPos1)
-- ...e anche di posizionare possibilmente Y alla posizione finale
if dYDeltaDiff > 0 then
dCorsaYfc = MaxX1 - dX1Pos1
dCorsaVfc = dX2Pos1 - MinX2
dDistBkN = EMC.LB - (dX1Pos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'X2')
else
dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1
end
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **3: accentro** (Y+T) e V
dX1PosA = dX1PosA - dYDispl1 - dCorsaYTrA -- POS. FINALE
dTPosA = dTPosA - dYDispl1 - dCorsaYTrA
dX2PosA = dX2PosA - dVDispl1 + dCorsaVra -- POS. FINALE
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B1Vs-xs1/-xs2]
-- **[B1Vs-xn]** |dExtraX2 ancora > 0 ma non 'significativo')|
else --if dExtraX2 < DeltaToll/2
EmitComment( vCmd, '[B1Vs-xn]')
-- ev' chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- 1: accentro (Y+T) alla posizione impostate e V al max
dExtraX2 = 0
dX2PosA = MaxX2 -- (pos. finale)
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B1s-xs/xn]
-- **[B1Vs-r]** |dExtraX2 < 0 (pos. V raggiungibile)|
else
EmitComment( vCmd, '[B1Vs-r]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- posiziono ev' (Y+T) come impostato sopra e V in posizione finale
dX2PosA = dTPosA + dNewVDelta
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B1Vs]
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
else -- **[B1Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'|
EmitComment( vCmd, '[B1Vns]')
if SpecTestOnlyRemarkInCmds( vCmd) then
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- emetto posizione di V
table.insert( vCmd, { 1, 'X2', dX2PosA})
end
end -- [B1-s/ns]
-- aggiorno la verifica di movimento 'significativo' per Y
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
-- **[B1Ys]** Se vi è uno |spostamento residuo di Y significativo'|
if bYDeltaS then
EmitComment( vCmd, '[B1Ys]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
local dNewY = dTPosA + dNewYDelta
local dExtraX1 = dNewY - MyMinX1
-- **[B1Ys-r]** se pos. NewY è raggiungibile direttamente
if dExtraX1 >= 0 then --dNewY > MyMinX1 then
EmitComment( vCmd, '[B1Ys-r]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- sposto il carrello Y
dX1PosA = dTPosA + dNewYDelta
table.insert( vCmd, { 1, 'X1', dX1PosA})
-- **[B1Ys-xn]** se pos. NewY non è raggiungibile direttamente, ma ExtraX1 non è 'significativo'
elseif -dExtraX1 <= dYDeltaTol / 2 then
EmitComment( vCmd, '[B1Ys-xn]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- accentro Y
dX1PosA = MyMinX1
table.insert( vCmd, { 1, 'X1', dX1PosA})
-- [B1sY-nr.xs] ma ExtraX1 'significativo'
else -- **[B1Ys-xs]**
EmitComment( vCmd, '[B1Ys-xs]')
EgtOutLog( ' CLAMP : caso [B1Ys-xs] non gestito')
error( ' CLAMP : caso [B1Ys-xs] non gestito')
end --[B1Ys-r/-nr]
else -- [B1Yns] spostamento residuo di Y non significativo
EmitComment( vCmd, '[B1Yns]')
end -- [B1Ys/ns]
-- calcolo i nuovi parametri di aggancio
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- se non emessi movimenti, imposto posizione V
if not bZmaxOk then
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
table.insert( vCmd, { 1, 'X2', dX2PosA})
end
-- imposto stato carrelli, per eventuale uso pressori (sempre eseguita risalita Z)
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
-- imposto i nuovi parametri di aggancio
table.insert( vCmd, { 21, dYDeltaA, dVDeltaA})
EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end -- SpecAdjustCarrB1
---------------------------------------------------------------------
-- *** [B2] da entrambi a entrambi i carrelli : X1+X2 -> X1+X2 ***
---------------------------------------------------------------------
function SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
EgtOutLog( ' *[B2] = X1+X2 -> X1+X2', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1+X2 -> X1+X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
-- recupero le posizioni correnti
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = dTPosI + dVDeltaI
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dVDeltaI
local dNewYDelta
local dNewVDelta
-- incremento la distanza tra le due posizioni ( se abilitato e possibile)
local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta)
-- tolleranze
local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta)
local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
-- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 2
else
dNewYDelta = dYDeltaA
end
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 2
else
dNewVDelta = dVDeltaA
end
-- definisco 'ExtraX1' e ExtraX2'
local dNewY = dTPosA + dNewYDelta
local dNewV = dTPosA + dNewVDelta
local dExtraX1 = dNewY - MyMinX1 -- < 0 => nuova pos. di Y 'non raggiungibile'
local dExtraX2 = dNewV - MaxX2 -- > 0 => nuova pos. di V 'non raggiungibile'
local bYxs = -dExtraX1 > dYDeltaTol/2
local bVxs = dExtraX2 > dVDeltaTol/2
EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) ..
' TPosI='.. EgtNumToString( dTPosI), 1)
EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1)
EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1)
-- flag risalita a Zmax
local bZmaxOk = false
-- **[B2V]** |accentramento di V|
if dVDeltaF > dVDeltaI then
EmitComment( vCmd, '[B2V]')
-- calcoli preliminari in caso di spostamento richiesto per V significativo
local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw
if bVDeltaS then
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
if bVxs then
-- calcolo le corse disponibili dei carrelli **dalle posizioni iniziali**
-- per allontanare Y e (V+T)
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- calcolo le corse di 'recupero' accentrando (Y+T) e V dopo l'allontanamento
dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1)
dCorsaVr = dCorsaVTd -- ((MaxX2-dNewV) non fa parte del recupero in quanto già disponibile!)
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr
end
end
-- **[B2V-xsw]** posizione NewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYTr|
-- e spostamento richiesto di V significativo;
while bXsw do
EmitComment( vCmd, '[B2V-xsw]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1**: allontano Y e V(+T) quanto possibile
dX1PosA = dX1PosA + dCorsaYd
dX2PosA = dX2PosA - dCorsaVTd
dTPosA = dTPosA - dCorsaVTd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2:** accentro (Y+T) e V
dX1PosA = dX1PosA - dCorsaYTr -- = MyMinX1
dTPosA = dTPosA - dCorsaYTr
dX2PosA = MaxX2
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- aggiorno ExtraX2 residuo
dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr
-- **aggiorno i recuperi disponibili** riallontanando Y e (V+T) e riaccentrando (Y+T) e V
dCorsaYfc = dCorsaY -- MaxX1 - dNewY
dCorsaVfc = dCorsaV -- dNewV - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
dCorsaYTr = dCorsaYd
dCorsaVr = dCorsaVTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr
end -- [B2V-xsw]
--[B2Vs] |accentramento| (ev' residuo) |di V 'significativo'|
if bVDeltaS then
--[B2Vs-x] accentramento di V 'significativo' |con pos. NewV 'non raggiungibile'|(= oltre MaxX2)
if dExtraX2 > 0 then
-- (ExtraX2 <= (CorsaYTr+CorsaVr) da ciclo precedente)
--[B2Vs-xs] accentramento di V con |ExtraX2 'significativo'|
if bVxs then
local dCorsaYTrA = dX1PosA - MyMinX1
local dCorsaVra = MaxX2 - dX2PosA
-- **[B2Vs-xs1]** se posso recuperare ExtraX2 solo accentrando V e (Y+T)
if dCorsaYTrA >= dExtraX2 then
EmitComment( vCmd, '[B2Vs-xs1]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** accentro (Y+T) q.b. e V
dX1PosA = dX1PosA - dExtraX2
dTPosA = dTPosA - dExtraX2
dX2PosA = MaxX2 -- (pos. finale)
dExtraX2 = 0
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[B2Vs-xs2]**
EmitComment( vCmd, '[B2Vs-xs2]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: allontano** (V+T) e Y
-- tenendo conto di dover 'recuperare' ExtraX2...
local dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2')
local dYDispl1 = dX1Pos1 - dX1PosA
local dVDispl1 = dX2Pos1 - dX2PosA
--local dTDispl1 = dTPos1 - dTPosA
local dYDeltaDiff = dNewYDelta - (dX1Pos1 - dTPos1)
-- ...e anche possibilmente di posizionare Y alla posizione finale
if dYDeltaDiff > 0 then
dCorsaYfc = MaxX1 - dX1Pos1
dCorsaVfc = dX2Pos1 - MinX2
dDistBkN = EMC.LB - (dX1Pos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
--dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd-dYDispl1, dCorsaVTd+dVDispl1, 'X2')
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'X2')
else
dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1
end
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2: accentro** (Y+T) e V
dX1PosA = dX1PosA - dYDispl1 - dCorsaYTrA -- POS. FINALE
dTPosA = dTPosA - dYDispl1 - dCorsaYTrA
dX2PosA = dX2PosA - dVDispl1 + dCorsaVra -- POS. FINALE
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B2Vs-xs1/xs2]
-- **[B2Vs-xn]** |dExtraX2 non 'significativo'|
else
EmitComment( vCmd, '[B2Vs-xn]')
dExtraX2 = 0
-- ev' chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- 1: posiziono V assumendo maxX2 come pos. finale
dX2PosA = MaxX2 -- (pos finale)
table.insert( vCmd, { 1, 'X2', dX2PosA})
end -- [B2Vs-xs/xn]
-- **[B2Vs-r]** accentramento di |V| 'significativo' con pos.|'raggiungibile'| (= non oltre MaxX2)
else
EmitComment( vCmd, '[B2Vs-r]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- 1: posiziono V -- (pos finale)
dX2PosA = dTPosA + dNewVDelta
dExtraX2 = 0
table.insert( vCmd, { 1, 'X2', dX2PosA})
end --[B2Vs]
-- **[B2Vns]** accentramento di V non 'significativo'|
else
EmitComment( vCmd, '[B2Vns]')
dExtraX2 = 0
end --[B2Vs/ns]
end --[B2V] ( accentramento di V)
-- ---------------------------------------------------------------------------
-- **[B2Y]** |accentramento di Y|
if dYDeltaF < dYDeltaI then
EmitComment( vCmd, '[B2Y]')
-- calcoli preliminari in caso di spostamento richiesto per Y significativo
local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr
if bYDeltaS then
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
if bYxs then
-- calcolo le **corse disponibili** dei carrelli dalle posizioni iniziali
-- per allontanare (Y+T) e V
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd + (MaxX2 - dX2PosA)
dCorsaYr = dCorsaYTd
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end
end
-- **[B2Ys-xsw]** |-dExtraX1 > dCorsaYr + dCorsaVTr|
while bXsw do
EmitComment( vCmd, '[B2Y-xsw]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- |1:| allontano (Y+T) e V quanto possibile
dX1PosA = dX1PosA + dCorsaYTd
dTPosA = dTPosA + dCorsaYTd
dX2PosA = dX2PosA - dCorsaVd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |2:| accentro Y e (V+T)
dX1PosA = MyMinX1 -- = dX1PosA - dCorsaYr
dX2PosA = dX2PosA + dCorsaVTr -- = MaxX2
dTPosA = dTPosA + dCorsaVTr
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto Delta 'attuali'
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- aggiorno ExtraX1 residuo
dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr
-- aggiorno i recuperi disponibili riallontanando (Y+T) V e riaccentrando succ' Y e (V+T)
dCorsaYfc = dCorsaY -- MaxX1 - dNewY
dCorsaVfc = dCorsaV -- dNewV - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd
dCorsaYr = dCorsaYTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end -- [B2Ys-xsw]
-- **[B2Ys]** |accentramento di Y 'significativo'|
if bYDeltaS then
-- **[B2Ys-x]** accentramento di Y 'significativo' |con pos. NewY 'non raggiungibile'|(= oltre MyMinX1)
if dExtraX1 < 0 then
-- (-ExtraX1 <= (dCorsaYr + dCorsaVTr ) a ciclo precedente
-- **[B2Ys-xs]** accentramento di Y con |'ExtraX1 'significativo'|
if bYxs then
local dCorsaVTrA = MaxX2 - dX2PosA
local dCorsaYra = dX1PosA - MyMinX1
-- **[B2Ys-xs1]** se posso recuperare ExtraX1 solo accentrando Y e (V+T)
if dCorsaVTrA >= -dExtraX1 then
EmitComment( vCmd, '[B2Ys-xs1]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- accentro Y e (V+T) q.b.
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = dX2PosA - dExtraX1 -- = +(-dExtraX1)
dTPosA = dTPosA - dExtraX1 -- = +(-dExtraX1)
dExtraX1 = 0
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[B2Ys-xs2]**
EmitComment( vCmd, '[B2Ys-xs2]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: allontano** (Y+T) e V
-- tenendo conto di dover 'recuperare' ExtraX1...
dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1')
local dYDispl1 = dX1Pos1 - dX1PosA
local dVDispl1 = dX2Pos1 - dX2PosA
local dVDeltaDiff = dNewVDelta - (dX2Pos1 - dTPos1)
-- ...e anche possibilmente di posizionare V alla posizione finale
if dVDeltaDiff < 0 then
dCorsaYfc = MaxX1 - dX1Pos1
dCorsaVfc = dX2Pos1 - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'X1')
else
dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1
end
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
--dVDeltaA = dX2PosA - dTPosA
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |2:| accentro Y e (V+T)
dX1PosA = dX1PosA - dYDispl1 - dCorsaYra -- POS. FINALE
dX2PosA = dX2PosA - dVDispl1 + dCorsaVTrA -- POS. FINALE
dTPosA = dTPosA - dVDispl1 + dCorsaVTrA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B2Ys-xs1/xs2]
-- **[B2Ys-xn]** |dExtraX1 non 'significativo'|
else
EmitComment( vCmd, '[B2Ys-xn]')
dExtraX1 = 0
-- ev' chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- 1: posiziono Y assumendo MyMinX1 come pos. finale
dX1PosA = MyMinX1 -- (pos finale)
table.insert( vCmd, { 1, 'X1', dX1PosA})
end -- [B2Ys-xs/xn]
--[B2Ys-r] accentramento di |Y| 'significativo' con pos.|'raggiungibile'| (non oltre MyMinX1)
else
EmitComment( vCmd, '[B2Ys-r]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |1:| posiziono Y -- (pos finale)
dX1PosA = dTPosA + dNewYDelta
dExtraX2 = 0
table.insert( vCmd, { 1, 'X1', dX1PosA})
end --[B2Ys]
-- [B2Yns] accentramento di V non 'significativo'|
else
EmitComment( vCmd, '[B2Yns]')
dExtraX2 = 0
end --[B2Ys/ns]
end --[B2Y] ( accentramento di V)
-- ricalcolo gli 'spostamenti significativi'
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- ------------------------------------------------------------------------------------------
-- **[B2C]** |Spostamenti| di Y e/o V (ev' |residui| da cicli precedenti)
-- ++ possono essere solo allontanamenti ? +++++++++++++++++++++
EmitComment( vCmd, '[B2C]')
-- **[B2Cs]** se c'è uno |spostamento (ev' residuo) significativo|
if bYDeltaS or bVDeltaS then
-- **[B2CYs]** se lo |spostamento (ev' residuo) di Y è 'significativo'|
if bYDeltaS then
EmitComment( vCmd, '[B2CYs]')
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
local dNewY = dTPosA + dNewYDelta
local dExtraX1 = dNewY - MyMinX1
-- **[B2CYs-r]** se posizione di |Y raggiungibile|
if dExtraX1 >= 0 and dNewY <= MaxX1 then
EmitComment( vCmd, '[B2CYs-r]')
-- chiudo eventualmente V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- sposto il carrello Y
dX1PosA = dNewY
table.insert( vCmd, { 1, 'X1', dX1PosA})
-- **[B2CYs-nr]**
else
EmitComment( vCmd, '[B2CYs-nr]')
EgtOutLog( ' CLAMP : posizione Y non raggiungibile' .. '- caso [B2Ys-nr] non gestito')
error( 'CLAMP : posizione Y non raggiungibile')
end
end -- [B2CYs]
-- **[B2CVs]** se lo |spostamento (ev' residuo) di V è 'significativo'|
if bVDeltaS then
EmitComment( vCmd, '[B2CVs]')
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
local dNewV = dTPosA + dNewVDelta
local dExtraX2 = dNewV - MaxX2
-- **[B2CVs-r]** se posizione NewV raggiungibile
if dExtraX2 <= 0 and dNewV >= MinX2 then
EmitComment( vCmd, '[B2CVs-r]')
-- chiudo eventualmente Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- sposto il carrello V
dX2PosA = dNewV
table.insert( vCmd, { 1, 'X2', dX2PosA})
-- **[B2CVs-nr]**
else -- se ExtraX2 > 0 anche se non significativo
EmitComment( vCmd, '[B2CVs-nr]')
EgtOutLog( ' CLAMP : posizione V non raggiungibile' .. '- caso [B2cVs-nr] non gestito')
error( 'CLAMP : posizione V non raggiungibile')
end
end --[B2CsV]
-- **[B2Cn]** |nessuno spostamento (ev' residuo significativo)|
else
EmitComment( vCmd, '[B2Cn]')
end -- [B2C]
-- calcolo i nuovi parametri di aggancio
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- imposto stato carrelli, per eventuale uso pressori
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
-- imposto i nuovi parametri di aggancio
table.insert( vCmd, { 21, dYDeltaA, dVDeltaA})
EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrB2
---------------------------------------------------------------------------------------------------------
-- *** [B3] da carrello X2 a entrambi i carrelli : X2 -> X1+X2 ***
---------------------------------------------------------------------------------------------------------
function SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
EgtOutLog( ' *[B3] = X2 -> X1+X2', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X2 -> X1+X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
local dCorsaY = MaxX1 - MyMinX1
local dCorsaV = MaxX2 - MinX2
-- recupero le posizioni correnti
local dX2PosA = dTPosI + dVDeltaI
local dX1PosA = ParkX1
local dTPosA = dTPosI
local dVDeltaA = dVDeltaI
local dYDeltaA = dX1PosA - dTPosA
local dNewYDelta
local dNewVDelta
-- incremento la distanza tra le due posizioni ( se abilitato e possibile)
local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta)
-- tolleranze
local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X1', bFixedDelta)
local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
-- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze
local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze
if bYDeltaS then
dNewYDelta = dYDeltaF + dYDeltaTol / 2
else
dNewYDelta = dYDeltaA
end
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 2
else
dNewVDelta = dVDeltaA
end
EgtOutLog( ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA)..' VDeltaI=' .. EgtNumToString( dVDeltaA) ..
' TPosI='.. EgtNumToString( dTPosI), 1)
EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1)
EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1)
-- risalita testa a Zmax
local bZmaxOk = false
-- calcoli preliminari in caso di spostamento richiesto per Y significativo
local dX1Pos, dX2Pos, dTPos
local dNewY, dExtraX1, bYxs
local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw
if bYDeltaS then
-- definisco 'ExtraX1' con (V+T) e Y accentrati q.b. per la presa di Y
dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1')
dNewY = dTPos + dNewYDelta
dExtraX1 = dNewY - MyMinX1 -- se < 0 pos. Y non direttamente 'raggiungibile'
bYxs = -dExtraX1 > dYDeltaTol/2 -- ExtraX1 'significativo'
if bYxs then
-- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1Pos
dCorsaVfc = dX2Pos - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd + (MaxX2 - dX2Pos)
dCorsaYr = dCorsaYTd
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end
-- inizializzo
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
end
-- **[B3Ys-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX1 > CorsaVr + CorsaYr|
while bXsw do
EmitComment( vCmd, '[B3Ys-xsw]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- |1:| posiziono (V+T) e Y come calcolato sopra
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- |2:| allontano (Y+T) e V quanto possibile
dX1PosA = dX1PosA + dCorsaYTd
dTPosA = dTPosA + dCorsaYTd
dX2PosA = dX2PosA - dCorsaVd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |3:| accentro (V+T) e Y
dX2PosA = dX2PosA + dCorsaVTr
dTPosA = dTPosA + dCorsaVTr
dX1PosA = MyMinX1
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto i Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC)
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- aggiorno ExtraX1
dExtraX1 = dExtraX1 + dCorsaYr + dCorsaVTr
-- **aggiorno la valutazione delle corse disponibili**
-- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T)
dCorsaVTr = dCorsaVd
dCorsaYr = dCorsaYTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bYDeltaS and bYxs and -dExtraX1 > dCorsaVTr + dCorsaYr
end --[B3Ys-xsw]
-- **[B3Ys]** |spostamento| finale richiesto (ev' residuo) di |Y| |'significativo'|
if bYDeltaS then
EmitComment( vCmd, '[B3Ys]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- **[B3Ys-x]** posizione di |Y non raggiungibile|
-- ( -dExtraX1 <= (CorsaYr+CorsaVr) da ciclo precedente )
if dExtraX1 < 0 then
--EmitComment( vCmd, '[B3Ys-x]')
-- **[B3Ys-xs]** |ExtraX1 'significativo'|
if bYxs then
--EmitComment( vCmd, '[B3Ys-xs]')
local dCorsaVTrA = MaxX2 - dX2PosA
local dCorsaYra = dX1PosA - MyMinX1
-- **[B3Ys-xs1]** se posso recuperare ExtraX1 semplicem' accentrando Y e (V+T)
-- ulteriormente rispetto a YPos e Vpos definiti c.s.
if dCorsaVTrA >= -dExtraX1 then
EmitComment( vCmd, '[B3Ys-xs1]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: accentro** Y e (V+T)
dX1PosA = MyMinX1 -- (pos. finale)
dX2PosA = dX2PosA - dExtraX1
dTPosA = dTPosA - dExtraX1
dYDeltaA = dX1PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[B3Ys-xs2]**
EmitComment( vCmd, '[B3Ys-xs2]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: accentro** ev' Y e (V+T) alle posizioni impostate
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dYDeltaA = dX1PosA - dTPosA
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2: allontano** (Y+T) e V
-- tenendo conto di dover 'recuperare' ExtraX1...
dX1Pos1, dX2Pos1, dTPos1 = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX1, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'X1')
local dYDispl1 = dX1Pos1 - dX1PosA
local dVDispl1 = dX2Pos1 - dX2PosA
local dVDeltaDiff = dNewVDelta - (dX2Pos1 - dTPos1)
-- ...e anche di posizionare possibilmente V alla posizione finale
if dVDeltaDiff < 0 then
CorsaYfc = MaxX1 - dX1Pos1
dCorsaVfc = dX2Pos1 - MinX2
dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta'
dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr')
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1Pos1, dX2Pos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'X1')
else
dX1PosA = dX1Pos1; dX2PosA = dX2Pos1; dTPosA = dTPos1
end
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
-- chiudo il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **3: accentro** Y e (V+T)
dX1PosA = dX1PosA - dYDispl1 - dCorsaYra -- POS. FINALE
dX2PosA = dX2PosA - dVDispl1 + dCorsaVTrA -- POS. FINALE
dTPosA = dTPosA - dVDispl1 + dCorsaVTrA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B3Ys-xs1/-xs2]
-- **[B3Ys-xn]** |dExtraX1 ancora < 0 ma non 'significativo')|
else --if -dExtraX1 < DeltaToll/2
EmitComment( vCmd, '[B3Ys-xn]')
-- ev' chiudo V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- 1: accentro Y e porto (V+T) alla posizione impostata
dExtraX1 = 0
dX1PosA = MyMinX1 -- (pos. finale)
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end --[B3Ys-xs/xn]
-- **[B3Ys-r]** |dExtraX1 > 0 (pos. Y raggiungibile)|
else
EmitComment( vCmd, '[B3Ys-r]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- posizione ev' (V+T) come impostato sopra e Y in posizione finale
dX1PosA = dTPosA + dNewYDelta
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [B3Ys]
--
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
else -- [B3Yns] |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'|
EmitComment( vCmd, '[B3Yns]')
end --[B3Ys/ns]
-- aggiorno la verifica di movimento 'significativo' per V
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- **[B3Vs]** Se vi è uno |spostamento residuo di V significativo'|
if bVDeltaS then
EmitComment( vCmd, '[B3Vs]')
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
local dNewV = dTPosA + dNewVDelta
local dExtraX2 = dNewV - MaxX2
-- **[B3Vs-x]** se pos. |NewV non è raggiungibile direttamente| (oltre MaxX2)
if dExtraX2 > 0 then --dNewV <= MaxX2 then
-- **[B3Vs-xs]** |ExtraX2 'significativo'|
if dExtraX2 > dVDeltaTol /2 then
EmitComment( vCmd, '[B3Vs-xs]')
EgtOutLog( ' CLAMP : caso [B3Vs-xs] non gestito')
error( ' CLAMP : caso [B3Vs-xs] non gestito')
-- **[B3Vs-xn]** |ExtraX2 non 'significativo'|
else
EmitComment( vCmd, '[B3Vs-xn]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- accentro V q.p.
dX2PosA = MaxX2
table.insert( vCmd, { 1, 'X2', dX2PosA})
end -- [B3Vs-xs/xn]
else -- **[B3Vs-r]** pos. |NewV raggiungibile direttamente| (non oltre MaxX2)
EmitComment( vCmd, '[B3Vs-r]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- sposto il carrello V
dX2PosA = dNewV
table.insert( vCmd, { 1, 'X2', dX2PosA})
end --[B3Vs-x/-r]
else -- [B3Vns] spostamento residuo di V non significativo
EmitComment( vCmd, '[B3Vns]')
end -- [B3Vs/ns]
-- calcolo i nuovi parametri di aggancio
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- se non emessi movimenti, imposto posizione Y
if not bZmaxOk then
-- risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
table.insert( vCmd, { 1, 'X1', dX1PosA})
end
-- imposto stato carrelli, per eventuale uso pressori (sempre effettuato movimento)
table.insert( vCmd, { 11, CalcCharStatus( 'X1', dYDeltaA)})
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
-- imposto i nuovi parametri di aggancio
table.insert( vCmd, { 21, dYDeltaA, dVDeltaA})
EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end -- SpecAdjustCarrB3
---------------------------------------------------------------------
-- *** [C1] da carrello X1 a X2 : X1 -> X2 ***
---------------------------------------------------------------------
function SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
EgtOutLog( ' *[C1] = X1 -> X2 ', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1 -> X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
-- recupero le posizioni correnti
--local dCorsaY = MaxX1 - MyMinX1
--local dCorsaV = MaxX2 - MinX2
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = ParkX2
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dX2PosA - dTPosA
local dNewVDelta -- = dVDeltaF
-- tolleranza
local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 4
else
dNewVDelta = dVDeltaA
end
EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA)..
' TPosI=' .. EgtNumToString( dTPosI) , 1)
EgtOutLog(' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta) , 1)
-- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli)
local bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- calcoli preliminari in caso di spostamento richiesto per V significativo
local dX1Pos, dX2Pos, dTPos
local dNewV, dExtraX2, bVxs
local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw
if bVDeltaS then
-- definisco 'ExtraX2' con (Y+T) e V accentrati q.b. per la presa di V
dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X2')
dNewV = dTPos + dNewVDelta
dExtraX2 = dNewV - MaxX2
bVxs = dExtraX2 > dVDeltaTol/2 -- ExtraX2 'significativo'
if bVxs then
-- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. Y e (V+T)
dCorsaYfc = MaxX1 - dX1Pos
dCorsaVfc = dX2Pos - MinX2
--local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dDistBkN = EMC.LB - (dX1Pos-dTPos) - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V
dCorsaYTr = dCorsaYd + (dX1Pos -MyMinX1)
dCorsaVr = dCorsaVTd
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr
end
-- inizializzo
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
end
-- **[C1Vs-xsw]** posizione finale di V non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr|
-- con spostamento richiesto significativo e ExtraX2 significativo
while bXsw do
EmitComment( vCmd, '[C1Vs-xsw]')
-- **1:** posiziono (Y+T) e V come calcolato sopra
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2:** allontano Y e (V+T) quanto possibile
dX1PosA = dX1PosA + dCorsaYd
dX2PosA = dX2PosA - dCorsaVTd
dTPosA = dTPosA - dCorsaVTd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **3:** accentro (Y+T) e V
dX1PosA = dX1PosA - dCorsaYTr -- = MyMinX1
dTPosA = dTPosA - dCorsaYTr
dX2PosA = MaxX2
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto i Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- **aggiorno ExtraX2**
dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr
-- **aggiorno la valutazione di ulteriori corse disponibili**
-- a partire da Y e V c.s. per allontanare q.p. Y e (V+T)
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- aggiorno i prossimi recuperi disponibili
dCorsaYTr = dCorsaYd
dCorsaVr = dCorsaVTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaVr + dCorsaYTr
end --[C1Vs-xw]
-- **[C1Vs]** |spostamento| richiesto (ev' residuo) |di V| |'significativo'|
if bVDeltaS then
-- **[C1Vs-x]** posizione di |V non raggiungibile|
if dExtraX2 > 0 then
-- (dExtraX2 <= (CorsaYr+CorsaVr) da ciclo precedente)
-- **[C1Vs-xs]** posizione di V non raggiungibile, |con ExtraX2 'significativo'|
if bVxs then
local dCorsaYTrA = dX1PosA - MyMinX1
-- **[C1Vs-xs1]** se posso recuperare dExtraX2 solo accentrando V e (Y+T)
if dCorsaYTrA >= dExtraX2 then
EmitComment( vCmd, '[C1Vs-xs1]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** accentro (Y+T) q.b. e V
dX1PosA = dX1PosA - dExtraX2
dTPosA = dTPosA - dExtraX2
dX2PosA = MaxX2 -- (pos. finale)
dVDeltaA = dX2PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
-- **[C1Vs-xs2]** dCorsaYTrA < dExtraX2
else
EmitComment( vCmd, '[C1Vs-xs2]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: accentro** ev' (Y+T) e V alle posizioni impostate
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
dVDeltaA = dX2PosA - dTPosA
-- chiudo (ev') il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **2:allontano** (V+T) q.b./q.p. e Y per preparare il recupero di ExtraX2
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2')
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dYDeltaA = dX1PosA - dTPosA
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **3: accentro**(Y+T) e V (pos. finale)
dX1PosA = MyMinX1
dTPosA = dX1PosA - dYDeltaA
dX2PosA = MaxX2
dVDeltaA = dX2PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
end -- [C1Vs-xs1/xs2]
-- **[C1Vs-xn]** |ExtraX2 ancora > 0 , ma non 'significativo'| (<= DeltaTol/2)
else
EmitComment( vCmd, '[C1Vs-xn]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- 1: porto ev' (Y+T) alla posizione impostata sopra e accentro V
dExtraX2 = 0
dX2PosA = MaxX2 -- pos. finale
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo V (?)
table.insert( vCmd, { 12, 1})
end -- [C1Vs-xs/xn]
-- **[C1Vs-r]** posizione di V 'raggiungibile' (ExtraX2 <= 0)
else
EmitComment( vCmd, '[C1Vs-r]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- posizione ev' (Y+T) come impostato sopra e V in posizione finale
dX2PosA = dTPosA + dNewVDelta
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [C1V-s]
-- **[C1Vns]** |spostamento| richIesto per V |non 'significativo'|
else
EmitComment( vCmd, '[C1Vns]')
end
-- calcolo i nuovi parametri di aggancio
dVDeltaA = dX2PosA - dTPosA
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
table.insert( vCmd, { 11, 0})
-- sposto il carrello Y in parcheggio
table.insert( vCmd, { 1, 'X1', ParkX1})
-- imposto i nuovi parametri di aggancio
table.insert( vCmd, { 21, 0, dVDeltaA})
EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrC1
---------------------------------------------------------------------
-- *** [C2] da entrambi i carrelli a X2 : X1+X2 -> X2 ***
---------------------------------------------------------------------
function SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta)
EgtOutLog( ' *[C2] = X1+X2 -> X2', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X1+X2 -> X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
local dCorsaY = MaxX1 - MyMinX1
local dCorsaV = MaxX2 - MinX2
-- recupero le posizioni correnti dei carrelli
local dX1PosA = dTPosI + dYDeltaI
local dX2PosA = dTPosI + dVDeltaI
local dTPosA = dTPosI
local dYDeltaA = dYDeltaI
local dVDeltaA = dVDeltaI
local dNewVDelta -- = dVDeltaF
-- tolleranze
local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
-- definisco spostamento 'significativo' in base alle tolleranze
local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- reimposto ev' il delta finale
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 4
else
dNewVDelta = dVDeltaA
end
-- definisco 'ExtraX2'
local dNewV = dTPosI + dNewVDelta
local dExtraX2 = dNewV - MaxX2 -- > 0 se nuova pos. di X2 'non raggiungibile' (= oltre MaxX2)
local bVxs = dExtraX2 > dVDeltaTol/2 -- 'ExtraX2 significativo'
EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) ..
' VDeltaF=' .. EgtNumToString( dVDeltaF) ,1)
EgtOutLog( ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1)
-- risalita testa a Zmax (da effettuare comunque, per il parcheggio di Y)
local bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- calcoli preliminari in caso di spostamento richiesto per YV significativo
local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw
if bVDeltaS then
if bVxs then
-- calcolo le corse disponibili dei carrelli dalle posizioni attuali (=iniziali)
-- per allontanare Y e (V+T) q.p.
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V
dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1)
dCorsaVr = dCorsaVTd
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr
end
end
-- **[C2Vs-xsw]** posizione finale di V non raggiungibile, |con dExtraX2 > CorsaYTr + CorsaVr|
while bXsw do
EmitComment( vCmd, '[C2Vs-xsw]')
-- chiudo eventualmente il carrello V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- |1:| allontano Y e (V+T) quanto possibile
dX1PosA = dX1PosA + dCorsaYd
dX2PosA = dX2PosA - dCorsaVTd
dTPosA = dTPosA - dCorsaVTd
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- |3:| accentro (Y+T) e V
dX1PosA = dX1PosA - dCorsaYTr
dTPosA = dTPosA - dCorsaYTr
dX2PosA = MaxX2
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
-- valuto i Delta ottenuti
dYDeltaA = dX1PosA - dTPosA
dVDeltaA = dX2PosA - dTPosA
-- aggiorno la verifica di spostamento significativo
bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC)
-- **aggiorno ExtraX2**
dExtraX2 = dExtraX2 - dCorsaYTr - dCorsaVr
-- **aggiorno la valutazione di ulteriori corse disponibili**
dCorsaYfc = MaxX1 - dX1PosA
dCorsaVfc = dX2PosA - MinX2
dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- aggiorno i prossimi recuperi disponibili
dCorsaYTr = dCorsaYd + (dX1PosA - MyMinX1)
dCorsaVr = dCorsaVTd
-- aggiorno verifica per ripetizione del ciclo
bXsw = bVDeltaS and bVxs and dExtraX2 > dCorsaYTr + dCorsaVr
end -- [C2V-xsw]
-- **[C2Vs]** se lo |spostamento richiesto per V è significativo|
if bVDeltaS then
-- **[C2Vs-x]** posizione di |V non raggiungibile| (oltre MaxX2)
if dExtraX2 > 0 then
-- **[C2Vs-xs]** |ExtraX2 'significativo'|
if bVxs then
local dCorsaYTrA = dX1PosA - MyMinX1
-- **[C2Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando V e (Y+T)
if dCorsaYTrA >= dExtraX2 then
EmitComment( vCmd, '[C2Vs-xs1]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: accentro** (Y+T) e V
dX1PosA = dX1PosA - dExtraX2
dTPosA = dTPosA - dExtraX2
dX2PosA = MaxX2 -- (pos. finale)
dVDeltaA = dX2PosA - dTPosA
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
else -- **[C2Vs-xs2]**
EmitComment( vCmd, '[C2Vs-xs2]')
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, 1})
table.insert( vCmd, { 11, 0})
-- **1: allontano** (V+T) e Y
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2')
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dYDeltaA = dX1PosA - dTPosA
-- chiudo il carrello Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2: accentro** (Y+T) e V
dX1PosA = MyMinX1
dTPosA = dX1PosA - dYDeltaA
dX2PosA = MaxX2 -- (pos. finale)
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [C2Vs-xs1/-xs2]
-- **[C2Vs-xn]** |dExtraX2 ancora > 0 ma non 'significativo')|
else --if dExtraX2 < DeltaToll/2
EmitComment( vCmd, '[B1Vs-xn]')
-- ev' chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** accentro V
dExtraX2 = 0
dX2PosA = MaxX2 -- (pos. finale)
table.insert( vCmd, { 1, 'X2', dX2PosA})
end -- [C2s-xs/xn]
-- **[C2Vs-r]** |dExtraX2 < 0 (pos. V raggiungibile)|
else
EmitComment( vCmd, '[C2Vs-r]')
-- chiudo ev' Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- porto V in posizione finale
dX2PosA = dTPosA + dNewVDelta
table.insert( vCmd, { 1, 'X2', dX2PosA})
end --[C2Vs]
-- **[C2Vns]** = |spostamento di V non significativo|
else
EmitComment( vCmd, '[C2Vns]')
end --[C2Vs/n]
-- calcolo il nuovo parametro di aggancio
dVDeltaA = dX2PosA - dTPosA
-- chiudo eventualmente il carrello V e apro Y
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
table.insert( vCmd, { 11, 0})
-- sposto il carrello Y in parcheggio
table.insert( vCmd, { 1, 'X1', ParkX1})
-- imposto il nuovo parametro di aggancio
table.insert( vCmd, { 21, 0, dVDeltaA})
EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
-- reset contatore
EMC.CNT = nil
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrC2
---------------------------------------------------------------------
-- *** [C3] da carrello X2 a X2 : X2 -> X2 ***
---------------------------------------------------------------------
function SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos)
EgtOutLog( ' *[C3] = X2 -> X2', 1)
-- elenco comandi
local vCmd = {}
-- Commento
table.insert( vCmd, { 0, 'X2 -> X2'})
-- se primo scambio
local MyMinX1 = EgtIf( EMC.CNT == 1, MinX1 + AGG_LOAD, MinX1)
-- recupero le posizioni correnti dei carrelli
local dX2PosA = dTPosI + dVDeltaI
local dX1PosA = ParkX1
local dTPosA = dTPosI
local dVDeltaA = dVDeltaI
local dYDeltaA = dX1PosA - dTPosA
local dNewVDelta
-- tolleranza
local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'X2', bFixedDelta)
local bVDeltaS = (( dVDeltaF > dVDeltaA + dVDeltaTol and not bFixedPos) or dVDeltaF < dVDeltaA - DELTA_SIC)
if bVDeltaS then
dNewVDelta = dVDeltaF - dVDeltaTol / 4
else
dNewVDelta = dVDeltaA
end
EgtOutLog( ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1)
EgtOutLog( ' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1)
-- flag per risalita testa a Zmax
local bZmaxOk = false
-- **[C3Vs]** |pos. di V cambia in modo significativo|
if bVDeltaS then
EmitComment( vCmd, '[C3Vs]')
-- eventuale risalita testa a Zmax
bZmaxOk = EnsureZmax( bZmaxOk, vCmd)
-- definisco 'ExtraX2' con (V+T) e Y accentrati q.b. per la presa con Y
local dX1Pos, dX2Pos, dTPos = PosxExtraYV( dX1PosA, dX2PosA, dTPosA, MyMinX1, MaxX2, 'X1')
local dNewV = dTPos + dNewVDelta
local dExtraX2 = dNewV - MaxX2
-- effettuo spostamenti per predisporre all'aggancio di T con Y
dX1PosA = dX1Pos
dX2PosA = dX2Pos
dTPosA = dTPos
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dYDeltaA = dX1PosA - dTPosA
-- **[C3Vs-x]** posizione di |V non raggiungibile| (oltre MaxX2)
if dExtraX2 > 0 then
-- **[C3Vs-xs]** posizione di V non raggiungibile, |con ExtraX2 'significativo'|
if dExtraX2 > dVDeltaTol /2 then
-- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (V+T) e Y
local dCorsaYfc = MaxX1 - dX1Pos
local dCorsaVfc = dX2Pos - MinX2
local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta'
local dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk')
-- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V
local dCorsaYTr = dCorsaYd + (dX1Pos - MyMinX1)
local dCorsaVr = dCorsaVTd
-- **[C3Vs-xsw]** posizione finale dNewV non raggiungibile, con |dExtraX2 > CorsaVr + CorsaYr|
if dExtraX2 > ( dCorsaYTr + dCorsaVr) and bVDeltaS then
EmitComment( vCmd, '[C3Vs-xsw]' .. 'CASO NON GESTITO')
return
end
local dCorsaYTrA = dX1Pos - MyMinX1 -- !! att.ne: non dX1PosA !!
-- **[C3Vs-xs1]** se posso recuperare ExtraX2 semplicem' accentrando (Y+T) e V
-- (dalle posizione impostate sopra per l'aggancio di Y)
if dCorsaYTrA >= dExtraX2 then
EmitComment( vCmd, '[C3Vs-xs1]')
-- chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1: accentro** (Y+T) e V
dX1PosA = dX1PosA - dExtraX2
dTPosA = dTPosA - dExtraX2
dX2PosA = MaxX2 -- (pos. finale)
table.insert( vCmd, { 3, 'X1', dX1PosA , 'T', dTPosA, 'X2', dX2PosA})
dVDeltaA = dX2PosA - dTPosA
else -- **[C3Vs-xs2]**
-- ci sarebbe un doppio movimento di V ? => caso impossibile ?
EmitComment( vCmd, '[C3Vs-xs2]')
-- **1:** posiziono (ulteriormente!) Y e (V+T)
dX1PosA, dX2PosA, dTPosA = PosXs2Enl( dX1PosA, dX2PosA, dTPosA, dExtraX2, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'X2')
table.remove( vCmd)
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA })
dYDeltaA = dX1PosA - dTPosA
-- chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2: accentro** (Y+T) e V
dX1PosA = MyMinX1
dX2PosA = MaxX2 -- (pos. finale)
dTPosA = dX1PosA - dYDeltaA
table.insert( vCmd, { 3, 'X1', dX1PosA, 'T', dTPosA, 'X2', dX2PosA})
end -- [C3Vs-xs1/-xs2]
-- **[C3Vs-xn]** |dExtraX2 > 0 ma 'non significativo')|
else --if dExtraX2 < DeltaToll/2
EmitComment( vCmd, '[C3Vs-xn]')
-- chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **1:** accentro V
dExtraX2 = 0
dX2PosA = MaxX2 -- (pos. finale)
table.insert( vCmd, { 1, 'X2', dX2PosA})
end --[C3Vs-xs/xn]
-- **[C3Vs-r]** |posizione di Y raggiungibile| (ExtraX1 >=0)
-- (si esclude la possibilità di extra corsa oltre maxX1)
else
EmitComment( vCmd, '[C3Vs-r]')
-- chiudo Y e apro V
table.insert( vCmd, { 11, 1})
table.insert( vCmd, { 12, 0})
-- **2:** posiziono V alla posizione richiesta
dX2PosA = dNewV
table.insert( vCmd, { 1, 'X2', dX2PosA})
end -- [C3Vs]
-- calcolo il nuovo parametro di aggancio
dVDeltaA = dX2PosA - dTPosA
-- chiudo ev' V e apro Y
table.insert( vCmd, { 12, CalcCharStatus( 'X2', dVDeltaA)})
table.insert( vCmd, { 11, 0})
-- sposto il carrello Y in parcheggio
table.insert( vCmd, { 1, 'X1', ParkX1})
-- imposto il nuovo parametro di aggancio
table.insert( vCmd, { 21, 0, dVDeltaA})
-- reset contatore
EMC.CNT = nil
else -- **[C3Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'|
EmitComment( vCmd, '[C3Vns]')
end --[C3Vs/ns]
EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1)
SpecOutputCNT()
return vCmd
end --SpecAdjustCarrC3
---------------------------------------------------------------------
function SpecOutputCNT()
if EMC.CNT == 1 then
EgtSetInfo( EMC.PATHID, 'CNT', 1)
else
EgtRemoveInfo( EMC.PATHID, 'CNT')
end
end
---------------------------------------------------------------------
function SpecOutputCmds( vCmd, bEnd)
local sRoot = EgtIf( not bEnd, 'AS', 'AE')
-- Registro il numero di comandi
if #vCmd > 0 then
EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd)
else
EgtRemoveInfo( EMC.PATHID, sRoot..'#')
end
-- Registro i comandi
for i = 1, #vCmd do
local Cmd = vCmd[i]
local sKey = sRoot..tostring( i)
-- commento
if Cmd[1] == 0 then
local sInfo = '0,'..Cmd[2]
if Cmd[3] then sInfo = sInfo..','..Cmd[3] end
EgtSetInfo( EMC.PATHID, sKey, sInfo)
-- movimento di 1 asse
elseif Cmd[1] == 1 then
local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)
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)
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)
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)
if Cmd[2] == 0 then EMC.YDELTA = nil end
-- apertura/chiusura morsa V
elseif Cmd[1] == 12 then
local sInfo = '12,'..EgtNumToString( Cmd[2],0)
EgtSetInfo( EMC.PATHID, sKey, sInfo)
if Cmd[2] == 0 then EMC.VDELTA = nil end
-- 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.YDELTA = Cmd[2]
EMC.VDELTA = Cmd[3]
elseif Cmd[2] > 0 then
EMC.YDELTA = Cmd[2]
EMC.VDELTA = nil
elseif Cmd[3] > 0 then
EMC.YDELTA = nil
EMC.VDELTA = Cmd[3]
end
-- aggancio grezzo a carrello
elseif Cmd[1] == 31 then
local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3]
EgtSetInfo( EMC.PATHID, sKey, sInfo)
end
end
-- Salvo i nuovi delta dei carrelli
if EMC.YDELTA then
EgtSetInfo( EMC.PATHID, 'YDELTA', EMC.YDELTA)
else
EgtRemoveInfo( EMC.PATHID, 'YDELTA')
end
if EMC.VDELTA then
EgtSetInfo( EMC.PATHID, 'VDELTA', EMC.VDELTA)
else
EgtRemoveInfo( EMC.PATHID, 'VDELTA')
end
end
---------------------------------------------------------------------
function SpecSetCarrPosFromCmds( vCmd)
-- recupero nuova posizione carrelli
for i = 1, #vCmd do
local Cmd = vCmd[i]
if Cmd[1] == 21 then
if Cmd[2] > 0 and Cmd[3] > 0 then
EMC.YDELTA = Cmd[2]
EMC.VDELTA = Cmd[3]
elseif Cmd[2] > 0 then
EMC.YDELTA = Cmd[2]
EMC.VDELTA = nil
elseif Cmd[3] > 0 then
EMC.YDELTA = nil
EMC.VDELTA = Cmd[3]
end
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