'---------------------------------------------------------------------------- ' EgalTech 2015-2015 '---------------------------------------------------------------------------- ' File : Camera.vb Data : 08.10.15 Versione : 1.6j1 ' Contenuto : Classe Camera (gestione della macchina fotografica). ' ' ' ' Modifiche : 08.10.15 DS Creazione modulo. ' ' '---------------------------------------------------------------------------- Imports System.Threading Imports System.IO Imports EgtUILib Imports System.Reflection Public Class Camera ' Riferimento alla MainWindow Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow) ' Dati Private m_bCameraLink As Boolean = False Private m_bCalcContour As Boolean = False Private m_nCameraCount As Integer = 0 Private m_sCameraPath As String = String.Empty 'Private m_sCameraPath2 As String = String.Empty Private m_sCameraProcName As String = String.Empty 'Private m_sCameraProcName2 As String = String.Empty Private m_sImage As String = String.Empty 'Private m_sImage2 As String = String.Empty Private m_sInfo As String = String.Empty 'Private m_sInfo2 As String = String.Empty Private m_sResult As String = String.Empty 'Private m_sResult2 As String = String.Empty Private m_sContour As String = String.Empty 'Private m_sContour2 As String = String.Empty Private m_nThreshold As Integer = 60 Private m_dTolerance As Double = 5 Private m_nTimeout As Integer = 30 Private m_sImageDir As String = String.Empty Private Const CAMERAMNG As String = "CameraMng" Private Const N_LOOP As Integer = 20 'Public m_ProcessCmg As New Process() ' Lista dei processi Cmg associati ad igni tavola Public m_ProcessCmgList As New List(Of Process) ' restituisce lo stato che il processo associato alla tavola corrente (PrepareCamera) Private m_bIsRunnigProc As Boolean = False ' restituisce l'esito dello scatto di una foto Private m_bClickOk As Boolean = False Private m_dClickOk As Double = 10 ' restituisce l'esito dello scatto di una foto Private m_bCorrectedImgOk As Boolean = False Private m_dCorrectedImgOk As Double = 10 ' restituisce l'esito di salvataggio BackImage Private m_bSavedBackImage As Boolean = False Private m_dSavedBackImage As Double = 90 ' Private m_bDowloadedPicFromCamera As Boolean = False Private m_dDowloadedPicFromCamera As Double = 10 ' Private m_bReadOCV As Boolean = False Private m_dReadOCV As Double = 10 ' Private m_bStartDistCorrect As Boolean = False Private m_dStartDistCorrect As Double = 30 ' Private m_bStartProspCorrect As Boolean = False Private m_dStartProspCorrect As Double = 20 Private DeltaCameraTab As Integer = 0 ' Flag per foto in esecuzione Friend m_bBusy As Boolean = False Public Function Init() As Boolean ' Lettura dati di configurazione da file Ini m_bCameraLink = (GetPrivateProfileInt(S_GENERAL, K_CAMERALINK, 0, m_MainWindow.GetIniFile()) <> 0) And Not m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.OFFICE_TYPE) GetPrivateProfileString(S_CAMERA, K_CAM_EXEPATH, "", m_sCameraPath, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_IMAGE, "", m_sImage, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_INFO, "", m_sInfo, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_RESULT, "", m_sResult, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_CONTOUR, "", m_sContour, m_MainWindow.GetIniFile()) m_nThreshold = GetPrivateProfileInt(S_CAMERA, K_CAM_THRESHOLD, 60, m_MainWindow.GetIniFile()) m_dTolerance = GetPrivateProfileDouble(S_CAMERA, K_CAM_TOLERANCE, 5, m_MainWindow.GetIniFile()) m_nTimeout = GetPrivateProfileInt(S_CAMERA, K_CAM_TIMEOUT, 30, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_GENERAL, K_IMAGEDIR, "", m_sImageDir, m_MainWindow.GetIniFile()) ' Verifico abilitazione riconoscimento contorno automatico del grezzo m_bCalcContour = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.AUTO_PHOTO) AndAlso (GetPrivateProfileInt(S_GENERAL, K_CONTOURFROMCAMERA, 1, m_MainWindow.GetIniFile()) <> 0) ' Ricavo il nome del processo associato m_sCameraProcName = Path.GetFileNameWithoutExtension(m_sCameraPath) ' Avvio processi del camera manager per ogni tavola CamerasHide() Return True End Function Public Function Close() As Boolean If m_bBusy Then Return False If m_bCameraLink Then KillProcess() End If Return True End Function Public Function GetCalcContour() As Boolean Return m_bCalcContour End Function Public Function GetCameraLink() As Boolean Return m_bCameraLink End Function Friend Property Threshold As Integer Get Return m_nThreshold End Get Set(value As Integer) ' Porto il valore nel range valido If value < 10 Then value = 10 ElseIf value > 90 Then value = 90 End If ' Se cambiato, aggiorno file INI If value <> m_nThreshold And WritePrivateProfileString(S_CAMERA, K_CAM_THRESHOLD, DoubleToString(value, 3), m_MainWindow.GetIniFile()) Then ' Aggiorno il valore corrente m_nThreshold = value End If End Set End Property Friend Property Tolerance As Double Get Return m_dTolerance End Get Set(value As Double) ' Porto il valore nel range valido If value < 100 * EPS_SMALL Then value = 100 * EPS_SMALL End If ' Se cambiato, aggiorno file INI If value <> m_dTolerance And WritePrivateProfileString(S_CAMERA, K_CAM_TOLERANCE, DoubleToString(value, 3), m_MainWindow.GetIniFile()) Then ' Aggiorno il valore corrente m_dTolerance = value End If End Set End Property ' OK: Restituisce la tavola a cui è associato il processo Private Function GetCurrentTableFromCameraProcess(nIndProc As Integer) As Integer Dim nIndTab As Integer = 1 Select Case DeltaCameraTab Case 0 nIndTab = nIndProc Case 1 ' La cameraHq è sempre associata all'ultimo processo e sempre alla prima tavola nIndTab = 1 Case -1 nIndTab = GetCurrentTable() End Select Return nIndTab End Function ' OK: Restituisce il processo a cui è associata la tavola Private Function GetProcessFromCurrentTable(nIndTab As Integer) As Integer Dim nIndProc As Integer = 1 Select Case DeltaCameraTab Case 0 ' Indice di processo uguale all'indice della tavola nIndProc = nIndTab Case 1 ' Alla tavola 1 possono essre associati 2 processi (solo se camera Hq abilitata e attiva) If nIndTab = 1 And (GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ENABLE, 0, m_MainWindow.GetMachIniFile()) <> 0) AndAlso (GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ACTIVATE, 0, m_MainWindow.GetMachIniFile()) <> 0) Then ' forzo l'utilizzo della seconda Hq (sopra alla tavola 1 di lavoro) nIndProc = nIndTab + 1 Else nIndProc = 1 End If Case -1 nIndProc = 1 End Select Return nIndProc End Function ' OK: Avvio un processo per ogni tavola presente in macchina Public Function CamerasHide() As Boolean If Not m_bCameraLink Then Return False ' Lancio il programma in cieco, se già attivo lo nascondo m_nCameraCount = GetTableCount() ' Se esiste una configurazione, ne verifico la sua valità If m_MainWindow.m_CurrentMachine.CameraCounter > -1 Then DeltaCameraTab = m_MainWindow.m_CurrentMachine.CameraCounter - GetTableCount() Select Case DeltaCameraTab Case 0 ' ad ogni tavola associo una camera/configurazione Case 1 ' Gestisco correttamente solo il caso: 1 tavola e 2 camere If GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ENABLE, 0, m_MainWindow.GetMachIniFile()) = 1 Then m_nCameraCount = m_nCameraCount + 1 End If Case -1 ' Gestisco correttamente solo il caso: 2 tavole e 1 camera m_nCameraCount = m_nCameraCount - 1 Case Else EgtOutLog(" --> CAUTION : Differenza tra numero di camere e numero di tavole: " & DeltaCameraTab.ToString & ", sarà attivata solo la prima camera.") DeltaCameraTab = 0 End Select Else ' 🚨 CAUTION: EgtOutLog(" --> CAUTION : In file *.ini machine '[Photo]' there is not param 'CameraCounter'.") ' Aggiungo un altro processo se camera Hq abilitata (non esite una vera tavola associata) If GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ENABLE, 0, m_MainWindow.GetMachIniFile()) = 1 Then m_nCameraCount = m_nCameraCount + 1 DeltaCameraTab = 1 End If End If Try For Index As Integer = 1 To m_nCameraCount Dim m_ProcessCmg As New Process() m_ProcessCmg.StartInfo.FileName = m_sCameraPath m_ProcessCmg.StartInfo.RedirectStandardInput = True m_ProcessCmg.StartInfo.RedirectStandardOutput = True ' Assegno argomento 0 per avvio in cieco, index per specificare il numero di processo m_ProcessCmg.StartInfo.Arguments = "0" & " " & Index.ToString() m_ProcessCmg.StartInfo.UseShellExecute = False m_ProcessCmg.StartInfo.CreateNoWindow = True AddHandler m_ProcessCmg.OutputDataReceived, AddressOf Thread_OutputDataReceived If m_ProcessCmg.Start() Then m_ProcessCmg.BeginOutputReadLine() ' Richiesta lettura configurazione corrente m_ProcessCmg.StandardInput.WriteLine("0") m_ProcessCmgList.Add(m_ProcessCmg) Else Return False End If Next Return True Catch ex As Exception EgtOutLog(ex.Message) Return False End Try End Function ' OK: Creo un nuovo processo associato alla tavola indicata Public Function ReloadCameraHide(nInd As Integer) As Boolean Dim m_ProcessCmg As New Process() m_ProcessCmg.StartInfo.FileName = m_sCameraPath m_ProcessCmg.StartInfo.RedirectStandardInput = True m_ProcessCmg.StartInfo.RedirectStandardOutput = True ' Assegno argomento 0 per avvio in cieco, index per specificare il numero di processo m_ProcessCmg.StartInfo.Arguments = "0" & " " & nInd.ToString() m_ProcessCmg.StartInfo.UseShellExecute = False m_ProcessCmg.StartInfo.CreateNoWindow = True AddHandler m_ProcessCmg.OutputDataReceived, AddressOf Thread_OutputDataReceived If m_ProcessCmg.Start() Then m_ProcessCmg.BeginOutputReadLine() m_ProcessCmgList(nInd) = m_ProcessCmg Return True End If Return False End Function ' OK: Ogni processo cameramanager che restituisce un messaggio passa di qua Private Sub Thread_OutputDataReceived(sender As Object, e As DataReceivedEventArgs) ' Il formato del messaggio è 'esempio messaggio: #IndProc' If Not IsNothing(e.Data) Then Dim sMsg As String() = e.Data.Split(":"c) ' reinserisco eventuali ":" che sono stati rimossi If sMsg.Length > 2 Then For Index As Integer = 2 To sMsg.Length - 1 sMsg(1) &= ":" & sMsg(Index) Next End If If sMsg.Length > 1 Then Select Case sMsg(0) ' Metodo WaitingForInstruction ' Se richiesto comando 7 stampo questo messaggio Case "PROCESSO ATTIVO" m_bIsRunnigProc = True ' Metodo TakeFoto Case "SCATTO FOTO AVVENUTO" m_bClickOk = True ' Metodo Camera_DownloadedCompleted Case "DOWNLOAD DA CAMERA COMPLETATO" m_bDowloadedPicFromCamera = True ' Metodo LeggiFileCalibrazioneLenteOCV Case "LETTURA OCV" m_bReadOCV = True ' Metodo CorrezioneCompleta Case "RICHIESTA CORREZIONE DISTORSIONE" m_bStartDistCorrect = True Case "RICHIESTA CORREZIONE PROSPETTICA" m_bStartProspCorrect = True ' Metodo CorreggiProspettivaDaMatriceOCV Case "FINE CREAZIONE IMMAGINE CON CORREZIONE OCV" m_bCorrectedImgOk = True ' Metodo SalvaNuovoBackGround Case "BACKIMAGE PRONTA" m_bSavedBackImage = True End Select If m_MainWindow.GetDebug > 3 Then EgtOutLog(" § " & sMsg(0) & " Process_" & sMsg(1)) End If End If End If End Sub ' OK : Accendo fari e vado in Home Private Sub PrepareMachine(nInd As Integer) ' ------------------------------------ accensione riflettori ------------------------------------ Dim sPLCVarSpotLightList As New List(Of String) For IndexSpot As Integer = 1 To GetTableCount() Dim sPLCVarSpotLight As String = String.Empty GetPrivateProfileString(S_NCDATA, K_SPOTLIGHT & IndexSpot.ToString(), "", sPLCVarSpotLight, m_MainWindow.GetMachIniFile()) ' eventualmente rimuovo inizio stringa: "PLC, ___" Dim sItemString() As String = Split(sPLCVarSpotLight, ","c) If sItemString.Count > 1 Then sPLCVarSpotLight = sItemString(1).Trim End If sPLCVarSpotLightList.Add(sPLCVarSpotLight) Next Dim nPhotoDeley As Integer = GetPrivateProfileInt(S_NCNUM, K_PHOTODELEY, "100", m_MainWindow.GetMachIniFile()) Select Case m_MainWindow.m_CNCommunication.m_nNCType Case 1, 2 If m_MainWindow.m_CNCommunication.m_nNCType = 2 Then ' solo per Flexium m_MainWindow.m_CNCommunication.m_CN.DPlcVariables_WriteVariables(sPLCVarSpotLightList(nInd - 1), "1") ' altrimenti scrittura delle variabili E Else m_MainWindow.m_CNCommunication.m_CN.DVariables_WriteVariables2(sPLCVarSpotLightList(nInd - 1), "1") End If System.Threading.Thread.Sleep(nPhotoDeley) Case 3 ' SIEMENS End Select ' ------------------------------------ accensione riflettori ------------------------------------ ' ------------------------------------ mando la testa in home ------------------------------------ If Not GoHomeForPhoto() Then EgtOutLog("Error in positioning") End If ' ------------------------------------ mando la testa in home ------------------------------------ End Sub Private Function GoHomeForPhoto() As Boolean Dim bGoHome As Boolean = GetPrivateProfileInt(S_PHOTO, K_ENABELE_GOHOME_FOR_PHOTO, 0, m_MainWindow.GetMachIniFile()) <> 0 ' Se non configurato esco senza generare errore If Not bGoHome Then Return True ' Costruisco il bottone per potere eseguire il comando MDI Dim GoHome As MachineButton = Nothing Dim sDirectCmdFile As String = String.Empty GetPrivateProfileString(S_PHOTO, K_CAMERA_DIRECT_CMD, "", sDirectCmdFile, m_MainWindow.GetMachIniFile()) If String.IsNullOrEmpty(sDirectCmdFile) Then Return False Else EgtOutLog("Direct command for positionig head: " & sDirectCmdFile) End If GoHome = New TwoStateButton("", sDirectCmdFile, "", "", "") ' eseguo lo script lua associato GoHome.ExecuteMDICommand(GoHome.TLuaScriptName) ' Leggo nome variabile posizione home raggiunta Dim CameraStateNameVar As String = String.Empty GetPrivateProfileString(S_PHOTO, K_CAMERA_STATE_VAR, "", CameraStateNameVar, m_MainWindow.GetMachIniFile()) Dim nSteps As Integer = 20 nSteps = GetPrivateProfileInt(S_PHOTO, K_PENDIG_TIME_FOR_PHOTO, nSteps, m_MainWindow.GetMachIniFile()) If String.IsNullOrEmpty(CameraStateNameVar) Then 'Return False Else EgtOutLog("Variable for read status of positioning head: " & CameraStateNameVar) End If ' 91144=Going home m_MainWindow.m_CurrentProjectPageUC.SetInfoMessage(EgtMsg(91144)) UpdateUI() ' Eseguo reset variabile posizione home raggiunta m_MainWindow.m_CNCommunication.m_CN.DVariables_WriteVariables2(CameraStateNameVar, "0") System.Threading.Thread.Sleep(300) ' Definisco flag posizionamento completato Dim bPositionOk As Boolean = False For I As Integer = 0 To nSteps ' Devo rileggere la variabile ad ogni ciclo m_MainWindow.m_CNCommunication.m_CN.ReadEls_Add_Parameter(CameraStateNameVar, 3) System.Threading.Thread.Sleep(100) If m_MainWindow.m_CNCommunication.m_CN.n_DReadELS_handle = 3 Then Dim CameraStateVal As Integer = CInt(m_MainWindow.m_CNCommunication.m_CN.d_DReadELS_value) Select Case CameraStateVal Case 0 ' Non faccio alcunchè perchè si sta posizionando Case 1 ' Posizionamento completato bPositionOk = True Exit For Case 2 ' Errore bPositionOk = False Exit For End Select End If System.Threading.Thread.Sleep(900) Next m_MainWindow.m_CurrentProjectPageUC.ClearMessage() UpdateUI() Return bPositionOk End Function ' OK: Ottengo l'indice del processo associato alla tavola e la configurazione del processo Private Function PrepareCamera() As Integer ' Stati del processo m_bIsRunnigProc = False m_bClickOk = False m_bCorrectedImgOk = False m_bSavedBackImage = False ' Argomento utilizzato per verificare lo stato della comunicazione Dim sArgs As String = "7" Dim nIndTab As Integer = GetCurrentTable() Dim nIndProc As Integer = GetProcessFromCurrentTable(nIndTab) ' Invio richiesta al processo per vedere se la comunicazione è aperta Try If Not m_ProcessCmgList(nIndProc - 1).HasExited Then m_ProcessCmgList(nIndProc - 1).StandardInput.WriteLine(sArgs) Else Return -2 End If Catch ex As Exception EgtOutLog(ex.Message()) End Try ' Attendo massimo N_LOOP secondi per avere una risposta dal programma (la risposta arriva al metodo Thread_OutputDataReceived) For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bIsRunnigProc Then Exit For Next ' Se processo non attivo allora provo a rilanciarlo If Not m_bIsRunnigProc Then EgtOutLog(" ~ PROCESSO NON RISPONDE: Process_" & (nIndProc).ToString()) ReloadCameraHide(nIndProc - 1) For i As Integer = 0 To N_LOOP Thread.Sleep(1000) ' Invio richiesta al processo per vedere se la comunicazione è aperta m_ProcessCmgList(nIndProc - 1).StandardInput.WriteLine(sArgs) If m_bIsRunnigProc Then Exit For Next End If ' ----------------------------------------------------------------- ' ----- PREPARAZIONE PERCORSO FILE ----- ' ----------------------------------------------------------------- GetPrivateProfileString(S_CAMERA, K_CAM_IMAGE, "", m_sImage, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_INFO, "", m_sInfo, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_RESULT, "", m_sResult, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_CONTOUR, "", m_sContour, m_MainWindow.GetIniFile()) m_sImage = m_sImage.Replace(CAMERAMNG, CAMERAMNG & (nIndProc).ToString()) m_sInfo = m_sInfo.Replace(CAMERAMNG, CAMERAMNG & (nIndProc).ToString()) m_sResult = m_sResult.Replace(CAMERAMNG, CAMERAMNG & (nIndProc).ToString()) m_sContour = m_sContour.Replace(CAMERAMNG, CAMERAMNG & (nIndProc).ToString()) Return If(m_bIsRunnigProc, nIndProc, -1) End Function ' OK: Scatto foto e aspetto WaitBackImage Public Function CameraBackImage() As Boolean ' Verifiche preliminari Dim nIndProc As Integer = PrepareCamera() ' Se non è stato trovato il processo associato alla tavola allora esco Select Case nIndProc Case -2 EgtOutLog("Direttorio di configurazione 'CamerMng" & GetCurrentTable().ToString() & "' non è stato trovato") Case -1 EgtOutLog("Camera " & GetCurrentTable().ToString() & " spenta") End Select If nIndProc < 0 Then Return False ' Visualizzo progressbar m_bBusy = True m_MainWindow.m_CurrentProjectPageUC.ClearMessage() m_MainWindow.m_CurrentProjectPageUC.PhotoProgressStackPanel.Visibility = Visibility.Visible m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = 0 ' Cancellazione eventuali vecchi file rimasti Try If My.Computer.FileSystem.FileExists(m_sResult) Then My.Computer.FileSystem.DeleteFile(m_sResult) End If Catch ex As Exception End Try ' Se richiesto: accendo fari ed eventualmente mando la testa in Home Dim nIndTab As Integer = GetCurrentTableFromCameraProcess(nIndProc) PrepareMachine(nIndTab) ' Scatto una foto come sfondo (il programma deve essere già attivo) Dim bOk As Boolean = False Dim sArgs As String = "4" Try m_ProcessCmgList(nIndProc - 1).StandardInput.WriteLine(sArgs) bOk = WaitBackImage(nIndProc) Catch ex As Exception bOk = False End Try ' Nascondo progressbar m_MainWindow.m_CurrentProjectPageUC.PhotoProgressStackPanel.Visibility = Visibility.Hidden m_bBusy = False Return bOk End Function ' OK: cerco l'immagine nella confidurazione di indica nInd Private Function WaitBackImage(nInd As Integer) As Boolean Dim dProgVal As Double = 0 ' verifico che abbia scattato la foto (dalla lettura degli eventi restituiti dal processo) m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "CLICK" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bClickOk Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = m_dClickOk ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = m_dClickOk / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = m_dClickOk If Not m_bClickOk Then Return False ' verifico che sia stata scaricata l'immagine m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "DOWNLOAD PIC" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bDowloadedPicFromCamera Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dDowloadedPicFromCamera ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dDowloadedPicFromCamera / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dDowloadedPicFromCamera If Not m_bDowloadedPicFromCamera Then Return False ' verifico che sia stata scaricata l'immagine m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "SAVE BACKIMG" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bSavedBackImage Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dSavedBackImage ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dSavedBackImage / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dSavedBackImage If Not m_bSavedBackImage Then Return False ' Se esiste il file di risultato (NON ho modo di vedere se il risultato è andato a buon fine) Dim nErr = 999 If VerifyResult(nInd, nErr) Then If nErr = 0 Then Return True Else EgtOutLog("Camera err=" & nErr.ToString()) Return False End If ' Altrimenti aspetto End If EgtOutLog("Camera generic error") Return False End Function ' OK: Scatto foto e aspetto WaitPhoto Public Function CameraClick() As Boolean ' Verifiche preliminari Dim nIndProc As Integer = PrepareCamera() ' Se non è stato trovato il processo associato alla tavola allora esco Select Case nIndProc Case -2 EgtOutLog("Direttorio di configurazione 'CamerMng" & GetCurrentTable().ToString() & "' non è stato trovato") Case -1 EgtOutLog("Camera " & GetCurrentTable().ToString() & " spenta") End Select If nIndProc < 0 Then Return False ' Visualizzo progressbar m_bBusy = True m_MainWindow.m_CurrentProjectPageUC.ClearMessage() m_MainWindow.m_CurrentProjectPageUC.PhotoProgressStackPanel.Visibility = Visibility.Visible m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = 0 ' Costringo ad aggiornare UI UpdateUI() ' Cancellazione eventuali vecchi file rimasti Try If My.Computer.FileSystem.FileExists(m_sResult) Then My.Computer.FileSystem.DeleteFile(m_sResult) End If If My.Computer.FileSystem.FileExists(m_sImage) Then My.Computer.FileSystem.DeleteFile(m_sImage) End If If My.Computer.FileSystem.FileExists(m_sContour) Then My.Computer.FileSystem.DeleteFile(m_sContour) End If If My.Computer.FileSystem.FileExists(m_sInfo) Then My.Computer.FileSystem.DeleteFile(m_sInfo) End If Catch ex As Exception End Try ' Se richiesto: accendo fari ed eventualmente mando la testa in Home Dim nIndTab As Integer = GetCurrentTableFromCameraProcess(nIndProc) PrepareMachine(nIndTab) ' Scatto una foto con eventuale riconoscimento del contorno (il programma deve essere già attivo) Dim bOk As Boolean = False Dim sArgs As String = "2" ' Per ricavare il contorno bisogna passare i segunti valori: 5,Valore_Soglia If m_bCalcContour Then sArgs = "5" & "," & m_nThreshold.ToString() Try ' invio la richiesta di scattare una foto m_ProcessCmgList(nIndProc - 1).StandardInput.WriteLine(sArgs) bOk = WaitPhoto() Catch ex As Exception EgtOutLog(ex.Message()) bOk = False End Try ' Nascondo progressbar m_MainWindow.m_CurrentProjectPageUC.PhotoProgressStackPanel.Visibility = Visibility.Hidden m_bBusy = False Return bOk End Function ' OK: attendo che sia pronta l'immagine Private Function WaitPhoto() As Boolean Dim dProgVal As Double = 0 ' verifico che abbia scattato la foto (dalla lettura degli eventi restituiti dal processo) m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "CLICK" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bClickOk Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = m_dClickOk ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = m_dClickOk / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = m_dClickOk If Not m_bClickOk Then Return False ' m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "DOWNLOAD PIC" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bDowloadedPicFromCamera Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dDowloadedPicFromCamera ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dDowloadedPicFromCamera / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dDowloadedPicFromCamera If Not m_bDowloadedPicFromCamera Then Return False ' m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "READ OCV" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bReadOCV Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dReadOCV ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dReadOCV / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dReadOCV If Not m_bReadOCV Then Return False ' m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "START DIST" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bStartDistCorrect Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dStartDistCorrect ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dStartDistCorrect / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dStartDistCorrect If Not m_bStartDistCorrect Then Return False ' m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "START PROSP" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bStartProspCorrect Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dStartProspCorrect ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dStartProspCorrect / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dStartProspCorrect If Not m_bStartProspCorrect Then Return False ' verifico che il processo di correzione della foto sia terminato correttamente m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "CORRECT IMG" For i As Integer = 0 To N_LOOP Thread.Sleep(1000) If m_bCorrectedImgOk Then m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dCorrectedImgOk ' Costringo ad aggiornare UI UpdateUI() Exit For End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = dProgVal + m_dCorrectedImgOk / N_LOOP * (i + 1) ' Costringo ad aggiornare UI UpdateUI() Next dProgVal = dProgVal + m_dCorrectedImgOk m_MainWindow.m_CurrentProjectPageUC.PhotoProgressText.Content = "IMPORT IMG" ' Copio i file Dim sImageDest As String = m_sImageDir & "\" & Path.GetFileName(m_sImage) Dim sInfoDest As String = Path.ChangeExtension(sImageDest, "txt") File.Copy(m_sImage, sImageDest, True) File.Copy(m_sInfo, sInfoDest, True) ' Se richiesto il riconoscimento del contorno Dim sContourDest As String = String.Empty If m_bCalcContour Then sContourDest = Path.ChangeExtension(sImageDest, "dxf") File.Copy(m_sContour, sContourDest, True) ' altrimenti cancello eventuale contorno presente Else m_MainWindow.m_CurrentProjectPageUC.RemoveContour() End If m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = 95 ' Costringo ad aggiornare UI UpdateUI() ' Lancio caricamento della foto e del contorno m_MainWindow.m_CadCutPageUC.PostPhoto(sImageDest, sContourDest) Return True End Function ' OK: verifica che la backimage sia stata scaricata correttamente nel direttorio CameraMng#n Private Function VerifyResult(nInd As Integer, ByRef nErr As Integer) As Boolean ' Se non esiste il file con il risultato If Not My.Computer.FileSystem.FileExists(m_sResult) Then Return False End If ' Leggo il file Dim bOk As Boolean = False Try ' Controllo errori nel file di info Dim sLine As String = String.Empty Dim sr As StreamReader = New StreamReader(m_sResult) Do While sr.Peek() > -1 sLine = sr.ReadLine() sLine = sLine.Replace(" ", "") If sLine.StartsWith("Err=") Then If Int32.TryParse(sLine.Substring(4), nErr) Then bOk = True Exit Do End If End If Loop sr.Close() Catch ex As Exception bOk = False End Try Return bOk End Function Private Function ProcessIsRunning() As Boolean Dim Procs() As Process Procs = Process.GetProcessesByName(m_sCameraProcName) Return (Procs.Length() > 0) End Function ' OK: chiudo tutti i processi che hanno il nome CameraMng.exe Private Sub KillProcess() Dim Procs() As Process Procs = Process.GetProcessesByName(m_sCameraProcName) For i As Integer = 0 To Procs.Length() - 1 Procs(i).Kill() Procs(i).WaitForExit(2000) Next i End Sub End Class