- Prima bozza gestione matrice delle rotazioni

- Adeguamento strategia 0002 e SPLITCUT a nuovo metodo gestione matrice
This commit is contained in:
andrea.villa
2024-11-04 16:52:42 +01:00
parent c24fef22a7
commit 21da5f633d
6 changed files with 330 additions and 13 deletions
+259 -10
View File
@@ -101,9 +101,6 @@ function BeamExec.GetToolsFromDB()
-- se verifica condizioni minime, recupero tutti gli altri dati
if bToolLoadedOnSetup and sToolType then
-- TODO Tool.AName -> da rimuovere perchè non serve. Per il momento lo manteniamo solo perchè è più facile vedere e interpretare la lista utensili nella watch di zerobrane
-- Nell'utilizzo, si legge sempre il Tool.Name
Tool.AName = Tool.sName
Tool.sTcPos = sToolTCPos
Tool.sFamily = sToolFamily
Tool.sType = sToolType
@@ -673,6 +670,8 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
-- controllo indici
if nIndex1 == 0 and nIndex2 == 0 then
dChosenIndex = 0
elseif nIndex1 == nIndex2 then
dChosenIndex = nIndex1
elseif nIndex1 == 0 then
-- basta che sia applicabile
if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then
@@ -695,8 +694,8 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
-- 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
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.nQuality * AvailableStrategies[nIndex1].Result.nCompletionIndex * AvailableStrategies[nIndex1].Result.dMRR
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.nQuality * AvailableStrategies[nIndex2].Result.nCompletionIndex * AvailableStrategies[nIndex2].Result.dMRR
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.dCompositeRating
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.dCompositeRating
-- si predilige strategia con rating composito più alto
if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then
dChosenIndex = nIndex1
@@ -756,6 +755,7 @@ local function CalculateStrategies( vProcSingleRot, Part)
-- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
_, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters)
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = FeatureData.CalculateCompositeRating( Proc.AvailableStrategies[nIndexCurrentStrategy].Result)
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
-- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
if BEAM.GetFirstCompletedStrategy and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
@@ -924,12 +924,259 @@ function BeamExec.GetProcessings( PROCESSINGS, PARTS)
end
-------------------------------------------------------------------------------------------------------------
local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart)
-- TODO funziona da sviluppare completamente
local BestCombination = {}
BestCombination = ProcessingsOnPart.Rotation[1]
return BestCombination
-- funzione che controlla validità delle combinazioni proposte
local function IsCombinationAvailable( sCombination, nUnloadPos)
-- TODO : DA COMPLETARE CON LE POSSIBILI TIPOLOGIA DI SCELTA ROTAZIONE
local ExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
-- NON VALIDA SE : rotazione di partenza non attiva o se attiva la 3 rotazione(non gestita attualmente)
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, ExtraRotation, ExtraRotation) == '1' then
return false
else
return true
end
end
-------------------------------------------------------------------------------------------------------------
-- funzione che decide le combinazioni di rotazione per lavorare la trave
local function GetBestCombination( ListToCompare)
-- TODO scellta combinazione da fare!!!
local ChosenCombination = ListToCompare[1]
return ChosenCombination
end
-------------------------------------------------------------------------------------------------------------
-- funzione che decide le combinazioni di rotazione per lavorare la trave
local function GetProcessingListFromCombination( BestCombination)
local vProc = {}
-- aggiungo processing da fare in fase ribaltata
if #BestCombination.Rot180 > 0 then
for i = 1, #BestCombination.Rot180 do
BestCombination.Rot180[i].bDown = true
table.insert( vProc, BestCombination.Rot180[i])
end
end
-- aggiungo processing da fare in fase ruotata
if #BestCombination.Rot90 > 0 then
for i = 1, #BestCombination.Rot90 do
BestCombination.Rot90[i].bSide = true
table.insert( vProc, BestCombination.Rot90[i])
end
end
-- aggiungo processing da fare in ultima fase
if #BestCombination.Rot0 > 0 then
for i = 1, #BestCombination.Rot0 do
table.insert( vProc, BestCombination.Rot0[i])
end
end
return vProc
end
-------------------------------------------------------------------------------------------------------------
-- funzione che ritorna la Proc nella rotazione scelta
local function GetProcBestMachRotationFromList( ListToCompare)
local Data = {}
local Proc = {}
local nIndexChosenProcInRot = 1
-- se ci sono almeno 2 possibili soluzioni, scelgo la posizione migliore di lavorazione
if #ListToCompare > 1 then
-- formatto lista strategie disponibili come se le aspetta la funzione di compare
local AvailableStrategiesInRot = {}
for i = 1, #ListToCompare do
table.insert( AvailableStrategiesInRot, ListToCompare[i][1].ChosenStrategy)
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)
end
-- altrimenti prendo la prima
else
nIndexChosenProcInRot = 1
end
Proc = ListToCompare[nIndexChosenProcInRot][1]
Data.nIndexRotation = ListToCompare[nIndexChosenProcInRot].nRotation
Data.dCompositeRating = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.dCompositeRating
Data.bComplete = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Completed'
Data.bNotComplete = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Not-Completed'
Data.bNotExecute = ListToCompare[nIndexChosenProcInRot][1].ChosenStrategy.Result.sStatus == 'Not-Applicable'
return Proc, Data
end
-------------------------------------------------------------------------------------------------------------
local function WriteMatrixLog( ProcessingsOnPart)
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)
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
end
sLogLine = sLogLine .. sLogLineProc
else
sLogLine = sLogLine .. ' 0 (STR----) |'
end
end
EgtOutLog( sLogLine)
end
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
end
-------------------------------------------------------------------------------------------------------------
local function WriteCombinationLog( CombinationsList, BestCombination)
EgtOutLog( ' === === === === === === === === === === COMBINATIONS === === === === === === ')
EgtOutLog( ' COMBI (UNL) | RATING | COMPLETE | NO COMPL | NO EXEC | ROTATE |')
EgtOutLog( '---------------------------------------------------------------------------')
for CombiLog = 1, #CombinationsList do
local sLogLine = ' ' .. CombinationsList[CombiLog].sBitIndexCombination .. ' (' .. CombinationsList[CombiLog].nUnloadPos .. ') |'
-- rating
local sOtherField = tostring( CombinationsList[CombiLog].dTotalRating) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- completed
sOtherField = tostring( CombinationsList[CombiLog].nComplete) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- not completed
sOtherField = tostring( CombinationsList[CombiLog].nNotComplete) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- not executed
sOtherField = tostring( CombinationsList[CombiLog].nNotExecute) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- rotations
sOtherField = tostring( CombinationsList[CombiLog].nRotations) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
EgtOutLog( sLogLine)
end
EgtOutLog( '----------------------------------------')
EgtOutLog( ' BEST ROTATION : ' .. BestCombination.sBitIndexCombination .. ' (' .. BestCombination.nUnloadPos .. ')')
EgtOutLog( '---------------------------------------------------------------------------')
end
-------------------------------------------------------------------------------------------------------------
-- funzione che decide le combinazioni di rotazione per lavorare la trave
local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart)
-- TODO funzione da sviluppare completamente
local BestCombination = {}
local CombinationsList = {}
-- scrittura nel log della matrice delle rotazioni
if EgtGetDebugLevel() >= 3 then
WriteMatrixLog( ProcessingsOnPart)
end
-- per ogni posizione di scarico
for nUnloadPos = 1, 4 do
-- verifico tutte le combinazioni che ripettano lo scarico come desiderato
for i = 1, BeamLib.BinaryToDecimal( 1111) do
local nBitIndexCombination = BeamLib.DecimalToBinary( i)
local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4)
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos) then
local bRot90, bRot180
local SingleCombination = {}
SingleCombination.nRotations = 0
SingleCombination.dTotalRating = 0
SingleCombination.nComplete = 0
SingleCombination.nNotComplete = 0
SingleCombination.nNotExecute = 0
SingleCombination.sBitIndexCombination = sBitIndexCombination
SingleCombination.nUnloadPos = nUnloadPos
-- creo liste dei proc suddivisi per rotazione
SingleCombination.Rot0 = {}
SingleCombination.Rot90 = {}
SingleCombination.Rot180 = {}
-- ciclo su tutte le feature
for nProc = 1, #ProcessingsOnPart.Rotation[1] do
-- ciclo sulle rotazioni
local nNextRot = nUnloadPos
local ResultsList = {}
for nRotation = 1, 3 do
-- se rotazione abilitata da combinazione
if string.sub( sBitIndexCombination, nNextRot, nNextRot) == '1' then
-- controllo se è stata scelta una strategia
if ProcessingsOnPart.Rotation[nRotation][nProc].ChosenStrategy then
local Proc = {}
Proc.nRotation = nNextRot
table.insert( Proc, ProcessingsOnPart.Rotation[nNextRot][nProc])
table.insert( ResultsList, Proc)
end
end
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
end
-- se la feature può essere lavorata in almeno una rotazione
if #ResultsList > 0 then
local Proc, Data = GetProcBestMachRotationFromList( ResultsList)
-- inserisco la Proc nell'apposita lista
if Data.nIndexRotation == nUnloadPos then
table.insert( SingleCombination.Rot0, Proc)
elseif Data.nIndexRotation == nUnloadPos + 1 then
table.insert( SingleCombination.Rot90, Proc)
bRot90 = true
else
table.insert( SingleCombination.Rot180, Proc)
bRot180 = true
end
SingleCombination.dTotalRating = SingleCombination.dTotalRating + Data.dCompositeRating
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotExecute, 1, 0)
else
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
end
end
-- aggiungo rotazioni
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
table.insert( CombinationsList, SingleCombination)
end
end
end
BestCombination = GetBestCombination( CombinationsList)
-- scrittura nel log delle combinazioni possibili
if EgtGetDebugLevel() >= 3 then
WriteCombinationLog( CombinationsList, BestCombination)
end
local vFinalProc = GetProcessingListFromCombination( BestCombination)
return vFinalProc
end
-------------------------------------------------------------------------------------------------------------
function BeamExec.ProcessMachinings( PROCESSINGS, PARTS)
-- ciclo sui pezzi
@@ -1003,6 +1250,8 @@ function BeamExec.ProcessMachinings( PROCESSINGS, PARTS)
MachiningLib.AddOperations( vProc, PARTS[nPart])
EgtOutLog( ' *** End AddMachinings ***', 1)
-- azzero lavorazioni per pezzo successivo
MACHININGS = {}
-- indice pezzo successivo
nOrd = nOrd + 1
end
+48
View File
@@ -350,5 +350,53 @@ function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
return ''
end
---------------------------------------------------------------------
function BeamLib.BinaryToDecimal( dNumber)
local sNumberToConvert = tostring( dNumber)
local dResult = 0
local k = 0
for i = #sNumberToConvert, 1, -1 do
k = k + 1
local n = string.sub(sNumberToConvert, k, k)
dResult = dResult + n*(2^(i-1))
end
return dResult
end
---------------------------------------------------------------------
function BeamLib.DecimalToBinary( dNumber)
local sNumberToConvert = tostring( dNumber)
local n = sNumberToConvert
local tmp = {}
local sResult = ""
for i = sNumberToConvert, 0, -1 do
local q = math.modf(n)
n = n/2
local b = q%2
table.insert(tmp, b)
if (q == 1) then
break
end
end
for i = #tmp, 1, -1 do
sResult = sResult..tmp[i]
end
return tonumber( sResult)
end
---------------------------------------------------------------------
function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
local NumberString = tostring( dNumber)
while #NumberString < CharNumber do
NumberString = '0' .. NumberString
end
return NumberString
end
-------------------------------------------------------------------------------------------------------------
return BeamLib
+13 -1
View File
@@ -275,12 +275,24 @@ function FeatureData.GetFeatureQuality( sTypeTools)
end
-- se si utilizzano più utensili si perde in qualità
if #TypeTools > 1 then
nQuality = nQuality - 1
nQuality = max( nQuality - 1, 0.5)
end
return nQuality
end
-------------------------------------------------------------------------------------------------------------
-- funzione che calcola il 'CompositeRating' di ogni strategia
function FeatureData.CalculateCompositeRating( StrategyResult)
-- se ho tutti i dati che mi servono calcolo il rating della strategia applicato alla feature
if StrategyResult and StrategyResult.nQuality and StrategyResult.nCompletionIndex and StrategyResult.dMRR then
StrategyResult.dCompositeRating = ceil( StrategyResult.nQuality * StrategyResult.nCompletionIndex * StrategyResult.dMRR)
else
StrategyResult.dCompositeRating = 0
end
return StrategyResult
end
-------------------------------------------------------------------------------------------------------------
return FeatureData
-2
View File
@@ -527,7 +527,6 @@ function MachiningLib.AddOperations( vProc, Part)
EgtSetOperationMode( nOperationId, false)
end
-- TODO è giusto inserire queste info alla fine della lavorazione? oppure conviene creare un record in MACHININGS apposito per la disposizione?
-- se era taglio di separazione, aggiungo nuova fase
if MACHININGS[i].AuxiliaryData.bAddNewPhase then
@@ -542,7 +541,6 @@ function MachiningLib.AddOperations( vProc, Part)
EgtSetInfo( nDispId, 'TYPE', 'END')
EgtSetInfo( nDispId, 'ORD', MACHININGS[i].Proc.nIndexPartInParts)
end
else
return false, 'UNEXPECTED ERROR: Error on creating machining'
end
@@ -183,6 +183,7 @@ local function GetSplitStrategy( Proc, Part)
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
@@ -191,6 +192,8 @@ local function GetSplitStrategy( Proc, Part)
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
@@ -198,6 +201,7 @@ local function GetSplitStrategy( Proc, Part)
return Machining
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
@@ -206,6 +210,8 @@ local function GetSplitStrategy( Proc, Part)
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
+4
View File
@@ -134,6 +134,10 @@ local function GetBestPocketingStrategy( Proc)
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
-- se utensile scelto è su aggregato, ricalcolo la qualità
if TOOLS[Milling.ToolInfo.nToolIndex].SetupInfo.bToolOnAggregate then
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'MillOnAggregate')
end
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex