From 7ee7b63224507dffb1e8a8a93df7fe155da6bfcb Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Mon, 19 May 2025 14:47:45 +0200 Subject: [PATCH] Prima versione funzionante foratura. Per ora gestisce solo lavorazione con punta a forare --- LuaLibs/BasicCustomerStrategies.lua | 2 + LuaLibs/BeamExec.lua | 2 + LuaLibs/FeatureLib.lua | 20 ++- LuaLibs/MachiningLib.lua | 104 +++++++++++++- Strategies/Standard/STR0011/STR0011.lua | 174 +++++++++++++++++++++++- 5 files changed, 293 insertions(+), 9 deletions(-) diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index a27b17a..98068a4 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -223,6 +223,7 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Drilling (0-40) elseif ID.IsDrilling( Proc) then + Strategies = { { sStrategyId = 'STR0011'}} --------------------------------------------------------------------- -- Feature : Tenon (1-50) elseif ID.IsTenon( Proc) then @@ -548,6 +549,7 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Drilling (0-40) elseif ID.IsDrilling( Proc) then + Strategies = { { sStrategyId = 'STR0011'}} --------------------------------------------------------------------- -- Feature : Tenon (1-50) elseif ID.IsTenon( Proc) then diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 6399efa..dd69e53 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -187,6 +187,8 @@ function BeamExec.GetToolsFromDB() end -- drillbit else + Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP', 'd') or ( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero un terzo del tagliente + Tool.dSideStep = Tool.dDiameter -- si utilizza SOLO per i calcoli del MRR Tool.dPerformanceIndex = Tool.dDiameter / Tool.dLength Tool.nQuality = 4 end diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 719140b..8f6c0e6 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -279,21 +279,27 @@ end ------------------------------------------------------------------------------------------------------------- -- Recupero dati foro e adattamento se speciale function FeatureLib.GetDrillingData( Proc) - local AuxId = EgtGetInfo( Proc.id, 'AUXID', 'i') + local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i') + if idAux then idAux = idAux + Proc.id end + local FeatureExtraInfo = {} -- verifico se foro da adattare if EgtExistsInfo( Proc.id, 'DiamUser') then - if AuxId then AuxId = AuxId + Proc.id end - if AuxId and EgtGetType( AuxId) == GDB_TY.CRV_ARC and BeamData.USER_HOLE_DIAM and BeamData.USER_HOLE_DIAM > 1 then - EgtModifyArcRadius( AuxId, BeamData.USER_HOLE_DIAM / 2) + if idAux and EgtGetType( idAux) == GDB_TY.CRV_ARC and BeamData.USER_HOLE_DIAM and BeamData.USER_HOLE_DIAM > 1 then + EgtModifyArcRadius( idAux, BeamData.USER_HOLE_DIAM / 2) end end - FeatureExtraInfo.dDrillDiam = EgtGetInfo( Proc.id, 'P12', 'd') or 0 - FeatureExtraInfo.dDrillLen = abs( EgtCurveThickness( Proc.id + AuxId)) or 0 + FeatureExtraInfo.dDrillDiam = 2 * EgtArcRadius( idAux) or EgtGetInfo( Proc.id, 'P12', 'd') or 0 + FeatureExtraInfo.dDrillLen = abs( EgtCurveThickness( idAux)) or 0 + FeatureExtraInfo.ptDrillCenter = EgtCP( idAux, GDB_RT.GLOB) + FeatureExtraInfo.vtDrillExtrusion = EgtCurveExtrusion( idAux, GDB_RT.GLOB) FeatureExtraInfo.nDrillFcs = EgtGetInfo( Proc.id, 'FCS', 'i') or 0 FeatureExtraInfo.nDrillFce = EgtGetInfo( Proc.id, 'FCE', 'i') or 0 + FeatureExtraInfo.bIsDrillOpen = ( FeatureExtraInfo.nDrillFcs ~= 0 and FeatureExtraInfo.nDrillFce ~= 0) + FeatureExtraInfo.bIsDrillHorizontal = abs( FeatureExtraInfo.vtDrillExtrusion:getZ()) < 10 * GEO.EPS_SMALL + FeatureExtraInfo.idAddAuxGeom = idAux return FeatureExtraInfo end @@ -512,7 +518,7 @@ function FeatureLib.GetFeatureQuality( sTypeTools) -- indice in base a utensile for i=1, #TypeTools do - if TypeTools[i] == 'Blade' then + if TypeTools[i] == 'Blade' or TypeTools[i] == 'Drill' then nQuality = min( nQuality, 5) elseif TypeTools[i] == 'Mill' then nQuality = min( nQuality, 4) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index ea262b2..264c22a 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -415,7 +415,109 @@ end ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche -- TODO da fare -function MachiningLib.FindDrill() +function MachiningLib.FindDrill( Proc, ToolSearchParameters) + local ToolInfo = {} + local nBestToolIndex + local dBestToolResidualDepth = 0 + + -- settio valori obbligatori + if not ToolSearchParameters.dToolDiameter then + ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam or 0 + end + if not ToolSearchParameters.dMaxToolDiameter then + ToolSearchParameters.dMaxToolDiameter = ToolSearchParameters.dToolDiameter + 100 * GEO.EPS_SMALL + end + if not ToolSearchParameters.dMinToolDiameter then + ToolSearchParameters.dMinToolDiameter = ToolSearchParameters.dToolDiameter - 100 * GEO.EPS_SMALL + end + + for i = 1, #TOOLS do + -- prima verifico che utensile sia compatibile + local bIsToolCompatible = true + -- se non è punta, non è compatibile + if TOOLS[i].sFamily ~= 'DRILLBIT' then + bIsToolCompatible = false + -- se viene passato il nome, tutti gli altri sono incompatibili + elseif ToolSearchParameters.sName and ToolSearchParameters.sName ~= TOOLS[i].sName then + bIsToolCompatible = false + -- controlli standard + elseif TOOLS[i].dDiameter > ToolSearchParameters.dMaxToolDiameter then + bIsToolCompatible = false + elseif TOOLS[i].dDiameter < ToolSearchParameters.dMinToolDiameter then + bIsToolCompatible = false + elseif TOOLS[i].SetupInfo.HeadType.bTop and + ToolSearchParameters.vtToolDirection:getZ() < TOOLS[i].SetupInfo.GetMinNz( ToolSearchParameters.vtToolDirection, TOOLS[i]) - GEO.EPS_ZERO then + bIsToolCompatible = false + elseif TOOLS[i].SetupInfo.HeadType.bBottom and + ToolSearchParameters.vtToolDirection:getZ() > TOOLS[i].SetupInfo.GetMaxNz( ToolSearchParameters.vtToolDirection, TOOLS[i]) + GEO.EPS_ZERO then + bIsToolCompatible = false + end + + -- scelgo il migliore + if bIsToolCompatible then + -- calcolo riduzione del massimo materiale utilizzabile + local ToolEntryAngle = GetToolEntryAngle( Proc, ToolSearchParameters.vtToolDirection) + -- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore. + local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, TOOLS[i].SetupInfo.dCAxisEncumbrance) + local dCurrentMaxMatReduction = BeamData.COLL_SIC or 5 + + -- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom) + -- TODO considerare anche il caso in cui lo stelo sia più grande del diametro utensile + -- TODO nei confronti tra valori gestire tolleranze + -- calcolo riduzione per non toccare con ToolHolder / Motore + if ToolEntryAngle.dValue > 0 and ToolEntryAngle.dValue < 90 then + dCurrentMaxMatReduction = dCurrentMaxMatReduction / ToolEntryAngle.dSin + ( ( dDimObjToCheck - TOOLS[i].dDiameter) / 2) / ToolEntryAngle.dTan + end + -- dCurrentResidualDepth = negativo -> mm extra disponibili, positivo -> limitare + local dCurrentResidualDepth = ToolSearchParameters.dElevation + dCurrentMaxMatReduction - TOOLS[i].dMaxDepth + + -- se non ancora trovato, oppure se completo e il migliore fino ad ora non è completo: corrente è il migliore + if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 0) then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + -- altrimenti scelgo il migliore + else + -- se entrambi completi + if dBestToolResidualDepth <= 0 and dCurrentResidualDepth <= 0 then + -- se il migliore era su aggregato e corrente montanto direttamente, prediligo utensile montato direttamente + if not TOOLS[i].SetupInfo.bToolOnAggregate and TOOLS[nBestToolIndex].SetupInfo.bToolOnAggregate then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + -- se hanno stesso montaggio + elseif TOOLS[i].SetupInfo.bToolOnAggregate == TOOLS[nBestToolIndex].SetupInfo.bToolOnAggregate then + -- se diametro diverso + if abs( TOOLS[i].dDiameter - TOOLS[nBestToolIndex].dDiameter) > 10 * GEO.EPS_SMALL then + -- si sceglie utensile dello stesso diametro del foro da lavorare + if abs( TOOLS[i].dDiameter - ToolSearchParameters.dToolDiameter) < 10 * GEO.EPS_SMALL then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + -- oppure utensile con performance maggiore + elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex then + nBestToolIndex = i + BestToolResidualDepth = dCurrentResidualDepth + end + -- scelgo utensile con indice di bontà utensile calcolato come: lunghezza / massimo materiale / diametro + elseif TOOLS[i].dPerformanceIndex > TOOLS[nBestToolIndex].dPerformanceIndex then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + end + end + -- se entrambi incompleti + elseif dBestToolResidualDepth > 0 and dCurrentResidualDepth > 0 then + --scelgo quello che lavora di più + if dCurrentResidualDepth < dBestToolResidualDepth then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + end + end + end + end + end + + ToolInfo.nToolIndex = nBestToolIndex + ToolInfo.dResidualDepth = dBestToolResidualDepth + + return ToolInfo end ------------------------------------------------------------------------------------------------------------- diff --git a/Strategies/Standard/STR0011/STR0011.lua b/Strategies/Standard/STR0011/STR0011.lua index 88aabdd..7e94409 100644 --- a/Strategies/Standard/STR0011/STR0011.lua +++ b/Strategies/Standard/STR0011/STR0011.lua @@ -9,11 +9,181 @@ local BeamData = require( 'BeamData') local MachiningLib = require( 'MachiningLib') local FeatureLib = require( 'FeatureLib') -- strategie di base -local FaceByMill = require('FACEBYMILL') -- Tabella per definizione modulo local STR0011 = {} local Strategy = {} + + +------------------------------------------------------------------------------------------------------------- +function GetDrillingStrategy( Proc, Part) + local ToolSearchParameters = {} + local Machining = {} + local Results = {} + + + -- TODO SISTEMARE!! Gestione foratura doppia con 2 teste da fare + -- TODO se non trova foratura, cercare tra le frese + -- TODO se foratura non completa, provare a cercare tra le frese + + -- se lavorazione orizzontale + if Proc.FeatureInfo.bIsDrillHorizontal then + local bDouble = false + local Drilling = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING) + Drilling.bIsApplicable = false + ToolSearchParameters = {} + ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP + ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion + ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam + Drilling.ToolInfo = {} + Drilling.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters) + if Drilling.ToolInfo.nToolIndex then + Drilling.nType = MCH_MY.DRILLING + Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + Drilling.dStep = TOOLS[Drilling.ToolInfo.nToolIndex].dStep + -- se lavorazione non completa + if Drilling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL then + bDouble = true + local dHalfDrill = ( Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP) / 2 + Drilling.sDepth = min( dHalfDrill, Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth) + Drilling.vtFaceNormal = Proc.FeatureInfo.vtDrillExtrusion + Drilling.bInvert = false + table.insert( Machining, Drilling) + local Drilling2 = BeamLib.TableCopyDeep( Drilling) + Drilling2.bInvert = true + table.insert( Machining, Drilling2) + else + Drilling.sDepth = 'TH' + Drilling.vtFaceNormal = Proc.FeatureInfo.vtDrillExtrusion + Drilling.bInvert = false + table.insert( Machining, Drilling) + end + + -- voto + if Drilling.ToolInfo.dResidualDepth < 0 or Proc.FeatureInfo.dDrillLen / 2 > Drilling.ToolInfo.dResidualDepth then + Strategy.Result.sStatus = 'Completed' + Strategy.Result.nCompletionIndex = 5 + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + Strategy.Result.sInfo = '' + else + Strategy.Result.sStatus = 'Not-Completed' + local dMachinedLen = EgtIf( bDouble, Machining[1].sDepth * 2, Proc.FeatureInfo.dDrillLen) + local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen) + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) + Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + end + end + -- se lavorazione verticale + else + -- si cerca utensile 1 + local Drilling = {} + ToolSearchParameters = {} + ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP + ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion + ToolSearchParameters.dToolDiameter = Proc.FeatureInfo.dDrillDiam + Drilling.ToolInfo = {} + Drilling.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters) + -- si cerca utensile 2 + local Drilling2 = {} + ToolSearchParameters = {} + ToolSearchParameters.dElevation = Proc.FeatureInfo.dDrillLen + BeamData.MILL_OVERLAP + ToolSearchParameters.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion + Drilling2.ToolInfo = {} + Drilling2.ToolInfo = MachiningLib.FindDrill( Proc, ToolSearchParameters) + + -- se utensile 1 esegue completamente + if Drilling.ToolInfo.nToolIndex and Drilling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then + Drilling.sDepth = 'TH' + Drilling.nType = MCH_MY.DRILLING + Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + table.insert( Machining, Drilling) + -- voto + Strategy.Result.sStatus = 'Completed' + Strategy.Result.nCompletionIndex = 5 + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + Strategy.Result.sInfo = '' + -- se utensile 2 esegue completamente + elseif Drilling2.ToolInfo.nToolIndex and Drilling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then + Drilling2.sDepth = 'TH' + Drilling2.nType = MCH_MY.DRILLING + Drilling2.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + Drilling2.bInvert = true + table.insert( Machining, Drilling2) + -- voto + Strategy.Result.sStatus = 'Completed' + Strategy.Result.nCompletionIndex = 5 + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + Strategy.Result.sInfo = '' + -- se possono lavorare entrambi + elseif Drilling.ToolInfo.nToolIndex and Drilling2.ToolInfo.nToolIndex then + Drilling.nType = MCH_MY.DRILLING + Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + table.insert( Machining, Drilling) + + Drilling2.nType = MCH_MY.DRILLING + Drilling2.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + Drilling2.bInvert = true + table.insert( Machining, Drilling2) + if Drilling.ToolInfo.dResidualDepth + Drilling2.ToolInfo.dResidualDepth < Proc.FeatureInfo.dDrillLen then + Strategy.Result.sStatus = 'Not-Completed' + local dMachinedLen = Machining[1].sDepth + Machining[2].sDepth + local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen) + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) + Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' + else + Strategy.Result.sStatus = 'Completed' + Strategy.Result.nCompletionIndex = 5 + Strategy.Result.sInfo = '' + end + -- voto + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + -- se utensile 1 non completo + elseif Drilling.ToolInfo.nToolIndex then + Drilling.sDepth = Proc.FeatureInfo.dDrillLen - Drilling.ToolInfo.dResidualDepth + Drilling.nType = MCH_MY.DRILLING + Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + table.insert( Machining, Drilling) + -- voto + Strategy.Result.sStatus = 'Not-Completed' + local dMachinedLen = Machining[1].sDepth + local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen) + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) + Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + -- se utensile 2 non completo + elseif Drilling2.ToolInfo.nToolIndex then + Drilling2.sDepth = Proc.FeatureInfo.dDrillLen - Drilling2.ToolInfo.dResidualDepth + Drilling2.nType = MCH_MY.DRILLING + Drilling2.nToolIndex = Drilling.ToolInfo.nToolIndex + Drilling2.Geometry = {{ Proc.FeatureInfo.idAddAuxGeom, 0}} + Drilling2.bInvert = true + table.insert( Machining, Drilling2) + -- voto + Strategy.Result.sStatus = 'Not-Completed' + local dMachinedLen = Machining[1].sDepth + local dMachinedPrercentage = 100 * ( dMachinedLen / Proc.FeatureInfo.dDrillLen) + Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage) + Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%' + Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo) + Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Drill') + end + end + return Machining, Results +end + ------------------------------------------------------------------------------------------------------------- function STR0011.Make( bAddMachining, Proc, Part, CustomParameters) -- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti) @@ -26,6 +196,8 @@ function STR0011.Make( bAddMachining, Proc, Part, CustomParameters) local bAreAllMachiningsAdded + Strategy.Machinings, Strategy.Results = GetDrillingStrategy( Proc, Part) + if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then -- aggiunge lavorazione for j = 1, #Strategy.Machinings do