Files
OmagCUT/CadCuts/VacuumCups.vb
T
Demetrio Cassarino 5145accc39 -aggiornato messggi
2025-07-14 08:41:49 +02:00

848 lines
35 KiB
VB.net

Imports EgtUILib
Module VacuumCups
' Tipo manipolatore con ventosa (0=assente, 1=dietro, 2=laterale)
Private m_nVacType As Integer = 0
' Dati del manipolatore
Private m_nTempId As Integer = GDB_ID.NULL
Private m_nVacId As Integer = GDB_ID.NULL
Private m_nRefId As Integer = GDB_ID.NULL
Private m_dPreferredRot As Double = 0
Private m_dPrefVertRotXMinus As Double = 0
Private m_dPrefVertRotXPlus As Double = 0
Private m_dPrefVertRotYMinus As Double = 0
Private m_dPrefVertRotYPlus As Double = 0
Private m_dDripRefAng As Double = 0
' dati carico massimo manipolatore
Private m_RawDensity As Double = 2500
Private m_RawWeight As Double = 0
Private m_MaxWeightSinglePlugger As Double = 250
Private m_MaxWeightDoublePlugger As Double = 750
Public bOverWeight As Boolean = False
' dati per rotazione ventose vicono al fine corsa Y e X
Private bRotateVacuumNearExtraStrokeY As Boolean = False
Private bRotateVacuumNearExtraStrokeX As Boolean = False
' dati stroke
Public bExtraStroke As Boolean = False
Public ptStartPointLift As Point3d
Public dDegRotStartAng As Double
' Nome del gruppo temporaneo per le ventose
Private Const VACTMP_GRP As String = "VacTmp"
Private m_sHeadName As String = VACUUM_HEAD
Public Sub ResetHeadName()
Dim bReload As Boolean = (m_sHeadName <> VACUUM_HEAD)
m_sHeadName = VACUUM_HEAD
If bReload Then LoadVacuumCups()
End Sub
Public Function ChangeHeadName() As Boolean
If EgtGetHeadId( VACUUM_HEAD_2) = GDB_ID.NULL Then Return False
m_sHeadName = If( m_sHeadName = VACUUM_HEAD, VACUUM_HEAD_2, VACUUM_HEAD)
LoadVacuumCups()
Return True
End Function
'-----------------------------------------------------------------------------------------------
Friend Class RawMoveData
Public m_nId As Integer
Public m_vtRawMove As Vector3d
Public m_dRawAngRotDeg As Double
Public m_vtDelta As Vector3d
Public m_dAngRotDeg As Double
Public m_sCups As String
Sub New()
m_nId = GDB_ID.NULL
m_vtRawMove = Vector3d.NULL()
m_dRawAngRotDeg = 0
m_vtDelta = Vector3d.NULL()
m_dAngRotDeg = 0
m_sCups = String.Empty
End Sub
Sub New(nId As Integer)
m_nId = nId
m_vtRawMove = Vector3d.NULL()
m_dRawAngRotDeg = 0
m_vtDelta = Vector3d.NULL()
m_dAngRotDeg = 0
m_sCups = String.Empty
End Sub
End Class
'-----------------------------------------------------------------------------------------------
Friend Function GetVacuumType() As Integer
Return m_nVacType
End Function
' carico i dati macchina relativi al peso massimo movimentabile
Friend Sub SetWeightInformation(Density As Double, MaxSingle As Double, MaxDouble As Double)
m_RawDensity = Density
m_MaxWeightSinglePlugger = MaxSingle
m_MaxWeightDoublePlugger = MaxDouble
End Sub
Friend Sub SetRotationForExtraStrokeY(Rotate As Boolean)
bRotateVacuumNearExtraStrokeY = Rotate
End Sub
Friend Sub SetRotationForExtraStrokeX(Rotate As Boolean)
bRotateVacuumNearExtraStrokeX = Rotate
End Sub
Friend Function GetVacuumId() As Integer
Return m_nVacId
End Function
Friend Function LoadVacuumCups() As Boolean
' Leggo tipo manipolatore con ventosa
m_nVacType = 0
EgtGetInfo(EgtGetHeadId(m_sHeadName), KEY_VAC_TYPE, m_nVacType)
' Cancello eventuali vecchie ventose
RemoveVacuumCups()
' Identificativo ventose nella macchina
Dim nLayId As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(m_sHeadName), VACUUM_HEAD_LAYOUT)
If nLayId = GDB_ID.NULL Then Return False
' Identificativo riferimento della testa nella macchina
Dim nT1Id As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(m_sHeadName), HEAD_FIRST_EXIT)
If nT1Id = GDB_ID.NULL Then Return False
' imposto la l'uscita della ventosa come fosse l'uscita di un utensile
EgtSetCalcTool("", m_sHeadName, 1)
' Creo gruppo temporaneo in cui copiarli
m_nTempId = EgtCreateGroup(GDB_ID.ROOT)
If m_nTempId = GDB_ID.NULL Then Return False
EgtSetName(m_nTempId, VACTMP_GRP)
EgtSetLevel(m_nTempId, GDB_LV.TEMP)
' Eseguo copia in globale
m_nVacId = EgtCopyGlob(nLayId, m_nTempId)
If m_nVacId = GDB_ID.NULL Then Return False
' Angolo di rotazione preferito
EgtGetInfo(m_nVacId, KEY_VACLAY_PREFROT, m_dPreferredRot)
' Angoli di rotazione preferiti per ventosa in verticale (lungo Y) a sinistra e a destra del centro tavola
EgtGetInfo(m_nVacId, KEY_VACLAY_PREFVROTXMINUS, m_dPrefVertRotXMinus)
EgtGetInfo(m_nVacId, KEY_VACLAY_PREFVROTXPLUS, m_dPrefVertRotXPlus)
EgtGetInfo(m_nVacId, KEY_VACLAY_PREFVROTYMINUS, m_dPrefVertRotYMinus)
EgtGetInfo(m_nVacId, KEY_VACLAY_PREFVROTYPLUS, m_dPrefVertRotYPlus)
' Direzione di riferimento per tagli Drip
EgtGetInfo(m_nVacId, KEY_VACLAY_DRIPREFDIR, m_dDripRefAng)
' Nascondo il gruppo ma rendo visibili le curve di contorno delle ventose
EgtSetStatus(m_nVacId, GDB_ST.OFF)
Dim nId As Integer = EgtGetFirstInGroup(m_nVacId)
While nId <> GDB_ID.NULL
Select Case EgtGetType(nId)
Case GDB_TY.CRV_LINE, GDB_TY.CRV_ARC, GDB_TY.CRV_BEZ, GDB_TY.CRV_COMPO
EgtSetStatus(nId, GDB_ST.ON_)
Case Else
EgtSetStatus(nId, GDB_ST.OFF)
End Select
nId = EgtGetNext(nId)
End While
m_nRefId = EgtCopyGlob(nT1Id, m_nVacId)
If m_nRefId = GDB_ID.NULL Then Return False
EgtSetStatus(m_nRefId, GDB_ST.ON_)
Return True
End Function
Friend Function RemoveVacuumCups() As Boolean
' Cancello eventuali gruppi per ventose usati appena prima
EgtErase(m_nTempId)
m_nTempId = GDB_ID.NULL
m_nVacId = GDB_ID.NULL
m_nRefId = GDB_ID.NULL
' Cancello eventuali vecchi gruppi per ventose
Dim nId As Integer = EgtGetFirstNameInGroup(GDB_ID.ROOT, VACTMP_GRP)
While nId <> GDB_ID.NULL
Dim nNextId As Integer = EgtGetNextName(nId, VACTMP_GRP)
EgtErase(nId)
nId = nNextId
End While
Return True
End Function
Friend Function ResetVacuumCups() As Boolean
' Ripristino posizione e rotazione originali
Dim frOriRef As New Frame3d
EgtFrame(EgtGetFirstNameInGroup(EgtGetHeadId(m_sHeadName), HEAD_FIRST_EXIT), GDB_ID.ROOT, frOriRef)
Dim frCurrRef As New Frame3d
EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef)
EgtMove(m_nVacId, frOriRef.Orig() - frCurrRef.Orig(), GDB_RT.GLOB)
frCurrRef.ToLoc(frOriRef)
Dim dLen, dAngVertDeg, dAngOrizzDeg As Double
frCurrRef.VersX().ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg)
EgtRotate(m_nVacId, frOriRef.Orig(), frOriRef.VersZ(), -dAngOrizzDeg, GDB_RT.GLOB)
' Ripristino visualizzazione originale
Dim nId As Integer = EgtGetFirstInGroup(m_nVacId)
While nId <> GDB_ID.NULL
Select Case EgtGetType(nId)
Case GDB_TY.CRV_LINE, GDB_TY.CRV_ARC, GDB_TY.CRV_BEZ, GDB_TY.CRV_COMPO
EgtSetStatus(nId, GDB_ST.ON_)
Case Else
EgtSetStatus(nId, GDB_ST.OFF)
End Select
nId = EgtGetNext(nId)
End While
EgtSetStatus(m_nRefId, GDB_ST.ON_)
Return True
End Function
Friend Function PutVacuumCupsOnRaw(nRawId As Integer, ByRef rmData As RawMoveData) As Boolean
' Ripristino posizione originale ventose
ResetVacuumCups()
' Box e baricentro del grezzo (riportato sopra al grezzo)
Dim b3Raw As New BBox3d
EgtGetRawPartBBox(nRawId, b3Raw)
Dim ptRawCen As Point3d
EgtGetRawPartCenter(nRawId, ptRawCen)
ptRawCen.z += b3Raw.DimZ() / 2
' Se non esiste, creo la regione del kerf del grezzo
Dim nKerfId As Integer = EgtGetFirstNameInGroup(nRawId, NAME_KERF)
Dim nRKerfId = EgtGetFirstNameInGroup(nRawId, NAME_KERF_REGION)
If nRKerfId = GDB_ID.NULL Then
nRKerfId = EgtCreateSurfFlatRegion(nRawId, nKerfId)
' se non sono riuscito a crearla, allora è nulla e posso uscire
If nRKerfId = GDB_ID.NULL Then Return False
EgtSetName(nRKerfId, NAME_KERF_REGION)
EgtSetMode(nRKerfId, GDB_MD.HIDDEN)
End If
' Box e baricentro della regione di kerf
Dim b3Kerf As New BBox3d
EgtGetBBoxGlob(nRKerfId, GDB_BB.STANDARD, b3Kerf)
Dim ptKerfCen As Point3d
EgtCentroid(nRKerfId, GDB_ID.ROOT, ptKerfCen)
'-------------------- INIZIO CALCOLO PESO --------------------
' recupero l'area del grezzo da muovere
Dim RawArea As Double = 0
' superficie del grezzo senza considerare eventuali fori
EgtSurfFrGrossArea(nRKerfId, RawArea)
' volume calcolato in mmc
Dim RawVolume As Double = RawArea * b3Raw.DimZ()
' peso calcolato in kg
m_RawWeight = RawVolume * m_RawDensity / Math.Pow(10, 9)
'-------------------- FINE CALCOLO PESO --------------------
' Eseguo ricerca
If FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nKerfId, nRKerfId, rmData) Then
Return True
Else
If ChangeHeadName() Then Return False
End If
' In caso di fallimento, provo riducendo con offset la regione di kerf
' (così si simula la proiezione del centro sul MAT - medial axis transform)
Dim bOkFind As Boolean = False
Dim vOffset() As Double = {-450, -350, -250, -150}
For i As Integer = 0 To vOffset.Length() - 1
Dim nRKerfOffsId = EgtCopy(nRKerfId, nRKerfId, GDB_POS.AFTER)
If EgtSurfFrOffset(nRKerfOffsId, vOffset(i), OFF_TYPE.FILLET) AndAlso
EgtCentroid(nRKerfOffsId, GDB_ID.ROOT, ptKerfCen) Then
Dim nOutOffsId As Integer = GetRegionOutLoop(nRKerfOffsId, nRawId)
bOkFind = FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nOutOffsId, nRKerfId, rmData)
EgtErase(nOutOffsId)
End If
EgtErase(nRKerfOffsId)
If bOkFind Then Return True
Next
Return False
End Function
' utilizzata per gestire la movimentazione dei pezzi per eseguire i drip
Friend Function PutVacuumCupsOnPart(nPartId As Integer,
ByRef rmData As RawMoveData, ByRef b3Part As BBox3d) As Boolean
' Ripristino posizione originale ventose
ResetVacuumCups()
' Verifico sia veramente un pezzo
If EgtGetRawPartFromPart(nPartId) = GDB_ID.NULL Then Return False
' Cerco la direzione del primo taglio attivo da sotto
Dim nDripLayId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_DRIPCUT)
Dim nDripLineId As Integer = EgtGetFirstInGroup(nDripLayId)
While nDripLineId <> GDB_ID.NULL
Dim nMchId As Integer = EgtGetOperationId("DripSaw" & nDripLineId.ToString())
Dim nMode As Integer
If EgtGetMode(nMchId, nMode) AndAlso nMode = GDB_MD.STD Then Exit While
nDripLineId = EgtGetNext(nDripLineId)
End While
Dim vtDir As New Vector3d
If EgtStartVector(nDripLineId, GDB_ID.ROOT, vtDir) Then
Dim dLen, dAngV, dAngH As Double
vtDir.ToSpherical(dLen, dAngV, dAngH)
Dim dOffsAng = dAngH - m_dDripRefAng
While dOffsAng - m_dPreferredRot >= 90
dOffsAng -= 180
End While
While dOffsAng - m_dPreferredRot <= -90
dOffsAng += 180
End While
m_dPreferredRot = dOffsAng
End If
' Recupero la regione del pezzo
Dim nGrpRegId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_REGION)
Dim nRegId As Integer = EgtGetFirstInGroup(nGrpRegId)
While nRegId <> GDB_ID.NULL
If EgtGetType(nRegId) = GDB_TY.SRF_FRGN Then Exit While
nRegId = EgtGetNext(nRegId)
End While
If nRegId = GDB_ID.NULL Then Return False
' Box e baricentro del pezzo (sempre sopra)
EgtGetBBoxGlob(nRegId, GDB_BB.STANDARD, b3Part)
Dim ptPartCen As Point3d
EgtCentroid(nRegId, GDB_ID.ROOT, ptPartCen)
' Calcolo il contorno esterno del pezzo
Dim nOutId As Integer = GetRegionOutLoop(nRegId, nGrpRegId)
If nOutId = GDB_ID.NULL Then Return False
' Eseguo ricerca
If FindVacuumCupsOnRaw(nPartId, ptPartCen, b3Part, ptPartCen, nOutId, nRegId, rmData) Then
EgtErase(nOutId)
Return True
Else
EgtErase(nOutId)
End If
' In caso di fallimento, provo riducendo con offset la regione di kerf
' (così si simula la proiezione del centro sul MAT - medial axis transform)
Dim bOkFind As Boolean = False
Dim vOffset() As Double = {-450, -350, -250, -150}
For i As Integer = 0 To vOffset.Length() - 1
Dim nRegOffsId As Integer = EgtCopy(nRegId, nRegId, GDB_POS.AFTER)
Dim ptRegOffsCen As Point3d
If EgtSurfFrOffset(nRegOffsId, vOffset(i), OFF_TYPE.FILLET) AndAlso
EgtCentroid(nRegOffsId, GDB_ID.ROOT, ptRegOffsCen) Then
Dim nOutOffsId As Integer = GetRegionOutLoop(nRegOffsId, nGrpRegId)
bOkFind = FindVacuumCupsOnRaw(nPartId, ptRegOffsCen, b3Part, ptPartCen, nOutOffsId, nRegId, rmData)
EgtErase(nOutOffsId)
End If
EgtErase(nRegOffsId)
If bOkFind Then Return True
Next
Return False
End Function
Private Function FindVacuumCupsOnRaw(nRawId As Integer, ptRawCen As Point3d,
b3Kerf As BBox3d, ptKerfCen As Point3d, nOutlineId As Integer, nRKerfId As Integer,
ByRef rmData As RawMoveData) As Boolean
' Cerco migliore configurazione di ventose per prendere il grezzo
Const MAX_SEL As Integer = 20
For nI As Integer = 1 To MAX_SEL
' Recupero la configurazione di ventose nI-esima
Dim sCups() As String = Nothing
Dim sCups2() As String = Nothing
If Not GetVacuumCupSelection(nI, sCups, sCups2) Then Return False
bExtraStroke = False
' Determino validità soluzioni della configurazione
Dim vtMove As New Vector3d
Dim ptRotCen As New Point3d
Dim dRotAngDeg As Double = 0
Dim vtMove2 As New Vector3d
Dim ptRotCen2 As New Point3d
Dim dRotAngDeg2 As Double = 0
Dim dDist = TestVacuumCupSelection(sCups, b3Kerf, ptKerfCen, nOutlineId, nRKerfId, vtMove, ptRotCen, dRotAngDeg)
Dim dDist2 = TestVacuumCupSelection(sCups2, b3Kerf, ptKerfCen, nOutlineId, nRKerfId, vtMove2, ptRotCen2, dRotAngDeg2)
If dDist > INFINITO - 1 And dDist2 > INFINITO - 1 Then Continue For
If dDist2 < dDist Then
sCups = sCups2
vtMove = vtMove2
ptRotCen = ptRotCen2
dRotAngDeg = dRotAngDeg2
End If
' Eseguo il movimento
EgtMove(m_nVacId, vtMove, GDB_RT.GLOB)
EgtRotate(m_nVacId, ptRotCen, Vector3d.Z_AX(), dRotAngDeg, GDB_RT.GLOB)
' Visualizzo le ventose
For nJ As Integer = 0 To sCups.Length() - 1
Dim nCupId = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ))
EgtSetStatus(nCupId, GDB_ST.ON_)
Next
' Calcolo delta posizione
Dim frCurrRef As New Frame3d
EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef)
Dim vtDelta As Vector3d = frCurrRef.Orig() - ptRawCen
' Assegno dati noti al movimento del grezzo
rmData.m_nId = nRawId
rmData.m_vtRawMove = Vector3d.NULL()
rmData.m_vtDelta = vtDelta
rmData.m_dAngRotDeg = dRotAngDeg
Dim sVal As String = String.Empty
For Each sCup As String In sCups
If String.IsNullOrEmpty(sVal) Then
sVal &= sCup
Else
sVal &= "," & sCup
End If
Next
rmData.m_sCups = sVal
Return True
Next
Return False
End Function
Private Function GetVacuumCupSelection(nInd As Integer, ByRef sCups() As String, ByRef sCups2() As String) As Boolean
' Recupero elenco ventose nella soluzione
Dim sSel As String = KEY_VACLAY_SEL & nInd.ToString()
Dim sVal As String = String.Empty
If Not EgtGetInfo(m_nVacId, sSel, sVal) Then Return False
If sVal.IndexOf("/") >= 0 Then
Dim sSplit() As String = sVal.Split("/".ToCharArray)
If sSplit.Length() >= 2 Then
sCups = sSplit(0).Split(",".ToCharArray)
sCups2 = sSplit(1).Split(",".ToCharArray)
ElseIf sSplit.Length() >= 1 Then
sCups = sSplit(0).Split(",".ToCharArray)
sCups2 = Nothing
Else
sCups = Nothing
sCups2 = Nothing
End If
Else
sCups = sVal.Split(",".ToCharArray)
sCups2 = Nothing
End If
Return True
End Function
Private Function GetVacRotAxisSteps(ByRef vAngRot As List(Of Double)) As Boolean
' Recupero l'asse rotante della testa ventosa
Dim nRotAxId As Integer = EgtGetParent(EgtGetHeadId(m_sHeadName))
' Verifico se contiene info con STEPS
Dim sSteps As String = ""
If Not EgtGetInfo(nRotAxId, KEY_ROTVAC_STEPS, sSteps) Then Return False
' Leggo gli step previsti
Dim vStep() As String = sSteps.Split(",".ToCharArray)
For Each sStep As String In vStep
Dim dStep As Double = 0
If StringToDouble(sStep, dStep) Then
vAngRot.Add(dStep)
End If
Next
Return True
End Function
Private Function TestVacuumCupSelection(sCups() As String, b3Raw As BBox3d, ptRawCen As Point3d, nOutlineId As Integer, nRawRegId As Integer,
ByRef vtMove As Vector3d, ByRef ptRotCen As Point3d, ByRef dRotAngDeg As Double) As Double
' Se definizione mancante, scarto soluzione
If IsNothing(sCups) Then Return INFINITO
' Ne calcolo il box
Dim b3Vac As New BBox3d
For nJ As Integer = 0 To sCups.Length() - 1
Dim nCupId = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ))
Dim b3Cup As New BBox3d
If EgtGetBBoxGlob(nCupId, GDB_BB.STANDARD, b3Cup) Then b3Vac.Add(b3Cup)
Next
If b3Vac.IsEmpty() Then Return INFINITO
' Se box maggiore di quello del pezzo, scarto soluzione
If b3Vac.Radius() > b3Raw.Radius() Then Return INFINITO
'-------------------- INIZIO VERIFICA PESO --------------------
bOverWeight = False
Select Case GetPluggerFromCameras(sCups)
Case 2
' se peso del grezzo oltre il limite consentito allora scarto la soluzione
If m_RawWeight > m_MaxWeightDoublePlugger Then
bOverWeight = True
Return INFINITO
End If
Case 1
' se peso del grezzo oltre il limite consentito allora scarto la soluzione
If m_RawWeight > m_MaxWeightSinglePlugger Then
bOverWeight = True
Return INFINITO
End If
End Select
'-------------------- FINE VERIFICA PESO --------------------
' Recupero l'area della tavola
Dim b3Tab As New BBox3d
EgtGetTableArea(1, b3Tab)
' Determino il movimento
vtMove = ptRawCen - b3Vac.Center()
b3Vac.Move(vtMove)
' Determino la rotazione, allineando il lato lungo delle ventose con quello del grezzo
ptRotCen = b3Vac.Center()
Dim frMinRect As New Frame3d
If EgtCurveMinAreaRectangleXY(nOutlineId, GDB_ID.ROOT, frMinRect) Then
Dim dLen, dAngVertDeg, dAngOrizzDeg As Double
frMinRect.VersX().ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg)
dRotAngDeg = dAngOrizzDeg
If b3Vac.DimY() > b3Vac.DimX() + EPS_SMALL Then dRotAngDeg -= 90
Dim dPreferredRot As Double = m_dPreferredRot
' -------------------- INIZIO GESTIONE ROTAZIONE ASSE C PER NON ANDARE IN EXTRA-CORSA --------------------
' verifico l'orientamento del pezzo
If bRotateVacuumNearExtraStrokeX And Not IsHorizontal(dAngOrizzDeg) Then
' se l'orientamento è verticale
If frMinRect.Orig().x < b3Tab.Center().x Then
dPreferredRot = m_dPrefVertRotXMinus
Else
dPreferredRot = m_dPrefVertRotXPlus
End If
ElseIf bRotateVacuumNearExtraStrokeY And IsHorizontal(dAngOrizzDeg) Then
' se l'orientemanto è orizzontale e la macchina è stata abilitata
If frMinRect.Orig().y < b3Tab.Center().y Then
dPreferredRot = m_dPrefVertRotYPlus
Else
dPreferredRot = m_dPrefVertRotYMinus
End If
End If
' -------------------- FINE GESTIONE ROTAZIONE ASSE C PER NON ANDARE IN EXTRA-CORSA --------------------
Dim dAngDelta As Double = If(Math.Abs(b3Vac.DimY() - b3Vac.DimX()) < 10 * EPS_SMALL, 90, 180)
While dRotAngDeg - dPreferredRot >= dAngDelta / 2
dRotAngDeg -= dAngDelta
End While
While dRotAngDeg - dPreferredRot <= -dAngDelta / 2
dRotAngDeg += dAngDelta
End While
Else
dRotAngDeg = 0
If (b3Vac.DimX() >= b3Vac.DimY() And b3Raw.DimX() < b3Raw.DimY()) Or
(b3Vac.DimX() < b3Vac.DimY() And b3Raw.DimX() >= b3Raw.DimY()) Then
dRotAngDeg = m_dPreferredRot
End If
End If
' Identificativi delle ventose
Dim nCups(sCups.Length() - 1) As Integer
For nJ As Integer = 0 To sCups.Length() - 1
nCups(nJ) = EgtGetFirstNameInGroup(m_nVacId, sCups(nJ))
Next
' Angoli di prova
Dim vAngRot As New List(Of Double)
' Se asse rotante ventosa a step
If GetVacRotAxisSteps(vAngRot) Then
' Ordino secondo distanza angolare crescente da direzione di allineamento (modulo 180 deg)
Dim dRotRefDeg As Double = dRotAngDeg
vAngRot.Sort(Function(P, Q)
Dim dDiffP = Math.Abs(P - dRotRefDeg)
If Math.Abs(dDiffP - 180) < 10 * EPS_ANG_SMALL Then dDiffP = 1
Dim dDiffQ = Math.Abs(Q - dRotRefDeg)
If Math.Abs(dDiffQ - 180) < 10 * EPS_ANG_SMALL Then dDiffQ = 1
Return (dDiffP - dDiffQ)
End Function)
' Annullo la rotazione di allineamento
dRotAngDeg = 0
' altrimenti in continuo
Else
' Assegno più valori di ricerca e conservo angolo di allineamento
vAngRot.AddRange({0, +5, -5, +12.5, -12.5, +25, -25, +45, -45})
End If
' Eseguo verifica delle ventose rispetto al grezzo
Dim bVacOk As Boolean = False
For i As Integer = 0 To vAngRot.Count() - 1
If TestVacuumCups(nCups, nRawRegId, vtMove, ptRotCen, dRotAngDeg + vAngRot(i)) Then
dRotAngDeg += vAngRot(i)
bVacOk = True
Exit For
End If
Next
If Not bVacOk Then Return INFINITO
' Recupero riferimento della testa ventose
Dim frCurrRef As New Frame3d
EgtFrame(m_nRefId, GDB_ID.ROOT, frCurrRef)
Dim ptRef As Point3d = frCurrRef.Orig()
' Applico movimento e rotazione al punto
ptRef.Move(vtMove)
ptRef.Rotate(ptRotCen, Vector3d.Z_AX(), dRotAngDeg)
' -------------- INIZIO verifica di essere nel limite delle corse macchina --------------
If VerifyOutOfStrokes(ptRef, dRotAngDeg) <> 0 Then
bExtraStroke = True
Return INFINITO
End If
' se la posizione è accettbaile allora salvo i dati
ptStartPointLift = ptRef
dDegRotStartAng = dRotAngDeg
' -------------- FINE verifica di essere nel limite delle corse macchina --------------
' Ne calcolo la distanza dal centro della tavola
Dim dDist As Double = Point3d.DistXY(ptRef, b3Tab.Center())
Return dDist
End Function
Private Function IsHorizontal(dDegAng As Double) As Boolean
If (Math.Abs(dDegAng) > 45 And Math.Abs(dDegAng) < 135) Or (Math.Abs(dDegAng) > 225 And Math.Abs(dDegAng) < 315) Then
Return False
End If
Return True
End Function
' assegnate le posizioni del centro delle ventose e l'angolo di posizionamento orizzontale verifica che la posizione sia raggiungibile
Public Function VerifyOutOfStrokes(ptRef As Point3d, dRotAngDeg As Double) As Integer
Dim sAxisName As String = "C"
' verifico che il nome dell'asse impostato sia corretto
If EgtGetAxisId(sAxisName) = GDB_ID.NULL Then
If m_sHeadName = VACUUM_HEAD Then
sAxisName = "C1"
Else
sAxisName = "C2"
End If
End If
' Posizione Home dell'asse rotante
Dim dCHome As Double
EgtGetAxisHomePos(sAxisName, dCHome)
' Corse dell'asse
Dim dCMin As Double
EgtGetAxisMin(sAxisName, dCMin)
Dim dCMax As Double
EgtGetAxisMax(sAxisName, dCMax)
' Porto l'angolo nel range
Dim dRotAngMachDeg As Double = dRotAngDeg + dCHome
AdjustAngleInRange(dRotAngMachDeg, dCMin, dCMax)
' Imposto la ventosa come fosse un utensile
EgtSetCalcTool("", m_sHeadName, 1)
' Calcolo gli assi macchina
Dim dX, dY, dZ As Double
Dim nStat As Integer
If EgtGetAxisId("A") <> GDB_ID.NULL Then
' Asse tavola rotante (movimenti solo con A0)
EgtGetCalcPositions(ptRef, 0, dRotAngMachDeg, nStat, dX, dY, dZ)
' Verifico le corse
EgtVerifyOutstroke(dX, dY, dZ, 0, dRotAngMachDeg, nStat)
Else
EgtGetCalcPositions(ptRef, dRotAngMachDeg, 0, nStat, dX, dY, dZ)
' Verifico le corse
EgtVerifyOutstroke(dX, dY, dZ, dRotAngMachDeg, 0, nStat)
End If
Return nStat
End Function
' dall'informazione di extra corsa recupera il valore indicato
Public Function GetExtraStrokeValue(sInfo As String) As Double
Dim dExtraStroke As Double = 0
Dim sItems As String() = sInfo.Split("="c)
If sItems.Count = 2 Then
Dim nStartIndex As Integer = 0
For Each ItemChar As Char In sItems(1)
If ItemChar = "("c Then
Exit For
End If
nStartIndex += 1
Next
If nStartIndex > 0 Then
Dim sValue As String = sItems(1).Remove(nStartIndex, sItems(1).Count - nStartIndex)
StringToLen(sValue, dExtraStroke)
End If
End If
Return dExtraStroke
End Function
Private Function TestVacuumCups(nCups() As Integer, nRawRegId As Integer,
vtMove As Vector3d, ptRotCen As Point3d, dRotAngDeg As Double) As Boolean
' Eseguo verifica delle ventose rispetto al grezzo
Dim bVacOk As Boolean = True
For nJ As Integer = 0 To nCups.Length() - 1
Dim nCupId = nCups(nJ)
' Eseguo rototraslazione delle ventose per verificare se sono contenute nel grezzo
EgtMove(nCupId, vtMove, GDB_RT.GLOB)
EgtRotate(nCupId, ptRotCen, Vector3d.Z_AX(), dRotAngDeg, GDB_RT.GLOB)
' Confronto le regioni
If EgtSurfFrChunkSimpleClassify(nRawRegId, 0, nCupId, 0) <> REGC.IN2 Then bVacOk = False
' Annullo rototraslazione
EgtRotate(nCupId, ptRotCen, Vector3d.Z_AX(), -dRotAngDeg, GDB_RT.GLOB)
EgtMove(nCupId, -vtMove, GDB_RT.GLOB)
' Se verifica fallita, esco dal ciclo
If Not bVacOk Then Exit For
Next
Return bVacOk
End Function
' dato il vettore delle camere restituisco il quali attuatori sono coinvolti
Private Function GetPluggerFromCameras(sCups() As String) As Integer
Dim nCountPlunger As Integer = 1
Dim bPlugger1 As Boolean = False
Dim bPlugger2 As Boolean = False
For Each Camera As String In sCups
If (Camera.Contains("1") Or Camera.Contains("2") Or Camera.Contains("3")) Then
bPlugger1 = True
Else
bPlugger2 = True
End If
Next
' verifico quali sono le camere attive
If bPlugger1 And bPlugger2 Then
nCountPlunger = 2
ElseIf Not bPlugger1 And Not bPlugger2 Then
nCountPlunger = 0
End If
' restituisco il numero di Plugger in uso
Return nCountPlunger
End Function
Friend Function SaveOneMoveInfo(nId As Integer, rmData As RawMoveData) As Boolean
' Assegno le informazioni
EgtSetInfo(nId, "Id", rmData.m_nId)
EgtSetInfo(nId, "Mv", rmData.m_vtRawMove)
EgtSetInfo(nId, "Rr", rmData.m_dRawAngRotDeg)
EgtSetInfo(nId, "Dt", rmData.m_vtDelta)
EgtSetInfo(nId, "Ad", rmData.m_dAngRotDeg)
EgtSetInfo(nId, "Vc", rmData.m_sCups)
EgtSetInfo(nId, "Vt", GetVacuumType())
Return True
End Function
Friend Function RemoveOneMoveInfo(nId As Integer) As Boolean
' Rimuovo le informazioni
EgtRemoveInfo(nId, "Id")
EgtRemoveInfo(nId, "Mv")
EgtRemoveInfo(nId, "Rr")
EgtRemoveInfo(nId, "Dt")
EgtRemoveInfo(nId, "Ad")
EgtRemoveInfo(nId, "Vc")
EgtRemoveInfo(nId, "Vt")
Return True
End Function
Friend Function SaveOneMoveInfoInDisposition(nDispId As Integer, rmData As RawMoveData) As Boolean
' Se movimento e rotazione trascurabili, inutile salvare
If rmData.m_vtRawMove.IsSmall() AndAlso Math.Abs(rmData.m_dRawAngRotDeg) < EPS_ANG_SMALL Then Return True
' Creo il gruppo
Dim nRpmId As Integer = EgtCreateGroup(nDispId)
If nRpmId = GDB_ID.NULL Then Return False
EgtSetName(nRpmId, "Rpm" & rmData.m_nId.ToString())
' Assegno le informazioni
SaveOneMoveInfo(nRpmId, rmData)
Return True
End Function
Friend Function SaveMoveInfoInDisposition(nDispId As Integer, rmList As List(Of RawMoveData)) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' aggiungo al gruppo disposizione dei sottogruppi con i dati di movimento dei grezzi spostati
For Each rmData As RawMoveData In rmList
If Not SaveOneMoveInfoInDisposition(nDispId, rmData) Then Return False
Next
Return True
End Function
Friend Function GetMoveInfoInDisposition(nDispId As Integer, ByRef rmList As List(Of RawMoveData)) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' Recupero i gruppi con i dati
Dim nRpmId As Integer = EgtGetFirstNameInGroup(nDispId, "Rpm*")
While nRpmId <> GDB_ID.NULL
' Recupero le informazioni
Dim rmData As New RawMoveData
EgtGetInfo(nRpmId, "Id", rmData.m_nId)
EgtGetInfo(nRpmId, "Mv", rmData.m_vtRawMove)
EgtGetInfo(nRpmId, "Rr", rmData.m_dRawAngRotDeg)
EgtGetInfo(nRpmId, "Dt", rmData.m_vtDelta)
EgtGetInfo(nRpmId, "Ad", rmData.m_dAngRotDeg)
EgtGetInfo(nRpmId, "Vc", rmData.m_sCups)
EgtGetInfo(nRpmId, "Vt", GetVacuumType())
' se non già presenti, le inserisco nella lista
If FindRawMoveData(rmData.m_nId, rmList) = -1 Then
rmList.Add(rmData)
End If
' Cerco un altro gruppo
nRpmId = EgtGetNextName(nRpmId, "Rpm*")
End While
Return True
End Function
Friend Function FindRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData)) As Integer
' Cerco in lista record con dati del grezzo indicato
Dim nInd As Integer = -1
For i As Integer = 0 To rmList.Count() - 1
If rmList(i).m_nId = nRawId Then
nInd = i
Exit For
End If
Next
Return nInd
End Function
Private Function AddRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData)) As Integer
' Cerco in lista record con dati del grezzo indicato
Dim nInd As Integer = -1
For i As Integer = 0 To rmList.Count() - 1
If rmList(i).m_nId = nRawId Then
nInd = i
Exit For
End If
Next
' Se trovato
If nInd <> -1 Then
' Se con movimenti trascurabili e non alla fine, lo sposto alla fine
If rmList(nInd).m_vtRawMove.IsSmall() AndAlso Math.Abs(rmList(nInd).m_dRawAngRotDeg) < EPS_ANG_SMALL AndAlso nInd <> rmList.Count() - 1 Then
rmList.Add(rmList(nInd))
rmList.RemoveAt(nInd)
nInd = rmList.Count() - 1
End If
' Se non trovato, lo accodo
Else
rmList.Add(New RawMoveData(nRawId))
nInd = rmList.Count() - 1
End If
Return nInd
End Function
Friend Function AddRawMoveData(nRawId As Integer, vtMove As Vector3d, ByRef rmList As List(Of RawMoveData)) As Integer
' Recupero o creo record con dati del grezzo indicato
Dim nInd As Integer = AddRawMoveData(nRawId, rmList)
If nInd = -1 Then Return -1
' Aggiorno i valori
rmList(nInd).m_vtRawMove += vtMove
Return nInd
End Function
Friend Function AddRawMoveData(nRawId As Integer, dRawAngRotDeg As Double, ByRef rmList As List(Of RawMoveData)) As Integer
' Recupero o creo record con dati del grezzo indicato
Dim nInd As Integer = AddRawMoveData(nRawId, rmList)
If nInd = -1 Then Return -1
' Aggiorno i valori
rmList(nInd).m_dRawAngRotDeg += dRawAngRotDeg
Return nInd
End Function
Friend Function AddRawMoveData(rmData As RawMoveData, ByRef rmList As List(Of RawMoveData)) As Integer
' Recupero o creo record con dati del grezzo indicato
Dim nInd As Integer = AddRawMoveData(rmData.m_nId, rmList)
If nInd = -1 Then Return -1
' Aggiorno i valori (tengo conto di quanto già ruotato il pezzo)
Dim vtDeltaRot As New Vector3d(rmData.m_vtDelta)
vtDeltaRot.Rotate(Vector3d.Z_AX(), -rmList(nInd).m_dRawAngRotDeg)
rmList(nInd).m_vtDelta = vtDeltaRot
rmList(nInd).m_dAngRotDeg = rmData.m_dAngRotDeg - rmList(nInd).m_dRawAngRotDeg
rmList(nInd).m_sCups = rmData.m_sCups
Return nInd
End Function
Friend Sub RemoveRawMoveData(nRawId As Integer, ByRef rmList As List(Of RawMoveData))
' Cerco in lista record con dati del grezzo indicato
Dim nInd As Integer = -1
For i As Integer = 0 To rmList.Count() - 1
If rmList(i).m_nId = nRawId Then
nInd = i
Exit For
End If
Next
' Se trovato, lo elimino
If nInd >= 0 Then
rmList.RemoveAt(nInd)
End If
End Sub
Friend Function SaveRemoveByHandInDisposition(nDispId As Integer, bRemoveByHand As Boolean) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' Imposto flag
EgtSetInfo(nDispId, "Rbh", bRemoveByHand)
Return True
End Function
Friend Function GetRemoveByHandInDisposition(nDispId As Integer) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' Leggo flag
Dim bRemoveByHand As Boolean = False
EgtGetInfo(nDispId, "Rbh", bRemoveByHand)
Return bRemoveByHand
End Function
Friend Function SaveMovePartsOnAuxTable(nDispId As Integer, bMovePartsOnAuxTab As Boolean) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' Imposto flag
EgtSetInfo(nDispId, "Pat", bMovePartsOnAuxTab)
Return True
End Function
End Module