Modificate funzioni per lettura e gestione parametri generali

This commit is contained in:
andrea.villa
2025-10-09 08:33:52 +02:00
parent 738b2af502
commit 810bf4f7ab
4 changed files with 181 additions and 139 deletions
+118 -77
View File
@@ -239,43 +239,16 @@ function BeamExec.GetStrategiesFromJSONinBD( sAISetupConfigName)
-- metto la tabella letta nella lista globale STRATEGIES
STRATEGIES[sAISetupConfigName] = {}
STRATEGIES[sAISetupConfigName].PROJECT = FeatureList.PROJECT
STRATEGIES[sAISetupConfigName].BTL = FeatureList.BTL
STRATEGIES[sAISetupConfigName].PIECE = FeatureList.PIECE
STRATEGIES[sAISetupConfigName].GENERAL = FeatureList.GENERAL
STRATEGIES[sAISetupConfigName].FEATURE = FeatureList.FEATURE
STRATEGIES[sAISetupConfigName].sAISetupConfigName = sAISetupConfigName
end
end
-------------------------------------------------------------------------------------------------------------
-- funzione che controlla validità delle combinazioni proposte
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection, bCalcBestPieceUnloadPosition)
-- STANDARD : posizione di scarico come posizionamento iniziale
if not bCalcBestPieceUnloadPosition then
local ExtraRotation = nUnloadPos + 3
if nUnloadPos ~= 1 then
return false
elseif string.sub( sCombination, nUnloadPos, nUnloadPos) == '1' and string.sub( sCombination, ExtraRotation, ExtraRotation) == '0' then
if not BeamData.ROT90 and string.sub( sCombination, nUnloadPos+1, nUnloadPos+1) == '1' then
return false
elseif not BeamData.ROT180 and string.sub( sCombination, nUnloadPos+2, nUnloadPos+2) == '1' then
return false
else
return true
end
else
return false
end
-- TODO capire come passare info che il pezzo non ha bisogno di rotazioni per velocizzare il caclolo. Magari non serve neanche entrare in questa funzione
-- NO ROTATION : solo posizione di partenza
elseif BEAM.Rotation and BEAM.Rotation.bNoRotation then
if sCombination == '1000' and nUnloadPos == 1 then
return true
else
return false
end
-- PREROTATION : ammesse anche le prerotazioni e le inversioni (serve per preparare il pezzo nella posizione migliore prima di metterlo nella barra)
elseif bCalcBestPieceUnloadPosition then
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection, GeneralParameters, bCalcBestPieceUnloadPosition)
-- PREROTATION : flip-rot, si considerano tutte le posizioni possibili, a meno che non si voglia come da BTL
if bCalcBestPieceUnloadPosition and GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then
local nRotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1)
local nRotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
local nExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
@@ -295,6 +268,32 @@ local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection,
end
end
end
-- se invece si è nel caso standard di calcolo
else
-- NO ROTATION : solo posizione di partenza e non sono ammesse rotazioni
if GeneralParameters.GEN_sPieceRotation == 'NOT_ALLOWED' then
if sCombination == '1000' and nUnloadPos == 1 then
return true
else
return false
end
-- STANDARD : posizione di scarico come posizionamento iniziale
else
local ExtraRotation = nUnloadPos + 3
if nUnloadPos ~= 1 then
return false
elseif string.sub( sCombination, nUnloadPos, nUnloadPos) == '1' and string.sub( sCombination, ExtraRotation, ExtraRotation) == '0' then
if not BeamData.ROT90 and string.sub( sCombination, nUnloadPos+1, nUnloadPos+1) == '1' then
return false
elseif not BeamData.ROT180 and string.sub( sCombination, nUnloadPos+2, nUnloadPos+2) == '1' then
return false
else
return true
end
else
return false
end
end
end
end
@@ -303,8 +302,8 @@ function BeamExec.GetAvailableCombinations( PartInfo, bCalcBestPieceUnloadPositi
local CombinationList = {}
CombinationList.Rotations = {0, 0, 0, 0} -- indice rotazione attiva, per calcolo collect feature
-- se sto effettivamente calcolando, il pezzo è già in posizione e non può essere invertito. Se sono in preverifica, allora devo consoderare anche eventuali inversioni del pezzo
local nCycles = EgtIf( bCalcBestPieceUnloadPosition, 2, 1)
-- se sto effettivamente calcolando, il pezzo è già in posizione e non può essere invertito. Se sono in preverifica, allora devo considerare anche eventuali inversioni del pezzo
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PartInfo.GeneralParameters.GEN_sPiecesLoadingPosition == 'BEST_POSITION', 2, 1)
-- verifico tutte le combinazioni che possono essere considerate
for nInvertIndex = 1, nCycles do
for nUnloadPos = 1, 4 do
@@ -312,7 +311,7 @@ function BeamExec.GetAvailableCombinations( PartInfo, bCalcBestPieceUnloadPositi
local nBitIndexCombination = BeamLib.DecimalToBinary( i)
local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4)
-- si calcolano le combinazioni all'inizio, ottimizzando calcolo della collect solo nelle rotazioni che possono essere considerate
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, PartInfo.bSquareSection, bCalcBestPieceUnloadPosition) then
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, PartInfo.bSquareSection, PartInfo.GeneralParameters, bCalcBestPieceUnloadPosition) then
local Combination = {}
Combination.sBitIndexCombination = sBitIndexCombination
Combination.nUnloadPos = nUnloadPos
@@ -480,11 +479,10 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
PARTS[i].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[i].nIndexInParts = i
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition)
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
PARTS[i].dHeadOverMaterial = dDeltaS
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJECT', 's') or nil
-- TODO LE INFO BTL ci devono sempre essere!! ripristinare dopo aver sistemato lettura da BtlInfo
--PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig or GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
@@ -493,7 +491,9 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
-- si carica configurazione lavorazioni
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i].id, GENERAL_PARAMETERS_JSON)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition)
else
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')'
return false, sOut
@@ -862,7 +862,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- ritorna l'indice della strategia migliore, tra le due passate
local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1, nIndex2)
local function GetIndexBestStrategyFromComparison( AvailableStrategies, Part, nIndex1, nIndex2)
local dChosenIndex = 0
-- controllo indici
if nIndex1 == 0 and nIndex2 == 0 then
@@ -888,16 +888,21 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then
dChosenIndex = nIndex2
else
-- TODO gestire parametri scelta strategia
-- 1) tempo
-- 2) qualità
-- 3) prima strategia nell'ordine tra quelle disponibili
-- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete)
if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and
AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then
AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.dCompositeRating
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.dCompositeRating
if Part.GeneralParameters.GEN_sMachiningStrategy == 'BALANCED' then
dCompositeRatingStrategy1 = dCompositeRatingStrategy1 * ( 1 / AvailableStrategies[nIndex1].Result.dTimeToMachine)
dCompositeRatingStrategy2 = dCompositeRatingStrategy2 * ( 1 / AvailableStrategies[nIndex2].Result.dTimeToMachine)
elseif Part.GeneralParameters.GEN_sMachiningStrategy == 'FASTEST' then
dCompositeRatingStrategy1 = ( dCompositeRatingStrategy1 * 0.25) * ( 1 / ( AvailableStrategies[nIndex1].Result.dTimeToMachine * 0.75))
dCompositeRatingStrategy2 = ( dCompositeRatingStrategy2 * 0.25) * ( 1 / ( AvailableStrategies[nIndex2].Result.dTimeToMachine * 0.75))
elseif Part.GeneralParameters.GEN_sMachiningStrategy == 'HIGH_QUALITY' then
dCompositeRatingStrategy1 = ( dCompositeRatingStrategy1 * 0.75) * ( 1 / ( AvailableStrategies[nIndex1].Result.dTimeToMachine * 0.25))
dCompositeRatingStrategy2 = ( dCompositeRatingStrategy2 * 0.75) * ( 1 / ( AvailableStrategies[nIndex2].Result.dTimeToMachine * 0.25))
end
-- si predilige strategia con rating composito più alto
if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then
dChosenIndex = nIndex1
@@ -914,7 +919,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che trova la strategia migliore tra quelle disponibili
local function GetBestStrategy( vProcSingleRot)
local function GetBestStrategy( vProcSingleRot, Part)
for i = 1, #vProcSingleRot do
-- processo tutte le feature attive
local Proc = vProcSingleRot[i]
@@ -925,7 +930,7 @@ local function GetBestStrategy( vProcSingleRot)
-- ciclo tutte le strategie della feature
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, Part, nIndexCurrentStrategy, nIndexBestStrategy)
-- salvo sulla proc la migliore strategia
end
if nIndexBestStrategy ~= 0 then
@@ -975,8 +980,7 @@ local function CalculateStrategies( vProcSingleRot, Part)
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = FeatureLib.CalculateCompositeRating( Proc.AvailableStrategies[nIndexCurrentStrategy].Result)
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
-- TODO serve parametro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
if BEAM.GetFirstCompletedStrategy and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
break
end
@@ -1275,44 +1279,81 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che decide la migliore tra le combinazioni di rotazione disponibili
local function GetBestCombination( ListToCompare)
-- TODO da completare
local function GetBestCombination( ListToCompare, Part)
local nIndexBestCombination = 1
if #ListToCompare == 1 then
nIndexBestCombination = 1
else
for ListIndex = 2, #ListToCompare do
local bBestComplete = ListToCompare[nIndexBestCombination].nNotComplete == 0 and ListToCompare[nIndexBestCombination].nNotExecute == 0
local bOtherComplete = ListToCompare[ListIndex].nNotComplete == 0 and ListToCompare[ListIndex].nNotExecute == 0
-- prediligo combinazione completa
if bBestComplete and not bOtherComplete then
; -- la migliore resta la stessa
elseif not bBestComplete and bOtherComplete then
nIndexBestCombination = ListIndex
-- altrimenti guardo il voto
-- se rotazione non ammessa, si sceglie la migliore soluzione SENZA rotazioni
if Part.GeneralParameters.GEN_sPieceRotation == 'NOT_ALLOWED' then
-- scelgo soluzione senza rotazioni
if ListToCompare[ListIndex].nRotations == 0 then
-- scelgo soluzione con voto più alto
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
nIndexBestCombination = ListIndex
end
end
-- se rotazioni ammesse, si sceglie in base a peso singola rotazione
else
-- si sceglie soluzione con più feature complete
if ListToCompare[ListIndex].nComplete > ListToCompare[nIndexBestCombination].nComplete then
local bBestComplete = ListToCompare[nIndexBestCombination].nNotComplete == 0 and ListToCompare[nIndexBestCombination].nNotExecute == 0
local bOtherComplete = ListToCompare[ListIndex].nNotComplete == 0 and ListToCompare[ListIndex].nNotExecute == 0
-- prediligo combinazione completa
if bBestComplete and not bOtherComplete then
; -- la migliore resta la stessa
elseif not bBestComplete and bOtherComplete then
nIndexBestCombination = ListIndex
elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then
-- se stesso voto
if ListToCompare[nIndexBestCombination].dTotalRating == ListToCompare[ListIndex].dTotalRating then
-- TODO il voto dovrebbe essere considerato già pesando le rotazioni, con un coefficiente o un peso fisso aggiuntivo
-- scelgo soluzione con meno rotazioni
-- altrimenti guardo il voto
else
-- se rotazione ha un grande impatto
if Part.GeneralParameters.GEN_sPieceRotation == 'IF_NECESSARY' then
-- scelgo soluzione con meno rotazioni indipendentemente dal voto
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
nIndexBestCombination = ListIndex
-- se anche le rotazioni sono le stesse, prendo la soluzione con più lavorazioni alla fine
elseif #ListToCompare[nIndexBestCombination].Rot0 < #ListToCompare[ListIndex].Rot0 then
nIndexBestCombination = ListIndex
-- se stesso numero di rotazioni
elseif ListToCompare[nIndexBestCombination].nRotations == ListToCompare[ListIndex].nRotations then
-- si sceglie soluzione con più feature complete
if ListToCompare[ListIndex].nComplete > ListToCompare[nIndexBestCombination].nComplete then
nIndexBestCombination = ListIndex
elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then
-- scelgo soluzione con voto più alto
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
nIndexBestCombination = ListIndex
end
end
end
-- se voto diverso
-- GEN_sPieceRotation = 'MODERATE_IMPACT' oppure 'NO_CONSTRAINT'
else
-- scelgo soluzione con voto più alto
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then
-- si sceglie soluzione con più feature complete
if ListToCompare[ListIndex].nComplete > ListToCompare[nIndexBestCombination].nComplete then
nIndexBestCombination = ListIndex
elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then
local dBestTotalRating = ListToCompare[nIndexBestCombination].dTotalRating
local dOtherTotalRating = ListToCompare[ListIndex].dTotalRating
-- se la rotazione ha un moderato impatto, si calcola che ogni rotazione aumenta il dTotalRating del 10%
if Part.GeneralParameters.GEN_sPieceRotation == 'MODERATE_IMPACT' then
-- TODO IMPROVEMENT: si potrebbe avere un tempo di rotazione e aggiungere quello alla somma dei tempi delle lavorazioni delle feature
dBestTotalRating = dBestTotalRating * ( 1 + ( ListToCompare[nIndexBestCombination].nRotations / 10))
dOtherTotalRating = dOtherTotalRating * ( 1 + ( ListToCompare[ListIndex].nRotations / 10))
end
-- scelgo soluzione con voto più alto
if dBestTotalRating < dOtherTotalRating then
nIndexBestCombination = ListIndex
-- se stesso voto
elseif dBestTotalRating == dOtherTotalRating then
-- scelgo soluzione con meno rotazioni
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
nIndexBestCombination = ListIndex
-- se anche le rotazioni sono le stesse, prendo la soluzione con più lavorazioni alla fine
elseif #ListToCompare[nIndexBestCombination].Rot0 < #ListToCompare[ListIndex].Rot0 then
nIndexBestCombination = ListIndex
end
end
end
end
end
end
end
@@ -1365,7 +1406,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che ritorna la Proc nella rotazione scelta
local function GetProcBestMachRotationFromList( ListToCompare)
local function GetProcBestMachRotationFromList( ListToCompare, Part)
local Data = {}
local Proc = {}
local nIndexChosenProcInRot = 1
@@ -1379,7 +1420,7 @@ local function GetProcBestMachRotationFromList( ListToCompare)
end
for nIndexCurrentStrategy = 1, #AvailableStrategiesInRot do
-- la scelta tra le differenti strategie tra le rotazioni utilizza gli stessi criteri della scelta strategie all'interno della feature stessa
nIndexChosenProcInRot = GetIndexBestStrategyFromComparison( AvailableStrategiesInRot, nIndexCurrentStrategy, nIndexChosenProcInRot)
nIndexChosenProcInRot = GetIndexBestStrategyFromComparison( AvailableStrategiesInRot, Part, nIndexCurrentStrategy, nIndexChosenProcInRot)
end
-- altrimenti prendo la prima
else
@@ -1460,7 +1501,7 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo)
-- se la feature può essere lavorata in almeno una rotazione
if #ResultsList > 0 then
local Proc, Data = GetProcBestMachRotationFromList( ResultsList)
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
Proc.nIndexRotation = Data.nIndexRotation
-- inserisco la Proc nell'apposita lista
if Data.nIndexRotation == nUnloadPos then
@@ -1517,7 +1558,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])
PROCESSINGS[nPart].Rotation[nIndex] = GetBestStrategy( PROCESSINGS[nPart].Rotation[nIndex], PARTS[nPart])
-- rotazione pezzo di 90° per volta
BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo
@@ -1579,7 +1620,7 @@ function BeamExec.ProcessMachinings( PARTS)
end
-- scelta delal migliore combinazione
local BestCombination = GetBestCombination( CombinationListFromMatrix)
local BestCombination = GetBestCombination( CombinationListFromMatrix, PARTS[nPart])
PARTS[nPart].ChosenCombination = BestCombination.sBitIndexCombination
PARTS[nPart].bPartInCombiIsInverted = BestCombination.bPartInCombiIsInverted