-- Special Operations macchina Essetre-FAST by EgalWare s.r.l. 2024/03/28 -- Intestazioni require( 'EmtGenerator') EgtEnableDebug( false) -- carico librerie local BD = require( 'BeamData') ---------------------- 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 = 210 local DELTA_TOL_L = 410 local DELTA_TOL_FIXED = 50 local DeltaTol = DELTA_TOL_S local DELTA_SIC = 1 local AGG_LOAD = 50 local MIN_JOIN_VV = EgtClamp( MinJoinVV or 75, 60, 150) local MIN_JOIN_SS = EgtClamp( MinJoinSS or 100, 80, 200) local MIN_JOIN_LS = EgtClamp( MinJoinLS or 290, 250, 400) local MIN_JOIN_SL = EgtClamp( MinJoinSL or 100, 80, 200) local MIN_JOIN_LL = EgtClamp( MinJoinLL or 400, 300, 600) local MinJoin = MIN_JOIN_SS local MinOther = abs( MinY) + abs( MaxV) + MinJoin ----------------------- 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 = 200 local H_L = 400 local W_V = 90 local W_S = 150 local W_L = 250 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( MinY) + abs( MaxV) + 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 -- Recupero il grezzo in lavoro local nCurrRawId = GDB_ID.NULL local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then 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 = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 -- Devo scaricare il pezzo o il grezzo rimasto -- 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 - EMC.HOVM end vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD - EMC.HOVM, MaxY - 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, MaxY - 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 dDistFront = EgtIf( EMC.LB < abs( MinV - UnloadT), MinJoin, EMC.LB - abs( MinV - UnloadT) + MinJoin + DeltaTol) + EMC.HOVM 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 EMC.CNT = 1 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 EMC.CNT = nil 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') EMC.CNT = nil end -- 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 EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 -- 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 -- 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 bAngTrasm = ( sHead == 'H5' or sHead == 'H6') local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) local dThLen = EgtTdbGetCurrToolThLength() -- 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 vtAux = vtTool else vtAux = vtTool ^ vtAux end end -- Se rinvio da sotto, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C if bAngTrasm then local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) vtAux = vtTool ^ vtAux if nExit == 2 then vtAux = -vtAux end end -- Calcolo limiti derivanti dalla lavorazione local dDistFront, dDistBack = SpecCalcEncumbrance( vtTool, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dThLen) 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, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam, dThLen) -- 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 riferimento pezzo in Y e Z) local ptHeadMin = ptMin + vtTool * dTLen - Vector3d( 0, EMC.YMIN + EMC.SB, EMC.ZMIN) local ptHeadMax = ptMax + vtTool * dTLen - Vector3d( 0, 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.06 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 = 660 end else dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) end 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 interferenza con triangolo di rinforzo sulla pinza Y if ( vtTool:getZ() < 0.25 and vtTool:getX() < 0.10 and vtTool:getY() > 0 and vtArm:getX() < -0.707 and not BD.RIGHT_LOAD) or ( vtTool:getZ() < 0.25 and vtTool:getX() < 0.10 and vtTool:getY() < 0 and vtArm:getX() < -0.707 and BD.RIGHT_LOAD)then dHeadBack = dHeadBack + 90 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.06 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 = 660 end else dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) end 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 forature di coda abbastanza lontane dai bordi pezzo in Y if BD.ENABLE_TOOL_BETWEEN_VICES and not bChain and vtTool:getX() < -0.999 and ptHeadMax:getY() + dTDiam / 2 < -15 and ptHeadMin:getY() - dTDiam / 2 > -EMC.SB + 15 then dHeadFront = - ( dTLen - dThLen - 15) end -- per interferenza con triangolo di rinforzo sulla pinza V if ( vtTool:getZ() < 0.25 and vtTool:getX() > -0.10 and vtTool:getY() > 0 and vtArm:getX() > 0.707 and not BD.RIGHT_LOAD) or ( vtTool:getZ() < 0.25 and vtTool:getX() > -0.10 and vtTool:getY() < 0 and vtArm:getX() > 0.707 and BD.RIGHT_LOAD) then dHeadFront = dHeadFront + 90 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 - MaxY > 0 then dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - dPosT - TurnerOffs) EgtOutLog( ' *[L1]', 1) end --[L-2] if EMC.LB - dNewYDelta < MinJoin then dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - 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, 'Y', dPosT + dNewYDelta, 'V', ParkV}) -- 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, 'Y'}) 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, 'Y', 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, 'Y'}) end -- riporto il carrello Y al carico con il resto della trave local dLDelta = EMC.YDELTA - dLenRaw table.insert( vCmd, { 1, 'Y', 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, 'Y', ParkY}) -- 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 = UnloadT - EMC.LB local dFinV = dFinT + EMC.VDELTA table.insert( vCmd, { 2, 'T', dFinT, 'V', dFinV}) else table.insert( vCmd, { 1, 'V', MaxV}) end -- apro la morsa table.insert( vCmd, { 12, 0}) -- riporto il carrello in home table.insert( vCmd, { 1, 'V', ParkV}) -- 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, 'Y', RotT + EMC.YDELTA, 'T', RotT}) -- apro la morsa table.insert( vCmd, { 11, 0}) -- riporto il carrello in home table.insert( vCmd, { 1, 'Y', ParkY}) -- 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 == 'Y' 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 == 'Y' then local dLenPreEff = dLenPresa - TCING if dLenPreEff < MinJoin + DeltaTol then dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) else if BD.GO_FAST and BD.GO_FAST ~= 0 then if bFixedDelta == false then dDeltaTolEff = min( EMC.LB + 700, dLenPreEff, 3200) else dDeltaTolEff = 900 end else dDeltaTolEff = DeltaTol end end elseif Carr == 'V' 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( dYPosA, dVPosA, dTPosA, dMinY, dMaxV, 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 dYPos, dVPos, dTPos -- per aggancio del carrello V if sYV == 'V' then dTPos = min( dTPosA, dVPosA - MinJoin - EgtIf( EMC.HCING_IGNORE, 0, EMC.HCING) - EMC.HOVM) dYPos = dYPosA + ( dTPos - dTPosA) if dYPos < dMinY then dVPos = dVPosA + ( dMinY - dYPos) if dVPos > dMaxV + GEO.EPS_SMALL then EmitComment( vCmd, ' Error CLAMP V') error( 'Error CLAMP V') return elseif dVPos > dMaxV - GEO.EPS_SMALL then dVPos = dMaxV end dYPos = dMinY dTPos = dTPosA + ( dYPos - dYPosA) else --dYPos = dMinY --dYPos = dYPos! --dTPos = dTPosA + ( dYPos - dYPosA) --dTPos = dTPos! dVPos = dVPosA end end -- per aggancio del carrello Y if sYV == 'Y' then dTPos = max( dTPosA, dYPosA + MinJoin + EMC.TCING - EMC.LB) dVPos = dVPosA + ( dTPos - dTPosA) if dVPos > dMaxV then dYPos = dYPosA - ( dVPos - dMaxV) if dYPos < dMinY - GEO.EPS_SMALL then EmitComment( vCmd, ' Error CLAMP Y') error( 'Error CLAMP Y') return elseif dYPos < dMinY + GEO.EPS_SMALL then dYPos = dMinY end dVPos = dMaxV dTPos = dTPosA + ( dVPos - dVPosA) else -- ++++++++++++++++++++++++++++++++ --dVPos = dMaxV --dVPos = dVPos! --dTPos = dTPosA + ( dVPos - dVPosA) --dTpos = dTPos!! dYPos = dYPosA end end return dYPos, dVPos, dTPos end --------------------------------------------------------------------- local function PosXs2Enl (dYa, dVa, dTa, dExtraC, dCorsaTra, dCorsaYd, dCorsaVd, sYV) -- svolge la fase di allontanamento dei carrelli per il recupero di 'ExtraV'/'ExtraY' -- richiesto alle posizioni [--.xs2] delle funzioni SpecAdjustCarr.. if sYV == 'V' then -- caso di ExtraV (ed eventuale ulteriore allontanamento di Y) local dCorsaYTrA = dCorsaTra local dExtraVn = dExtraC - dCorsaYTrA -- eseguo allontanamento di Y e (V+T) if dExtraVn / 2 <= dCorsaYd then if dExtraVn / 2 <= dCorsaVd then dYa = dYa + dExtraVn / 2 dVa = dVa - dExtraVn / 2 dTa = dTa - dExtraVn / 2 else dVa = dVa - dCorsaVd dTa = dTa - dCorsaVd dYa = dYa + min( dExtraVn - dCorsaVd, dCorsaYd) end else dYa = dYa + dCorsaYd dVa = dVa - min( dExtraVn - dCorsaYd, dCorsaVd) dTa = dTa - min( dExtraVn - dCorsaYd, dCorsaVd) end end if sYV == 'Y' then -- caso di ExtraY (ed eventuale ulteriore allontanamento di V) local dCorsaVTrA = dCorsaTra local dExtraYn = -dExtraC - dCorsaVTrA -- eseguo allontanamento di (Y+T) e V if dExtraYn / 2 <= dCorsaVd then if dExtraYn / 2 <= dCorsaYd then dVa = dVa - dExtraYn / 2 dYa = dYa + dExtraYn / 2 dTa = dTa + dExtraYn / 2 else dYa = dYa + dCorsaYd dTa = dTa + dCorsaYd dVa = dVa - min( dExtraYn - dCorsaYd, dCorsaVd) end else dVa = dVa - dCorsaVd dYa = dYa + min( dExtraYn - dCorsaVd, dCorsaYd) dTa = dTa + min( dExtraYn - dCorsaVd, dCorsaYd) end end return dYa, dVa, dTa end --------------------------------------------------------------------- -- *** [A1] da carrello Y a Y : Y -> Y *** --------------------------------------------------------------------- function SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) EgtOutLog( ' *[A1] = Y -> Y', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y -> Y'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) -- recupero le posizioni correnti dei carrelli local dYPosA = dTPosI + dYDeltaI local dVPosA = ParkV local dTPosA = dTPosI local dYDeltaA = dYDeltaI local dVDeltaA = dVPosA - dTPosA local dNewYDelta -- = dYDeltaF local dCorsaYfc = MaxY - dYPosA local dCorsaYd = min( dCorsaYfc, EMC.LB - dYDeltaI - MinJoin) -- tolleranza local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) if bYDeltaS then dNewYDelta = dYDeltaF + dYDeltaTol/2 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 'ExtraY' con (Y+T) e V accentrati q.b. per la presa con V local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') local dNewY = dTPos + dNewYDelta local dExtraY = dNewY - MyMinY -- effettuo spostamenti di (Y+T) e V per predisporre all'aggancio di T con V dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dVDeltaA = dVPosA - dTPosA -- **[A1Ys-x]** posizione di |Y non raggiungibile| (oltre MyMinY) if dExtraY < 0 then -- **[A1Ys-xs]** posizione di Y non raggiungibile, |con ExtraY 'significativo'| if -dExtraY > 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 = MaxY - dYPos local dCorsaVfc = dVPos - MinV local dDistFrN = (dVPos-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 + (MaxV - dVPos) local dCorsaYr = dCorsaYTd -- **[A1Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| if -dExtraY > ( dCorsaVTr + dCorsaYr) and bYDeltaS then EmitComment( vCmd, '[A1Ys-xsw]' .. 'CASO NON GESTITO') return end local dCorsaVTrA = MaxV - dVPos -- !! att.ne: non dVPosA !! -- **[A1Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) -- (dalle posizione impostate sopra per l'aggancio di V) if dCorsaVTrA >= -dExtraY 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) dYPosA = MyMinY -- (pos. finale) dVPosA = dVPosA + (-dExtraY) dTPosA = dTPosA + (-dExtraY) table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dYDeltaA = dYPosA - dTPosA else -- **[A1Ys-xs2]** -- ci sarebbe un doppio movimento di Y ? => caso impossibile ? EmitComment( vCmd, '[A1Ys-xs2]') -- **1:** posiziono (ulteriormente!) (Y+T) e V dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dVDeltaA = dVPosA - dTPosA -- chiudo V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **2: accentro** Y e (V+T) dYPosA = MyMinY -- (pos. finale) dVPosA = MaxV dTPosA = dVPosA - dVDeltaA --dVDeltaA = dVPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [A1Ys-xs1/-xs2] -- **[A1Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| else --if -dExtraY < DeltaToll/2 EmitComment( vCmd, '[A1Ys-xn]') -- chiudo V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **1:** accentro Y dExtraY = 0 dYPosA = MyMinY -- (pos. finale) table.insert( vCmd, { 1, 'Y', dYPosA}) -- dYDeltaA = dYPosA - dTPosA end --[A1Ys-xs/xn] -- **[A1Ys-r]** |posizione di Y raggiungibile| (ExtraY >=0) -- (si esclude la possibilità di extra corsa oltre maxY) 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 dYPosA = dNewY table.insert( vCmd, { 1, 'Y', dYPosA}) end -- [A1Ys] -- calcolo il nuovo parametro di aggancio dYDeltaA = dYPosA - dTPosA -- chiudo Y e apro V table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, 0}) -- sposto il carrello V in parcheggio table.insert( vCmd, { 1, 'V', ParkV}) -- 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 Y : Y+V -> Y *** --------------------------------------------------------------------- function SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) EgtOutLog( ' *[A2] = Y+V -> Y ', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y+V -> Y'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) local dCorsaY = MaxY - MyMinY local dCorsaV = MaxV - MinV -- recupero le posizioni correnti dei carrelli local dYPosA = dTPosI + dYDeltaI local dVPosA = 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, 'Y') local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) if bYDeltaS then dNewYDelta = dYDeltaF + dYDeltaTol/2 else dNewYDelta = dYDeltaA end -- definisco 'ExtraY' local dNewY = dTPosA + dNewYDelta local dExtraY = dNewY - MyMinY -- < 0 = nuova pos. di Y 'non raggiungibile' (= oltre MyMinY) -- definisco 'ExtraY significativo' local bYxs = -dExtraY > 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 + (MaxV - dVPosA) dCorsaYr = dCorsaYTd bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaYr + dCorsaVTr end end -- **[A2Ys-xsw]** posizione NewY non raggiungibile (oltre MyMinY), con ||dEXtraY | > 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 dYPosA = dYPosA + dCorsaYTd dTPosA = dTPosA + dCorsaYTd dVPosA = dVPosA - dCorsaVd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **2:** accentro Y e (V+T) dYPosA = MyMinY dVPosA = dVPosA + dCorsaVTr dTPosA = dTPosA + dCorsaVTr table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto Delta attuali dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- aggiorno la verifica di spostamento significativo bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) -- aggiorno l'extra corsa residua per Y dExtraY = dExtraY + dCorsaYr + dCorsaVTr bYxs = -dExtraY > 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 -dExtraY > 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 dExtraY < 0 then -- **[A2Ys-xs]** se |ExtraY 'significativo'| if bYxs then local dCorsaVTrA = MaxV - dVPosA -- **[A2Ys-xs1]** se posso recuperare ExtraY solo accentrando (V+T) e Y if dCorsaVTrA >= -dExtraY 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 dVPosA = dVPosA + (-dExtraY) dTPosA = dTPosA + (-dExtraY) dYPosA = MyMinY -- (pos. finale) --dYDeltaA = dYPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) 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 dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dVDeltaA = dVPosA - 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 dExtraY dYPosA = MyMinY dVPosA = MaxV dTPosA = dVPosA - dVDeltaA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end --[A2Ys-xs1/-xs2] -- [A2Ys-xn] |ExtraY ancora <= 0, ma 'non significativo'| else --if dExtraY <= 0 then EmitComment( vCmd, '[A2Ys-xn]') dExtraY = 0 -- chiudo ev' V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- 1: accentro Y dYPosA = MyMinY -- (pos. finale) table.insert( vCmd, { 1, 'Y', dYPosA}) end -- [A2Ys-xs/xn] --[A2Ys-r] dExtrav > 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 dYPosA = dTPosA + dNewYDelta -- (pos. finale) table.insert( vCmd, { 1, 'Y', dYPosA}) 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 = dYPosA - dTPosA -- chiudo ev' Y e apro V table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, 0}) -- sposto il carrello V in parcheggio table.insert( vCmd, { 1, 'V', ParkV}) -- 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 V a Y : V -> Y *** --------------------------------------------------------------------- function SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) EgtOutLog( ' *[A3] = V -> Y', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'V -> Y'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) -- recupero le posizioni correnti local dYPosA = ParkY local dTPosA = dTPosI local dVPosA = dTPosI + dVDeltaI local dYDeltaA = dYPosA - dTPosA local dVDeltaA = dVDeltaI local dNewYDelta -- = dVDeltaF -- tolleranza local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') 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/2 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 dYPos, dVPos, dTPos local dNewY, dExtraY, bYxs local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw if bYDeltaS then -- definisco 'ExtraY' con Y e (V+T) accentrati q.b. per la presa con Y dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') dNewY = dTPos + dNewYDelta dExtraY = dNewY - MyMinY --( <0 <=> pos. 'non raggiungibile') bYxs = -dExtraY > 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 = MaxY - dYPos dCorsaVfc = dVPos - MinV --local dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' dDistFrN = (dVPos-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 + (MaxV - dVPos) dCorsaYr = dCorsaYTd bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr end -- inizializzo dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos end -- **[A3Ys-xsw]** posizione finale dNewY non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| while bXsw do EmitComment( vCmd, '[A3Ys-xsw]') -- |1:| posiziono (V+T) e Y come calcolato sopra table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- 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 dYPosA = dYPosA + dCorsaYTd dTPosA = dTPosA + dCorsaYTd dVPosA = dVPosA - dCorsaVd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- |3:| accentro (V+T) e Y dVPosA = dVPosA + dCorsaVTr dTPosA = dTPosA + dCorsaVTr dYPosA = MyMinY table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto i Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- aggiorno la verifica di spostamento significativo bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) -- aggiorno ExtraY dExtraY = dExtraY + 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 -dExtraY > 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 dExtraY < 0 then -- **[A3Ys-xs]** |pos. NewY non raggiungibile, con ExtraY 'significativo'| -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) if bYxs then local dCorsaVTrA = MaxV - dVPosA -- **[A3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) -- ulteriormente rispetto a YPos e Vpos definiti c.s. if dCorsaVTrA >= -dExtraY 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) dYPosA = MyMinY -- (pos. finale) dVPosA = dVPosA - dExtraY dTPosA = dTPosA - dExtraY dYDeltaA = dYPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dYDeltaA = dYPosA - dTPosA -- chiudo ev' Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **2: allontano** (Y+T) e V dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dVDeltaA = dVPosA - dTPosA -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **3: accentro** Y e (V+T) dYPosA = MyMinY -- (pos. finale) dVPosA = MaxV dTPosA = dVPosA - dVDeltaA --dYDeltaA = dYPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [A3Ys-xs1/-xs2] -- **[A3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| else --if -dExtraY < 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 dExtraY = 0 dYPosA = MyMinY -- (pos. finale) table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end --[A3Ys-xs/xn] -- **[A3Ys-r]** |posizione di Y raggiungibile (ExtraY >=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 dYPosA = dTPosA + dNewYDelta table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) 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 = dYPosA - dTPosA -- chiudo ev' Y e apro V table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, 0}) -- sposto il carrello V in parcheggio table.insert( vCmd, { 1, 'V', ParkV}) -- 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 Y a entrambi : Y -> Y+V *** --------------------------------------------------------------------- function SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) EgtOutLog( ' *[B1] = Y -> Y+V', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y -> Y+V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) local dCorsaY = MaxY - MyMinY local dCorsaV = MaxV - MinV -- recupero le posizioni correnti local dYPosA = dTPosI + dYDeltaI local dVPosA = ParkV local dTPosA = dTPosI local dYDeltaA = dYDeltaI local dVDeltaA = dVPosA - 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, 'Y', bFixedDelta) local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', 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 dYPos, dVpos, dTPos local dNewV, dExtraV, bVxs local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw if bVDeltaS then -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') dNewV = dTPos + dNewVDelta dExtraV = dNewV - MaxV -- se > 0 pos. V non direttamente 'raggiungibile' bVxs = dExtraV > dVDeltaTol/2 -- ExtraV '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 = MaxY - dYPos dCorsaVfc = dVPos - MinV 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 + (dYPos - MyMinY) dCorsaVr = dCorsaVTd bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr end -- inizializzo dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos end -- **[B1Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > 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, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo ev' V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- |2:| allontano Y e (V+T) quanto possibile dYPosA = dYPosA + dCorsaYd dVPosA = dVPosA - dCorsaVTd dTPosA = dTPosA - dCorsaVTd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- |3:| accentro (Y+T) e V dYPosA = dYPosA - dCorsaYTr dTPosA = dTPosA - dCorsaYTr dVPosA = MaxV table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto i Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 dExtraV = dExtraV - 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 dExtraV > 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 dExtraV > 0 then -- **[B1Vs-xs]** |ExtraV 'signfificativo'| -- (ExtraV <= (CorsaYr+CorsaVr) da ciclo precedente ) if bVxs then local dCorsaYTrA = dYPosA - MyMinY local dCorsaVra = MaxV - dVPosA -- **[B1Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) -- ulteriormente rispetto a YPos e Vpos definiti c.s. if dCorsaYTrA >= dExtraV 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 dYPosA = dYPosA - dExtraV dTPosA = dTPosA - dExtraV dVPosA = MaxV -- (pos. finale) dVDeltaA = dVPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dVDeltaA = dVPosA - 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' ExtraV.... local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') local dYDispl1 = dYPos1 - dYPosA local dVDispl1 = dVPos1 - dVPosA --local dTDispl1 = dTPos1 - dTPosA local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) -- ...e anche di posizionare possibilmente Y alla posizione finale if dYDeltaDiff > 0 then dCorsaYfc = MaxY - dYPos1 dCorsaVfc = dVPos1 - MinV dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') else dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 end table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **3: accentro** (Y+T) e V dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE dTPosA = dTPosA - dYDispl1 - dCorsaYTrA dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B1Vs-xs1/-xs2] -- **[B1Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| else --if dExtraV < 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 dExtraV = 0 dVPosA = MaxV -- (pos. finale) table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B1s-xs/xn] -- **[B1Vs-r]** |dExtraV < 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 dVPosA = dTPosA + dNewVDelta table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B1Vs] dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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, 'V', dVPosA}) 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 dExtraY = dNewY - MyMinY -- **[B1Ys-r]** se pos. NewY è raggiungibile direttamente if dExtraY >= 0 then --dNewY > MyMinY 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 dYPosA = dTPosA + dNewYDelta table.insert( vCmd, { 1, 'Y', dYPosA}) -- **[B1Ys-xn]** se pos. NewY non è raggiungibile direttamente, ma ExtraY non è 'significativo' elseif -dExtraY <= 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 dYPosA = MyMinY table.insert( vCmd, { 1, 'Y', dYPosA}) -- [B1sY-nr.xs] ma ExtraY '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 = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- se non emessi movimenti, imposto posizione V if not bZmaxOk then -- risalita testa a Zmax bZmaxOk = EnsureZmax( bZmaxOk, vCmd) table.insert( vCmd, { 1, 'V', dVPosA}) end -- imposto stato carrelli, per eventuale uso pressori (sempre eseguita risalita Z) table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, CalcCharStatus( 'V', 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 : Y+V -> Y+V *** --------------------------------------------------------------------- function SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) EgtOutLog( ' *[B2] = Y+V -> Y+V', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y+V -> Y+V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) -- recupero le posizioni correnti local dYPosA = dTPosI + dYDeltaI local dVPosA = 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, 'Y', bFixedDelta) local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', 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 'ExtraY' e ExtraV' local dNewY = dTPosA + dNewYDelta local dNewV = dTPosA + dNewVDelta local dExtraY = dNewY - MyMinY -- < 0 => nuova pos. di Y 'non raggiungibile' local dExtraV = dNewV - MaxV -- > 0 => nuova pos. di V 'non raggiungibile' local bYxs = -dExtraY > dYDeltaTol/2 local bVxs = dExtraV > 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 + (dYPosA - MyMinY) dCorsaVr = dCorsaVTd -- ((MaxV-dNewV) non fa parte del recupero in quanto già disponibile!) bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr end end -- **[B2V-xsw]** posizione NewV non raggiungibile, con |dEXtraV > 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 dYPosA = dYPosA + dCorsaYd dVPosA = dVPosA - dCorsaVTd dTPosA = dTPosA - dCorsaVTd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **2:** accentro (Y+T) e V dYPosA = dYPosA - dCorsaYTr -- = MyMinY dTPosA = dTPosA - dCorsaYTr dVPosA = MaxV table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 ExtraV residuo dExtraV = dExtraV - dCorsaYTr - dCorsaVr -- **aggiorno i recuperi disponibili** riallontanando Y e (V+T) e riaccentrando (Y+T) e V dCorsaYfc = dCorsaY -- MaxY - dNewY dCorsaVfc = dCorsaV -- dNewV - MinV 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 dExtraV > 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 MaxV) if dExtraV > 0 then -- (ExtraV <= (CorsaYTr+CorsaVr) da ciclo precedente) --[B2Vs-xs] accentramento di V con |ExtraV 'significativo'| if bVxs then local dCorsaYTrA = dYPosA - MyMinY local dCorsaVra = MaxV - dVPosA -- **[B2Vs-xs1]** se posso recuperare ExtraV solo accentrando V e (Y+T) if dCorsaYTrA >= dExtraV 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 dYPosA = dYPosA - dExtraV dTPosA = dTPosA - dExtraV dVPosA = MaxV -- (pos. finale) dExtraV = 0 table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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' ExtraV... local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') local dYDispl1 = dYPos1 - dYPosA local dVDispl1 = dVPos1 - dVPosA --local dTDispl1 = dTPos1 - dTPosA local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) -- ...e anche possibilmente di posizionare Y alla posizione finale if dYDeltaDiff > 0 then dCorsaYfc = MaxY - dYPos1 dCorsaVfc = dVPos1 - MinV dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') --dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd-dYDispl1, dCorsaVTd+dVDispl1, 'V') dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') else dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 end table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **2: accentro** (Y+T) e V dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE dTPosA = dTPosA - dYDispl1 - dCorsaYTrA dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B2Vs-xs1/xs2] -- **[B2Vs-xn]** |dExtraV non 'significativo'| else EmitComment( vCmd, '[B2Vs-xn]') dExtraV = 0 -- ev' chiudo Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- 1: posiziono V assumendo maxV come pos. finale dVPosA = MaxV -- (pos finale) table.insert( vCmd, { 1, 'V', dVPosA}) end -- [B2Vs-xs/xn] -- **[B2Vs-r]** accentramento di |V| 'significativo' con pos.|'raggiungibile'| (= non oltre MaxV) 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) dVPosA = dTPosA + dNewVDelta dExtraV = 0 table.insert( vCmd, { 1, 'V', dVPosA}) end --[B2Vs] -- **[B2Vns]** accentramento di V non 'significativo'| else EmitComment( vCmd, '[B2Vns]') dExtraV = 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 + (MaxV - dVPosA) dCorsaYr = dCorsaYTd bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr end end -- **[B2Ys-xsw]** |-dEXtraY > 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 dYPosA = dYPosA + dCorsaYTd dTPosA = dTPosA + dCorsaYTd dVPosA = dVPosA - dCorsaVd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- |2:| accentro Y e (V+T) dYPosA = MyMinY -- = dYPosA - dCorsaYr dVPosA = dVPosA + dCorsaVTr -- = MaxV dTPosA = dTPosA + dCorsaVTr table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto Delta 'attuali' dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 ExtraY residuo dExtraY = dExtraY + dCorsaYr + dCorsaVTr -- aggiorno i recuperi disponibili riallontanando (Y+T) V e riaccentrando succ' Y e (V+T) dCorsaYfc = dCorsaY -- MaxY - dNewY dCorsaVfc = dCorsaV -- dNewV - MinV 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 -dExtraY > 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 MyMinY) if dExtraY < 0 then -- (-ExtraY <= (dCorsaYr + dCorsaVTr ) a ciclo precedente -- **[B2Ys-xs]** accentramento di Y con |'ExtraY 'significativo'| if bYxs then local dCorsaVTrA = MaxV - dVPosA local dCorsaYra = dYPosA - MyMinY -- **[B2Ys-xs1]** se posso recuperare ExtraY solo accentrando Y e (V+T) if dCorsaVTrA >= -dExtraY 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. dYPosA = MyMinY -- (pos. finale) dVPosA = dVPosA - dExtraY -- = +(-dEXtraY) dTPosA = dTPosA - dExtraY -- = +(-dEXtraY) dExtraY = 0 table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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' ExtraY... dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') local dYDispl1 = dYPos1 - dYPosA local dVDispl1 = dVPos1 - dVPosA local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) -- ...e anche possibilmente di posizionare V alla posizione finale if dVDeltaDiff < 0 then dCorsaYfc = MaxY - dYPos1 dCorsaVfc = dVPos1 - MinV dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') else dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 end table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) --dVDeltaA = dVPosA - dTPosA -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- |2:| accentro Y e (V+T) dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE dTPosA = dTPosA - dVDispl1 + dCorsaVTrA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B2Ys-xs1/xs2] -- **[B2Ys-xn]** |dExtraY non 'significativo'| else EmitComment( vCmd, '[B2Ys-xn]') dExtraY = 0 -- ev' chiudo V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- 1: posiziono Y assumendo MyMinY come pos. finale dYPosA = MyMinY -- (pos finale) table.insert( vCmd, { 1, 'Y', dYPosA}) end -- [B2Ys-xs/xn] --[B2Ys-r] accentramento di |Y| 'significativo' con pos.|'raggiungibile'| (non oltre MyMinY) 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) dYPosA = dTPosA + dNewYDelta dExtraV = 0 table.insert( vCmd, { 1, 'Y', dYPosA}) end --[B2Ys] -- [B2Yns] accentramento di V non 'significativo'| else EmitComment( vCmd, '[B2Yns]') dExtraV = 0 end --[B2Ys/ns] end --[B2Y] ( accentramento di V) -- ricalcolo gli 'spostamenti significativi' dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 dExtraY = dNewY - MyMinY -- **[B2CYs-r]** se posizione di |Y raggiungibile| if dExtraY >= 0 and dNewY <= MaxY 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 dYPosA = dNewY table.insert( vCmd, { 1, 'Y', dYPosA}) -- **[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 dExtraV = dNewV - MaxV -- **[B2CVs-r]** se posizione NewV raggiungibile if dExtraV <= 0 and dNewV >= MinV 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 dVPosA = dNewV table.insert( vCmd, { 1, 'V', dVPosA}) -- **[B2CVs-nr]** else -- se ExtraV > 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 = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- imposto stato carrelli, per eventuale uso pressori table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, CalcCharStatus( 'V', 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 V a entrambi i carrelli : V -> Y+V *** --------------------------------------------------------------------------------------------------------- function SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) EgtOutLog( ' *[B3] = V -> Y+V', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'V -> Y+V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) local dCorsaY = MaxY - MyMinY local dCorsaV = MaxV - MinV -- recupero le posizioni correnti local dVPosA = dTPosI + dVDeltaI local dYPosA = ParkY local dTPosA = dTPosI local dVDeltaA = dVDeltaI local dYDeltaA = dYPosA - 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, 'Y', bFixedDelta) local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', 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 dYPos, dVPos, dTPos local dNewY, dExtraY, bYxs local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw if bYDeltaS then -- definisco 'ExtraY' con (V+T) e Y accentrati q.b. per la presa di Y dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') dNewY = dTPos + dNewYDelta dExtraY = dNewY - MyMinY -- se < 0 pos. Y non direttamente 'raggiungibile' bYxs = -dExtraY > dYDeltaTol/2 -- ExtraY '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 = MaxY - dYPos dCorsaVfc = dVPos - MinV 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 + (MaxV - dVPos) dCorsaYr = dCorsaYTd bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr end -- inizializzo dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos end -- **[B3Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > 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, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo ev' Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- |2:| allontano (Y+T) e V quanto possibile dYPosA = dYPosA + dCorsaYTd dTPosA = dTPosA + dCorsaYTd dVPosA = dVPosA - dCorsaVd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- |3:| accentro (V+T) e Y dVPosA = dVPosA + dCorsaVTr dTPosA = dTPosA + dCorsaVTr dYPosA = MyMinY table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto i Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 ExtraY dExtraY = dExtraY + 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 -dExtraY > 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| -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) if dExtraY < 0 then --EmitComment( vCmd, '[B3Ys-x]') -- **[B3Ys-xs]** |ExtraY 'significativo'| if bYxs then --EmitComment( vCmd, '[B3Ys-xs]') local dCorsaVTrA = MaxV - dVPosA local dCorsaYra = dYPosA - MyMinY -- **[B3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) -- ulteriormente rispetto a YPos e Vpos definiti c.s. if dCorsaVTrA >= -dExtraY 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) dYPosA = MyMinY -- (pos. finale) dVPosA = dVPosA - dExtraY dTPosA = dTPosA - dExtraY dYDeltaA = dYPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dYDeltaA = dYPosA - 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' ExtraY... dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') local dYDispl1 = dYPos1 - dYPosA local dVDispl1 = dVPos1 - dVPosA local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) -- ...e anche di posizionare possibilmente V alla posizione finale if dVDeltaDiff < 0 then CorsaYfc = MaxY - dYPos1 dCorsaVfc = dVPos1 - MinV dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') else dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 end table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) -- chiudo il carrello V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **3: accentro** Y e (V+T) dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE dTPosA = dTPosA - dVDispl1 + dCorsaVTrA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B3Ys-xs1/-xs2] -- **[B3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| else --if -dExtraY < 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 dExtraY = 0 dYPosA = MyMinY -- (pos. finale) table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end --[B3Ys-xs/xn] -- **[B3Ys-r]** |dExtraY > 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 dYPosA = dTPosA + dNewYDelta table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [B3Ys] -- dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - 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 dExtraV = dNewV - MaxV -- **[B3Vs-x]** se pos. |NewV non è raggiungibile direttamente| (oltre MaxV) if dExtraV > 0 then --dNewV <= MaxV then -- **[B3Vs-xs]** |ExtraV 'significativo'| if dExtraV > dVDeltaTol /2 then EmitComment( vCmd, '[B3Vs-xs]') EgtOutLog( ' CLAMP : caso [B3Vs-xs] non gestito') error( ' CLAMP : caso [B3Vs-xs] non gestito') -- **[B3Vs-xn]** |ExtraV 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. dVPosA = MaxV table.insert( vCmd, { 1, 'V', dVPosA}) end -- [B3Vs-xs/xn] else -- **[B3Vs-r]** pos. |NewV raggiungibile direttamente| (non oltre MaxV) EmitComment( vCmd, '[B3Vs-r]') -- chiudo ev' Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- sposto il carrello V dVPosA = dNewV table.insert( vCmd, { 1, 'V', dVPosA}) 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 = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- se non emessi movimenti, imposto posizione Y if not bZmaxOk then -- risalita testa a Zmax bZmaxOk = EnsureZmax( bZmaxOk, vCmd) table.insert( vCmd, { 1, 'Y', dYPosA}) end -- imposto stato carrelli, per eventuale uso pressori (sempre effettuato movimento) table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) table.insert( vCmd, { 12, CalcCharStatus( 'V', 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 Y a V : Y -> V *** --------------------------------------------------------------------- function SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) EgtOutLog( ' *[C1] = Y -> V ', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y -> V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) -- recupero le posizioni correnti --local dCorsaY = MaxY - MyMinY --local dCorsaV = MaxV - MinV local dYPosA = dTPosI + dYDeltaI local dVPosA = ParkV local dTPosA = dTPosI local dYDeltaA = dYDeltaI local dVDeltaA = dVPosA - dTPosA local dNewVDelta -- = dVDeltaF -- tolleranza local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', 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/2 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 dYPos, dVPos, dTPos local dNewV, dExtraV, bVxs local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw if bVDeltaS then -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') dNewV = dTPos + dNewVDelta dExtraV = dNewV - MaxV bVxs = dExtraV > dVDeltaTol/2 -- ExtraV '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 = MaxY - dYPos dCorsaVfc = dVPos - MinV --local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' dDistBkN = EMC.LB - (dYPos-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 + (dYPos -MyMinY) dCorsaVr = dCorsaVTd bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr end -- inizializzo dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos end -- **[C1Vs-xsw]** posizione finale di V non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| -- con spostamento richiesto significativo e ExtraV significativo while bXsw do EmitComment( vCmd, '[C1Vs-xsw]') -- **1:** posiziono (Y+T) e V come calcolato sopra table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo ev' V e apro Y table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) -- **2:** allontano Y e (V+T) quanto possibile dYPosA = dYPosA + dCorsaYd dVPosA = dVPosA - dCorsaVTd dTPosA = dTPosA - dCorsaVTd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **3:** accentro (Y+T) e V dYPosA = dYPosA - dCorsaYTr -- = MyMinY dTPosA = dTPosA - dCorsaYTr dVPosA = MaxV table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto i Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- aggiorno la verifica di spostamento significativo bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) -- **aggiorno ExtraV** dExtraV = dExtraV - 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 dExtraV > dCorsaVr + dCorsaYTr end --[C1Vs-xw] -- **[C1Vs]** |spostamento| richiesto (ev' residuo) |di V| |'significativo'| if bVDeltaS then -- **[C1Vs-x]** posizione di |V non raggiungibile| if dExtraV > 0 then -- (dExtraV <= (CorsaYr+CorsaVr) da ciclo precedente) -- **[C1Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| if bVxs then local dCorsaYTrA = dYPosA - MyMinY -- **[C1Vs-xs1]** se posso recuperare dExtraV solo accentrando V e (Y+T) if dCorsaYTrA >= dExtraV 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 dYPosA = dYPosA - dExtraV dTPosA = dTPosA - dExtraV dVPosA = MaxV -- (pos. finale) dVDeltaA = dVPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) -- **[C1Vs-xs2]** dCorsaYTrA < dExtraV 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, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) dVDeltaA = dVPosA - 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 ExtraV dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dYDeltaA = dYPosA - 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) dYPosA = MyMinY dTPosA = dYPosA - dYDeltaA dVPosA = MaxV dVDeltaA = dVPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) end -- [C1Vs-xs1/xs2] -- **[C1Vs-xn]** |ExtraV 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 dExtraV = 0 dVPosA = MaxV -- pos. finale table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo V (?) table.insert( vCmd, { 12, 1}) end -- [C1Vs-xs/xn] -- **[C1Vs-r]** posizione di V 'raggiungibile' (ExtraV <= 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 dVPosA = dTPosA + dNewVDelta table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [C1V-s] -- **[C1Vns]** |spostamento| richIesto per V |non 'significativo'| else EmitComment( vCmd, '[C1Vns]') end -- calcolo i nuovi parametri di aggancio dVDeltaA = dVPosA - dTPosA -- chiudo ev' V e apro Y table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) table.insert( vCmd, { 11, 0}) -- sposto il carrello Y in parcheggio table.insert( vCmd, { 1, 'Y', ParkY}) -- 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 V : Y+V -> V *** --------------------------------------------------------------------- function SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) EgtOutLog( ' *[C2] = Y+V -> V', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Y+V -> V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) local dCorsaY = MaxY - MyMinY local dCorsaV = MaxV - MinV -- recupero le posizioni correnti dei carrelli local dYPosA = dTPosI + dYDeltaI local dVPosA = 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, 'V', 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/2 else dNewVDelta = dVDeltaA end -- definisco 'ExtraV' local dNewV = dTPosI + dNewVDelta local dExtraV = dNewV - MaxV -- > 0 se nuova pos. di V 'non raggiungibile' (= oltre MaxV) local bVxs = dExtraV > dVDeltaTol/2 -- 'ExtraV 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 = MaxY - dYPosA dCorsaVfc = dVPosA - MinV 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 + (dYPosA - MyMinY) dCorsaVr = dCorsaVTd bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr end end -- **[C2Vs-xsw]** posizione finale di V non raggiungibile, |con dEXtraV > 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 dYPosA = dYPosA + dCorsaYd dVPosA = dVPosA - dCorsaVTd dTPosA = dTPosA - dCorsaVTd table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- |3:| accentro (Y+T) e V dYPosA = dYPosA - dCorsaYTr dTPosA = dTPosA - dCorsaYTr dVPosA = MaxV table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) -- valuto i Delta ottenuti dYDeltaA = dYPosA - dTPosA dVDeltaA = dVPosA - dTPosA -- aggiorno la verifica di spostamento significativo bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) -- **aggiorno ExtraV** dExtraV = dExtraV - dCorsaYTr - dCorsaVr -- **aggiorno la valutazione di ulteriori corse disponibili** dCorsaYfc = MaxY - dYPosA dCorsaVfc = dVPosA - MinV dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') -- aggiorno i prossimi recuperi disponibili dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) dCorsaVr = dCorsaVTd -- aggiorno verifica per ripetizione del ciclo bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr end -- [C2V-xsw] -- **[C2Vs]** se lo |spostamento richiesto per V è significativo| if bVDeltaS then -- **[C2Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) if dExtraV > 0 then -- **[C2Vs-xs]** |ExtraV 'significativo'| if bVxs then local dCorsaYTrA = dYPosA - MyMinY -- **[C2Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) if dCorsaYTrA >= dExtraV 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 dYPosA = dYPosA - dExtraV dTPosA = dTPosA - dExtraV dVPosA = MaxV -- (pos. finale) dVDeltaA = dVPosA - dTPosA table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) 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 dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dYDeltaA = dYPosA - dTPosA -- chiudo il carrello Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **2: accentro** (Y+T) e V dYPosA = MyMinY dTPosA = dYPosA - dYDeltaA dVPosA = MaxV -- (pos. finale) table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [C2Vs-xs1/-xs2] -- **[C2Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| else --if dExtraV < 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 dExtraV = 0 dVPosA = MaxV -- (pos. finale) table.insert( vCmd, { 1, 'V', dVPosA}) end -- [C2s-xs/xn] -- **[C2Vs-r]** |dExtraV < 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 dVPosA = dTPosA + dNewVDelta table.insert( vCmd, { 1, 'V', dVPosA}) end --[C2Vs] -- **[C2Vns]** = |spostamento di V non significativo| else EmitComment( vCmd, '[C2Vns]') end --[C2Vs/n] -- calcolo il nuovo parametro di aggancio dVDeltaA = dVPosA - dTPosA -- chiudo eventualmente il carrello V e apro Y table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) table.insert( vCmd, { 11, 0}) -- sposto il carrello Y in parcheggio table.insert( vCmd, { 1, 'Y', ParkY}) -- 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 V a V : V -> V *** --------------------------------------------------------------------- function SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) EgtOutLog( ' *[C3] = V -> V', 1) -- elenco comandi local vCmd = {} -- Commento table.insert( vCmd, { 0, 'V -> V'}) -- se primo scambio local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) -- recupero le posizioni correnti dei carrelli local dVPosA = dTPosI + dVDeltaI local dYPosA = ParkY local dTPosA = dTPosI local dVDeltaA = dVDeltaI local dYDeltaA = dYPosA - dTPosA local dNewVDelta -- tolleranza local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) local bVDeltaS = (( dVDeltaF > dVDeltaA + dVDeltaTol and not bFixedPos) or dVDeltaF < dVDeltaA - DELTA_SIC) if bVDeltaS then dNewVDelta = dVDeltaF - dVDeltaTol / 2 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 'ExtraV' con (V+T) e Y accentrati q.b. per la presa con Y local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') local dNewV = dTPos + dNewVDelta local dExtraV = dNewV - MaxV -- effettuo spostamenti per predisporre all'aggancio di T con Y dYPosA = dYPos dVPosA = dVPos dTPosA = dTPos table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dYDeltaA = dYPosA - dTPosA -- **[C3Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) if dExtraV > 0 then -- **[C3Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| if dExtraV > 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 = MaxY - dYPos local dCorsaVfc = dVPos - MinV 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 + (dYPos - MyMinY) local dCorsaVr = dCorsaVTd -- **[C3Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| if dExtraV > ( dCorsaYTr + dCorsaVr) and bVDeltaS then EmitComment( vCmd, '[C3Vs-xsw]' .. 'CASO NON GESTITO') return end local dCorsaYTrA = dYPos - MyMinY -- !! att.ne: non dYPosA !! -- **[C3Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando (Y+T) e V -- (dalle posizione impostate sopra per l'aggancio di Y) if dCorsaYTrA >= dExtraV 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 dYPosA = dYPosA - dExtraV dTPosA = dTPosA - dExtraV dVPosA = MaxV -- (pos. finale) table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) dVDeltaA = dVPosA - dTPosA else -- **[C3Vs-xs2]** -- ci sarebbe un doppio movimento di V ? => caso impossibile ? EmitComment( vCmd, '[C3Vs-xs2]') -- **1:** posiziono (ulteriormente!) Y e (V+T) dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) dYDeltaA = dYPosA - dTPosA -- chiudo Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **2: accentro** (Y+T) e V dYPosA = MyMinY dVPosA = MaxV -- (pos. finale) dTPosA = dYPosA - dYDeltaA table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) end -- [C3Vs-xs1/-xs2] -- **[C3Vs-xn]** |dExtraV > 0 ma 'non significativo')| else --if dExtraV < DeltaToll/2 EmitComment( vCmd, '[C3Vs-xn]') -- chiudo Y e apro V table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- **1:** accentro V dExtraV = 0 dVPosA = MaxV -- (pos. finale) table.insert( vCmd, { 1, 'V', dVPosA}) end --[C3Vs-xs/xn] -- **[C3Vs-r]** |posizione di Y raggiungibile| (ExtraY >=0) -- (si esclude la possibilità di extra corsa oltre maxY) 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 dVPosA = dNewV table.insert( vCmd, { 1, 'V', dVPosA}) end -- [C3Vs] -- calcolo il nuovo parametro di aggancio dVDeltaA = dVPosA - dTPosA -- chiudo ev' V e apro Y table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) table.insert( vCmd, { 11, 0}) -- sposto il carrello Y in parcheggio table.insert( vCmd, { 1, 'Y', ParkY}) -- 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