Files
OmagCUT/VacuumCups.vb
T
Dario Sassi 3ccffe53b4 OmagCUT :
- sistemazioni per ventose manipolatore su pezzi a L
- PrevBtn attivo anche in muovi grezzi
- migliorata gestione componenti interni
- griglia ora si adatta all'unità di misura.
2016-08-31 18:09:34 +00:00

373 lines
16 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
'-----------------------------------------------------------------------------------------------
Friend Class RawMoveData
Public m_nId As Integer
Public m_vtMove As Vector3d
Public m_vtDelta As Vector3d
Public m_dAngRotDeg As Double
Public m_sCups As String
Sub New()
m_nId = GDB_ID.NULL
m_vtMove = Vector3d.NULL()
m_vtDelta = Vector3d.NULL()
m_dAngRotDeg = 0
m_sCups = String.Empty
End Sub
Sub New(nId As Integer)
m_nId = nId
m_vtMove = Vector3d.NULL()
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
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(VACUUM_HEAD), "VacType", m_nVacType)
' Cancello eventuali vecchie ventose
RemoveVacuumCups()
' Identificativo ventose nella macchina
Dim nLayId As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), VACUUM_HEAD_LAYOUT)
If nLayId = GDB_ID.NULL Then Return False
' Identificativo riferimento della testa nella macchina
Dim nT1Id As Integer = EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), HEAD_FIRST_EXIT)
If nT1Id = GDB_ID.NULL Then Return False
' 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")
EgtSetLevel(m_nTempId, GDB_LV.SYSTEM)
' Eseguo copia in globale
m_nVacId = EgtCopyGlob(nLayId, m_nTempId)
If m_nVacId = GDB_ID.NULL Then Return False
' 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 eventuale gruppo per ventose
EgtErase(m_nTempId)
m_nTempId = GDB_ID.NULL
m_nVacId = GDB_ID.NULL
m_nRefId = GDB_ID.NULL
Return True
End Function
Friend Function ResetVacuumCups() As Boolean
' Ripristino posizione e rotazione originali
Dim frOriRef As New Frame3d
EgtFrame(EgtGetFirstNameInGroup(EgtGetHeadId(VACUUM_HEAD), 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
GetRawBox(nRawId, b3Raw)
Dim ptRawCen As Point3d
GetRawCenter(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)
EgtSetStatus(nRKerfId, GDB_ST.OFF)
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)
' Eseguo ricerca
If FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nKerfId, nRKerfId, rmData) Then
Return True
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
bOkFind = FindVacuumCupsOnRaw(nRawId, ptRawCen, b3Kerf, ptKerfCen, nRKerfOffsId, nRKerfId, rmData)
End If
EgtErase(nRKerfOffsId)
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
' 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_vtMove = 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 = "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 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 Not ((b3Vac.DimX() < b3Raw.DimX() And b3Vac.DimY() < b3Raw.DimY()) Or
(b3Vac.DimX() < b3Raw.DimY() And b3Vac.DimY() < b3Raw.DimX())) Then
Return INFINITO
End If
' 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, nOutlineId, frMinRect) Then
Dim dLen, dAngVertDeg, dAngOrizzDeg As Double
frMinRect.VersX().ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg)
dRotAngDeg = dAngOrizzDeg
If b3Vac.DimY() > b3Vac.DimX() Then dRotAngDeg += 90
While dRotAngDeg > 90
dRotAngDeg -= 180
End While
While dRotAngDeg < -90
dRotAngDeg += 180
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 = 90
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
' Eseguo verifica delle ventose rispetto al grezzo
Dim bVacOk As Boolean = False
Dim vAngRot() As Double = {0, +5, -5, +12.5, -12.5, +25, -25, +45, -45}
For i As Integer = 0 To vAngRot.Length() - 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)
' Ne calcolo la distanza dal centro della tavola
Dim b3Tab As New BBox3d
EgtGetTableArea(1, b3Tab)
Dim dDist As Double = Point3d.DistXY(ptRef, b3Tab.Center())
Return dDist
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
Friend Function SaveMoveInfoInDisposition(nDispId As Integer, rmData As RawMoveData) As Boolean
' Verifico DispId
If EgtGetOperationType(nDispId) <> MCH_OY.DISP Then Return False
' 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
Dim sInfo As String = String.Empty
sInfo = rmData.m_nId.ToString()
EgtSetInfo(nRpmId, "Id", sInfo)
sInfo = DoubleToString(rmData.m_vtMove.x, 4) & "," &
DoubleToString(rmData.m_vtMove.y, 4) & "," &
DoubleToString(rmData.m_vtMove.z, 4)
EgtSetInfo(nRpmId, "Mv", sInfo)
sInfo = DoubleToString(rmData.m_vtDelta.x, 4) & "," &
DoubleToString(rmData.m_vtDelta.y, 4) & "," &
DoubleToString(rmData.m_vtDelta.z, 4)
EgtSetInfo(nRpmId, "Dt", sInfo)
sInfo = DoubleToString(rmData.m_dAngRotDeg, 4)
EgtSetInfo(nRpmId, "Ad", sInfo)
sInfo = rmData.m_sCups
EgtSetInfo(nRpmId, "Vc", sInfo)
sInfo = GetVacuumType().ToString()
EgtSetInfo(nRpmId, "Vt", sInfo)
Return True
End Function
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
End Module