From f2816185cdf89d237977f8c8a871c95bf7241634 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Wed, 23 Jul 2025 16:02:22 +0200 Subject: [PATCH] Proma versione funzionante aggregato BlockHaus --- Beam/BeamData.lua | 3 +++ Common_ONE-PF.NUM.mlpe | 18 +++++++++++++++--- Common_ONE-PF.mlpe | 8 ++++---- Common_ONE-PF.mlse | 4 ++-- Essetre-PF.mlde | 16 ++++++++++------ Scripts/SetUp.lua | 9 +++++---- THolders/AngTransmBH.nge | Bin 6502 -> 6509 bytes 7 files changed, 39 insertions(+), 19 deletions(-) diff --git a/Beam/BeamData.lua b/Beam/BeamData.lua index 6cd5611..0b30ba3 100644 --- a/Beam/BeamData.lua +++ b/Beam/BeamData.lua @@ -68,6 +68,9 @@ local BeamData = { KIOTP = 5, -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare MAXDIAM_POCK_CORNER = 201, -- diametro massimo utensile ammesso per tasche con angoli interni USE_LONGCUT = true, -- per i tagli longitudinali usare solo la lavorazione di lama LongCut + HEAD_DIM_FOR_BH = 125, -- dimensione di ingombro della testa per block haus + MAX_LEN_BH_FROM_BOTTOM = 210, -- massima lunghezza lavorabile da un lato di block haus da sotto + MAX_DIST_BH_FROM_BOTTOM = 600, -- massima distanza tra naso mandrino e sopra della trave senza collisione ADVANCE_TAIL_CUT = true, -- per spostare prima del taglio di separazione il taglio di coda su pezzi corti con robabile caduta ADVANCE_TAIL_OFFS = 10, -- accorciamento taglio di coda avanzato (minimo 1) DOUBLE_HEAD_DOVETAIL = false, -- flag abilitazione lavorazione mortase a coda di rondine in doppio diff --git a/Common_ONE-PF.NUM.mlpe b/Common_ONE-PF.NUM.mlpe index 782da97..de52ab1 100644 --- a/Common_ONE-PF.NUM.mlpe +++ b/Common_ONE-PF.NUM.mlpe @@ -129,6 +129,11 @@ function OnToolData() local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( EMT.TDIST or ChSawLen, 1) sOut = sOut .. EgtIf( EMT.TCPOS == 'T111', ' G76H9998.2N411N414', ' G76H9998.2N511N514') EmtOutput( '('..sOut..')') + -- emissione dati aggregato BlockHaus + elseif EMT.HEAD == 'H17' then + sPos = EgtIf( #EMT.TCPOS == 2, EMT.TCPOS:gsub( 'T', 'N30'), EMT.TCPOS:gsub( 'T', 'N3')) + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( ( AngTrBHOffs), 1)..' G76H9998.2'..sPos..sPos + EmtOutput( '('..sOut..')') -- emissione dati utensile (esclusa sega a catena) else -- output info @@ -142,7 +147,6 @@ function OnToolData() if EMT.TCPOS == 'T201' then sPos = 'N411' else - sPos = EgtIf( #EMT.TCPOS == 2, EMT.TCPOS:gsub( 'T', 'N30'), EMT.TCPOS:gsub( 'T', 'N3')) end local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( dAddLen + EMT.TTOTLEN, 1)..' G76H9998.2'..sPos..sPos @@ -2507,10 +2511,15 @@ function MyAdjustLinearAxes() local Len = ( EMT.TDIST or ChSawLen) + Mill2Offs local LenRef = Mill2Offs vtE = Vector3d( EMT.ADIR) * Len - Z_AX() * LenRef + elseif EMT.HEAD == 'H17' then + local LenAux = AngTrBHOffs + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtAux * LenAux - Z_AX() * LenRef else EmtSetLastError( 1211, 'Head not defined ' .. ( EMT.HEAD or '')) end - if EMT.HEAD == 'H11' or EMT.HEAD == 'H12' or EMT.HEAD == 'H13' or EMT.HEAD == 'H15' then + if EMT.HEAD == 'H11' or EMT.HEAD == 'H12' or EMT.HEAD == 'H13' or EMT.HEAD == 'H15' or sHead == 'H17' then EMT.L1 = EMT.L1 - vtE:getX() EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() @@ -2623,6 +2632,9 @@ function GetToolRadLen() -- se sega a catena elseif HeadIsChainSaw( EMT.HEAD) then return EMT.TLEN, ( EMT.TDIST or ChSawLen) + -- se aggregato BlockHaus + elseif EMT.HEAD == 'H17' then + return EMT.TDIAM / 2, AngTrBHOffs end end @@ -3107,7 +3119,7 @@ function PreselectNextDiffHead( nMchId, sHead) EmitMoveStartHead( 1) EmitMoveWaitHead( 1) end - -- Emetto preselezione (non ammessa per sega a catena H13 e H23) + -- Emetto preselezione (non ammessa per sega a catena H13 e H23 e aggregato BlockHaus H17) if sNextHead == 'H11' then EmitMoveDataHead( 1, { X=-ParkX1, Z=MaxZ1, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos)}) EmitMoveStartHead( 1) diff --git a/Common_ONE-PF.mlpe b/Common_ONE-PF.mlpe index 2a5224e..fefbbee 100644 --- a/Common_ONE-PF.mlpe +++ b/Common_ONE-PF.mlpe @@ -648,7 +648,7 @@ function OnSimulToolDeselect( dPrevA) SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) -- deposito utensile lama - elseif EMT.PREVHEAD_H1 == 'H12' then + elseif EMT.PREVHEAD_H1 == 'H12' or EMT.PREVHEAD_H1 == 'H17' then -- simulo movimento SimulMoveAxes( 'B1', ParkB1, MCH_SIM_STEP.RAPROT, 'C1', ParkC1, MCH_SIM_STEP.RAPROT) SimulMoveAxis( 'X1', ParkX1, MCH_SIM_STEP.RAPID) @@ -716,7 +716,7 @@ function OnSimulToolDeselect( dPrevA) -- nascondo l'utensile sulla testa EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) -- prendo utensile fresa o lama - if EMT.NEXTHEAD == 'H11' or EMT.NEXTHEAD == 'H12' then + if EMT.NEXTHEAD == 'H11' or EMT.NEXTHEAD == 'H12' or EMT.NEXTHEAD == 'H17' then local MyParkX1 = EgtIf( GetHeadTCSet( EMT.NEXTHEAD, EMT.NEXTTCPOS) == 'Head1_TC1', ParkX1, ParkFrnX1) local MyParkB1 = ParkB1 local MyParkC1 = ParkC1 @@ -1084,7 +1084,7 @@ function OnSimulMoveStart() else if GetHeadTCSet( EMT.HEAD, EMT.TCPOS) == 'Head1_TC2' then -- se movimento iniziale da Zmax con lama o fresa - if EMT.HEAD == 'H11' or EMT.HEAD == 'H12' then + if EMT.HEAD == 'H11' or EMT.HEAD == 'H12' or EMT.HEAD == 'H17' then if EMT.ZMAX or EMT.FLAG == 1 or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then --EgtOutBox( 'Flag 2,1', 'Info Rapid') local bMoveZbeforeX = false @@ -2848,7 +2848,7 @@ end --------------------------------------------------------------------- function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2) - if sHead == 'H11' or sHead == 'H12' or HeadIsChainSaw( sHead) then + if sHead == 'H11' or sHead == 'H12' or sHead == 'H17' or HeadIsChainSaw( sHead) then return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) elseif sHead == 'H21' or sHead == 'H22' or HeadIsChainSaw( sHead) then return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) diff --git a/Common_ONE-PF.mlse b/Common_ONE-PF.mlse index 5a16ac7..68f9e34 100644 --- a/Common_ONE-PF.mlse +++ b/Common_ONE-PF.mlse @@ -72,7 +72,7 @@ function OnSpecialGetMaxZ() local vMZ = {{ Tz=0.85, Ez=390}, { Tz=0.5, Ez=280}, { Tz=-0.01, Ez=160}, { Tz=-0.5, Ez=1}, { Tz=-0.61, Ez=1}} EMC.MAXZ = ParkZ1 + CalcExtraZ( vtTpZm, vtT, vMZ) end - elseif EMC.HEAD == 'H12' and sHead_TC == 'Head1_TC1' then + elseif ( EMC.HEAD == 'H12' or EMC.HEAD == 'H17') and sHead_TC == 'Head1_TC1' then if vtTp:getX() > 0.4 and vtT:getX() > 0.4 then if bBSameSign and abs( EMC.R1 - EMC.R1p) < 165 then EMC.MAXZ = MaxZ1 - EgtIf( abs( EMC.R2) < 90.1 and abs( EMC.R2p) < 90.1, 0, 130) @@ -173,7 +173,7 @@ function OnSpecialMoveZup() if EMC.HEAD == 'H11' or EMC.HEAD == 'H21' then ; -- se lama posizionata su CU prossimo a testa 1 - elseif EMC.HEAD == 'H12' and sHead_TC == 'Head1_TC1' then + elseif ( EMC.HEAD == 'H12' or EMC.HEAD == 'H17') and sHead_TC == 'Head1_TC1' then -- se inclinata oltre 90 gradi e interferisce con la trave if ( EMC.R2 > 87.9 and ( EMC.R1 < 15.0 or EMC.R1 > 180.0)) or ( EMC.R2 < -87.9 and ( EMC.R1 > -15.0 and EMC.R1 < 180.0)) then local dZref = dZmax + min( 330 * vtT:getZ(), 0) + 260 * ( 1 - sqrt( 1- vtT:getZ() * vtT:getZ())) diff --git a/Essetre-PF.mlde b/Essetre-PF.mlde index a88670d..56966e6 100644 --- a/Essetre-PF.mlde +++ b/Essetre-PF.mlde @@ -378,7 +378,7 @@ if AggreBlockHaus then Parent = 'B1', HSet = 'H11', Type = MCH_HT.STD, - Pos = Point3d( AngTrBHLen, 0, -AngTrBHOffs), + Pos = Point3d( -AngTrBHLen, 0, -AngTrBHOffs), TDir = X_AX(), ADir = Z_AX(), Rot1W = 0.2, @@ -881,12 +881,16 @@ function OnSetHead() EmtModifyAxisHome( 'B1', ParkB1) EmtModifyAxisDirection( 'B1', X_AX()) -- se testa H12 (lama) - elseif EMC.HEAD == 'H12' then + elseif EMC.HEAD == 'H12' or EMC.HEAD == 'H17' then EmtModifyAxisHome( 'X1', ParkX1) EmtModifyAxisHome( 'Z1', ParkZ1) EmtModifyAxisHome( 'C1', ParkC1) EmtModifyAxisHome( 'B1', ParkB1) - EmtModifyAxisDirection( 'B1', Vector3d( cos( SawC1Offs), -sin( SawC1Offs), 0)) + if EMC.HEAD == 'H12' then + EmtModifyAxisDirection( 'B1', Vector3d( cos( SawC1Offs), -sin( SawC1Offs), 0)) + else + EmtModifyAxisDirection( 'B1', X_AX()) + end -- se testa H21 (fresa2) elseif EMC.HEAD == 'H21' then local dRawH = GetRawHeight() @@ -923,7 +927,7 @@ end --------------------------------------------------------------------- function GetHeadSet( sHead) - if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H15' then + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H15' or sHead == 'H17' then return 1 elseif sHead == 'H21' or sHead == 'H22' or sHead == 'H23' then return 2 @@ -937,7 +941,7 @@ end function GetHeadTCSet( sHead, sTcPos) local nPos = tonumber( string.sub( sTcPos, 2)) or 0 -- testa 1 - if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H15' then + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' or sHead == 'H15' or sHead == 'H17' then -- testa 1 su CU prossimo a testa 2 if nPos > 10 then return 'Head1_TC2' @@ -1001,7 +1005,7 @@ end --------------------------------------------------------------------- -- Funzione che ritorna ZExtra partendo dalla testa e dall'angolo verticale function GetZExtra( sHead, dAngV) - if sHead == 'H11' or sHead == 'H21' then + if sHead == 'H11' or sHead == 'H21' or sHead == 'H17' then if abs( dAngV) < 30.1 then return 400 elseif abs( dAngV) < 45.1 then diff --git a/Scripts/SetUp.lua b/Scripts/SetUp.lua index 78847d5..f00db67 100644 --- a/Scripts/SetUp.lua +++ b/Scripts/SetUp.lua @@ -25,11 +25,12 @@ local INVALIDPOS = "" local POS = "Pos" -- Geom Set -local GS = {{"H11", "H17"}} +local GS = {} -- Configurazione posizioni (con o senza TC2) local PositionTable = {} local SecondSaw = ( EgtGetHeadId( 'H22') ~= nil) +local AggreBH = ( EgtGetHeadId( 'H17') ~= nil) if SecondSaw then PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, @@ -38,7 +39,7 @@ if SecondSaw then {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, - {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = EgtIf( AggreBH, "H17", "H11"), Group = "G1"}, {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, {Pos = "Pos10", TcPos = "T11", Head = "H22", Group = "G3"}, {Pos = "Pos11", TcPos = "T13", Head = "H21", Group = "G3"}, @@ -61,7 +62,7 @@ else {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, - {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = EgtIf( AggreBH, "H17", "H11"), Group = "G1"}, {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, {Pos = "Pos10", TcPos = "T11", Head = "H21", Group = "G3"}, {Pos = "Pos11", TcPos = "T12", Head = "H21", Group = "G3"}, @@ -78,7 +79,7 @@ else table.insert( PositionTable, {Pos = "Pos21", TcPos = "T211", Head = "H23", Group = "G2"}) end end -local UsePositionHead = true +local UsePositionHead = false local function IsInGeomSet( ToolHead, PosHead) for GsIndex = 1, #GS do diff --git a/THolders/AngTransmBH.nge b/THolders/AngTransmBH.nge index 276505f5b4dc15f461ef4ef9e7eefc3c1bbf6755..ef9fe96c3a8c3fce3cc219dd8da6818329b243c8 100644 GIT binary patch delta 6389 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 DY{2yT delta 6389 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