-- Special Operations macchine standard ONE e PF by EgalWare s.r.l. 2023/11/24 -- Intestazioni require( 'EmtGenerator') EgtEnableDebug( false) -- Carico libreria local BD = require( 'BeamData') --------------------------------------------------------------------- -- *** Generic Machinings *** --------------------------------------------------------------------- require( 'EmtGenMachining') --------------------------------------------------------------------- -- *** Special GetPrevMachiningOffset *** --------------------------------------------------------------------- ----------------------------------------------------------------------------------------- function OnSpecialGetPrevMachiningOffset() -- Aggiorno posizione della testa della trave a seguito di movimenti delle pinze non previsti tra le fasi local function TPosUpdate() local nClId = EgtGetFirstNameInGroup( EMC.CURRMCHID, 'CL') -- recupero Id del gruppo CL della lavorazione corrente local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) -- Id del primo gruppo nella lavorazione (P1) if not nPathId then EMC.ERR = 12 EMC.MSG = ' Error : CL group path not found' return end local dAuxMoveCount = EgtGetInfo( nPathId, 'AS#', 'd') or 0 -- numero di movimenti ausiliari local dTRepos = nil -- controlla ogni gruppo di movimenti ausiliari for i = 1, dAuxMoveCount do local aAuxMove = EgtGetInfo( nPathId, 'AS' .. tostring( i), 'vs') or {} -- array contenete i parametri di ogni gruppo -- controlla solo i movimenti della testa trave e salva l'ultimo if aAuxMove[1] == '2' or aAuxMove[1] == '3' then for j = 2, #aAuxMove do if aAuxMove[j] == 'T' then dTRepos = aAuxMove[j+1] break end end end end return dTRepos end -- default EMC.ERR = 0 EMC.PREVOFFSX = 0 -- se c'è cambio di fase tra le lavorazioni (quindi la precedente è l'ultima della sua fase e la corrente la prima) if EMC.PREVPHASE ~= EMC.CURRPHASE then -- se la fase corrente è di inizio lavorazione di nuova trave if IsStartOrRestPhase( EMC.CURRPHASE) then -- recupero la posizione finale della lavorazione precedente local vPrevAx = EmtGetFinalAxesPos( EMC.PREVMCHID) -- ricava se e quanto la trave viene spostata tra le due fasi dai movimenti ausiliari e corregge l'offset di fine fase local dNewTPos = TPosUpdate() -- se ci sono dei movimenti della testa trave tra le due fasi ricava il delta tra la vecchia e la nuova posizione if dNewTPos then EMC.PREVOFFSX = dNewTPos - vPrevAx[1] -- oppure la X (L1) di questa corrisponde alla posizione iniziale della nuova trave, se ne deduce l'offset else EMC.PREVOFFSX = ParkV1 - vPrevAx[1] end end end end --------------------------------------------------------------------- -- *** Special Link moves *** --------------------------------------------------------------------- ----------------------------------------------------------------------------------------- local function IsPrevSplit() local sPrevUserNotes = '' if EMC.LINKTYPE == 2 then sPrevUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) elseif EMC.LINKTYPE == 3 then EgtSetCurrMachining( EMC.PREVMCHID) sPrevUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) EgtSetCurrMachining( EMC.NEXTMCHID) end return ( sPrevUserNotes:find( 'Split;', 1, true) ~= nil) end ----------------------------------------------------------------------------------------- local function IsLinkSafe( vPrec, vNext) local bSafeMove = true local DirectionsToTest = { { Z=vPrec[3], C=vPrec[4], B=vPrec[5]}, { Z=vNext[3], C=vNext[4], B=vNext[5]}} -- aggiungo anche il punto medio table.insert( DirectionsToTest, { Z=( vNext[3] + vPrec[3]) / 2, C=( vNext[4] + vPrec[4]) / 2, B=( vNext[5] + vPrec[5]) / 2}) for t=1, #DirectionsToTest do local vtToolDir = EgtGetCalcToolDirFromAngles( DirectionsToTest[t].C, DirectionsToTest[t].B) -- se testa standard if EMC.HEAD == 'H11' then -- TODO considerare caso sotto la traversa -- se sotto la traversa if vtToolDir:getX() > -0.1 then bSafeMove = true end -- se lama su aggregato elseif EMC.HEAD == 'H12' then -- se sotto la traversa if vtToolDir:getX() < 0.342 then local dLen = SawOffsZ - MillOffs local dToolRadius = 275 -- leggere dall'utensile!! local dNewOffZ = ( dLen * cos( DirectionsToTest[t].B) + dToolRadius * abs( sin( DirectionsToTest[t].B))) - dToolRadius local dMaxZ = ParkZ1 - dNewOffZ if dMaxZ < DirectionsToTest[t].Z then bSafeMove = false break end end end end return bSafeMove end ----------------------------------------------------------------------------------------- function OnSpecialLink() -- se fresa su testa 1 if EMC.HEAD == 'H11' then -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'FirstClimb=1;') -- se asse B resta girato verso home e C resta vicino alla home if abs( EMC.R2 - EMC.R2p) < 90 and abs( EMC.R1 - EMC.R1p) < 5 then ; -- discesa diretta elseif abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, 0}, 30, 2, 2) if abs( EMC.R1 - EMC.R1p) > 1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, 0}, 30, 2, 2) end end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0}, 30, 3, 2, 'FirstRise=1;') if abs( EMC.R1 - EMC.R1p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0}, 30, 3, 2) end else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2p}, 30, 3, 2, 'FirstRise=1;') end EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else -- recupero quota massima di collegamento local vFinalAxLink = EmtGetFinalAxesPos( EMC.PREVMCHID, EMC.PREVMAIN, false) local vInitAxLink = EmtGetInitialAxesPos( EMC.NEXTMCHID, EMC.NEXTMAIN, false) local bSafeMove = IsLinkSafe( vFinalAxLink, vInitAxLink) -- se gli assi rotanti non sono cambiati e il collegamento è come ultimo punto della lavorazione if abs( EMC.R1 - EMC.R1p) < 1 and abs( EMC.R2 - EMC.R2p) < 1 and abs( EMC.L3p - vFinalAxLink[3]) < 1 and abs( EMC.L3 - vInitAxLink[3]) < 1 then bSafeMove = true end -- se superata quota massima ammessa if not bSafeMove then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1, EMC.R1p, 0}, 30, 3, 2, 'UniqueRise=1;') -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, MaxZ1, EMC.R1, 0}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') end end -- se lama su rinvio standard o opposto di testa 1 elseif EMC.HEAD == 'H12' then -- recupero se split da note utente di lavorazione precedente local bSplit = IsPrevSplit() -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2p, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2) -- se assi cambiano di molto if abs( EMC.R1 - EMC.R1p) > 10 or abs( EMC.R2 - EMC.R2p) > 90 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, 0}, 30, 2, 2) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, 0}, 30, 2, 2) end if abs( EMC.R2) > 75 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkZ1, EMC.R1, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2) else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2p}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') end EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else -- recupero quota massima di collegamento local vFinalAxLink = EmtGetFinalAxesPos( EMC.PREVMCHID, EMC.PREVMAIN, false) local vInitAxLink = EmtGetInitialAxesPos( EMC.NEXTMCHID, EMC.NEXTMAIN, false) local bSafeMove = IsLinkSafe( vFinalAxLink, vInitAxLink) -- se gli assi rotanti non sono cambiati e il collegamento è come ultimo punto della lavorazione if abs( EMC.R1 - EMC.R1p) < 1 and abs( EMC.R2 - EMC.R2p) < 1 and abs( EMC.L3p - vFinalAxLink[3]) < 1 and abs( EMC.L3 - vInitAxLink[3]) < 1 then bSafeMove = true end -- se superata quota massima ammessa if not bSafeMove then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R2) > 91 then EmtAddRise( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1p, EMC.L2p, ParkZ1, EMC.R1p, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1Blade, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'LastRise=1;') else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1Blade, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'UniqueRise=1;') end -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, MaxZ1Blade, EMC.R1, 0}, 30, 2, 2, 'FirstClimb=1;') if abs( EMC.R2) > 91 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkZ1, EMC.R1, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') end end -- se sega a catena su testa 1 elseif EMC.HEAD == 'H13' or EMC.HEAD == 'H15' then -- recupero se split da note utente di lavorazione precedente local bSplit = IsPrevSplit() -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2p, EMC.L3p, EMC.R1p, EMC.R2p, EMC.R3}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, EMC.R2p, EMC.R3}, 30, 2, 2) if abs( EMC.R3) < 0.1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkCSaw0Z1, EMC.R1, EMC.R2, EMC.R3}, 30, 2, 2) else EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, EMC.R2, EMC.R3}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3}, 31, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2, EMC.R3p}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3p}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3p}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else end -- se aggregato foratore multiplo su testa 1 elseif EMC.HEAD == 'H17' then -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, 0}, 30, 2, 2) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, 0}, 30, 2, 2, 'LastClimb=1;') else EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'UniqueClimb=1;') end -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0, EMC.R3}, 30, 3, 2, 'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0, EMC.R3}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3}, 30, 3, 2, 'LastRise=1;') else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3}, 30, 3, 2, 'UniqueRise=1;') end end -- se fresa su testa 2 elseif EMC.HEAD == 'H21' then -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'FirstClimb=1;') -- se asse B resta girato verso home e C resta vicino alla home if abs( EMC.R2 - EMC.R2p) < 90 and abs( EMC.R1 - EMC.R1p) < 5 then ; -- discesa diretta elseif abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, 0}, 30, 2, 2) if abs( EMC.R1 - EMC.R1p) > 1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, 0}, 30, 2, 2) end end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0}, 30, 3, 2, 'FirstRise=1;') if abs( EMC.R1 - EMC.R1p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0}, 30, 3, 2) end else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2p}, 30, 3, 2, 'FirstRise=1;') end EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else -- recupero quota massima di collegamento local vLFiAx = EmtGetFinalAxesPos( EMC.PREVMCHID, EMC.PREVMAIN, false) local vLInAx = EmtGetInitialAxesPos( EMC.NEXTMCHID, EMC.NEXTMAIN, false) -- se superata quota massima ammessa if max( vLFiAx[3], vLInAx[3]) > ParkZ1 + 1 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1, EMC.R1p, 0}, 30, 3, 2, 'UniqueRise=1;') -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, MaxZ1, EMC.R1, 0}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') end end -- se lama su testa 2 elseif EMC.HEAD == 'H22' then -- recupero se split da note utente di lavorazione precedente local bSplit = IsPrevSplit() -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2p, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, EMC.R2p}, 30, 2, 2) -- se assi cambiano di molto if abs( EMC.R1 - EMC.R1p) > 10 or abs( EMC.R2 - EMC.R2p) > 90 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1p, 0}, 30, 2, 2) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, 0}, 30, 2, 2) end if abs( EMC.R2) > 75 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkZ1, EMC.R1, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2) else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2p}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') end EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2, 'LastRise=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R1 - EMC.R1p) > 1 or abs( EMC.R2 - EMC.R2p) > 1 then EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, 0}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2) else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2p}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')) end EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else -- recupero quota massima di collegamento local vFinalAxLink = EmtGetFinalAxesPos( EMC.PREVMCHID, EMC.PREVMAIN, false) local vInitAxLink = EmtGetInitialAxesPos( EMC.NEXTMCHID, EMC.NEXTMAIN, false) local bSafeMove = IsLinkSafe( vFinalAxLink, vInitAxLink) -- se gli assi rotanti non sono cambiati e il collegamento è come ultimo punto della lavorazione if abs( EMC.R1 - EMC.R1p) < 1 and abs( EMC.R2 - EMC.R2p) < 1 and abs( EMC.L3p - vFinalAxLink[3]) < 1 and abs( EMC.L3 - vInitAxLink[3]) < 1 then bSafeMove = true end -- se superata quota massima ammessa if not bSafeMove then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) if abs( EMC.R2) > 91 then EmtAddRise( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1p, EMC.L2p, ParkZ1, EMC.R1p, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1Blade, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'LastRise=1;') else EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, MaxZ1Blade, EMC.R1p, 0}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'UniqueRise=1;') end -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, MaxZ1Blade, EMC.R1, 0}, 30, 2, 2, 'FirstClimb=1;') if abs( EMC.R2) > 91 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkZ1, EMC.R1, EgtClamp( EMC.R2, -90, 90)}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2}, 30, 2, 2, 'LastClimb=1;') end end -- se sega a catena su testa 2 elseif EMC.HEAD == 'H23' then -- recupero se split da note utente di lavorazione precedente local bSplit = IsPrevSplit() -- se inizio lavorazione con prelievo utensile if EMC.LINKTYPE == 1 then -- approccio EmtRemoveClimb( EMC.NEXTMCHID, EMC.NEXTMAIN) EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2p, EMC.L3p, EMC.R1p, EMC.R2p, EMC.R3}, 30, 2, 2, 'FirstClimb=1;') EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, EMC.R2p, EMC.R3}, 30, 2, 2) if abs( EMC.R3) < 0.1 then EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, ParkCSaw0Z1, EMC.R1, EMC.R2, EMC.R3}, 30, 2, 2) else EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3p, EMC.R1, EMC.R2, EMC.R3}, 30, 2, 2) end EmtAddClimb( EMC.NEXTMCHID, EMC.NEXTMAIN, { EMC.L1, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3}, 31, 2, 2, 'LastClimb=1;') -- se fine lavorazione con deposito utensile elseif EMC.LINKTYPE == 2 then -- retrazione EmtRemoveRise( EMC.PREVMCHID, EMC.PREVMAIN) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2p, EMC.L3, EMC.R1p, EMC.R2, EMC.R3p}, 30, 3, 2, EgtIf( bSplit, 'Split=1;', '')..'FirstRise=1;') EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3p}, 30, 3, 2) EmtAddRise( EMC.PREVMCHID, EMC.PREVMAIN, { EMC.L1p, EMC.L2, EMC.L3, EMC.R1, EMC.R2, EMC.R3p}, 30, 3, 2, 'LastRise=1;') -- altrimenti collegamento tra due lavorazioni (3) else end end EMC.ERR = 0 end ---------- OnSpecialApplyDisposition & OnPostApplyMachining --------- ----------------------- Costanti ------------------------------------ local DELTA_SIC = 1 local MinJoin = BD.MIN_JOIN_S local MinOther = abs( MinY1) + abs( MaxY2) + MinJoin local SIC_V = 50 -- sicurezza da testa local MIN_FRONT_ENG_V = 152 -- ingombro asse Z con cremagliera a destra local MIN_BACK_ENG_V = 115 -- ingombro asse Z a sinistra local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza local MIN_CLAMP_5 = 150 -- minima presa con la pinza speciale (pinza 5) local SIC_CLAMP_5 = 50 -- sicurezza testa da pinza speciale local MAX_BACK_CLAMP_5 = EgtClamp( MaxBackClamp5 or 320, 200, 380) -- massima sporgenza posteriore del pezzo da pinza speciale ----------------------- Variabili ----------------------------------- local Test = false local SPLIT --------------------------------------------------------------------- local function PrepareClGroup( nParentId) local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') -- se non c'è, lo aggiungo if not nClId then nClId = EgtGroup( EMC.DISPID) if not nClId then return nil end EgtSetName( nClId, 'CL') -- altrimenti lo svuoto else EgtEmptyGroup( nClId) end return nClId end --------------------------------------------------------------------- local function IsStartOrRestPhase( nPhase) local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') return ( sVal == 'START' or sVal == 'REST') end --------------------------------------------------------------------- local function IsMidPhase( nPhase) local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') return ( sVal == 'MID') end --------------------------------------------------------------------- local function IsEndPhase( nPhase) local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') return ( sVal == 'END') end --------------------------------------------------------------------- local function IsMid2Phase( nPhase) local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') return ( sVal == 'MID2') end --------------------------------------------------------------------- local function IsEnd2Phase( nPhase) local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') return ( sVal == 'END2') end --------------------------------------------------------------------- local function GetNextStartOrRestPhase( nPhase) local nNextPhase = nPhase + 1 while nNextPhase <= EgtGetPhaseCount() do if IsStartOrRestPhase( nNextPhase) then break ; end nNextPhase = nNextPhase + 1 end return nNextPhase end --------------------------------------------------------------------- local function IsFirstMachiningOfStart( nMchId) -- se non è fase inizio di pezzo, ritorno risultato negativo if not IsStartOrRestPhase( EMC.PHASE) then return false end -- recupero la precedente operazione attiva local nPrevOperId = EgtGetPrevActiveOperation( nMchId) -- se non esiste o non è una disposizione, ritorno risultato negativo if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then return false end -- è la prima return true end --------------------------------------------------------------------- local function GetPhaseRot( nPhase) return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) end --------------------------------------------------------------------- local function IsLastOperationBeforeRotation( nMchId) -- se ultima fase o ultima fase del pezzo, ritorno risultato negativo if EMC.PHASE == EgtGetPhaseCount() or IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then return false end -- recupero la successiva operazione attiva local nNextOperId = EgtGetNextActiveOperation( nMchId) -- se non esiste o non è una disposizione, ritorno risultato negativo if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then return false end -- recupero le rotazioni della fase corrente e della prossima fase local nRot = GetPhaseRot( EMC.PHASE) local nNextRot = GetPhaseRot( EMC.PHASE + 1) -- ritorno se sono diverse return ( nRot ~= nNextRot) end --------------------------------------------------------------------- local function IsFirstMachiningAfterRotation( nMchId) -- se prima fase o prima fase del pezzo, ritorno risultato negativo if EMC.PHASE == 1 or IsStartOrRestPhase( EMC.PHASE) then return false end -- recupero la precedente operazione attiva local nPrevOperId = EgtGetPrevActiveOperation( nMchId) -- se non esiste o non è una disposizione, ritorno risultato negativo if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then return false end -- recupero le rotazioni della fase corrente e della fase precedente local nRot = GetPhaseRot( EMC.PHASE) local nPrevRot = GetPhaseRot( EMC.PHASE - 1) -- ritorno se sono diverse return ( nRot ~= nPrevRot) end --------------------------------------------------------------------- local function UpdateMinJoin() MinJoin = BD.GetMinJoin( EMC.SB, EMC.HB, EMC.LB) MinOther = abs( MinY1) + abs( MaxY2) + MinJoin end --------------------------------------------------------------------- local function GetCUTID() -- recupero CUTID del pezzo in lavoro local nOrd = GetPhaseOrd( EMC.PHASE) local nPartRawId local nRawId = EgtGetFirstRawPart() while nRawId do local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') if nRawOrd == nOrd then nPartRawId = nRawId break end nRawId = EgtGetNextRawPart( nRawId) end local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 return CutID end --------------------------------------------------------------------- local function GetPartId() -- recupero Id del pezzo in lavoro local nOrd = GetPhaseOrd( EMC.PHASE) local nPartId local nRawId = EgtGetFirstRawPart() while nRawId do local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') if nRawOrd == nOrd then nPartId = EgtGetFirstPartInRawPart( nRawId) break end nRawId = EgtGetNextRawPart( nRawId) end return nPartId end --------------------------------------------------------------------- local function GetNextRawInOrd( nCurrRawId) local nCurrOrd = EgtGetInfo( nCurrRawId, 'ORD', 'i') if not nCurrOrd then return end local nRawId = EgtGetFirstRawPart() while nRawId do local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') if nRawOrd == nCurrOrd + 1 then return nRawId end nRawId = EgtGetNextRawPart( nRawId) end end ----------------------------------------------------------------------- local function EnsureZmax( bCloseV, vCmd, nInd) -- verifico non sia già inserito nella lista dei comandi for i = 1, #vCmd do if vCmd[i][1] == 4 then -- se richiesta chiusura, eventuale inserimento se non già presente if bCloseV and vCmd[i][2] == 0 then vCmd[i][2] = 1 end return true end end -- posizionamento sicuro teste e rulli if not nInd then table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)}) else table.insert( vCmd, nInd, { 4, EgtIf( bCloseV, 1, 0)}) end return true end ----------------------------------------------------------------------- local function EmitComment( vCmd, sOut) EgtOutLog( ' ' .. sOut, 1) if Test then table.insert( vCmd, { 0, sOut}) end end --------------------------------------------------------------------- function OnSpecialApplyDisposition() EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***', 1) -- Inizializzo codice di errore EMC.ERR = 0 -- Campi obbligatori ma non usati EMC.HEAD = '' EMC.EXIT = 1 EMC.TCPOS = '' EMC.SHIFTS = 0 EMC.SBH = false -- Se disposizione da saltare non devo fare alcunché if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end -- Assegno flag di pezzo separato dal resto del grezzo SPLIT = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) -- Recupero il tipo dell'operazione successiva local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) -- Se ci sono lavorazioni successive non devo fare alcunché if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end -- Imposto gruppo e path di movimento local nClId = PrepareClGroup( EMC.DISPID) if not nClId then EMC.ERR = 3 EMC.MSG = ' Error : creation CL group failed' return end local nPathId = EgtGroup( nClId) if not nPathId then EMC.ERR = 6 EMC.MSG = ' Error : creation path in CL group failed' return end EgtSetName( nPathId, 'Empty') EMC.PATHID = nPathId EMC.SHIFTS = -1 -- Se l'operazione successiva è una disposizione con rotazione, devo preparare il pezzo alla rotazione if IsLastOperationBeforeRotation( EMC.DISPID) then -- aggiornamento posizioni if IsStartPhase( EMC.PHASE) then -- carico le posizioni local dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') local dPosY = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd') EMC.TPOS = dPosT EMC.Y1DELTA = dPosY - dPosT EMC.Y2DELTA = nil EMC.W2DELTA = nil EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') or ParkV1 EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') or ParkV2 EMC.CNT = 1 else local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) local nLastEntId = EgtGetLastInGroup( nLastPathId) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') EMC.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', 'd') EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 EMC.CNT = SpecGetCNT( EMC.DISPID) end -- Determinazione delle dimensioni del grezzo in lavoro local b3Raw = BBox3d() local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then b3Raw = EgtGetRawPartBBox( nRawId) break end nRawId = EgtGetNextRawPart( nRawId) end EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda EMC.HOVM = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 EMC.HCING = 0 EMC.TCING = EgtGetInfo( nRawId, 'TCING', 'd') or 0 -- Eseguo preparazione alla rotazione local vCmd = SpecCalcPreRot() SpecOutputCmds( vCmd, true) return end -- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo if nNextOpeType == MCH_OY.DISP and SPLIT and not IsEnd2Phase( EMC.PHASE) then -- aggiornamento posizioni local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) local nLastEntId = EgtGetLastInGroup( nLastPathId) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') EMC.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', 'd') EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 EMC.CNT = SpecGetCNT( EMC.DISPID) -- Determinazione delle dimensioni del grezzo in lavoro local b3Raw = BBox3d() local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then b3Raw = EgtGetRawPartBBox( nRawId) break end nRawId = EgtGetNextRawPart( nRawId) end EMC.LB = b3Raw:getDimX() EMC.HOVM = EgtGetInfo( nRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 -- Eseguo scarico local vCmd = SpecCalcUnload() SpecOutputCmds( vCmd, true) return end -- Verifico ci sia un solo grezzo nella fase corrente local nRawCount = 0 local nCurrRawId = GDB_ID.NULL local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then nRawCount = nRawCount + 1 nCurrRawId = nRawId end nRawId = EgtGetNextRawPart( nRawId) end if nRawCount > 1 then EMC.ERR = 10 EMC.MSG = ' Error : too many Raw Parts in current Phase' return end -- Determinazione delle sue dimensioni local b3Raw = EgtGetRawPartBBox( nCurrRawId) if b3Raw:isEmpty() then EMC.ERR = 11 EMC.MSG = ' Error : null Raw Part' return end EMC.LB = b3Raw:getDimX() EMC.SB = b3Raw:getDimY() EMC.HB = b3Raw:getDimZ() -- Aggiorno limiti di presa UpdateMinJoin() -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda EMC.HOVM = 0 EMC.HCING = 0 EMC.TCING = 0 -- Devo scaricare il grezzo rimasto (deve essere unico) -- Posizione trave local dPosT -- Se fase 1 o dopo rotazione eseguo carico con carrello Y local vCmd = {} if EMC.PHASE == 1 or IsEnd2Phase( EMC.PHASE) then dPosT = LoadT if IsEnd2Phase( EMC.PHASE) then dPosT = dPosT + TurnerOffs end vCmd = SpecCalcLoad( dPosT, 0, max( MinJoin + EgtIf( SPLIT, EMC.TCING, 0), EMC.LB - ( MaxY1 - MinY1) + 6)) -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza elseif IsStartOrRestPhase( EMC.PHASE) then -- recupero posizione trave e quota di aggancio carrello dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') local dPosY1 = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd') -- se carrello agganciato if dPosY1 then -- confermo i nuovi parametri di aggancio table.insert( vCmd, { 21, dPosY1 - dPosT, 0}) -- recupero posizione rulli EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 -- recupero contatore pinza 1 EMC.CNT = SpecGetCNT( EMC.DISPID) -- altrimenti è grezzo scaricato al carico e devo ricaricarlo else vCmd = SpecCalcLoad( dPosT, 0, max( MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6)) end -- altrimenti fase successiva pari else EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd') EMC.W2DELTA = nil EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') -- recupero contatore pinza 1 EMC.CNT = SpecGetCNT( EMC.DISPID) end -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V local vCmd2 = {} if IsStartOrRestPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then EMC.TPOS = dPosT SpecSetCarrPosFromCmds( vCmd) local dDistFront = EMC.LB - MinJoin + 10 * GEO.EPS_SMALL local dDistBack = 0 local dY2DeltaMinUL = EMC.LB + MinY2 - UnloadT vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL) if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then table.insert( vCmd, { 0, 'CARR_MOVE'}) end end -- eseguo scarico SpecSetCarrPosFromCmds( vCmd2) local vCmd3 = SpecCalcUnload() -- unisco ed emetto i comandi vCmd = EgtJoinTables( vCmd, vCmd2) vCmd = EgtJoinTables( vCmd, vCmd3) SpecOutputCmds( vCmd, true) end --------------------------------------------------------------------- function OnPostApplyMachining() -- Inizializzo codice di errore EMC.ERR = 0 -- Verifico se ultima lavorazione della fase local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) -- Agisco sui diversi percorsi della lavorazione local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) while nPathId do -- recupero id del successivo nPathId = EgtGetNext( nPathId) -- verifico se ultimo percorso di ultima lavorazione della fase local bLast = ( bMchLast and ( not nPathId)) -- se ultimo, elimino ritorno in home if bLast then EgtRemoveOperationHome( EMC.MCHID) end end end --------------------------------------------------------------------- function OnSpecialApplyMachining() EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 1) -- Inizializzo codice di errore EMC.ERR = 0 EMC.ZMAX = false EMC.ENDZMAX = false -- Verifico flag di separazione e fase di scarico local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) local bZMaxForced = false if EgtGetValInNotes( sNotes, 'StartZmax', 's') == 'FORCED' then bZMaxForced = true end -- si cancella eventuale flag per risalita in ZMAX sNotes = EgtSetValInNotes( sNotes, 'StartZmax') EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) local sPrevTool, dPrevValR3 -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) -- se precedente operazione non esiste, errore if not nPrevOpeId then EMC.ERR = 1 EMC.MSG = ' Error : previous Disposition not found' return -- se precedente operazione è disposizione elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then if EMC.PHASE == 1 or IsFirstMachiningAfterRotation( EMC.MCHID) then -- posizioni home EMC.TPOS = nil EMC.Y1DELTA = nil EMC.Y2DELTA = nil EMC.W2DELTA = nil EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 EMC.CNT = nil elseif IsStartOrRestPhase( EMC.PHASE) then -- carico le posizioni local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') local dPosY = EgtGetInfo( nPrevOpeId, 'Y1POS', 'd') -- se carrello agganciato if dPosY then EMC.TPOS = dPosT EMC.Y1DELTA = dPosY - dPosT EMC.Y2DELTA = nil EMC.W2DELTA = nil EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 EMC.CNT = SpecGetCNT( EMC.MCHID) -- altrimenti è grezzo scaricato al carico e devo ricaricarlo else EMC.TPOS = nil EMC.Y1DELTA = nil EMC.Y2DELTA = nil EMC.W2DELTA = nil EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 EMC.CNT = 1 end else -- aggiornamento posizioni (da lavorazione precedente a disposizione) local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) if not nPrev2OpeId then EMC.ERR = 1 EMC.MSG = ' Error : previous Disposition not found' return end local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) local nLastEntId = EgtGetLastInGroup( nLastPathId) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') EMC.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', 'd') EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 EMC.CNT = SpecGetCNT( EMC.MCHID) end -- altrimenti precedente operazione è lavorazione else -- aggiornamento posizioni local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) local nLastEntId = EgtGetLastInGroup( nLastPathId) local bAtZMax = ( EgtGetClEntMove( nLastEntId) == 0 and EgtGetClEntFlag( nLastEntId) == 3) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') EMC.W2DELTA = EgtGetInfo( nLastPathId, 'W2DELTA', 'd') EMC.V1POS = EgtIf( bAtZMax, ParkV1, EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1) EMC.V2POS = EgtIf( bAtZMax, ParkV2, EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2) EMC.CNT = SpecGetCNT( EMC.MCHID) if vAxes[6] then -- imposto lavorazione e utensile correnti EgtSetCurrMachining( nPrevOpeId) dPrevValR3 = vAxes[6] local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not sTool then local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) sTool = EgtTdbGetToolFromUUID( sTuuid) or '' end sPrevTool = sTool EgtSetCurrMachining( EMC.MCHID) end 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 bPreSplit = ( false and sNotes:find( 'Presplit', 1, true) ~= nil) local bSplitting = ( sNotes:find( 'Split', 1, true) ~= nil) local bPreCut = ( sNotes:find( 'Precut', 1, true) ~= nil) local bCutting = ( sNotes:find( 'Cut', 1, true) ~= nil) local bUnload = IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) -- Agisco sui diversi percorsi della lavorazione local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) while nPathId do -- assegno id percorso da elaborare EMC.PATHID = nPathId -- recupero id del successivo nPathId = EgtGetNext( nPathId) -- verifico se ultimo percorso di ultima lavorazione della fase local bLast = ( bMchLast and ( not nPathId)) -- se ultimo, elimino ritorno in home -- if bLast then EgtRemoveOperationHome( EMC.MCHID) end -- salvo lo stato dei carrelli local OriTPos = EMC.TPOS local OriY1Delta = EMC.Y1DELTA local OriY2Delta = EMC.Y2DELTA local OriW2Delta = EMC.W2DELTA local OriV1Pos = EMC.V1POS local OriV2Pos = EMC.V2POS local OriCnt = EMC.CNT -- eseguo le elaborazioni SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) -- se separazione, verifico il risultato if bSplitting then -- recupero CUTID del pezzo in lavoro local CutID = GetCUTID() -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali if EMC.ERR == 18 then -- segnalazione warning EMC.ERR = -101 EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' -- ripristino lo stato originale dei carrelli EMC.TPOS = OriTPos EMC.Y1DELTA = OriY1Delta EMC.Y2DELTA = OriY2Delta EMC.W2DELTA = OriW2Delta EMC.V1POS = OriV1Pos EMC.V2POS = OriV2Pos EMC.CNT = OriCnt -- eseguo le elaborazioni SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) -- pinzaggio ancora impossibile, pezzo a caduta if EMC.ERR == 18 then -- segnalazione warning EMC.ERR = -102 EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' end -- scarico standard elseif EMC.ERR == 0 then -- segnalazione warning EMC.ERR = -100 EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' end -- se taglio del residuo finale, scarico standard elseif bCutting then -- recupero CUTID del pezzo in lavoro local CutID = GetCUTID() -- se non ci sono errori, segnalazione warning if EMC.ERR == 0 then EMC.ERR = -100 EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' end end if EMC.ERR > 0 then return end -- determino la posizione finale della trave local nLastEntId = EgtGetLastInGroup( EMC.PATHID) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end -- controllo se serve cambiare la presa if vAxes[6] and dPrevValR3 then local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not sTool then local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) sTool = EgtTdbGetToolFromUUID( sTuuid) or '' end -- se stesso utensile ma cambia la presa dell'aggregato if sTool == sPrevTool and abs( dPrevValR3 - vAxes[6]) > 10 * GEO.EPS_SMALL then EMC.CHANGETAKE = true end end end -- Se richiesto movimento preliminare della testa a Zmax perchè c'è stato un riposizionamento delle pinze if EMC.ZMAX or bZMaxForced then sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 11) EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end if EMC.CHANGETAKE then sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 12) EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end end --------------------------------------------------------------------- function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) -- mi salvo info lavorazione su una lista local AuxInfoMach = {} AuxInfoMach.bPreSplit = bPreSplit AuxInfoMach.bSplitting = bSplitting AuxInfoMach.bPreCut = bPreCut AuxInfoMach.bCutting = bCutting AuxInfoMach.bUnload = bUnload -- Assegno flag di pezzo separato dal resto del grezzo SPLIT = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro local b3Tot = BBox3d() local b3Raw = BBox3d() local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) local nRawId = EgtGetFirstRawPart() local nCurrRawId = GDB_ID.NULL while nRawId do if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then local b3Tmp = EgtGetRawPartBBox( nRawId) b3Tot:Add( b3Tmp) if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then b3Raw = b3Tmp nCurrRawId = nRawId end end nRawId = EgtGetNextRawPart( nRawId) end if b3Tot:isEmpty() then EMC.ERR = 11 EMC.MSG = ' Error : null Raw Parts' return end EMC.LB = EgtIf( SPLIT, b3Raw:getDimX(), b3Tot:getDimX()) EMC.SB = b3Tot:getDimY() EMC.HB = b3Tot:getDimZ() EMC.LT = b3Raw:getDimX() EgtOutLog( ' BarLen='..EgtNumToString( EMC.LB, 1), 3) -- Aggiorno limiti di presa UpdateMinJoin() -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 -- Recupero ingombro dei tagli di testa del prossimo pezzo (se esiste) EMC.NEXT_HCING = 0 local nNextRawId = GetNextRawInOrd( nCurrRawId) if nNextRawId then EMC.NEXT_HCING = EgtGetInfo( nNextRawId, 'HCING', 'd') or 0 end -- Calcolo dell'ingombro della lavorazione local dDistFront, dDistBack, dRollFront, dRollBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) if not dDistFront then return end local dMaxLenLeft = 0 if bPreSplit or bSplitting then local dDistF, dDistB, dRollF, dRollB, dMaxLF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) dDistFront = min( dDistFront, dDistF) -- Se split prima di rotazione, devo lasciare dietro spazio per scambio carrelli if bSplitting and IsMid2Phase( EMC.PHASE + 1) then dDistFront = min( dDistFront, EMC.LT - MinOther) end dDistBack = dDistBack if bSplitting then dMaxLenLeft = dMaxLF end elseif bPreCut or bCutting then local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) dDistFront = min( dDistFront, dDistF) dDistBack = min( dDistBack, dDistB) end -- Eventuale aggiuntivo al carico su distanza Back (finchè non c'è un riposizionamento carrelli) if EMC.CNT == 1 or not EMC.TPOS then dDistBack = dDistBack - AggLoad end -- Verifico lunghezza pezzo if not SPLIT and not VerifyPartLength() then return end -- Calcolo quali carrelli sono necessari local nChar if bPreSplit or bSplitting then nChar = 2 elseif bPreCut or bCutting then nChar = 3 end local dY1DeltaMaxSP if nChar == 2 then dY1DeltaMaxSP = MaxY1 - LoadT + EMC.LT end local dY2DeltaMinUL if nChar == 2 or nChar == 3 or IsEnd2Phase( EMC.PHASE) then dY2DeltaMinUL = EMC.LT + MinY2 - UnloadT end local vSaveCmd -- Se inizio o appena dopo rotazione, eseguo il carico if not EMC.TPOS then local dPosT = LoadT if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin + EgtIf( SPLIT, EMC.TCING, 0), EMC.LB - ( MaxY1 - MinY1) + 6)) local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) if bSplitting and EMC.ERR == 18 then table.insert( vCmd, { 22, dRollBack, -dRollFront}) end if vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then table.insert( vCmd, { 0, 'CARR_MOVE'}) end EgtJoinTables( vCmd, vCmd2) SpecOutputCmds( vCmd) vSaveCmd = vCmd -- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli elseif not IsEndPhase( EMC.PHASE) then local vCmd = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) -- se fase iniziale e ci sono stati movimenti di carrelli if IsStartPhase( EMC.PHASE) and #vCmd > 0 and IsFirstMachiningOfStart( EMC.MCHID) and not bPreSplit and not bSplitting and not bPreCut and not bCutting then local dLastTPos, dLastY1Delta = GetLastTPos( vCmd) -- se testa oltre lo zero if dLastTPos and dLastTPos < 0 then -- si sposta testa in posizione carico table.insert( vCmd, { 24, 'T', ParkV1, 'Y1', ParkV1 + dLastY1Delta}) end -- Se non ci sono spostamenti, confermo i parametri di aggancio e di posizione roller elseif SpecTestOnlyRemarkInCmds( vCmd) then table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) table.insert( vCmd, { 22, dRollBack, -dRollFront}) end SpecOutputCmds( vCmd) vSaveCmd = vCmd -- Altrimenti, non muovo i carrelli rispetto alla trave ma impongo la posizione dei rulli else SpecOutputCNT() local vCmd = {} table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) table.insert( vCmd, { 22, dRollBack, -dRollFront}) SpecOutputCmds( vCmd) vSaveCmd = vCmd end -- Se taglio di separazione local vCmd = {} if bSplitting then -- rimuovo eventuale vecchia info di Skip local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL EgtRemoveInfo( NextDispId, 'SKIP') -- verifico che la barra sia agganciata al secondo carrello if not EMC.Y2DELTA then local dTLen = EMC.LT - EMC.HOVM - BD.OVM_MID local dRefIng = EgtIf( dTLen < 350, 120, EgtIf( dTLen < 550, 150, 200)) local dClampLen = dTLen - min( EMC.HCING + EMC.TCING, dRefIng) -- se pinza 5, presa ammissibile e pezzo con dimensioni nei limiti if Clamp5 and dClampLen > MIN_CLAMP_5 + SIC_CLAMP_5 - 10 * GEO.EPS_SMALL and EMC.SB > MinWOpen - 10 * GEO.EPS_SMALL and EMC.SB < MaxWOpen + 10 * GEO.EPS_SMALL and EMC.HB < MaxWHeight + 10 * GEO.EPS_SMALL then EgtOutLog( ' Warning SPLITTING -> separazione con uso pinza speciale') SpecOutputCNT() -- reset errore EMC.ERR = 0 local dDeltaW = EgtGetValInNotes( EgtGetInfo( GetPartId() or GDB_ID.NULL, 'COMMENT') or '', 'DeltaW') or 0 local dDeltaP5 = EMC.LT - BD.OVM_MID - min( EMC.TCING, 0.5 * dRefIng) - SIC_CLAMP_5 - 0.4 * max( dClampLen - MIN_CLAMP_5 - SIC_CLAMP_5, 0) dDeltaP5 = max( dDeltaP5, EMC.LT- BD.OVM_MID - MAX_BACK_CLAMP_5) + dDeltaW local vCmd = vSaveCmd table.insert( vCmd, { 23, dDeltaP5}) SpecOutputCmds( vCmd) EgtOutLog( ' DeltaP5='..EgtNumToString( dDeltaP5, 1)..' DeltaW = '..EgtNumToString( dDeltaW, 1), 1) -- imposto risalita a Zmax se lavorazione successiva è ancora una fresatura con la stessa lama (per essere sicuro di evitare collisioni) local NextMachId = EgtGetNextActiveOperation( EgtGetNextActiveOperation( EMC.MCHID) or GDB_ID.NULL) if NextMachId and EgtGetOperationType( NextMachId) == MCH_OY.MILLING then -- salvo lavorazione e utensile correnti, per ripristinarli alla fine local nOrigMchId = EgtGetCurrMachining() local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) -- imposto lavorazione e utensile correnti EgtSetCurrMachining( NextMachId) local sTool = EgtGetMachiningParam( MCH_MP.TOOL) -- se utensile non cambiato if sTool and EgtTdbSetCurrTool( sTool) and sTool == sOrigTool then -- imposto risalita a Zmax local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 2) EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end -- ripristino lavorazione e utensile correnti if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end end -- altrimenti separazione con caduta else EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') SpecOutputCNT() -- forzo errore 18 EMC.ERR = 18 if IsEndPhase( EMC.PHASE + 1) then EgtSetInfo( NextDispId, 'SKIP', '1') local NextOpeId = EgtGetNextOperation( NextDispId) while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do EgtSetOperationMode( NextOpeId, false) NextOpeId = EgtGetNextOperation( NextOpeId) end end end -- verifico che la barra sia agganciata anche al primo carrello elseif not EMC.Y1DELTA then EMC.ERR = 19 EMC.MSG = ' Error SPLIT : Y1 or Y2 not clamped' return false end -- eseguo la separazione EgtOutLog( 'MaxLenLeft=' .. EgtNumToString( dMaxLenLeft, 1), 1) if not IsMid2Phase( EMC.PHASE + 1) then vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft) else vCmd = SpecCalcSplitRot( b3Raw:getDimX(), dMaxLenLeft) end end -- Se taglio finale di grezzo a perdere if bCutting then -- salvo distanza carrello Y2 da inizio grezzo rimasto nella disposizione della prossima fase local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) if NextDispId then EgtSetInfo( NextDispId, 'Y2POS', EMC.Y2DELTA) EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) end end -- Se previsto scarico, lo eseguo if bUnload then EMC.LB = b3Raw:getDimX() local vCmdTmp = SpecCalcUnload() vCmd = EgtJoinTables( vCmd, vCmdTmp) end -- Se ritorno al carico per rotazione if bPreRotMch then -- determino posizione testa trave local nLastEntId = EgtGetLastInGroup( EMC.PATHID) local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end -- eseguo movimento prima di rotazione local vCmdTmp = SpecCalcPreRot() vCmd = EgtJoinTables( vCmd, vCmdTmp) end -- Emetto eventuali comandi di separazione e/o scarico if #vCmd > 0 then SpecOutputCmds( vCmd, true) end end --SpecApplyPath( bLast) --------------------------------------------------------------------- function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) -- gruppi della lavorazione local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) if not nPathId then EMC.ERR = 12 EMC.MSG = ' Error : CL group path not found' return end -- recupero ptMin ptMax della lavorazione local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') if not ptMin or not ptMax then EMC.ERR = 13 EMC.MSG = ' Error : machining Min or Max not found' return end -- se pre-taglio, aggiorno ptMax con quello del taglio finale if bPreCut then local ptFinMax = GetFinalCutPmax( nMchId) if ptFinMax then ptMax = ptFinMax end end -- Recupero testa local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) -- Recupero minimi e massimi degli assi macchina della lavorazione local vAxMin = EgtGetInfo( nClId, 'MAXMIN', 'vd') local vAxMax = EgtGetInfo( nClId, 'MAXMAX', 'vd') if not vAxMin or not vAxMax or #vAxMin < 5 or ( ( sHead == 'H13' or sHead == 'H15' or sHead == 'H23') and #vAxMin < 6) then EMC.ERR = 15 EMC.MSG = ' Error : machine axes Min or Max not found' return end local vAxMid = {} for i = 1, #vAxMin do vAxMid[i] = ( vAxMin[i] + vAxMax[i]) / 2 end -- Calcolo dell'ingombro della testa rispetto allo Zero Macchina local b3Enc if sHead ~= 'H21' and sHead ~= 'H22' and sHead ~= 'H23' then EgtSetAxisPos( 'C1', vAxMid[4]) EgtSetAxisPos( 'B1', vAxMid[5]) if sHead == 'H13' or sHead == 'H15' then EgtSetAxisPos( 'A', vAxMid[6]) end b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE) else EgtSetAxisPos( 'C2', vAxMid[4]) EgtSetAxisPos( 'B2', vAxMid[5]) if sHead == 'H23' then EgtSetAxisPos( 'A', vAxMid[6]) end b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), GDB_BB.ONLY_VISIBLE) end -- Forzo la distanza di sicurezza da utensile local nSecRollerDist = EgtGetValInNotes( EgtTdbGetCurrToolParam( MCH_TP.USERNOTES), 'SECDIST', 'i') or SIC_V local dRollFront = max( b3Enc:getMax():getX(), MIN_FRONT_ENG_V) + nSecRollerDist local dRollBack = max( -b3Enc:getMin():getX(), MIN_BACK_ENG_V) + nSecRollerDist EgtOutLog( ' RollFront = ' .. EgtNumToString( dRollFront, 1) .. ' RollBack = ' .. EgtNumToString( dRollBack, 1), 3) -- Calcolo della posizione della Punta Utensile rispetto allo Zero Macchina local ptTip ptTip = EgtGetCalcTipFromPositions( 0, 0, 0, vAxMid[4], vAxMid[5], vAxMid[6] or 0, false) EgtOutLog( ' ToolTip = ' .. tostring( ptTip), 5) -- Calcolo dell'ingombro della testa rispetto alla Punta Utensile local dHeadFront = dRollFront + AGG_V - ptTip:getX() local dHeadBack = dRollBack + AGG_V + ptTip:getX() EgtOutLog( ' HeadFront = ' .. EgtNumToString( dHeadFront, 1) .. ' HeadBack = ' .. EgtNumToString( dHeadBack, 1), 5) -- Distanze limiti della pinza di destra da testa trave e della pinza di sinistra da coda trave local dDistFront = - ptMax:getX() - LoadT - dHeadFront local dDistBack = ptMin:getX() + LoadT + EMC.LB - dHeadBack EgtOutLog( ' DistFront = ' .. EgtNumToString( dDistFront, 1) .. ' DistBack = ' .. EgtNumToString( dDistBack, 1), 3) return dDistFront, dDistBack, dRollFront, dRollBack end --------------------------------------------------------------------- function SpecialCalcPhaseEncumbrance( nPhase) -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) local dDistFront = EMC.LB local dDistBack = EMC.LB local dRollFront = 0 local dRollBack = 0 local dMaxLenLeft = 0 -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine local nOrigMchId = EgtGetCurrMachining() local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) -- Ciclo sulle lavorazioni local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) while nMchId and EgtGetOperationPhase( nMchId) == nPhase do -- imposto lavorazione e utensile correnti EgtSetCurrMachining( nMchId) local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not sTool or not EgtTdbSetCurrTool( sTool) then local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) sTool = EgtTdbGetToolFromUUID( sTuuid) or '' EgtTdbSetCurrTool( sTool) end local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) EgtSetCalcTool( sTool, sHead, 1) -- calcolo ingombri local dDistF, dDistB, dRollF, dRollB = SpecialCalcMachiningEncumbrance( nMchId) if dDistF and dDistB then dDistFront = min( dDistFront, dDistF) dDistBack = min( dDistBack, dDistB) dRollFront = max( dRollFront, dRollF) dRollBack = max( dRollBack, dRollB) local dMaxLenL = EMC.LT - dDistF - AGG_V - dRollF EgtOutLog( ' MaxLenLeft = ' .. EgtNumToString( dMaxLenL, 1), 3) dMaxLenLeft = max( dMaxLenLeft, dMaxLenL) end nMchId = EgtGetNextActiveOperation( nMchId) end -- Ripristino lavorazione e utensile correnti if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end if sOrigTool and sOrigHead then EgtSetCalcTool( sOrigTool, sOrigHead, 1) end -- Restituisco gli ingombri trovati return dDistFront, dDistBack, dRollFront, dRollBack, dMaxLenLeft end --------------------------------------------------------------------- function GetFinalCutPmax( nMchId) local nFinalCutId local nId = EgtGetNextActiveOperation( nMchId) while nId and EgtGetOperationPhase( nId) == EMC.PHASE do nFinalCutId = nId nId = EgtGetNextActiveOperation( nId) end if not nFinalCutId then return end local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') if not nCLId then return end return EgtGetInfo( nCLId, 'MMAX', 'p') end --------------------------------------------------------------------- function VerifyPartLength() -- Verifico lunghezza pezzo if EMC.LB < MinJoin + MinOther + AggLoad + EMC.HCING + EMC.HOVM then EMC.ERR = 17 EMC.MSG = ' Error CLAMP : part too short' return false end return true end --------------------------------------------------------------------- function GetLastTPos( vCmd) -- se esiste tabella comandi, si cerca l'ultima posizione della trave if vCmd and #vCmd > 0 then local dTRepos = nil local dLastY1Delta = nil -- controlla ogni gruppo di movimenti ausiliari for i = 1, #vCmd do local Command = vCmd[i] -- controlla solo i movimenti della testa trave e salva l'ultimo if Command[1] == 2 or Command[1] == 3 then for j = 2, #Command-1 do if Command[j] == 'T' then dTRepos = Command[j+1] break end end elseif Command[1] == 21 then dLastY1Delta = Command[2] end end return dTRepos, dLastY1Delta else return nil, nil end end --------------------------------------------------------------------- function SpecCalcLoad( dPosT, dDistFront, dDistBack) --[L] local dNewY1min = max( EMC.LB - dDistBack, MinOther + AggLoad + EMC.HCING + EMC.HOVM) local dNewY1max = min( ( MaxY1 - MinY1) - 5, EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0)) if dNewY1min > dNewY1max then return nil end local dNewY1Delta = dNewY1max local dNewY2Delta = nil local dNewY1 = dPosT + dNewY1Delta local vCmd = {} EgtOutLog( ' *[L]', 1) -- [L-1] if dNewY1 + TurnerOffs - MaxY1 > 0 then dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs) EgtOutLog( ' *[L1]', 1) end --[L-2] if EMC.LB - dNewY1Delta < MinJoin then dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs) EgtOutLog( ' *[L2]', 1) end -- Commento table.insert( vCmd, { 0, 'Loading'}) -- posizionamento sicuro teste e rulli EnsureZmax( false, vCmd) -- Apro entrambe le morse table.insert( vCmd, { 11, 0}) EMC.CNT = nil table.insert( vCmd, { 12, 0}) -- Sposto il carrello Y per il carico table.insert( vCmd, { 2, 'Y1', dPosT + dNewY1Delta, 'Y2', ParkY2}) -- Chiudo morsa Y table.insert( vCmd, { 11, 1}) -- Sposto il carrello Y con la testa trave al parcheggio V1 table.insert( vCmd, { 2, 'T', ParkV1, 'Y1', ParkV1 + dNewY1Delta}) -- confermo i nuovi parametri di aggancio table.insert( vCmd, { 21, dNewY1Delta, 0}) -- Inizializzo contatore globale EMC.CNT = 1 SpecOutputCNT() -- Assegno stato corrente EMC.TPOS = ParkV1 EMC.Y1DELTA = dNewY1Delta EMC.Y2DELTA = nil EMC.W2DELTA = nil EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 -- Restituisco i comandi return vCmd end -- SpecAdjustLoad [L] --------------------------------------------------------------------- function SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar, AuxInfoMach) local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AggLoad, 0) local sMaxSplit = '' if dY1DeltaMaxSP then sMaxSplit = '/'..EgtNumToString( dY1DeltaMaxSP, 1)..'(MaxSplit)' end local sMinUnload = '' if dY2DeltaMinUL then sMinUnload = '/'..EgtNumToString( dY2DeltaMinUL, 1)..'(MinUnload)' end EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit .. ' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3) local bBackOk = ( dDistBack > MinJoin + EgtIf( SPLIT, EMC.TCING, 0) - GEO.EPS_SMALL) local bFrontOk = ( dDistFront > MinFrontJoin - GEO.EPS_SMALL) -- [A] se non richiesto solo carrello Y2 e posso mettere solo carrello Y1 if ( nChar ~= 2 and nChar ~= 3 and bBackOk) or ( nChar == 2 and bBackOk and not bFrontOk) then local WorkTab = {} WorkTab.dTPosI = EMC.TPOS WorkTab.dY1DeltaI = EMC.Y1DELTA WorkTab.dY2DeltaI = EMC.Y2DELTA WorkTab.dV1PosI = EMC.V1POS WorkTab.bV1CloseI = false WorkTab.dV2PosI = EMC.V2POS WorkTab.bV2CloseI = false WorkTab.dTPosF = nil WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM) WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0), MaxY1 + dDistFront + dRollFront + AGG_V) WorkTab.dY2DeltaMinF = nil WorkTab.dY2DeltaMaxF = nil if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end WorkTab.dV1PosF = dRollBack WorkTab.bV1CloseF = false WorkTab.dV2PosF = -dRollFront WorkTab.bV2CloseF = false -- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF) end end -- verifico validità intervallo ammesso per Y1 if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then EMC.ERR = 18 EMC.MSG = ' Error : CLAMP Y1 impossible' return {} end -- al carico o con prima lavorazione di un pezzo si deve ignorare l'ingombro delle lavorazioni di testa per il pinzaggio if EMC.LOAD or IsFirstMachiningOfStart( EMC.MCHID) then EMC.HCING = 0 end return SpecAdjustCarriages( WorkTab) -- [B] se richiesti entrambi e posso metterli elseif nChar == 2 and bBackOk and bFrontOk then local WorkTab = {} WorkTab.dTPosI = EMC.TPOS WorkTab.dY1DeltaI = EMC.Y1DELTA WorkTab.dY2DeltaI = EMC.Y2DELTA WorkTab.dV1PosI = EMC.V1POS WorkTab.bV1CloseI = false WorkTab.dV2PosI = EMC.V2POS WorkTab.bV2CloseI = false WorkTab.dTPosF = nil WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING) WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0), MaxY1 + dDistFront + dRollFront + AGG_V) WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dDistBack - AGG_V - dRollBack) WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end WorkTab.dV1PosF = dRollBack WorkTab.bV1CloseF = false WorkTab.dV2PosF = -dRollFront WorkTab.bV2CloseF = false -- dopo che si è calcolato il minimo e massimo dell'intervallo, verifico che in testa rimanga almeno il minimo per poter fare passaggio pinze e scaricare if AuxInfoMach and ( AuxInfoMach.bSplitting or AuxInfoMach.bCutting) then if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST and WorkTab.dY1DeltaMaxF > EMC.LT + BD.MINRAW_S + BD.CHAR_EXTRA_DIST then WorkTab.dY1DeltaMinF = max( min( EMC.LT + BD.MINRAW_S, WorkTab.dY1DeltaMaxF - 1), WorkTab.dY1DeltaMinF) end end -- verifico validità intervallo ammesso per Y1 if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then EMC.ERR = 18 EMC.MSG = ' Error : CLAMP Y1 impossible' return {} end -- verifico validità intervallo ammesso per Y2 if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then EMC.ERR = 18 EMC.MSG = ' Error : CLAMP Y2 impossible' return {} end return SpecAdjustCarriages( WorkTab) -- [C] se non richiesti entrambi e posso mettere carrello Y2 elseif bFrontOk then local WorkTab = {} WorkTab.dTPosI = EMC.TPOS WorkTab.dY1DeltaI = EMC.Y1DELTA WorkTab.dY2DeltaI = EMC.Y2DELTA WorkTab.dV1PosI = EMC.V1POS WorkTab.bV1CloseI = false WorkTab.dV2PosI = EMC.V2POS WorkTab.bV2CloseI = false WorkTab.dTPosF = nil WorkTab.dY1DeltaMinF = nil WorkTab.dY1DeltaMaxF = nil WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dDistBack - AGG_V - dRollBack) WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end WorkTab.dV1PosF = dRollBack WorkTab.bV1CloseF = false WorkTab.dV2PosF = -dRollFront WorkTab.bV2CloseF = false -- verifico validità intervallo ammesso per Y2 if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then EMC.ERR = 18 EMC.MSG = ' Error : CLAMP Y2 impossible' return {} end return SpecAdjustCarriages( WorkTab) -- altrimenti errore else if EgtGetDebugLevel() < 3 then EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. ' MinJoin=' .. EgtNumToString( MinJoin) .. ' MinFrontJoin=' .. EgtNumToString( MinFrontJoin)) end EMC.ERR = 18 EMC.MSG = ' Error : CLAMP impossible' return {} end end --------------------------------------------------------------------- function SpecCalcSplit( dLenRaw, dMaxLenLeft) local vCmd = {} EgtOutLog( ' *[S]', 1) local bSplit = ( EMC.Y2DELTA ~= nil or EMC.W2DELTA ~= nil) local ParkT = ParkV1 if bSplit then if dMaxLenLeft + 100 > LoadT then ParkT = dMaxLenLeft + 300 elseif dMaxLenLeft + 100 > ParkV1 then ParkT = LoadT end end local sType = EgtIf( EMC.Y2DELTA, 'Split', EgtIf( EMC.W2DELTA, 'SpecSplit', 'Fall')) table.insert( vCmd, { 0, sType}) if not bSplit then EnsureZmax( false, vCmd) end -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then table.insert( vCmd, { 31, nRawId, 'Y1'}) end nRawId = EgtGetNextRawPart( nRawId) end -- riporto il carrello Y al carico con il resto della trave local dLDelta = EMC.Y1DELTA - dLenRaw table.insert( vCmd, { 1, 'Y1', ParkT + dLDelta}) table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0}) -- imposto subito Y non più attaccato alla trave in lavoro EMC.Y1DELTA = nil -- salvo posizione carrello Y in disposizione del pezzo dopo split local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) if PostDispId then if not bSplit or EMC.W2DELTA then EgtSetInfo( PostDispId, 'TPOS', ParkT) else EgtRemoveInfo( PostDispId, 'TPOS') EgtSetInfo( PostDispId, 'TPARK', ParkT) end EgtSetInfo( PostDispId, 'Y1POS', ParkT + dLDelta) end -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) if NextDispId then EgtSetInfo( NextDispId, 'TPOS', ParkT) EgtSetInfo( NextDispId, 'Y1POS', ParkT + dLDelta) end return vCmd end --------------------------------------------------------------------- function SpecCalcSplitRot( dLenRaw, dMaxLenLeft) local vCmd = {} EgtOutLog( ' *[SR]', 1) local bSplit = ( EMC.Y2DELTA ~= nil) local ParkT = LoadT table.insert( vCmd, { 0, 'SplitRot'}) -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) local vRaw = {} local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) local nRawId = EgtGetFirstRawPart() while nRawId do if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then table.insert( vRaw, nRawId) end nRawId = EgtGetNextRawPart( nRawId) end for _, nId in ipairs( vRaw) do table.insert( vCmd, { 31, nId, 'Y1'}) end -- riporto il carrello Y1 al carico con il resto della trave local dLDelta = EMC.Y1DELTA - dLenRaw table.insert( vCmd, { 1, 'Y1', ParkT + TurnerOffs + dLDelta}) table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0}) -- imposto subito Y non più attaccato alla trave in lavoro EMC.Y1DELTA = nil -- apro il carrello Y table.insert( vCmd, { 11, 0}) -- sgancio i grezzi dal carrello Y for _, nId in ipairs( vRaw) do table.insert( vCmd, { 31, nId, ''}) end -- lo porto in parcheggio table.insert( vCmd, { 1, 'Y1', ParkY1}) -- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari) local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) if NextDispId then EgtSetInfo( NextDispId, 'TPOS', ParkT) end return vCmd end --------------------------------------------------------------------- function SpecCalcUnload() local vCmdPre = {} EgtOutLog( ' *[U]', 1) if EMC.W2DELTA then local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Unloading SpecSplit'}) EgtOutLog( ' *[U2]', 1) return vCmd elseif not EMC.Y1DELTA and not EMC.Y2DELTA then EMC.ERR = 21 EMC.MSG = ' Error : Y1 and Y2 not clamped for unloading' return {} end local dY2DeltaMinUL = EMC.LB + MinY2 - UnloadT -- Se pinza Y1 chiusa o Y2 troppo a destra, devo effettuare uno scambio if EMC.Y1DELTA or EMC.Y2DELTA < dY2DeltaMinUL then -- determino posizione testa trave local nLastEntId = EgtGetLastInGroup( EMC.PATHID) if not nLastEntId then local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL')) nLastEntId = EgtGetLastInGroup( nPathId) end local vAxes = EmtGetAxesPos( nLastEntId) if #vAxes > 0 then EMC.TPOS = vAxes[1] end -- imposto quote aggancio per avere solo pinza V local dDistFront = EMC.LB - MinJoin - EMC.HOVM + 10 * GEO.EPS_SMALL local dDistBack = 0 -- imposto rulli aperti (in ogni caso pezzo sicuramente grande) EMC.V1POS = ParkV1 EMC.V2POS = ParkV2 -- effettuo scambio vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, nil, dY2DeltaMinUL) -- recupero nuova posizione carrelli SpecSetCarrPosFromCmds( vCmdPre) EgtOutLog( ' *[U1]', 1) end local vCmd = {} -- Tipo di scarico local bStdUl = ( not MaxUnloadLen or MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1) -- Commento table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual Unloading')}) -- posizionamento sicuro teste e rulli (non serve ?) --table.insert( vCmd, { 4, 0}) -- Se pinza Y chiusa, la apro if EMC.Y1DELTA then table.insert( vCmd, { 11, 0}) EMC.CNT = nil end -- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico if bStdUl then local dFinT = UnloadT - EMC.LB local dFinY2 = dFinT + EMC.Y2DELTA table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2}) EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2), 1) else table.insert( vCmd, { 1, 'Y2', MaxY2}) end -- apro la morsa table.insert( vCmd, { 12, 0}) -- riporto il carrello in home table.insert( vCmd, { 1, 'Y2', ParkY2}) -- eventuale unione tabelle if #vCmdPre > 0 then vCmd = EgtJoinTables( vCmdPre, vCmd) end return vCmd end --------------------------------------------------------------------- function SpecCalcPreRot() local vCmdPre = {} EgtOutLog( ' *[PR]', 1) -- Se pinza Y2 chiusa, devo effettuare uno scambio local dY1DeltaMaxSP = MaxY1 - LoadT - TurnerOffs - 10 * GEO.EPS_SMALL if EMC.Y2DELTA or EMC.Y1DELTA > dY1DeltaMaxSP then -- imposto quote aggancio per avere solo pinza Y local dDistFront = 0 local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL -- effettuo scambio vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, dY1DeltaMaxSP) -- recupero nuova posizione carrelli SpecSetCarrPosFromCmds( vCmdPre) EgtOutLog( ' [PR1]', 1) end -- porto il pezzo alla zona di rotazione con il carro Y1 local vCmd = {} -- Commento table.insert( vCmd, { 0, 'Pre-Rotation'}) -- posizionamento sicuro teste e rulli if #vCmdPre > 0 then EnsureZmax( true, vCmdPre, 2) else EnsureZmax( true, vCmd) end -- Se pinza V chiusa, la apro if EMC.Y2DELTA then table.insert( vCmd, { 12, 0}) end -- riporto la trave al carico local RotT = LoadT + TurnerOffs table.insert( vCmd, { 2, 'Y1', RotT + EMC.Y1DELTA, 'T', RotT}) -- apro la morsa table.insert( vCmd, { 11, 0}) EMC.CNT = nil -- riporto il carrello in home table.insert( vCmd, { 1, 'Y1', ParkY1}) -- eventuale unione tabelle if #vCmdPre > 0 then vCmd = EgtJoinTables( vCmdPre, vCmd) end return vCmd end --------------------------------------------------------------------- local function ChangedTool( nMchId) local bChanged = true -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine local nOrigMchId = EgtGetCurrMachining() local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) -- Recupero l'utensile della lavorazione precedente local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL) while nPrevMchId and EgtGetOperationType( nPrevMchId) == MCH_OY.DISP do nPrevMchId = EgtGetPrevActiveOperation( nPrevMchId or GDB_ID.NULL) end if nPrevMchId then EgtSetCurrMachining( nPrevMchId) local sTool = EgtGetMachiningParam( MCH_MP.TOOL) bChanged = ( sTool ~= sOrigTool) end -- Ripristino lavorazione e utensile correnti if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end return bChanged end -------------------------------------------------------------------------------------------------------- -- **CHIAMATA DELLE FUNZIONI Spec** -------------------------------------------------------------------------------------------------------- function SpecAdjustCarriages( WorkTab) --EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_')) -- Aggiorno la posizione dei rulli per eventuale cambio utensile local bChangedTool = ChangedTool( EMC.DISPID or EMC.MCHID) if bChangedTool then WorkTab.dV1PosI = ParkV1 WorkTab.dV2PosI = ParkV2 end -- Verifico se compattare i rulli local bCloseV = false if WorkTab.dY1DeltaI then if WorkTab.dY1DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0) then bCloseV = true end end if WorkTab.dY2DeltaI then if EMC.LB - WorkTab.dY2DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EgtIf( SPLIT, EMC.TCING, 0) + EgtIf( EMC.CNT == 1, AggLoad, 0) then bCloseV = true end end if WorkTab.dY2DeltaMinF then if EMC.LB - WorkTab.dY2DeltaMinF <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EgtIf( SPLIT, EMC.TCING, 0) + EgtIf( EMC.CNT == 1, AggLoad, 0) then bCloseV = true end end -- se i pezzi del cliente sono molto storti, si forza la chiusura per evitare che vada a sbattere. Se parametro non presente, si chiude solo se necessario if ForceToCloseRollersGate then bCloseV = true end WorkTab.bCloseV = bCloseV EgtOutLog( ' Tool : '..( EgtIf( bChangedTool, 'CHANGED', 'same')).. ' CloseV : '..( EgtIf( bCloseV, 'TRUE', 'false')), 1) -- |POSIZIONO Y1| **[A]** if WorkTab.dY1DeltaMinF and ( not WorkTab.dY2DeltaMinF) then -- [A1]/[A2] continuazione da morsa Y1 ( Y1 -> Y1 ) scambio Y2 (Y2 -> Y1) if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then WorkTab.bY1Parked = not WorkTab.dY1DeltaI WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) WorkTab.bY2Parked = not WorkTab.dY2DeltaI WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) return SpecAdjustCarrA( WorkTab) else EgtOutLog( ' Error CLAMP NULL-> Y1 impossibile') error( 'Error CLAMP NULL-> Y1 impossibile') end -- |POSIZIONO Y1Y2| **[B]** elseif WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then -- [B1] passo da carrello Y1 a entrambi if WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI) then WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) return SpecAdjustCarrB1( WorkTab) -- [B2] passo da carrello Y2 a entrambi elseif WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI) then WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) return SpecAdjustCarrB2(WorkTab) -- [B3] rimango con due carrelli ( per ora accetto solo il caso in cui le posizioni sono già valide) elseif WorkTab.dY1DeltaI > WorkTab.dY1DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY1DeltaI < WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI > WorkTab.dY2DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI < WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then EgtOutLog( '*[B3]', 1) return {} else EgtOutLog( ' Error CLAMP NULL-> Y1+Y2 impossibile') error( 'Error CLAMP NULL-> Y1+Y2 impossibile') end -- |POSIZIONO Y2| **[C]** elseif not WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then -- [C1]/[C2] continuazione da morsa Y2 ( Y2 -> Y2 ) sacmbio Y1 (Y1 -> Y2) if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then WorkTab.bY1Parked = not WorkTab.dY1DeltaI WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) WorkTab.bY2Parked = not WorkTab.dY2DeltaI WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) return SpecAdjustCarrC( WorkTab) else EgtOutLog( ' Error CLAMP NULL-> Y2 impossibile') error( 'Error CLAMP NULL-> Y2 impossibile') end end end ----------------------------------------------------------------------- -- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **accentramento** local function PosForCent1FY1( dY1a, dY2a, dTa, dExtraY1, dCorsaY1c, dCorsaY2Tc) local dY2Delta = dY2a - dTa local dDispl = dCorsaY1c - dExtraY1 if dDispl / 2 <= dCorsaY2Tc then if dDispl / 2 <= dCorsaY1c then dY1a = dY1a - dDispl / 2 dY2a = dY2a + dDispl / 2 else dY1a = dY1a - dCorsaY1c dY2a = dY2a + dDispl - dCorsaY1c end else dY2a = dY2a + dCorsaY2Tc dY1a = dY1a - (dDispl - dCorsaY2Tc) end dTa = dY2a - dY2Delta return dY1a, dY2a, dTa end ----------------------------------------------------------------------- -- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **accentramento** local function PosForCent1FY2( dY1a, dY2a, dTa, dExtraY2, dCorsaY1Tc, dCorsaY2c) local dY1Delta = dY1a - dTa local dDispl = dCorsaY2c + dExtraY2 if dDispl / 2 <= dCorsaY1Tc then if dDispl / 2 <= dCorsaY2c then dY1a = dY1a - dDispl / 2 dY2a = dY2a + dDispl / 2 else dY2a = dY2a + dCorsaY2c dY1a = dY1a - min( dDispl - dCorsaY2c, dCorsaY1Tc) end else dY1a = dY1a - dCorsaY1Tc dY2a = dY2a + min( dDispl - dCorsaY1Tc, dCorsaY2c) end dTa = dY1a - dY1Delta return dY1a, dY2a, dTa end ----------------------------------------------------------------------- -- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **allontanamento** local function PosForEnl1FY1( dY1a, dY2a, dTa, dExtra, dCorsaY1e, dCorsaY2Te) local dDispl = MaxY1 - dY1a + dExtra -- eseguo il posizionamento di Y1 allontanando Y1 e (Y2+T) if dDispl/2 <= dCorsaY2Te then if dDispl/2 <= dCorsaY1e then dY1a = dY1a + dDispl / 2 dY2a = dY2a - dDispl / 2 dTa = dTa - dDispl / 2 else dY1a = dY1a + dCorsaY1e dY2a = dY2a - (dDispl - dCorsaY1e) dTa = dTa - (dDispl - dCorsaY1e) end else dY2a = dY2a - dCorsaY2Te dTa = dTa - dCorsaY2Te dY1a = dY1a + (dDispl - dCorsaY2Te) end return dY1a, dY2a, dTa end ----------------------------------------------------------------------- -- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **allontanamento** local function PosForEnl1FY2( dY1a, dY2a, dTa, dExtra, dCorsaY1Te, dCorsaY2e) local dDispl = dY2a - MinY2 - dExtra -- eseguo il posizionamento di Y2 allontanando (Y1+T) e Y2 if dDispl/2 <= dCorsaY1Te then if dDispl/2 <= dCorsaY2e then dY1a = dY1a + dDispl / 2 dTa = dTa + dDispl / 2 dY2a = dY2a - dDispl / 2 else dY2a = dY2a - dCorsaY2e dY1a = dY1a + (dDispl - dCorsaY2e) dTa = dTa + (dDispl - dCorsaY2e) end else dY1a = dY1a + dCorsaY1Te dTa = dTa + dCorsaY1Te dY2a = dY2a - (dDispl - dCorsaY1Te) end return dY1a, dY2a, dTa end ----------------------------------------------------------------------- local function MaxDispl( TabI, vCmd, sType) local dY1a, dY2a local dTa = TabI.dTPosI -- **[M1]** = allontanamento dei trascinatori con Y1 in presa if sType == 'M1' then EmitComment( vCmd, '[M1]') -- ev' chiudo Y1, apro Y2 table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- allontano (Y1+T) e (Y2) dY1a = MaxY1 dY2a = MinY2 dTa = ( dY1a - TabI.dY1PosI) + dTa -- **[M2]** = allontanamento dei trascinatori con Y2 in presa elseif sType == 'M2' then EmitComment( vCmd, '[M2]') -- ev' chiudo Y2, apro Y1 table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) EMC.CNT = nil -- allontano (Y2+T) e (Y1) dY1a = MaxY1 dY2a = MinY2 dTa = ( dY2a - TabI.dY2PosI) + dTa -- **[M3]** = accentramento dei trascinatori con Y1 in presa elseif sType == 'M3' then EmitComment( vCmd, '[M3]') -- ev' chiudo Y1, apro Y2 table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) -- accentro (Y1+T) e (Y2) dY1a = TabI.MyMinY1V1 dY2a = TabI.MaxY2V2 dTa = ( dY1a - TabI.dY1PosI) + dTa -- **[M4]** = accentramento dei trascinatori con Y2 in presa elseif sType == 'M4' then EmitComment( vCmd, '[M4]') -- ev' chiudo Y2, apro Y1 table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) EMC.CNT = nil -- accentro (Y2+T) e (Y1) dY1a = TabI.MyMinY1V1 dY2a = TabI.MaxY2V2 dTa = ( dY2a - TabI.dY2PosI) + dTa end -- table.insert( vCmd, { 3, 'Y1', dY1a, 'Y2', dY2a, 'T', dTa, EMC.CNT}) TabI.dY1PosI = dY1a TabI.dY2PosI = dY2a TabI.dTPosI = dTa end -- MaxDisplForRiXw ----------------------------------------------------------------------------------------------------------- -- **ALLONTANAMENTO di Y1** ------------------------------------------------------------------------------------------------------------------ local function PosY1FromY2A( TabI, vCmd) EmitComment( vCmd, '[PosY1FromY2A]') local t = {} -- **calcolo i delta dai dati iniziali** t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - MaxY1 --se > 0, la posizione non è raggiunginile -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per Y1 e (Y2+T) t.dCorsaY1eI = MaxY1 - TabI.dY1PosI t.dCorsaY2TeI= TabI.dY2PosI - MinY2 -- |RICONOSCO I CASI| -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then EmitComment( vCmd, '[Y1(0)] ') --return t.dY1DeltaI -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa elseif t.dExtraY1New > t.dCorsaY2TeI then EmitComment( vCmd, '[Y1A-ri]') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) end -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] MaxDispl( TabI, vCmd, 'M2') --t.bXW = true else -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo EmitComment( vCmd, '[Y1A-rp] ') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- **1:** calcolo pos. di allontanamento per (Y1) e (Y2+T) (da posizioni iniziali) TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1eI, t.dCorsaY2TeI) -- aggiornamento posizioni e dY1Delta dopo -- chiusura di Y1, apertura e parcheggio di Y2 a fine funzione -- ev' chiudo Y2 e apro Y1 ed eseguo allontanamento table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) EMC.CNT = nil table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti return t.dY1DeltaA end -- PosY1FromY2A -------------------------------------------------------------------------------------------------------- -- **ALLONTANAMENTO di Y2** -------------------------------------------------------------------------------------------------------- local function PosY2FromY1A( TabI, vCmd) EmitComment( vCmd, '[PosY2FromY1A]') local t = {} -- **calcolo i delta dai dati iniziali** t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali t.dExtraY2New = ( TabI.dTPosI + t.dY2NewDelta) - MinY2 --se < 0, la posizione non è raggiunginile -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per (Y1+T) e Y2 t.dCorsaY1Te = MaxY1 - TabI.dY1PosI t.dCorsaY2e = TabI.dY2PosI - MinY2 -- -- |RICONOSCO I CASI| -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere t.dY2DeltaI = TabI.dY2PosI- TabI.dTPosI if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then EmitComment( vCmd, '[Y2(0)] ') -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa elseif -t.dExtraY2New > t.dCorsaY1Te then EmitComment( vCmd, '[Y2A-ri]' ) if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] MaxDispl( TabI, vCmd, 'M1') else -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo EmitComment( vCmd, '[Y2A-rp] ') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- **1:** calcolo pos. di allontanamento per (Y1+T) e (Y2) (da posizioni iniziali) TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1Te, t.dCorsaY2e) -- chiudo Y1 e apro Y2 ed eseguo allontanamento (finale) table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI -- chiusura di Y2, ev' apertura e parcheggio di Y1 : in funzioni chiamanti return t.dY2DeltaA end -- PosY2FromY1A ------------------------------------------------------------------------------------------------------------ -- **ACCENTRAMENTO di Y1** ------------------------------------------------------------------------------------------------------------ local function PosY1FromY2B( TabI, vCmd) EmitComment( vCmd, '[PosY1FromY2B]') local t = {} -- **calcolo i delta dai dati iniziali** t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - TabI.MyMinY1V1 -- se < 0, la posizione non è raggiunginile -- corse in accentramento disponibili per Y1 e (Y2+T) dalle posizioni iniziali t.dCorsaY1cI = TabI.dY1PosI - TabI.MyMinY1V1 t.dCorsaY2TcI = TabI.MaxY2V2 - TabI.dY2PosI -- -- |RICONOSCO I CASI| -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then EmitComment( vCmd, '[Y1(0)] ') -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa elseif -t.dExtraY1New > t.dCorsaY2TcI then EmitComment( vCmd, '[Y1B-ri]') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] MaxDispl( TabI, vCmd, 'M4') else -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo EmitComment( vCmd, '[Y1B-rp] ') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- **1: calcolo accentramento di (Y1) e (Y2+T)** TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1cI, t.dCorsaY2TcI) -- posizionamento efettivo e aggiornamento di vCmd e dY1Delta dopo -- ch. di Y1 e ap. e parcheggio di Y2 a fine funzione chiamante -- chiudo Y2 e apro Y1 ed eseguo accentramento (finale) table.insert( vCmd, { 12, 1}) table.insert( vCmd, { 11, 0}) EMC.CNT = nil table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti return t.dY1DeltaA end -- PosY1FromY2B -------------------------------------------------------------------------------------------------------- -- **ACCENTRAMENTO di Y2** -------------------------------------------------------------------------------------------------------- local function PosY2FromY1B( TabI, vCmd) EmitComment( vCmd, '[PosY2FromY1B]') local t = {} -- **calcolo i delta dai dati iniziali** t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali t.dExtraY2New = (TabI.dTPosI + t.dY2NewDelta) - TabI.MaxY2V2 -- se > 0 la posizione non è raggiunginile -- corse in accentramento disponibili per (Y1+T) e (Y2) dalle posizioni iniziali t.dCorsaY1TcI = TabI.dY1PosI - TabI.MyMinY1V1 t.dCorsaY2cI = TabI.MaxY2V2 - TabI.dY2PosI -- |RICONOSCO I CASI| -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere t.dY2DeltaI = TabI.dY2PosI-TabI.dTPosI if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then EmitComment( vCmd, '[Y2(0)] ') -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa elseif t.dExtraY2New > t.dCorsaY1TcI then EmitComment( vCmd, '[Y2B-ri]' ) if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] MaxDispl( TabI, vCmd, 'M3') else -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo EmitComment( vCmd, '[Y2B-rp] ') if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end -- Y1 chiuso, Y2 aperto -- **1: calcolo accentramento di (Y1+T) e (Y2)** TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1TcI, t.dCorsaY2cI) -- ev' chiudo Y1 e apro Y2 ed eseguo movimento accentramento table.insert( vCmd, { 11, 1}) table.insert( vCmd, { 12, 0}) table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI, EMC.CNT}) end t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI -- chiusura di Y2, apertura e parcheggio di Y1 : in funzioni chiamanti return t.dY2DeltaA end -- PosY2FromY1B -------------------------------------------------------------------------------------------------------- -- **ALLONTANAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] -------------------------------------------------------------------------------------------------------- local function PosY1Y2A( TabI, vCmd) EmitComment( vCmd, '[PosY1Y2A]') -- |RICONOSCO I CASI| repeat local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 local bXW = true -- se intervallo per Y1 raggiungibile in una sola fase -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) -- e Y2 è in posizione per aggancio su T if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then -- |POSIZIONO MORSA 1| in **allontanamento** PosY1FromY2A( TabI, vCmd) -- |POSIZIONO MORSA 2| if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then -- in **allontanamento** PosY2FromY1A( TabI, vCmd) else -- in **accentramento** PosY2FromY1B( TabI, vCmd) end bXW = false else -- |POSIZIONO MORSA 2| e poi MORSA 1 -- in **allontanamento** if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then -- se intervallo per Y2 raggiungibile in una sola fase if - (( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI then PosY2FromY1A( TabI, vCmd) PosY1FromY2A( TabI, vCmd) bXW = false end else -- in **accentramento** -- sempre se intervallo per Y2 raggiungibile in una sola fase if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 then PosY2FromY1B( TabI, vCmd) PosY1FromY2A( TabI, vCmd) bXW = false end end end if bXW then -- Massimo trascinamento della trave in direzione negativa ( casi **[xw]**) EmitComment( vCmd, '[Y1A-xw]') if TabI.dY1PosI ~= TabI.MyMinY1V1 then -- accentramento morse, trascinamento trave con Y1 MaxDispl( TabI, vCmd, 'M3') else -- allontanamento morse, trascinamento trave con Y2 MaxDispl( TabI, vCmd, 'M2') end end until ( not bXW) -- chiusura/parcheggio dei trascinatori in funzioni chiamanti local dY1Delta = TabI.dY1PosI - TabI.dTPosI local dY2Delta = TabI.dY2PosI - TabI.dTPosI return dY1Delta, dY2Delta end -- PosY1Y2A -------------------------------------------------------------------------------------------------------- -- **ACCENTRAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] -------------------------------------------------------------------------------------------------------- local function PosY1Y2B( TabI, vCmd) EmitComment( vCmd, '[PosY1Y2B]') -- |RICONOSCO I CASI| local nCnt = 0 repeat local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF) / 2 local bXW = true -- se intervallo per Y1 raggiungibile in una sola fase -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) -- e Y2 è in posizione per aggancio su T if -(( TabI.dTPosI + TabI.dY1DeltaMaxF) - TabI.MyMinY1V1) < TabI.MaxY2V2 - TabI.dY2PosI and TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then -- |POSIZIONO MORSA 1| in **accentramento** PosY1FromY2B( TabI, vCmd) -- |POSIZIONO MORSA 2| local dY2DeltaI = TabI.dY2PosI - TabI.dTPosI -- Se il trascinatore 2 non è già nell'intervallo richiesto if dY2DeltaI > TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL or dY2DeltaI < TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then -- in **allontanamento** PosY2FromY1A( TabI, vCmd) else -- in **accentramento** PosY2FromY1B( TabI, vCmd) end end bXW = false -- se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 (casi [rp] o [ri]) else -- |POSIZIONO MORSA 2| e poi MORSA 1 -- in **allontanamento** if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then -- se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T if -(( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI and TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then PosY2FromY1A( TabI, vCmd) PosY1FromY2B( TabI, vCmd) bXW = false end -- in **accentramento** else -- sempre se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and TabI.dY1PosI <= TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then PosY2FromY1B( TabI, vCmd) PosY1FromY2B( TabI, vCmd) bXW = false end end end if bXW then -- Massimo trascinamento della trave in direzione positiva (casi **[xw]** ) -- se Y1 non è a f.c. e se Y1 può afferrare la trave EmitComment( vCmd, '[Y1B-xw]') if TabI.dY1PosI ~= MaxY1 and TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then -- allontanamento morse, trascinamento trave con Y1 MaxDispl( TabI, vCmd, 'M1') else -- accentramento morse, trascinamento trave con Y2 MaxDispl( TabI, vCmd, 'M4') end end nCnt = nCnt + 1 if nCnt > 10 then return end until ( not bXW) -- chiusura/parcheggio dei trascinatori in funzioni chiamanti local dY1Delta = TabI.dY1PosI - TabI.dTPosI local dY2Delta = TabI.dY2PosI - TabI.dTPosI return dY1Delta, dY2Delta end -- PosY1Y2B -------------------------------------------------------------------------------------------------------- -- **ALLONTANAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] -------------------------------------------------------------------------------------------------------- local function PosY2Y1A( TabI, vCmd) EmitComment( vCmd, '[PosY2Y1A]') -- |RICONOSCO I CASI| repeat local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 local bXW = true -- se intervallo per Y2 raggiungibile in una sola fase -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo <=> ( -ExtraI2MaxF < Corsa Y1Te and) -- e Y1 è in posizione per aggancio su T if MinY2 - ( TabI.dTPosI + TabI.dY2DeltaMaxF) < MaxY1 - TabI.dY1PosI and TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then -- |POSIZIONO MORSA 2| in **allontanamento** PosY2FromY1A( TabI, vCmd) -- |POSIZIONO MORSA 1| if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then -- in **allontanamento** PosY1FromY2A( TabI, vCmd) else -- in **accentramento** PosY1FromY2B( TabI, vCmd) end bXW = false else -- |POSIZIONO MORSA 1| e poi MORSA 2 -- caso di allontanamento if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then -- se l'intervallo per Y1 è raggiungibile in una sola fase if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 then PosY1FromY2A( TabI, vCmd) PosY2FromY1A( TabI, vCmd) bXW = false end -- in **accentramento** else -- sempre se l'intervallo per Y1 è raggiungibile in una sola fase if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI then PosY1FromY2B( TabI, vCmd) PosY2FromY1A( TabI, vCmd) bXW = false end end end if bXW then -- Massimo trascinamento della trave in direzione positiva (casi **[xw]**) EmitComment( vCmd, '[Y2A-xw]') -- accentramento morse, trascinamento trave con Y2 if TabI.dY2PosI ~= TabI.MaxY2V2 then MaxDispl( TabI, vCmd, 'M4') -- allontanamento morse, trascinamento trave con Y1 else MaxDispl( TabI, vCmd, 'M1') end end until ( not bXW) -- chiusura/parcheggio dei trascinatori in funzioni chiamanti local dY1Delta = TabI.dY1PosI - TabI.dTPosI local dY2Delta = TabI.dY2PosI - TabI.dTPosI return dY1Delta, dY2Delta end -- PosY2Y1A -------------------------------------------------------------------------------------------------------- -- **ACCENTRAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] -------------------------------------------------------------------------------------------------------- local function PosY2Y1B( TabI, vCmd) EmitComment( vCmd, '[PosY2Y1B]') -- |RICONOSCO I CASI| local nCnt = 0 repeat local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF) / 2 local bXW = true -- se intervallo per Y2 raggiungibile in una sola fase -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 <=> (-ExtraI2MinF < Corsa Y1Tc) -- e Y1 è in posizione per aggancio su T if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then -- |POSIZIONO MORSA 2| in **accentramento** PosY2FromY1B( TabI, vCmd) -- |POSIZIONO MORSA 1| local dY1DeltaI = TabI.dY1PosI - TabI.dTPosI -- Se il trascinatore 1 non è già nell'intervallo richiesto if dY1DeltaI > TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL or dY1DeltaI < TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then -- in **allontanamento** PosY1FromY2A( TabI, vCmd) else -- in **accentramento** PosY1FromY2B( TabI, vCmd) end end bXW = false -- se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 (casi [rp] o [ri]) else -- |POSIZIONO MORSA 1| e poi MORSA 2 -- in **allontanamento** if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then -- se intervallo per Y1 è raggiungibile in una sola fase e Y2 è in posizione per aggancio su T if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then PosY1FromY2A( TabI, vCmd) PosY2FromY1B( TabI, vCmd) bXW = false end -- in **accentramento** else -- se (-ExtraI1MaxF < Corsa Y2Tc) e (Y2 è in posizione per aggancio su T) if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI and TabI.dY2PosI >= TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then PosY1FromY2B( TabI, vCmd) PosY2FromY1B( TabI, vCmd) bXW = false end end end if bXW then -- Massimo trascinamento della trave in direzione negativa (casi x[w]) EmitComment( vCmd, '[Y2B-xw]') -- se Y2 non è a f.c. e se Y2 può afferrare la trave if TabI.dY2PosI > MinY2 and TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HOVM + EMC.HCING - 10 * GEO.EPS_SMALL then -- allontanamento morse, trascinamento trave con Y2 MaxDispl( TabI, vCmd, 'M2') else -- accentramento morse, trascinamento trave con Y1 MaxDispl( TabI, vCmd, 'M3') end end nCnt = nCnt + 1 if nCnt > 10 then return end until ( not bXW) -- la chiusura delle morse è fatta sopra local dY1Delta = TabI.dY1PosI - TabI.dTPosI local dY2Delta = TabI.dY2PosI - TabI.dTPosI return dY1Delta, dY2Delta end -- PosY2Y1FromY1B --------------------------------------------------------------------- -- **[A] Posizionamento trascinatore Y1 da (Y1 o Y2) <=> Y1/Y2 -> Y1** --------------------------------------------------------------------- function SpecAdjustCarrA( WorkTab) -- Elenco comandi local vCmd = {} table.insert( vCmd, { 0, 'Y1/Y2 -> Y1'}) EmitComment( vCmd, '*[A]') local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) -- se primo scambio local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) -- recupero le posizioni correnti local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI local dY1DeltaF -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1) EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) -- [A(1)] - Se il trascinatore Y1 non è nell'intervallo valido, devo posizionarlo if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF - GEO.EPS_SMALL or WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF + GEO.EPS_SMALL then EmitComment( vCmd, '*[A(1)]') -- ----------------------------------------- -- |VERIFICO POSIZIONE RULLI| -- ------------------------------------------ -- eseguo eventuale posizionamento sicuro di teste e rulli if WorkTab.bCloseV then EnsureZmax( true, vCmd) MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) MaxY2V2 = MaxY2 end -- ------------------------------------------ -- |DEFINISCO INTERVALLO 2| -- ------------------------------------------ WorkTab.dY2DeltaMaxF = WorkTab.dY1DeltaMinF - ( MyMinY1V1 - MaxY2V2) + ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) WorkTab.dY2DeltaMinF = WorkTab.dY1DeltaMaxF - ( MaxY1 - MinY2) - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) -- se Y2 deve allontanarsi assegno il primo punto valido (altrimenti mantengo tutto l'intervallo valido) if WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF), MinJoin + EMC.HCING + EMC.HOVM) end -- se la trave è più 'corta' dell'intervallo per Y2 aggiorno l'intervallo (potrei essere comunque in un punto valido) if WorkTab.dY2DeltaMinF < MinJoin + EMC.HCING + EMC.HOVM then WorkTab.dY2DeltaMinF = MinJoin + EMC.HCING + EMC.HOVM -- se Y2 deve accentrarsi if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF then WorkTab.dY2DeltaMaxF = 2 * ( MinJoin + EMC.HCING + EMC.HOVM) end end -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 -------------------------------------------- -- |RICONOSCO I CASI| -------------------------------------------- TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } if WorkTab.dY1DeltaI > dY1NewDelta then --[A(1)B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y1 EmitComment( vCmd, '[A-Y1B]') dY1DeltaF = PosY1Y2B( TabValI, vCmd) else --[A(1)A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y1 EmitComment( vCmd, '[A-Y1A]') dY1DeltaF = PosY1Y2A( TabValI, vCmd) end -- chiudo Y1 table.insert( vCmd, { 11, 1}) -- dichiaro Y2 da parcheggiare WorkTab.bY2Parked = false -- [A(0)] - Se Y1 è già nell'intervallo valido, si lascia dove è else EmitComment( vCmd, '*[A(0)]') if not WorkTab.bY2Parked then -- dichiaro posizione di Y2 e T table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y2', dY2PosI}) end if WorkTab.bY1Parked then -- chiudo Y1 table.insert( vCmd, { 11, 1}) end dY1DeltaF = WorkTab.dY1DeltaI end if not WorkTab.bY2Parked then -- apro e parcheggio Y2 table.insert( vCmd, { 12, 0}) table.insert( vCmd, { 1, 'Y2', ParkY2}) end -- aggiorno e segnalo la posizione finale Y1Delta table.insert( vCmd, { 21, dY1DeltaF, 0}) EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF), 1) -- segnalo la posizione dei rulli table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) SpecOutputCNT() return vCmd end -- SpecAdjustCarrAA -------------------------------------------------------------------- -- **[B1] da trascinatore Y1 a entrambi <=> Y1 -> Y1+Y2** -------------------------------------------------------------------- function SpecAdjustCarrB1( WorkTab) -- Elenco comandi local vCmd = {} table.insert( vCmd, { 0, 'Y1 -> Y1+Y2'}) EmitComment( vCmd, '*[B1]') local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) -- se primo scambio local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) -- recupero le posizioni correnti local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI local dY1DeltaF, dY2DeltaF -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 -- EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1) EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle -- ----------------------------------------- -- |VERIFICO POSIZIONE RULLI| -- ------------------------------------------ if WorkTab.bCloseV then EnsureZmax( true, vCmd) MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) MaxY2V2 = MaxY2 end -- ----------------------------------------- -- |RICONOSCO I CASI| -- ------------------------------------------ -- definisco la tabella delle posizioni iniziali TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } -- [B1-Y2A] **ALLONTANAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 if WorkTab.dY2DeltaI > dY2NewDelta then EmitComment( vCmd, '[B1-Y2A]') dY1DeltaF, dY2DeltaF = PosY2Y1A( TabValI, vCmd) else -- [B1-Y2B] **ACCENTRAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 EmitComment( vCmd, '[B1-Y2B] ') dY1DeltaF, dY2DeltaF = PosY2Y1B( TabValI, vCmd) end -- ----------------------------------------- -- |CHIUSURA MORSE| -- ------------------------------------------ if not SpecTestSomeMoveInCmds( vCmd) then table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT}) end table.insert( vCmd, { 12, 1}) -- Chiudo Y2 table.insert( vCmd, { 11, 1}) -- chiudo Y1 -- imposto i nuovi parametri di aggancio table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) -- segnalo la posizione dei rulli table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) SpecOutputCNT() return vCmd end -- SpecAdjustCarrB1 --------------------------------------------------------------------- -- **[B2] da trascinatore Y2 a entrambi <=> Y2 -> Y1+Y2** -------------------------------------------------------------------- function SpecAdjustCarrB2( WorkTab) -- Elenco comandi local vCmd = {} table.insert( vCmd, { 0, 'Y2 -> Y1+Y2'}) EmitComment( vCmd, '*[B2]') local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) -- se primo scambio local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) -- definisco le posizioni **Iniziali** (= recupero le posizioni correnti) local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI local dY2DeltaF, dY1DeltaF -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 -- EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI)..' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI), 1) EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF), 1) EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle -- ----------------------------------------- -- |VERIFICO POSIZIONE RULLI| -- ------------------------------------------ -- eseguo eventuale posizionamento sicuro di teste e rulli if WorkTab.bCloseV then EnsureZmax( true, vCmd) MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) MaxY2V2 = MaxY2 end -- ----------------------------------------- -- |RICONOSCO I CASI| -- ------------------------------------------ -- definisco la tabella delle posizioni iniziali TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } -- [B2-Y1A] **ALLONTANAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 if WorkTab.dY1DeltaI < dY1NewDelta then EmitComment( vCmd, '[B2-Y1A]') dY1DeltaF, dY2DeltaF = PosY1Y2A( TabValI, vCmd) else -- [B2-Y1B] **ACCENTRAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 EmitComment( vCmd, '[B2-Y1B]') dY1DeltaF, dY2DeltaF = PosY1Y2B( TabValI, vCmd) end -- ----------------------------------------- -- |CHIUSURA MORSE| -- ------------------------------------------ if not SpecTestSomeMoveInCmds( vCmd) then table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI, EMC.CNT}) end table.insert( vCmd, { 12, 1}) -- Chiudo Y2 table.insert( vCmd, { 11, 1}) -- chiudo Y1 -- imposto i nuovi parametri di aggancio table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) -- segnalo la posizione dei rulli table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) SpecOutputCNT() return vCmd end -- SpecAdjustCarrB2 --------------------------------------------------------------------- -- **[C] ex[C1]/[C2] Posizionamento trascinatore Y2 da (Y1 o Y2) <=> Y1/Y2 -> Y2** --------------------------------------------------------------------- function SpecAdjustCarrC( WorkTab) -- Elenco comandi local vCmd = {} table.insert( vCmd, { 0, 'Y1/Y2 -> Y2'}) EmitComment( vCmd, '*[C]') local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) local MyTCING = EgtIf( SPLIT, EMC.TCING, 0) -- se primo scambio local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) -- recupero le posizioni correnti local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI local dY2DeltaF -- EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI), 1) EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF), 1) -- [C(1)] - Se il trascinatore Y2 non è nell'intervallo valido, devo posizionarlo if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF - GEO.EPS_SMALL or WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF + GEO.EPS_SMALL then EmitComment( vCmd, '*[C(1)]') -- ----------------------------------------- -- |VERIFICO POSIZIONE RULLI| -- ------------------------------------------ -- eseguo eventuale posizionamento sicuro di teste e rulli if WorkTab.bCloseV then EnsureZmax( true, vCmd) MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) MaxY2V2 = MaxY2 end -- ------------------------------------------ -- |DEFINISCO INTERVALLO 1| -- ------------------------------------------ WorkTab.dY1DeltaMaxF = WorkTab.dY2DeltaMinF + (MaxY1 - MinY2) + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) WorkTab.dY1DeltaMinF = WorkTab.dY2DeltaMaxF + (MyMinY1V1 - MaxY2V2) - (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) -- se Y1 deve allontanarsi assegno il primo punto valido (altrimenti lascio l'intervallo) if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF), EMC.LB - MinJoin - MyTCING) end -- se la trave è più 'corta' dell'intervallo per Y1 aggiorno l'intervallo (potrei essere comunque in un punto valido) if WorkTab.dY1DeltaMaxF > EMC.LB - ( MinJoin + MyTCING) then WorkTab.dY1DeltaMaxF = EMC.LB - ( MinJoin + MyTCING) -- se Y1 deve accentrarsi if WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF then WorkTab.dY1DeltaMinF = EMC.LB - 2 * MinJoin - MyTCING end end -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 -- ------------------------------------------ -- |RICONOSCO I CASI| -- ------------------------------------------ TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF} if WorkTab.dY2DeltaI < dY2NewDelta then -- [C-Y2B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y2 EmitComment( vCmd, '[C-Y2B]') _, dY2DeltaF = PosY2Y1B( TabValI, vCmd) else -- [C-Y2A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y2 EmitComment( vCmd, '[C-Y2A]') _, dY2DeltaF = PosY2Y1A( TabValI, vCmd) end -- chiudo Y2 table.insert( vCmd, { 12, 1}) -- dichiaro Y1 da parcheggiare WorkTab.bY1Parked = false -- [C(0)] - Se Y2 è già nell'intervallo valido, si lascia dove è else EmitComment( vCmd, '*[C(0)]') if not WorkTab.bY1Parked then -- dichiaro posizione di Y1 e T table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y1', dY1PosI, EMC.CNT}) end if WorkTab.bY2Parked then -- chiudo Y2 table.insert( vCmd, { 12, 1}) end dY2DeltaF = WorkTab.dY2DeltaI end if not WorkTab.bY1Parked then -- apro e parcheggio Y1 table.insert( vCmd, { 11, 0}) EMC.CNT = nil table.insert( vCmd, { 1, 'Y1', ParkY1}) end -- aggiorno e segnalo la posizione finale Y2Delta table.insert( vCmd, { 21, 0, dY2DeltaF}) EgtOutLog( ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF), 1) -- segnalo la posizione dei rulli table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) SpecOutputCNT() return vCmd end -- SpecAdjustCarrC2 --------------------------------------------------------------------- function SpecOutputCNT() if EMC.CNT == 1 then EgtSetInfo( EMC.PATHID, 'CNT', 1) else EgtRemoveInfo( EMC.PATHID, 'CNT') end end --------------------------------------------------------------------- function SpecGetCNT( CurrOpeId) while CurrOpeId do local nPrevOpeId = EgtGetPrevActiveOperation( CurrOpeId) if not nPrevOpeId then return nil end local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) if nLastPathId then return EgtGetInfo( nLastPathId, 'CNT', 'i') end CurrOpeId = nPrevOpeId end return nil end --------------------------------------------------------------------- function SpecOutputCmds( vCmd, bEnd) local sRoot = EgtIf( not bEnd, 'AS', 'AE') -- Registro il numero di comandi if vCmd and #vCmd > 0 then EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) else EgtRemoveInfo( EMC.PATHID, sRoot..'#') end -- Registro i comandi for i = 1, #(vCmd or {}) do local Cmd = vCmd[i] local sKey = sRoot .. tostring( i) -- commento if Cmd[1] == 0 then local sInfo = '0,'..Cmd[2] EgtSetInfo( EMC.PATHID, sKey, sInfo) -- movimento di 1 asse elseif Cmd[1] == 1 then local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..EgtIf( Cmd[4], ',*', '') EgtSetInfo( EMC.PATHID, sKey, sInfo) -- movimento di 2 assi elseif Cmd[1] == 2 then local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..EgtIf( Cmd[6], ',*', '') EgtSetInfo( EMC.PATHID, sKey, sInfo) -- movimento di 3 assi elseif Cmd[1] == 3 then local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. Cmd[6]..','..EgtNumToString( Cmd[7],3)..EgtIf( Cmd[8], ',*', '') EgtSetInfo( EMC.PATHID, sKey, sInfo) -- posizione sicura per movimento carrelli elseif Cmd[1] == 4 then local sInfo = '4,'..EgtNumToString( Cmd[2],0) EgtSetInfo( EMC.PATHID, sKey, sInfo) -- se chiusura rulli if Cmd[2] == 1 then if bEnd then EMC.ENDZMAX = true else EMC.ZMAX = true end end -- apertura/chiusura morsa Y elseif Cmd[1] == 11 then local sInfo = '11,'..EgtNumToString( Cmd[2],0) EgtSetInfo( EMC.PATHID, sKey, sInfo) -- apertura/chiusura morsa V elseif Cmd[1] == 12 then local sInfo = '12,'..EgtNumToString( Cmd[2],0) EgtSetInfo( EMC.PATHID, sKey, sInfo) -- impostazione nuovo stato dei carrelli elseif Cmd[1] == 21 then local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) EgtSetInfo( EMC.PATHID, sKey, sInfo) if Cmd[2] > 0 and Cmd[3] > 0 then EMC.Y1DELTA = Cmd[2] EMC.Y2DELTA = Cmd[3] elseif Cmd[2] > 0 then EMC.Y1DELTA = Cmd[2] EMC.Y2DELTA = nil elseif Cmd[3] > 0 then EMC.Y1DELTA = nil EMC.Y2DELTA = Cmd[3] else EMC.Y1DELTA = nil EMC.Y2DELTA = nil end -- impostazione nuova posizione dei rulli elseif Cmd[1] == 22 then local sInfo = '22,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) EgtSetInfo( EMC.PATHID, sKey, sInfo) EMC.V1POS = Cmd[2] EMC.V2POS = Cmd[3] -- impostazione pinza speciale di uscita per pezzi corti (pinza 5) elseif Cmd[1] == 23 then local sInfo = '23,'..EgtNumToString( Cmd[2],3) EgtSetInfo( EMC.PATHID, sKey, sInfo) EMC.W2DELTA = Cmd[2] -- riporta trave in zona carico dopo una fase start partita con un riposizionam,ento elseif Cmd[1] == 24 then local sInfo = '24,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..EgtIf( Cmd[6], ',*', '') EgtSetInfo( EMC.PATHID, sKey, sInfo) -- aggancio grezzo a carrello elseif Cmd[1] == 31 then local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] EgtSetInfo( EMC.PATHID, sKey, sInfo) -- segnalazione errore elseif Cmd[1] == 99 then local sInfo = '99,' .. Cmd[2] .. ',' .. Cmd[3] EgtSetInfo( EMC.PATHID, sKey, sInfo) end end -- Salvo i nuovi delta dei carrelli if EMC.Y1DELTA then EgtSetInfo( EMC.PATHID, 'Y1DELTA', EMC.Y1DELTA) else EgtRemoveInfo( EMC.PATHID, 'Y1DELTA') end if EMC.Y2DELTA then EgtSetInfo( EMC.PATHID, 'Y2DELTA', EMC.Y2DELTA) else EgtRemoveInfo( EMC.PATHID, 'Y2DELTA') end if EMC.W2DELTA then EgtSetInfo( EMC.PATHID, 'W2DELTA', EMC.W2DELTA) else EgtRemoveInfo( EMC.PATHID, 'W2DELTA') end --Salvo le nuove posizioni dei rulli EgtSetInfo( EMC.PATHID, 'V1POS', EMC.V1POS) EgtSetInfo( EMC.PATHID, 'V2POS', EMC.V2POS) -- Se comandi finali if bEnd then -- Se operazione successiva è disposizione, salvo anche lì le posizioni dei rulli local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) if NextDispId and NextDispId == EgtGetNextActiveOperation( EMC.DISPID or EMC.MCHID) then EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) end -- se bisogna andare a ZMAX alla fine, si setta il parametro sulla lavorazione successiva in modo che la corrente vada in home if EMC.ENDZMAX and EMC.MCHID then -- recupero lavorazione successiva local nNextMchId = EgtGetNextActiveOperation( EMC.MCHID, true) while nNextMchId do if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then if EgtSetCurrMachining( nNextMchId) then -- Verifico flag di separazione e fase di scarico local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) -- si cancella eventuale flag per risalita in ZMAX sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 'FORCED') EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) EgtSetCurrMachining( EMC.MCHID) break end end nNextMchId = EgtGetNextActiveOperation( nNextMchId, true) end end end end --------------------------------------------------------------------- function SpecSetCarrPosFromCmds( vCmd) -- recupero nuova posizione carrelli for i = 1, #( vCmd or {}) do local Cmd = vCmd[i] if Cmd[1] == 21 then if Cmd[2] > 0 and Cmd[3] > 0 then EMC.Y1DELTA = Cmd[2] EMC.Y2DELTA = Cmd[3] elseif Cmd[2] > 0 then EMC.Y1DELTA = Cmd[2] EMC.Y2DELTA = nil elseif Cmd[3] > 0 then EMC.Y1DELTA = nil EMC.Y2DELTA = Cmd[3] end elseif Cmd[1] == 22 then EMC.V1POS = Cmd[2] EMC.V2POS = Cmd[3] elseif Cmd[1] == 23 then EMC.W2DELTA = Cmd[2] end end end --------------------------------------------------------------------- function SpecTestOnlyRemarkInCmds( vCmd) if not vCmd then return true end -- verifico se nella lista dei comandi ci sono solo commenti for i = 1, #vCmd do if vCmd[i][1] ~= 0 then return false end end return true end --------------------------------------------------------------------- function SpecTestSomeMoveInCmds( vCmd) if not vCmd then return false end -- verifico se nella lista dei comandi c'è almeno un movimento for i = 1, #vCmd do if vCmd[i][1] == 1 or vCmd[i][1] == 2 or vCmd[i][1] == 3 then return true end end return false end