- Modifica a strategie per nuovo standard parametri custom

- Funzione apposita per calcolo 'CompletionIndex'
- Modifica valori di ritorno delle strategie. BOOL + TABLE
- Versione primordiale funzione OrderFeature
- Aggiornamento finale lavorazioni
This commit is contained in:
andrea.villa
2024-05-28 17:10:01 +02:00
parent 8eeb7fa6d8
commit d191825118
7 changed files with 190 additions and 77 deletions
+4 -14
View File
@@ -23,17 +23,7 @@ local function GetStrategies_Egalware( Proc)
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE
if Proc.Topology.sName == 'FEATURE' then
Strategies = {
{ sStrategyId = 'STR0001',
Parameters = {
{ sName = 'Step', sValue = '15', sType = 'd'},
{ sName = 'AntiSplint', sValue = 'false', sType = 'b'}
}
}
}
end
if ID.IsHeadCut( Proc) then
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsSplitCut( Proc) then
@@ -263,10 +253,10 @@ local function GetStrategies_Essetre( Proc)
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE
if Proc.Topology.sName == 'FEATURE' then
if ID.IsHeadCut( Proc) then -- TODO TOGLIERE STRATEGIA. Inserita solo per mostrare come devono essere scritti i dati
if Proc.Topology.sName == 'QQQQQQQQQ' then
Strategies = {
{ sStrategyId = 'STR0001',
{ sStrategyId = 'STR9999',
Parameters = {
{ sName = 'Step', sValue = '15', sType = 'd'},
{ sName = 'AntiSplint', sValue = 'false', sType = 'b'}
+133 -30
View File
@@ -667,28 +667,28 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1,
dChosenIndex = 0
elseif nIndex1 == 0 then
-- basta che sia applicabile
if AvailableStrategies[nIndex2].RatingResult and ( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Completed' or AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Completed') then
if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then
dChosenIndex = nIndex2
end
elseif nIndex2 == 0 then
-- basta che sia applicabile
if AvailableStrategies[nIndex1].RatingResult and ( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Completed' or AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Completed') then
if AvailableStrategies[nIndex1].Result and ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' or AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed') then
dChosenIndex = nIndex1
end
elseif not AvailableStrategies[nIndex1].RatingResult or not AvailableStrategies[nIndex2].RatingResult then
elseif not AvailableStrategies[nIndex1].Result or not AvailableStrategies[nIndex2].Result then
dChosenIndex = 0
elseif ( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Completed' and AvailableStrategies[nIndex2].RatingResult.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Applicable') then
elseif ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].Result.sStatus == 'Not-Applicable') then
dChosenIndex = nIndex1
elseif ( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Completed' and AvailableStrategies[nIndex1].RatingResult.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Applicable') then
elseif ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' and AvailableStrategies[nIndex1].Result.sStatus ~= 'Completed') or
( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then
dChosenIndex = nIndex2
else
-- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete)
if AvailableStrategies[nIndex1].RatingResult.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].RatingResult.sStatus ~= 'Not-Applicable' and
AvailableStrategies[nIndex1].RatingResult.sStatus == AvailableStrategies[nIndex2].RatingResult.sStatus then
local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].RatingResult.dRating + AvailableStrategies[nIndex1].RatingResult.dCompletionIndex
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].RatingResult.dRating + AvailableStrategies[nIndex2].RatingResult.dCompletionIndex
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.dRating + AvailableStrategies[nIndex1].Result.dCompletionIndex
local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.dRating + AvailableStrategies[nIndex2].Result.dCompletionIndex
-- si predilige strategia con rating composito più alto
if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then
dChosenIndex = nIndex1
@@ -721,36 +721,112 @@ local function GetBestStrategy( vProcSingleRot, Part)
CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId)
-- controllo che le librerie siano state effettivamente caricate
if CurrentStrategy.Config and CurrentStrategy.Script then
local bStrategyOk
-- 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].RatingResult = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters)
bStrategyOk, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters)
-- se la strategia è andata a buon fine
if bStrategyOk then
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
-- scelgo la migliore strategia tra le due
nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy)
-- se scelta strategia standard, esco subito alla prima che trovo completa
-- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then
if Proc.AvailableStrategies[nIndexBestStrategy].RatingResult.sStatus == 'Complete' then
break
-- se scelta strategia standard, esco subito alla prima che trovo completa
-- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!!
if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then
if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then
break
end
end
end
-- se non trovo i file della strategia, scrivo che non è più disponibile
else
Proc.AvailableStrategies[nIndexCurrentStrategy].RatingResult = {}
Proc.AvailableStrategies[nIndexCurrentStrategy].RatingResult.sInfo = 'Strategy not found'
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {}
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found'
end
end
-- salvo sulla proc la migliore strategia
if nIndexBestStrategy ~= 0 then
Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy]
end
-- salvo sulla proc la migliore strategia
if nIndexBestStrategy ~= 0 then
Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy]
end
end
end
end
return vProcSingleRot
end
-------------------------------------------------------------------------------------------------------------
-- Ordina le feature in base a fase di lavorazione
-- 1) Head : ( intestatura)
-- 2) Standard : ( lavorazioni standard che non impattano sulal coda)
-- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo)
-- 4) Split : ( taglio di separazione)
-- 5) Tail : ( lavorazionio di coda, fatte dopo il taglio di separazione)
local function OrderFeatures( vProc)
local vProcToSort = vProc
-- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1
local function CompareFeatures( B1, B2)
-- se secondo disabilitato, va lasciato dopo
if B1.nFlg ~= 0 and B2.nFlg == 0 then
return true
-- se entrambi disabilitati seguo l'Id
elseif B1.nFlg == 0 and B2.nFlg == 0 then
return ( B1.id < B2.id)
-- se in rotazioni diverse, si mette in ordine di rotazioni
elseif B1.nRot ~= B2.nRot then
return ( B1.nRot < B2.nRot)
-- se primo è taglio di testa, va prima degli altri casi
elseif B1.Head and ( B2.Standard or B2.AdvanceTail or B2.Split or B2.Tail) then
return true
-- se primo è taglio standard, va prima degli altri casi
elseif B1.Standard and ( B2.AdvanceTail or B2.Split or B2.Tail) then
return true
-- se primo è taglio di testa anticipata, va prima degli altri casi
elseif B1.AdvanceTail and ( B2.Split or B2.Tail) then
return true
-- se primo è taglio di separazione, va prima delle lavorazioni di coda
elseif B1.Split and B2.Tail then
return true
-- se da lavorare in stessa fase pezzo
elseif B1.Head == B2.Head or B1.Standard == B2.Standard or B1.AdvanceTail == B2.AdvanceTail or B1.Split == B2.Split or B1.Tail == B2.Tail then
-- confronto standard
if abs( B1.b3Box:getCenter():getX() - B2.b3Box:getCenter():getX()) > 0.4 * ( B1.b3Box:getDimX() + B2.b3Box:getDimX()) then
return B1.b3Box:getCenter():getX() > B2.b3Box:getCenter():getX()
elseif abs( B1.b3Box:getCenter():getY() - B2.b3Box:getCenter():getY()) > 0.2 * ( B1.b3Box:getDimY() + B2.b3Box:getDimY()) then
return B1.b3Box:getCenter():getY() > B2.b3Box:getCenter():getY()
elseif abs( B1.b3Box:getCenter():getZ() - B2.b3Box:getCenter():getZ()) > 0.1 * ( B1.b3Box:getDimZ() + B2.b3Box:getDimZ()) then
return B1.b3Box:getCenter():getZ() > B2.b3Box:getCenter():getZ()
end
-- altrimenti si inverte
else
return false
end
end
-- test della funzione di ordinamento
if EgtGetDebugLevel() >= 3 then
EgtOutLog( ' CompareFeatures Test ')
local bCompTest = true
for i = 1, #vProcToSort do
for j = i + 1, #vProcToSort do
local bComp1 = CompareFeatures( vProcToSort[i], vProcToSort[j])
local bComp2 = CompareFeatures( vProcToSort[j], vProcToSort[i])
if bComp1 == bComp2 then
bCompTest = false
EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProcToSort[i].Id, vProcToSort[j].Id))
end
end
end
if bCompTest then
EgtOutLog( ' ALL OK')
end
end
-- eseguo ordinamento
table.sort( vProcToSort, CompareFeatures)
return vProcToSort
end
-------------------------------------------------------------------------------------------------------------
-- esegue le strategie migliori che ha precedentemente scelto
local function ExecPieceFeatures( vProc, Part)
@@ -876,13 +952,12 @@ end
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- TODO ordinare feature e decidere spezzoni
-- ordino le features
-- OrderFeatures( vProc, Part)
-- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna
vProc = vProcRot[1]
-- ordino le features
vProc = OrderFeatures( vProc)
-- TODO da fare
-- esegue le strategie migliori che ha precedentemente scelto
ExecPieceFeatures( vProc, Part)
@@ -897,6 +972,34 @@ end
Part.idRaw = EgtGetNextRawPart( Part.idRaw)
end
-- Aggiornamento finale di tutto
EgtSetCurrPhase( 1)
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
-- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo)
if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then
EgtOutLog( ' **** RECALC ****')
bApplOk, sApplErrors, _ = EgtApplyAllMachinings()
EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC')
end
if not bApplOk then
nTotErr = nTotErr + 1
table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0})
elseif sApplWarns and #sApplWarns > 0 then
local vLine = EgtSplitString( sApplWarns, '\r\n')
for i = 1, #vLine do
local nPos = vLine[i]:find( '(WRN', 1, true)
if nPos then
local sData = vLine[i]:sub( nPos + 1, -2)
local vVal = EgtSplitString( sData, ',')
local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i')
local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i')
if nWarn and nCutId then
table.insert( Stats, { Err=-nWarn, Msg=vLine[i], Rot=0, CutId=nCutId, TaskId=0})
end
end
end
end
return ( nTotErr == 0), Stats
end
+25 -12
View File
@@ -228,16 +228,38 @@ function FeatureData.GetDrillingData( Proc)
return dDiam, dLen, nFcs, nFce
end
-------------------------------------------------------------------------------------------------------------
-- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato
function FeatureData.GetFeatureCompletionIndex( dCompletionPercentage)
-- indice di completamento
local dCompletionIndex = 0
-- nullo
if dCompletionPercentage < 5 then
dCompletionIndex = 0
-- Low
elseif dCompletionPercentage < 50 then
dCompletionIndex = 1
-- Medium
elseif dCompletionPercentage < 80 then
dCompletionIndex = 2
-- High / Complete
else
dCompletionIndex = 5
end
return dCompletionIndex
end
-------------------------------------------------------------------------------------------------------------
-- funzione che restituisce rating feature in base al numero di lavorazioni, tipo di utensili e indice di completamento
-- TODO feature da sistemare
function FeatureData.GetFeatureRating( sTypeTools, dCompletionPercentage)
function FeatureData.GetFeatureRating( sTypeTools, dCompletionIndex)
local dRating = 5
local dCompletionIndex = 0
local TypeTools = EgtSplitString( sTypeTools)
-- se non è stato fatto nulla, esco subito
if dCompletionPercentage == 0 then
if dCompletionIndex == 0 then
return 0
end
@@ -254,15 +276,6 @@ function FeatureData.GetFeatureRating( sTypeTools, dCompletionPercentage)
end
end
-- indice di completamento
if dCompletionPercentage < 50 then
dCompletionIndex = 1
elseif dCompletionPercentage < 80 then
dCompletionIndex = 2
else
dCompletionIndex = 5
end
dRating = dRating + dCompletionIndex
return dRating
end
+4 -4
View File
@@ -293,16 +293,16 @@ function MachiningLib.AddNewMachining( Machining)
elseif Machining.nType == MCH_MY.MILLING then
-- se utensile lama
if TOOLS[Machining.nToolIndex].sFamily == 'SAWBLADE' then
Machining.sTypeName = 'Cut'
Machining.sTypeName = 'Cut_'
else
Machining.sTypeName = 'Milling'
Machining.sTypeName = 'Milling_'
end
-- Pocketing
elseif Machining.nType == MCH_MY.POCKETING then
Machining.sTypeName = 'Pocketing'
Machining.sTypeName = 'Pocketing_'
-- Mortising
elseif Machining.nType == MCH_MY.MORTISING then
Machining.sTypeName = 'Mortising'
Machining.sTypeName = 'Mortising_'
end
-- se nome non definito, assegno alla lavorazioen un nome standard
+21 -14
View File
@@ -39,14 +39,19 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.RatingResult = {}
Strategy.Result = {}
if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.Config.sStrategyId .. ' not implemented'
EgtOutLog( sErr)
return false, sErr
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.dCompletionPercentage = 0
Strategy.Result.dRating = 0
Strategy.Result.sInfo = sErr
return false, Strategy.Result
end
local bApplyMachiningOK = true
local ToolInfo = {}
local Pocketing = {}
Pocketing.Steps = {}
@@ -66,13 +71,14 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
if ToolInfo.nToolIndex and TOOLS[ToolInfo.nToolIndex].sName then
if ToolInfo.dResidualDepth > 0 then
Strategy.RatingResult.sStatus = 'Not-Completed'
Strategy.Result.sStatus = 'Not-Completed'
else
Strategy.RatingResult.sStatus = 'Completed'
Strategy.Result.sStatus = 'Completed'
end
Strategy.RatingResult.dCompletionIndex = min( 100, ( ( Proc.MainFaces.BottomFace.dElevation - ToolInfo.dResidualDepth) / Proc.MainFaces.BottomFace.dElevation) * 100)
Strategy.RatingResult.dRating = FeatureData.GetFeatureRating( 'Mill', Strategy.RatingResult.dCompletionIndex)
Strategy.RatingResult.sInfo = ''
Strategy.Result.dCompletionPercentage = min( 100, ( ( Proc.MainFaces.BottomFace.dElevation - ToolInfo.dResidualDepth) / Proc.MainFaces.BottomFace.dElevation) * 100)
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
Strategy.Result.dRating = FeatureData.GetFeatureRating( 'Mill', Strategy.Result.nCompletionIndex)
Strategy.Result.sInfo = ''
-- se richiesto applico lavorazione
if bAddMachining then
@@ -161,7 +167,7 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
if vtNSplitFace and AreSameVectorExact( vtNSplitFace, Proc.MainFaces.BottomFace.vtN) then
Pocketing.idFaceToMachine = j - 1
Pocketing.idProc = vAddId[i]
MachiningLib.AddNewMachining( Pocketing)
bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing)
break
end
end
@@ -178,18 +184,19 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
Pocketing.LeadIn.dElevation = TOOLS[ToolInfo.nToolIndex].dDiameter/2
Pocketing.idFaceToMachine = Proc.MainFaces.BottomFace.id
Pocketing.idProc = Proc.id
MachiningLib.AddNewMachining( Pocketing)
bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing)
end
end
else
Strategy.RatingResult.sStatus = 'Not-Applicable'
Strategy.RatingResult.dCompletionIndex = 0
Strategy.RatingResult.dRating = 0
Strategy.RatingResult.sInfo = 'Mill not found'
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.dCompletionPercentage = 0
Strategy.Result.dRating = 0
Strategy.Result.sInfo = 'Mill not found'
bApplyMachiningOK = false
end
return Strategy.RatingResult
return bApplyMachiningOK, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -3,7 +3,7 @@
local STR0002Data = {
sStrategyId = 'STR0002',
Parameters = {
{ sName = 'dMaxCornerRadius', sValue = '15', sDescription = 'Affondamento lavorazione', sType = 'd'}
{ sName = 'dMaxCornerRadius', sValue = '15', sDescriptionShort = 'Max radius left on corners', sDescriptionLong = 'Radius-limit left by the tool at each corner of the feature', sType = 'd', sMinUserLevel = '1', sMessageId = ''}
}
}
+2 -2
View File
@@ -3,8 +3,8 @@
local STR0003Data = {
sStrategyId = 'STR0003',
Parameters = {
{ sName = 'bApplyOnlyBlade', sValue = 'false', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', idMessage = ''},
{ sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', idMessage = ''}
{ sName = 'bApplyOnlyBlade', sValue = 'false', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
}
}