Merge branch 'CollectBasedOnCombinations' into develop

This commit is contained in:
andrea.villa
2024-11-14 10:25:24 +01:00
+156 -97
View File
@@ -215,6 +215,111 @@ function BeamExec.GetStrategiesFromJSONinBD()
end
end
-------------------------------------------------------------------------------------------------------------
-- funzione che controlla validità delle combinazioni proposte
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection)
-- se non utilizzo BEAMWALL, forzo comportamento BASIC
if not BEAM.BeamWall or not BEAM.Rotation then
BEAM.Rotation = {}
BEAM.Rotation.Basic = true
end
--------------------------------------------------------------------------
-- TODO scelta combinazione forzato DA RIMUOVERE!! Serve modifica al BEAM.
BEAM.BeamWall = true
BEAM.Rotation = {}
BEAM.Rotation.bBasic = true
BEAM.Rotation.bNoRotation = false
BEAM.Rotation.bAdvanced = false
--------------------------------------------------------------------------
-- BASIC : posizione di scarico come posizionamento iniziale
if not BEAM.BeamWall or BEAM.Rotation.bBasic 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
-- NO ROTATION : solo posizione di partenza
elseif BEAM.Rotation.bNoRotation then
if sCombination == '1000' and nUnloadPos == 1 then
return true
else
return false
end
-- ADVANCED : come BASIC ma ammesse anche le prerotazioni (posizione di scarico può essere diversa da posizione iniziale)
elseif BEAM.Rotation.bAdvanced then
local Rotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1)
local Rotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
local ExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
if not bSquareSection and ( nUnloadPos == 2 or nUnloadPos == 4) then
return false
else
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, ExtraRotation, ExtraRotation) == '1' then
return false
else
if not BeamData.ROT90 and string.sub( sCombination, Rotation90, Rotation90) == '1' then
return false
elseif not BeamData.ROT180 and string.sub( sCombination, Rotation180, Rotation180) == '1' then
return false
else
return true
end
end
end
end
end
-------------------------------------------------------------------------------------------------------------
local function GetAvailableCombinations( PartInfo)
local CombinationList = {}
CombinationList.Rotations = {0, 0, 0, 0} -- indice rotazione attiva, per calcolo collect feature
-- verifico tutte le combinazioni che possono essere considerate
for nUnloadPos = 1, 4 do
for i = 1, BeamLib.BinaryToDecimal( 1111) do
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) then
local Combination = {}
Combination.sBitIndexCombination = sBitIndexCombination
Combination.nUnloadPos = nUnloadPos
table.insert( CombinationList, Combination)
-- se posizionamento iniziale attivo
if string.sub( sBitIndexCombination, 1, 1) == '1' then
CombinationList.Rotations[1] = 1
end
-- se attiva rotazione 90
if string.sub( sBitIndexCombination, 2, 2) == '1' then
CombinationList.Rotations[2] = 1
end
-- se attiva rotazione 180
if string.sub( sBitIndexCombination, 3, 3) == '1' then
CombinationList.Rotations[3] = 1
end
-- se attiva rotazione 270
if string.sub( sBitIndexCombination, 4, 4) == '1' then
CombinationList.Rotations[4] = 1
end
end
end
end
return CombinationList
end
-------------------------------------------------------------------------------------------------------------
-- *** funzioni posizionamento pezzi all'interno della barra ***
-------------------------------------------------------------------------------------------------------------
@@ -342,8 +447,10 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS)
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
PARTS[i].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
PARTS[i].nIndexInParts = i
PARTS[i].CombinationList = GetAvailableCombinations( PARTS[i])
else
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')'
return false, sOut
@@ -891,17 +998,23 @@ function BeamExec.GetProcessings( PROCESSINGS, PARTS)
for nPart = 1, #PARTS do
if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end
local vProcRot = {}
-- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato
for dRotIndex = 1, 4 do
-- recupero le feature di lavorazione della trave
table.insert( vProcRot, CollectFeatures( PARTS[nPart]))
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart])
-- calcola le strategie applicabili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies)
vProcRot[dRotIndex] = CalculateStrategies( vProcRot[dRotIndex], PARTS[nPart])
for dRotIndex = 1, 4 do
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
if PARTS[nPart].CombinationList.Rotations[dRotIndex] == 1 then
-- recupero le feature di lavorazione della trave
table.insert( vProcRot, CollectFeatures( PARTS[nPart]))
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart])
-- calcola le strategie applicabili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies)
vProcRot[dRotIndex] = CalculateStrategies( vProcRot[dRotIndex], PARTS[nPart])
else
-- inserisco una tabella vuota
table.insert( vProcRot, {})
end
-- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione
-- vettore movimento grezzi per rotazione di 90deg ogni step
@@ -935,71 +1048,6 @@ function BeamExec.GetProcessings( PROCESSINGS, PARTS)
return PROCESSINGS
end
-------------------------------------------------------------------------------------------------------------
-- funzione che controlla validità delle combinazioni proposte
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection)
-- se non utilizzo BEAMWALL, forzo comportamento BASIC
if not BEAM.BeamWall or not BEAM.Rotation then
BEAM.Rotation = {}
BEAM.Rotation.Basic = true
end
-- TODO scelta combinazione forzato DA RIMUOVERE!! Serve modifica al BEAM.
BEAM.BeamWall = true
BEAM.Rotation = {}
BEAM.Rotation.bBasic = true
BEAM.Rotation.bNoRotation = false
BEAM.Rotation.bAdvanced = false
-- BASIC : posizione di scarico come posizionamento iniziale
if not BEAM.BeamWall or BEAM.Rotation.bBasic 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
-- NO ROTATION : solo posizione di partenza
elseif BEAM.Rotation.bNoRotation then
if sCombination == '1000' and nUnloadPos == 1 then
return true
else
return false
end
-- ADVANCED : come BASIC ma ammesse anche le prerotazioni (posizione di scarico può essere diversa da posizione iniziale)
elseif BEAM.Rotation.bAdvanced then
local Rotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1)
local Rotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
local ExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
if not bSquareSection and ( nUnloadPos == 2 or nUnloadPos == 4) then
return false
else
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, ExtraRotation, ExtraRotation) == '1' then
return false
else
if not BeamData.ROT90 and string.sub( sCombination, Rotation90, Rotation90) == '1' then
return false
elseif not BeamData.ROT180 and string.sub( sCombination, Rotation180, Rotation180) == '1' then
return false
else
return true
end
end
end
end
end
-------------------------------------------------------------------------------------------------------------
-- funzione che decide la migliore tra le combinazioni di rotazione disponibili
local function GetBestCombination( ListToCompare)
@@ -1113,27 +1161,42 @@ local function GetProcBestMachRotationFromList( ListToCompare)
end
-------------------------------------------------------------------------------------------------------------
local function WriteMatrixLog( ProcessingsOnPart)
local function WriteMatrixLog( ProcessingsOnPart, PartInfo)
EgtOutLog( ' === === === === === === === === === === ROTATION MATRIX === === === === === === === === === === === === ===')
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
for ProcLog = 1, #ProcessingsOnPart.Rotation[1] do
local sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[1][ProcLog].id)
local nProcessingsNumber
local nFirstAvailableRotation
-- ricerco prima rotazione effettivamente calcolata. In genere è sempre la prima
for i = 1, 4 do
if PartInfo.CombinationList.Rotations[i] == 1 then
nProcessingsNumber = #ProcessingsOnPart.Rotation[i]
nFirstAvailableRotation = i
break
end
end
for ProcLog = 1, nProcessingsNumber do
local sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[nFirstAvailableRotation][ProcLog].id)
while string.len( sLogLine) <= 20 do
sLogLine = sLogLine .. ' '
end
sLogLine = sLogLine .. '|'
for nRotLog = 1, 4 do
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy then
local sLogLineProc = tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.dCompositeRating) ..
' (' .. tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.sStrategyId) .. ') |'
while string.len( sLogLineProc) <= 20 do
sLogLineProc = ' ' .. sLogLineProc
if PartInfo.CombinationList.Rotations[nRotLog] == 1 then
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy then
local sLogLineProc = tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.dCompositeRating) ..
' (' .. tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.sStrategyId) .. ') |'
while string.len( sLogLineProc) <= 20 do
sLogLineProc = ' ' .. sLogLineProc
end
sLogLine = sLogLine .. sLogLineProc
else
sLogLine = sLogLine .. ' 0 (STR----) |'
end
sLogLine = sLogLine .. sLogLineProc
else
sLogLine = sLogLine .. ' 0 (STR----) |'
sLogLine = sLogLine .. ' NOT NEEDED |'
end
end
EgtOutLog( sLogLine)
@@ -1189,24 +1252,20 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore
local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
-- TODO funzione da sviluppare completamente
local BestCombination = {}
local CombinationsList = {}
local bSquareSection = abs( PartInfo.dWidth - PartInfo.dHeight) < 100 * GEO.EPS_SMALL
-- scrittura nel log della matrice delle rotazioni
if EgtGetDebugLevel() >= 3 then
WriteMatrixLog( ProcessingsOnPart)
WriteMatrixLog( ProcessingsOnPart, PartInfo)
end
-- per ogni posizione di scarico
for nUnloadPos = 1, 4 do
-- verifico tutte le combinazioni che possono essere considerate
for i = 1, BeamLib.BinaryToDecimal( 1111) do
local nBitIndexCombination = BeamLib.DecimalToBinary( i)
local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4)
-- TODO si potrebbero calcolare le combinazioni all'inizio, e ottimizzare facendo la collect solo nelle rotazioni che possono essere considerate
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, bSquareSection) then
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
for i = 1, #PartInfo.CombinationList do
-- controllo che la combinazione abbia ultima fase come quella calcolata in fase di definizione combinazioni
if PartInfo.CombinationList[i].nUnloadPos == nUnloadPos then
local bRot90, bRot180
local SingleCombination = {}
SingleCombination.nRotations = 0
@@ -1214,7 +1273,7 @@ local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
SingleCombination.nComplete = 0
SingleCombination.nNotComplete = 0
SingleCombination.nNotExecute = 0
SingleCombination.sBitIndexCombination = sBitIndexCombination
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
SingleCombination.nUnloadPos = nUnloadPos
-- creo liste dei proc suddivisi per rotazione
SingleCombination.Rot0 = {}
@@ -1228,7 +1287,7 @@ local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
local ResultsList = {}
for nRotation = 1, 3 do
-- se rotazione abilitata da combinazione
if string.sub( sBitIndexCombination, nNextRot, nNextRot) == '1' then
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
-- controllo se è stata scelta una strategia
if ProcessingsOnPart.Rotation[nNextRot][nProc].ChosenStrategy then
local Proc = {}
@@ -1276,7 +1335,7 @@ local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
error( 'UNEXPECTED ERROR: NO combinations available')
end
BestCombination = GetBestCombination( CombinationsList)
-- scrittura nel log delle combinazioni possibili
if EgtGetDebugLevel() >= 3 then
WriteCombinationLog( CombinationsList, BestCombination)