Merge branch 'CollectBasedOnCombinations' into develop
This commit is contained in:
+156
-97
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user