From 30f59b01759624c77a838ba1d730862ee6bd9c03 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Tue, 9 Dec 2025 10:42:29 +0100 Subject: [PATCH] - Se lavorazione in positione standard, si setta bStd - Prima versione ottimizzazione lavorazioni !! Non funzionante in caso di cloni !! --- LuaLibs/BeamExec.lua | 21 +++-- LuaLibs/MachiningLib.lua | 173 +++++++++++++++++++++++++++++++-------- Process.lua | 2 +- 3 files changed, 158 insertions(+), 38 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 9075f54..cc1a2c6 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1150,7 +1150,7 @@ local function CalculateMachinings( vProc, Part, nInitialRotation) elseif Proc.bSide and nCurrRotation ~= n90Rotation then BeamLib.RotateRawPart( Part, n90Rotation - nCurrRotation) nCurrRotation = n90Rotation - elseif nCurrRotation ~= n0Rotation and not( Proc.bSide) and not( Proc.bDown) then + elseif Proc.bStd and nCurrRotation ~= n0Rotation then BeamLib.RotateRawPart( Part, n0Rotation - nCurrRotation) nCurrRotation = n0Rotation end @@ -1368,6 +1368,7 @@ local function GetProcessingListFromCombination( BestCombination) -- aggiungo processing da fare in ultima fase if #BestCombination.Rot0 > 0 then for i = 1, #BestCombination.Rot0 do + BestCombination.Rot0[i].bStd = true table.insert( vProc, BestCombination.Rot0[i]) end end @@ -1634,6 +1635,7 @@ function BeamExec.ProcessMachinings( PARTS) end -- altrimenti si fanno tutti i calcoli else + -- TODO serve ancora ordinare le feature con nuovo metodo di calcolo ottimizzazione lavorazioni? -- ordinamento di base delle feature vProc = OrderFeatures( vProc) @@ -1670,12 +1672,16 @@ function BeamExec.ProcessMachinings( PARTS) PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true elseif MACHININGS.Info.nHeadCutRotation == 3 then PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true + else + PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true end -- si imposta flag rotazione per taglio di coda if MACHININGS.Info.nSplitCutRotation == 2 then PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true elseif MACHININGS.Info.nSplitCutRotation == 3 then PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true + else + PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true end local vProcHeadTail = {} @@ -1685,13 +1691,14 @@ function BeamExec.ProcessMachinings( PARTS) bAllStrategiesApplied = false MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition) + -- si preparano le lavorazioni assegnandole al proprio stage + MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart]) + -- ordinamento lavorazioni -- TODO sostituire con sorting Egt - -- TODO completare ordinamento. Mancano le dipendenze. -- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze - MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart]) - MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings) - MACHININGS = MachiningLib.FinalizeSorting() + -- MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings) + -- MACHININGS = MachiningLib.FinalizeSorting() -- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase nRawId = PARTS[nPart].idRaw @@ -1775,6 +1782,10 @@ function BeamExec.ProcessMachinings( PARTS) -- aggiunta lavorazioni in ultima fase MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD') + -- ottimizzazione con algoritmo ShortestPath + -- TODO completare ordinamento. Mancano le dipendenze + MACHININGS = MachiningLib.ShortestPathSorting( MACHININGS) + EgtOutLog( ' *** End AddMachinings ***', 1) -- azzero lavorazioni per pezzo successivo MACHININGS = {} diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index e063b4d..c55ac8c 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -980,7 +980,7 @@ local function AddNewMachining( ProcToAdd, MachiningToAdd, AuxiliaryDataToAdd) nHeadCutRotation = 3 elseif ProcToAdd.bSide then nHeadCutRotation = 2 - else + else -- ProcToAdd.bStd nHeadCutRotation = 1 end MACHININGS.Info.nHeadCutRotation = max( MACHININGS.Info.nHeadCutRotation or 0, nHeadCutRotation) @@ -990,7 +990,7 @@ local function AddNewMachining( ProcToAdd, MachiningToAdd, AuxiliaryDataToAdd) nSplitCutRotation = 3 elseif ProcToAdd.bSide and MachiningToAdd.sStage == 'AfterTail' then nSplitCutRotation = 2 - else + else -- ProcToAdd.bStd nSplitCutRotation = 1 end MACHININGS.Info.nSplitCutRotation = max( MACHININGS.Info.nSplitCutRotation or 0, nSplitCutRotation) @@ -1120,7 +1120,7 @@ function MachiningLib.AddOperations( vProc, Part, sRotation) for i = 1, #MACHININGS do -- si aggiungono solo quelle della fase richiesta - if ( sRotation == 'STD' and not MACHININGS[i].Proc.bDown and not MACHININGS[i].Proc.bSide) or + if ( MACHININGS[i].Proc.bStd and sRotation == 'STD') or ( MACHININGS[i].Proc.bDown and sRotation == 'DOWN') or ( MACHININGS[i].Proc.bSide and sRotation == 'SIDE') then local nClonesToAdd = 1 @@ -1130,7 +1130,6 @@ function MachiningLib.AddOperations( vProc, Part, sRotation) for j = 1, nClonesToAdd do -- creazione lavorazione local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName) - if nOperationId then -- impostazione geometria local Geometry @@ -1228,6 +1227,7 @@ function MachiningLib.AddOperations( vProc, Part, sRotation) end local bIsApplyOk = MachiningLib.ApplyMachining( true, false) + -- se errore in applicazione if not bIsApplyOk then bAreAllMachiningApplyOk = false nErr, sErr = EgtGetLastMachMgrError() @@ -1237,36 +1237,44 @@ function MachiningLib.AddOperations( vProc, Part, sRotation) RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sStatus = 'Not-Applicable' RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sApplyInfo = sErr RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.nApplyError = nErr - -- se non deve essere igniorato, si salva ingombro lavorazione attuale e fasi successive - elseif not MACHININGS[i].AuxiliaryData.bIgnoreNotClampableLength then - -- salvo ingombro non pinzabile testa/coda - local nCurrRotation = MACHININGS[i].Proc.nIndexRotation - local dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nCurrRotation) - Part.NotClampableLength[sRotation].dHead = max( Part.NotClampableLength[sRotation].dHead, dNotClampHead) - Part.NotClampableLength[sRotation].dTail = max( Part.NotClampableLength[sRotation].dTail, dNotClampTail) + -- se applicazione andata a buon fine + else + -- si salva sulla lista info lavorazione applicata + MACHININGS[i].Machining.MachStartAxesPos = EgtGetMachiningStartAxes() + MACHININGS[i].Machining.MachEndAxesPos = EgtGetMachiningEndAxes() + MACHININGS[i].Machining.nOperationId = nOperationId - if sRotation == 'DOWN' then + -- se non deve essere igniorato, si salva ingombro lavorazione attuale e fasi successive + if not MACHININGS[i].AuxiliaryData.bIgnoreNotClampableLength then + -- salvo ingombro non pinzabile testa/coda + local nCurrRotation = MACHININGS[i].Proc.nIndexRotation + local dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nCurrRotation) + Part.NotClampableLength[sRotation].dHead = max( Part.NotClampableLength[sRotation].dHead, dNotClampHead) + Part.NotClampableLength[sRotation].dTail = max( Part.NotClampableLength[sRotation].dTail, dNotClampTail) + + if sRotation == 'DOWN' then + local nNextRotation = EgtIf( nCurrRotation - 1 < 1, nCurrRotation - 1 + 4, nCurrRotation - 1) + -- se rotazione attiva (SIDE) + if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then + dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) + Part.NotClampableLength['SIDE'].dHead = max( Part.NotClampableLength['SIDE'].dHead, dNotClampHead) + Part.NotClampableLength['SIDE'].dTail = max( Part.NotClampableLength['SIDE'].dTail, dNotClampTail) + end + nNextRotation = EgtIf( nNextRotation - 1 < 1, nNextRotation - 1 + 4, nNextRotation - 1) + -- se rotazione attiva (STD) + if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then + dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) + Part.NotClampableLength['STD'].dHead = max( Part.NotClampableLength['STD'].dHead, dNotClampHead) + Part.NotClampableLength['STD'].dTail = max( Part.NotClampableLength['STD'].dTail, dNotClampTail) + end + elseif sRotation == 'SIDE' then local nNextRotation = EgtIf( nCurrRotation - 1 < 1, nCurrRotation - 1 + 4, nCurrRotation - 1) - -- se rotazione attiva (SIDE) - if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then - dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) - Part.NotClampableLength['SIDE'].dHead = max( Part.NotClampableLength['SIDE'].dHead, dNotClampHead) - Part.NotClampableLength['SIDE'].dTail = max( Part.NotClampableLength['SIDE'].dTail, dNotClampTail) - end - nNextRotation = EgtIf( nNextRotation - 1 < 1, nNextRotation - 1 + 4, nNextRotation - 1) - -- se rotazione attiva (STD) - if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then - dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) - Part.NotClampableLength['STD'].dHead = max( Part.NotClampableLength['STD'].dHead, dNotClampHead) - Part.NotClampableLength['STD'].dTail = max( Part.NotClampableLength['STD'].dTail, dNotClampTail) - end - elseif sRotation == 'SIDE' then - local nNextRotation = EgtIf( nCurrRotation - 1 < 1, nCurrRotation - 1 + 4, nCurrRotation - 1) - -- se rotazione attiva (STD) - if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then - dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) - Part.NotClampableLength['STD'].dHead = max( Part.NotClampableLength['STD'].dHead, dNotClampHead) - Part.NotClampableLength['STD'].dTail = max( Part.NotClampableLength['STD'].dTail, dNotClampTail) + -- se rotazione attiva (STD) + if string.sub( Part.ChosenCombination, nNextRotation, nNextRotation) == '1' then + dNotClampHead, dNotClampTail = FeatureLib.GetFeatureRotationNotClampableLengths( MACHININGS[i].Proc, Part, nNextRotation) + Part.NotClampableLength['STD'].dHead = max( Part.NotClampableLength['STD'].dHead, dNotClampHead) + Part.NotClampableLength['STD'].dTail = max( Part.NotClampableLength['STD'].dTail, dNotClampTail) + end end end end @@ -1708,5 +1716,106 @@ function MachiningLib.CompareMachinings( MachiningA, MachiningB) return false end + +------------------------------------------------------------------------------------------------------------- +local function OrderMachining( MachiningOptList) + -- Recupero l'identificativo del gruppo di lavoro corrente + for i = 1, #MachiningOptList - 1 do + local idSource = MACHININGS[MachiningOptList[i+1]].Machining.nOperationId + local idRef = MACHININGS[MachiningOptList[i]].Machining.nOperationId + EgtRelocateGlob( idSource, idRef, GDB_IN.AFTER) + end +end +------------------------------------------------------------------------------------------------------------- +function MachiningLib.ShortestPathSorting( MachiningList) + -- verificare se serve settare prima e ultima lavorazione + -- EgtOptMachSetFirstMachining( int nId) + -- EgtOptMachSetLastMachining( int nId) + + -- Recupero l'identificativo del gruppo di lavoro corrente + local nOperation = EgtGetFirstOperation() + + local nMachiningIndexInGlobList = 0 + while nOperation do + if EgtGetOperationType( nOperation) ~= MCH_OY.DISP then + local MachiningOptList = {} + + -- inizio + EgtOptMachInit() + + -- leggere feed dalla macchina + EgtOptMachSetFeeds( 10000, 2000) + + -- tra gruppi (stage) non si può ottimizzare + EgtOptMachSetAllGroupsDependencesAsMandatory( true) + + local nMachiningInDisp = 0 + while EgtGetOperationType( nOperation) ~= MCH_OY.DISP do + nMachiningIndexInGlobList = nMachiningIndexInGlobList + 1 + nMachiningInDisp = nMachiningInDisp + 1 + + table.insert( MachiningOptList, nMachiningIndexInGlobList) + local nToolIndex = MachiningList[nMachiningIndexInGlobList].Machining.nToolIndex + -- TODO leggere tempo cambio utensile e posizione del magazzino da macchina + EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C]) + + -- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande + local nGroup = 10 - MachiningList[nMachiningIndexInGlobList].Machining.nStage + local MachStartAxesPos = MachiningList[nMachiningIndexInGlobList].Machining.MachStartAxesPos + local MachEndAxesPos = MachiningList[nMachiningIndexInGlobList].Machining.MachEndAxesPos + EgtOptMachAddMachining( nMachiningIndexInGlobList, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos) + + nOperation = EgtGetNextOperation( nOperation) + end + + local nStartIndex = nMachiningIndexInGlobList - nMachiningInDisp + 1 + local nStopIndex = nMachiningIndexInGlobList + -- cliclo su tutte le lavorazioni + for i = nStartIndex, nStopIndex do + for j = nStartIndex, nStopIndex do + -- se non è stessa lavorazione, imposto dati e dipendenze + if i ~= j then + -- se stessa Proc + if MachiningList[i].Proc.id == MachiningList[j].Proc.id then + -- se lavorazioni della stessa feature, obbligatorio rispettare ordine + if MachiningList[i].Machining.nFeatureInternalIndex < MachiningList[j].Machining.nFeatureInternalIndex then + EgtOptMachAddDependence( i, j) + end + -- se tra due Proc diverse + else + -- TODO : + -- se ci sono dipendenze tra due feature diverse, la dipendenza è obbligatoria! ATTENZIONE A DIPENDENZE INCROCIATE A->B, B->C, C->A + + -- se in diversa rotazione dipendenza obbligatoria + if MachiningList[i].Proc.bDown and ( MachiningList[j].Proc.bStd or MachiningList[j].Proc.bSide) then + EgtOptMachAddDependence( i, j) + elseif MachiningList[i].Proc.bSide and MachiningList[j].Proc.bStd then + EgtOptMachAddDependence( i, j) + -- dipendenza suggerita se sono su segmenti diversi (non sempre il segmento è settato) + elseif MachiningList[i].Machining.nFeatureSegment and MachiningList[j].Machining.nFeatureSegment and + MachiningList[i].Machining.nFeatureSegment < MachiningList[j].Machining.nFeatureSegment then + EgtOptMachAddSuggestedDependence( i, j) + end + end + end + end + end + + -- calcolo ordine lavorazioni + MachiningOptList = EgtOptMachGetResult( MachiningOptList) + + OrderMachining( MachiningOptList) + + -- fine + EgtOptMachTerminate() + end + nOperation = EgtGetNextOperation( nOperation) + end + + + return MachiningList +end + + ------------------------------------------------------------------------------------------------------------- return MachiningLib diff --git a/Process.lua b/Process.lua index 448d9fc..ff9d242 100644 --- a/Process.lua +++ b/Process.lua @@ -7,7 +7,7 @@ -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() -EgtEnableDebug( false) +EgtEnableDebug( true) -- Imposto direttorio libreria specializzata per Travi EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')