5 Commits

Author SHA1 Message Date
andrea.villa 626183f310 Se feature respinta per extracorsa, viene salvata nota nel LOG 2026-02-10 09:45:27 +01:00
andrea.villa fe6c0bb31c - GetBestStrategy suddivisa in : GetBestStrategyFromProcList e GetFeatureBestStrategy
- Se si deve riprocessare, si riporta il pezzo in posizione originale
- in GetCombinationListFromMatrix si ricalcola la migliore strategia in caso ChosenStrategy non presente (solo se ReProcess)
- Piccole migliorie
2026-02-10 09:02:31 +01:00
andrea.villa 1c24f1046d - Prima versione per riprocessare il calcolo lavorazioni in caso l'applicazione di una (o più lavorazioni) abbia dato errore.
- Per ora cancella la ChosenStrategy, come se non avesse trovato alcuna strategia di sponibile
2026-02-09 15:20:21 +01:00
andrea.villa 70cfdd056f Piccola correzione in STR0008 in caso non trovi neanche un utensile per lavorare la mortasa 2026-02-09 09:20:48 +01:00
andrea.villa 9ebb9c77db Merge remote-tracking branch 'origin/STR0011_Improve' into develop 2026-02-09 08:15:44 +01:00
8 changed files with 308 additions and 245 deletions
+246 -211
View File
@@ -905,26 +905,34 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che trova la strategia migliore tra quelle disponibili
local function GetBestStrategy( vProcSingleRot, Part)
local function GetFeatureBestStrategy( Proc, Part)
if Proc.nFlg ~= 0 then
local nIndexBestStrategy = 0
-- controllo se ci sono strategie disponibili
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
-- ciclo tutte le strategie della feature
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, Part, nIndexCurrentStrategy, nIndexBestStrategy)
-- salvo sulla proc la migliore strategia
end
if nIndexBestStrategy ~= 0 then
Proc.ChosenStrategy = BeamLib.TableCopyDeep( Proc.AvailableStrategies[nIndexBestStrategy])
Proc.nIndexBestStrategy = nIndexBestStrategy
end
end
end
return Proc
end
-------------------------------------------------------------------------------------------------------------
-- funzione che trova la strategia migliore tra quelle disponibili
local function GetBestStrategyFromProcList( vProcSingleRot, Part)
for i = 1, #vProcSingleRot do
-- processo tutte le feature attive
local Proc = vProcSingleRot[i]
if Proc.nFlg ~= 0 then
local nIndexBestStrategy = 0
-- controllo se ci sono strategie disponibili
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
-- ciclo tutte le strategie della feature
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, Part, nIndexCurrentStrategy, nIndexBestStrategy)
-- salvo sulla proc la migliore strategia
end
if nIndexBestStrategy ~= 0 then
Proc.ChosenStrategy = BeamLib.TableCopyDeep( Proc.AvailableStrategies[nIndexBestStrategy])
Proc.nIndexBestStrategy = nIndexBestStrategy
end
end
end
Proc = GetFeatureBestStrategy( Proc, Part)
end
return vProcSingleRot
end
@@ -1146,7 +1154,6 @@ end
-------------------------------------------------------------------------------------------------------------
-- esegue le strategie migliori che ha precedentemente scelto
local function CalculateMachinings( vProc, Part, nInitialRotation)
local bAreAllApplyOk = true
local n0Rotation = nInitialRotation
local n90Rotation = nInitialRotation + 1
if n90Rotation > 4 then n90Rotation = n90Rotation - 4 end
@@ -1200,7 +1207,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
Part.b3Raw = EgtGetRawPartBBox( Part.idRaw)
Part.b3Part = EgtGetBBoxGlob( Part.idBoxTm, GDB_BB.STANDARD)
end
return MACHININGS, bAreAllApplyOk
return MACHININGS
end
-------------------------------------------------------------------------------------------------------------
@@ -1429,8 +1436,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore
local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo)
local BestCombination = {}
local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bReProcessEmptyChosenStrategy)
local CombinationsList = { dAllCombinationsTotalTime = 0}
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
@@ -1472,13 +1478,18 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo)
for nRotation = 1, 3 do
-- se rotazione abilitata da combinazione
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
local CurrProc = ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc]
-- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata
if nNextRot == nUnloadPos or not( ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc].bHindersLaserMeasure) then
if nNextRot == nUnloadPos or not( CurrProc.bHindersLaserMeasure) then
-- se non è settata la ChosenStrtegy, provo a cercare comunque tra quelle disponibili
if not CurrProc.ChosenStrategy and bReProcessEmptyChosenStrategy then
CurrProc = GetFeatureBestStrategy( CurrProc, PartInfo)
end
-- controllo se è stata scelta una strategia
if ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc].ChosenStrategy then
if CurrProc.ChosenStrategy then
local Proc = {}
Proc.nRotation = nNextRot
table.insert( Proc, ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc])
table.insert( Proc, CurrProc)
table.insert( ResultsList, Proc)
end
end
@@ -1556,7 +1567,7 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
-- calcola le strategie applicabili
PROCESSINGS[nPart].Rotation[nIndex] = CalculateStrategies( PROCESSINGS[nPart].Rotation[nIndex], PARTS[nPart])
-- tra le calcolate, sceglie la migliore
PROCESSINGS[nPart].Rotation[nIndex] = GetBestStrategy( PROCESSINGS[nPart].Rotation[nIndex], PARTS[nPart])
PROCESSINGS[nPart].Rotation[nIndex] = GetBestStrategyFromProcList( PROCESSINGS[nPart].Rotation[nIndex], PARTS[nPart])
-- rotazione pezzo di 90° per volta
BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo
@@ -1580,191 +1591,219 @@ function BeamExec.ProcessMachinings( PARTS)
local nTotErr = 0
local Stats = {}
local nOrd = 1
local nMaxReProcessCycles = EgtClamp( GENERAL_PARAMETERS.PROJECT.GEN_nMaxReProcessCycles, 1, 3)
local bTryToReProcess = false
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
for nPart = 1, #PARTS do
local nCycles = 1
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
if EgtGetDebugLevel() >= 3 then
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart])
end
local bAllStrategiesApplied = false
-- si ricavano tutte le combinazioni possibili
local CombinationListFromMatrix = GetCombinationListFromMatrix( PROCESSINGS[nPart], PARTS[nPart])
-- ci deve essere almeno una combinazione, altrimenti errore
if #CombinationListFromMatrix < 1 then
error( 'UNEXPECTED ERROR: NO combinations available')
end
-- scelta delal migliore combinazione
local BestCombination = GetBestCombination( CombinationListFromMatrix, PARTS[nPart])
PARTS[nPart].ChosenCombination = BestCombination.sBitIndexCombination
PARTS[nPart].bPartInCombiIsInverted = BestCombination.bPartInCombiIsInverted
-- scrittura nel log delle combinazioni possibili
if EgtGetDebugLevel() >= 3 then
Logs.WriteCombinationLog( CombinationListFromMatrix, BestCombination)
end
-- compilazione della vProc finale contenente le feature da lavorare nella giusta rotazione
local vProc, MatrixResult = GetProcessingListFromCombination( BestCombination)
-- si mette subito il pezzo nella fase
if nOrd == 1 then
EgtSetCurrPhase( 1)
local nPhase = EgtGetCurrPhase()
-- salvo info nuova fase aggiunta
local MachExtraInfo = { sType = 'DISP',
nPhase = nPhase}
table.insert( DB_MACH_APPLIED, MachExtraInfo)
else
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
end
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
local vtRawOffsetPos = PARTS[nPart].b3Raw:getMin() - EgtGetRawPartBBox( PARTS[nPart].idRaw):getMin()
local nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
-- se combinazione prevede inversione, si gira il pezzo
if PARTS[nPart].bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
-- debug
if EgtGetDebugLevel() >= 1 then
PrintFeatures( vProc, PARTS[nPart])
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- se la posizione iniziale non è calcolata, significa che non ci sono feature da eseguire. Solo taglio testa/coda
if not MatrixResult.nInitialPosition then
MatrixResult.nInitialPosition = 1
MACHININGS.Info.nHeadCutRotation = 1
MACHININGS.Info.nSplitCutRotation = 1
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
for nProc = 1, #vProc do
AddFeatureResultToGlobalList( vProc[nProc])
-- la parte di applicazione lavorazioni può essere lanciata più volte in caso della presenza di errori
local bProcess = true
while bProcess do
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
if EgtGetDebugLevel() >= 3 then
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart], nCycles)
end
-- altrimenti si fanno tutti i calcoli
else
-- TODO serve ancora ordinare le feature con nuovo metodo di calcolo ottimizzazione lavorazioni?
-- ordinamento di base delle feature
vProc = OrderFeatures( vProc)
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
bAllStrategiesApplied = false
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProc, PARTS[nPart], MatrixResult.nInitialPosition)
-- se non sono sono settate le rotazioni di lavorazione di testa e coda, significa che le feature da eseguire non sono state eseguite per qualche problema. Si forza rotazione 1
if not MACHININGS.Info.nHeadCutRotation or not MACHININGS.Info.nSplitCutRotation then
-- si ricavano tutte le combinazioni possibili
local CombinationListFromMatrix = GetCombinationListFromMatrix( PROCESSINGS[nPart], PARTS[nPart], nCycles > 1)
-- ci deve essere almeno una combinazione, altrimenti errore
if #CombinationListFromMatrix < 1 then
error( 'UNEXPECTED ERROR: NO combinations available')
end
-- scelta della migliore combinazione
local BestCombination = GetBestCombination( CombinationListFromMatrix, PARTS[nPart])
PARTS[nPart].ChosenCombination = BestCombination.sBitIndexCombination
PARTS[nPart].bPartInCombiIsInverted = BestCombination.bPartInCombiIsInverted
-- scrittura nel log delle combinazioni possibili
if EgtGetDebugLevel() >= 3 then
Logs.WriteCombinationLog( CombinationListFromMatrix, BestCombination)
end
-- compilazione della vProc finale contenente le feature da lavorare nella giusta rotazione
local vProc, MatrixResult = GetProcessingListFromCombination( BestCombination)
-- si mette subito il pezzo nella fase
if nOrd == 1 then
EgtSetCurrPhase( 1)
local nPhase = EgtGetCurrPhase()
-- salvo info nuova fase aggiunta
local MachExtraInfo = { sType = 'DISP',
nPhase = nPhase}
table.insert( DB_MACH_APPLIED, MachExtraInfo)
else
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
end
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
local vtRawOffsetPos = PARTS[nPart].b3Raw:getMin() - EgtGetRawPartBBox( PARTS[nPart].idRaw):getMin()
local nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
-- se combinazione prevede inversione, si gira il pezzo
if PARTS[nPart].bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
-- debug
if EgtGetDebugLevel() >= 1 then
PrintFeatures( vProc, PARTS[nPart])
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- se la posizione iniziale non è calcolata, significa che non ci sono feature da eseguire. Solo taglio testa/coda
if not MatrixResult.nInitialPosition then
MatrixResult.nInitialPosition = 1
MACHININGS.Info.nHeadCutRotation = 1
MACHININGS.Info.nSplitCutRotation = 1
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
for nProc = 1, #vProc do
AddFeatureResultToGlobalList( vProc[nProc])
end
-- altrimenti si fanno tutti i calcoli
else
-- TODO serve ancora ordinare le feature con nuovo metodo di calcolo ottimizzazione lavorazioni?
-- ordinamento di base delle feature
vProc = OrderFeatures( vProc)
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
MACHININGS = CalculateMachinings( vProc, PARTS[nPart], MatrixResult.nInitialPosition)
-- se non sono sono settate le rotazioni di lavorazione di testa e coda, significa che le feature da eseguire non sono state eseguite per qualche problema. Si forza rotazione 1
if not MACHININGS.Info.nHeadCutRotation or not MACHININGS.Info.nSplitCutRotation then
MACHININGS.Info.nHeadCutRotation = 1
MACHININGS.Info.nSplitCutRotation = 1
end
end
end
-- salvo sul PART la posizione di partenza che è stata scelta
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
-- salvo sul PART la posizione di partenza che è stata scelta
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
local nOffsetIndex = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 4, 0)
-- aggiunge tagli testa e coda in fasi opportune
local nRotHeadCut = MatrixResult.nInitialPosition + MACHININGS.Info.nHeadCutRotation - 1
if nRotHeadCut > 4 then
nRotHeadCut = nRotHeadCut - 4
end
nRotHeadCut = nRotHeadCut + nOffsetIndex
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4
end
nRotSplitCut = nRotSplitCut + nOffsetIndex
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
local nOffsetIndex = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 4, 0)
-- aggiunge tagli testa e coda in fasi opportune
local nRotHeadCut = MatrixResult.nInitialPosition + MACHININGS.Info.nHeadCutRotation - 1
if nRotHeadCut > 4 then
nRotHeadCut = nRotHeadCut - 4
end
nRotHeadCut = nRotHeadCut + nOffsetIndex
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4
end
nRotSplitCut = nRotSplitCut + nOffsetIndex
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
-- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
else
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true
end
-- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
else
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true
end
-- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
else
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true
end
-- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
else
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true
end
local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
bAllStrategiesApplied = false
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
-- si preparano le lavorazioni assegnandole al proprio stage
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
-- si preparano le lavorazioni assegnandole al proprio stage
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
-- TODO queste funzioni andrebbero rimosse e utilizzato algoritmo di sorting dedicato
-- #### #### #### #### #### #### #### #### #### ####
-- ordinamento lavorazioni per stage (N.B.: potrebbe compromettere ordine lavorazioni della feature, che non può essere cambiato)
MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings)
-- dopo il sorting bisogna riverificare che ordine delle lavorazioni della feature non sia compromesso
MACHININGS = MachiningLib.FinalizeSorting()
-- #### #### #### #### #### #### #### #### #### ####
-- TODO queste funzioni andrebbero rimosse e utilizzato algoritmo di sorting dedicato
-- #### #### #### #### #### #### #### #### #### ####
-- ordinamento lavorazioni per stage (N.B.: potrebbe compromettere ordine lavorazioni della feature, che non può essere cambiato)
MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings)
-- dopo il sorting bisogna riverificare che ordine delle lavorazioni della feature non sia compromesso
MACHININGS = MachiningLib.FinalizeSorting()
-- #### #### #### #### #### #### #### #### #### ####
-- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase
nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, -vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
-- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase
nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, -vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
local bAreAllMachiningApplyOk
local sErr
local bSplitAlreadyExecuted = false
local bSplitExecutedOnRot = false
local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'START')
EgtSetInfo( idDisp, 'ORD', nOrd)
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
local bAreAllMachiningApplyOk
local sErr
local bSplitAlreadyExecuted = false
local bSplitExecutedOnRot = false
local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'START')
EgtSetInfo( idDisp, 'ORD', nOrd)
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
-- creazione effettiva delle lavorazioni
MACHININGS.Info = {}
local nCurrPosition = 1
local nInitialPosition = MatrixResult.nInitialPosition
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
if MatrixResult.bSomeFeatureDown then
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -2)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
end
-- se c'è almeno una lavorazione in posizionamento con trave ruotata
if MatrixResult.bSomeFeatureSide then
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
-- creazione effettiva delle lavorazioni
MACHININGS.Info = {}
local nCurrPosition = 1
local nInitialPosition = MatrixResult.nInitialPosition
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
if MatrixResult.bSomeFeatureDown then
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -2)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess
end
-- se c'è almeno una lavorazione in posizionamento con trave ruotata
if MatrixResult.bSomeFeatureSide then
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd)
-- se c'è già stata separazione
if bSplitAlreadyExecuted then
EgtSetInfo( idDisp, 'TYPE', 'MID2')
else
EgtSetInfo( idDisp, 'TYPE', 'MID')
end
-- se combinazione prevede inversione, si gira il pezzo
if PARTS[nPart].bPartInCombiIsInverted and not PARTS[nPart].bIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
end
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -1)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess
end
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd)
-- se c'è già stata separazione
if bSplitAlreadyExecuted then
EgtSetInfo( idDisp, 'TYPE', 'MID2')
EgtSetInfo( idDisp, 'TYPE', 'END2')
else
EgtSetInfo( idDisp, 'TYPE', 'MID')
end
@@ -1773,37 +1812,33 @@ function BeamExec.ProcessMachinings( PARTS)
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
end
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -1)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
end
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd)
-- se c'è già stata separazione
if bSplitAlreadyExecuted then
EgtSetInfo( idDisp, 'TYPE', 'END2')
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
-- aggiunta lavorazioni in ultima fase
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
bProcess = bProcess or bTryToReProcess
-- se bisogna riprocessare, si annulla tutto
nCycles = nCycles + 1
if bProcess and nCycles <= nMaxReProcessCycles then
-- azzero liste
MACHININGS = {}
DB_MACH_APPLIED = {}
MACHININGS.Info = {}
RESULT = {}
EgtRemoveAllOperations()
-- se combinazione prevedeva inversione, si rigira il pezzo
if PARTS[nPart].bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], -2)
end
-- si ribalta il pezzo in posizione iniziale
BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition)
else
EgtSetInfo( idDisp, 'TYPE', 'MID')
end
-- se combinazione prevede inversione, si gira il pezzo
if PARTS[nPart].bPartInCombiIsInverted and not PARTS[nPart].bIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
bProcess = false
end
end
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
-- aggiunta lavorazioni in ultima fase
MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
-- ottimizzazione con algoritmo ShortestPath
TIMER:startElapsed( 'Sorting')
MachiningLib.ShortestPathSorting()
+8 -17
View File
@@ -926,8 +926,9 @@ end
-- funzione che verifica se la feature, lavorata in questa fase, compromette lettura misura laser
function FeatureLib.CalculateFeatureHindersLaserMeasure( Proc, Part)
local bFeatureHindersLaserMeasure = false
-- se la feature è aperta frontalmente, posteriormente e di testa, allora potrebbe impattare sulla misura laser, controllo caso per caso
if Proc.AffectedFaces.bRight and Proc.AffectedFaces.bFront and Proc.AffectedFaces.bBack then
-- se la feature è aperta frontalmente, posteriormente, di testa e più bassa di 40mm, allora potrebbe impattare sulla misura laser, controllo caso per caso
if Proc.AffectedFaces.bRight and Proc.AffectedFaces.bFront and Proc.AffectedFaces.bBack and
( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) < 40 then
bFeatureHindersLaserMeasure = true
end
return bFeatureHindersLaserMeasure
@@ -963,13 +964,13 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
-- condizioni per limitare pinzaggio testa/coda
local bUpdateIng = true
-- se dimensione del box della feature maggiore di metà pinzaggio minimo o metà spessore pezzo
bUpdateIng = bUpdateIng and Proc.b3Box:getDimZ() > dMinHIng
-- bUpdateIng = bUpdateIng and Proc.b3Box:getDimZ() > dMinHIng
-- se la feature si trova più in basso del minimo pinzabile in Z o il 35% dello spessore pezzo
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < Part.b3Raw:getMin():getZ() + dMinZ
-- se feature è al di sotto del pinzaggio massimo
bUpdateIng = bUpdateIng and Proc.b3Box:getMin():getZ() < dMaxHZ
-- se ho le morse verticali, o se la feature è in centro o verso alto, controllo se non prendo abbastanza.
if bIsVertClamps or ( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) > BeamData.MIN_HEIGHT then
-- se ho le morse verticali, o se la feature è in centro o verso alto, controllo se non prendo abbastanza
if bIsVertClamps or ( Proc.b3Box:getMin():getZ() - Part.b3Raw:getMin():getZ()) > BeamData.MIN_HEIGHT then
bUpdateIng = bUpdateIng and dDeltaZClamp < BeamData.VICE_MINH
end
@@ -981,24 +982,14 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
end
dNotClampableLengthHead = dOffs
elseif Proc.AffectedFaces.bLeft then
end
if Proc.AffectedFaces.bLeft then
local dOffs = Proc.b3Box:getMax():getX() - Part.b3Part:getMin():getX()
-- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
end
dNotClampableLengthTail = dOffs
-- TODO il controllo sul punto centrale non è corretto, deve essere rivisto.
-- Si lascia qui commentato perchè era così anche in quello vecchio, quindi potrebbe essere che in qualche caso potesse funzionare
-- elseif Proc.b3Box:getCenter():getX() > Part.b3Part:getCenter():getX() then
-- local dOffs = Part.b3Part:getMax():getX() - Proc.b3Box:getMin():getX()
-- local dDist = Part.b3Part:getMax():getX() - Proc.b3Box:getMax():getX()
-- -- se pinze a 45° e pinza abbastanza materiale, compenso comunque, ma solo inclinazione morse
-- if not bIsVertClamps and dDeltaZClamp > BeamData.VICE_MINH and BeamData.VICE_MAXH then
-- dOffs = min( dOffs, BeamData.VICE_MAXH - BeamData.VICE_MINH)
-- end
-- -- dDist serve??
-- dNotClampableLengthHead = dOffs
end
end
end
+11 -9
View File
@@ -5,7 +5,7 @@
local Logs = {}
-------------------------------------------------------------------------------------------------------------
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo, nReProcessCycles)
local nCycles = 1
local nOffsetIndex = 0
@@ -13,15 +13,13 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
nCycles = 2
end
EgtOutLog( ' === === === === === === === === === === REPROCESS CYCLES ' .. EgtNumToString( nReProcessCycles) .. ' === === === === === === === === === === === ===')
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
for nCycle = 1, nCycles do
local nStartIndex = 1 + nOffsetIndex
local nEndIndex = 4 + nOffsetIndex
if nCycle == 1 then
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
else
EgtOutLog( ' === === === === === === === === === === === === === === === === === === === === === === === === === === ===')
EgtOutLog( ' === === === === === === === === FEATURES STRATEGIES PIECE INVERTED === === === === === === === === === ===')
end
EgtOutLog( ' === === === === === === === === === === === === === === === === === === === === === === === === === === ===')
EgtOutLog( ' === === === === === === === === FEATURES STRATEGIES PIECE INVERTED === === === === === === === === === ===')
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
@@ -74,7 +72,11 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Applicable' then
sStatusStrategy = 'N'
sRating = '----'
sIndexes = ' (C:---|Q:---|T:---)'
if EgtStartsWith( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sInfo, 'REJECTED') then
sIndexes = ' ( --- REJECTED ---)'
else
sIndexes = ' (C:---|Q:---|T:---)'
end
else
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Completed' then
sStatusStrategy = 'C'
@@ -88,7 +90,7 @@ function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
end
-- se c'è una chosen strategy, si aggiunge prefisso '*' per indicare nel log qual è la strategia che è stata scelta
local nIndexBestStrategy = ProcessingsOnPart.Rotation[nRotLog][ProcLog].nIndexBestStrategy or 0
local sLogLineProc = EgtIf( nIndexBestStrategy == nCountStrategies, '*', '') .. sRating .. sIndexes .. ' (' ..
local sLogLineProc = EgtIf( nIndexBestStrategy == nCountStrategies, '*', '') .. sRating .. sIndexes .. ' (' ..
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].sStrategyId) .. ')' ..
sStatusStrategy .. ' |'
while string.len( sLogLineProc) <= 38 do
+29 -4
View File
@@ -1141,13 +1141,29 @@ function MachiningLib.AddMachinings( Proc, Machining, AuxiliaryData)
return bMachiningAdded
end
-------------------------------------------------------------------------------------------------------------
-- funzione che verifica se ha senso riprocessare tutto dall'inizio,
-- perchè ci sono buone probabilità che l'errore trovato in fase di applicazione si possa risolvere (escludendo la lavorazione scelta in precedenza)
local function IsReProcessWorthIt( nError)
local bReProcess = false
-- errori di Extra-corsa
if nError == 2110 or nError == 2216 or nError == 2318 or nError == 2424 or nError == 2508 then
bReProcess = true
end
return bReProcess
end
-------------------------------------------------------------------------------------------------------------
-- funzione per aggiungere una nuova lavorazione
function MachiningLib.AddOperations( vProc, Part, sRotation)
function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
local nErr
local sErr = ''
local bAreAllMachiningApplyOk = true
local bSplitExecuted = false
local bTryToReProcess = false
-- parametri generali lavorazione
local MachiningParameters = {
@@ -1345,6 +1361,15 @@ function MachiningLib.AddOperations( vProc, Part, sRotation)
bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false)
local CurrProc = PROCESSINGS[MACHININGS[i].Proc.nIndexPartInParts].Rotation[MACHININGS[i].Proc.nIndexRotation][MACHININGS[i].Proc.nIndexInVProc]
-- si annulla la feature scelta, in modo che un successivo ricalcolo non la tenga in considerazione
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sStatus = 'Not-Applicable'
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sInfo = 'REJECTED (' .. sErr .. ')'
CurrProc.ChosenStrategy= nil
-- si verifica se vale la pena riprocessare tutto (perchè si pensa possa risolvere il problema)
if IsReProcessWorthIt( nErr) then
bTryToReProcess = true
end
-- update risultati
-- TODO è corretto mettere non applicabile????? disattivare e dare un'incompleta gialla?
RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sStatus = 'Not-Applicable'
@@ -1429,7 +1454,7 @@ function MachiningLib.AddOperations( vProc, Part, sRotation)
EgtSetInfo( idDisp, 'ORD', MACHININGS[i].Proc.nIndexPartInParts)
end
else
return false, 'UNEXPECTED ERROR: Error on creating machining', bSplitExecuted
return false, 'UNEXPECTED ERROR: Error on creating machining', bSplitExecuted, false
end
end
end
@@ -1446,13 +1471,13 @@ function MachiningLib.AddOperations( vProc, Part, sRotation)
EgtSetInfo( idDisp, 'TCING', Part.NotClampableLength[sRotation].dTail or 0)
end
return bAreAllMachiningApplyOk, sErr, bSplitExecuted
return bAreAllMachiningApplyOk, sErr, bSplitExecuted, bTryToReProcess
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.ApplyMachining( bRecalc, bApplyPost)
local bResult = EgtApplyMachining( bRecalc, bApplyPost)
return bResult
end
-1
View File
@@ -232,7 +232,6 @@ end
-- check extracorsa da punti sul tip dell'utensile
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
-- check collisione sui punti in centro lama su naso mandrino o aggregato. In base a direzione e punto
for i = 1, #PointsOnToolTipCenter do
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool)
+1 -1
View File
@@ -7,7 +7,7 @@
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( true)
EgtEnableDebug( false)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
+11
View File
@@ -90,6 +90,17 @@
}
]
},
{
"nGroup": "MACHINING STRATEGY",
"sName": "GEN_nMaxReProcessCycles",
"sNameNge": "MAX_REPROCESS_CYCLES",
"sValue": "1",
"sDescriptionShort": "Max number of reprocessing cycles",
"sDescriptionLong": "",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "10"
},
{
"nGroup": "MACHINING STRATEGY",
"sName": "GEN_bReduceBladePath",
+2 -2
View File
@@ -174,13 +174,13 @@ local function GetBestPocketingStrategy( Proc, Part)
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[2].ToolInfo)
Machining.Pocketing[1].bIsApplicable = false
-- solo svuotatura diretta come normale mortasa, incompleta
elseif not Machining.Pocketing[2].bIsApplicable then
elseif Machining.Pocketing[1].bIsApplicable and not Machining.Pocketing[2].bIsApplicable then
Machining.sTypeMachining = 'Side1'
Machining.dResidual = Machining.Pocketing[1].ToolInfo.dResidualDepth
Machining.Pocketing[1].sDepth = -Machining.dResidual
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining.Pocketing[1].ToolInfo)
-- solo svuotatura diretta come normale mortasa, incompleta
elseif not Machining.Pocketing[1].bIsApplicable then
elseif Machining.Pocketing[2].bIsApplicable and not Machining.Pocketing[1].bIsApplicable then
Machining.sTypeMachining = 'Side2'
Machining.dResidual = Machining.Pocketing[2].ToolInfo.dResidualDepth
Machining.Pocketing[2].sDepth = Proc.FeatureInfo.dMortiseDepth - Machining.dResidual