pypylon icon indicating copy to clipboard operation
pypylon copied to clipboard

Camera connect lost after random interval.

Open nexus1203 opened this issue 2 years ago • 6 comments

I am using two GIGe cameras ICDA-ACA5472-5GM with a PCIe network card IFG-GIGE-POE-2AT. I using following code to acquire the camera images in a pyqt QThread. I am using the get_frame method from the main thread in UI to acquire the images.

import time
import cv2
import toml
from PyQt5.QtCore import QThread, pyqtSlot

from pypylon import pylon, genicam
from .signals import Signals


class Camera1(QThread):
    signal = Signals()

    def __init__(self, camera_settings: dict, parent=None) -> None:
        """
        GiGE camera class for controller Basler GiGE camera
        """
        super(Camera1, self).__init__(parent)
        self.threadactive = False
        self.online = False
        self.current_frame = None
        self.frame = None
        self.load_settings(camera_settings)

    def load_settings(self, settings):
        """
        assign settigns to class variables
        """
        self.ip = settings["ip"]
        self.resolution = settings["resolution"]
        
        # self.fps = settings["fps"]

        # set pylon camera ip address
        self.pylon_info = pylon.DeviceInfo()
        self.pylon_info.SetPropertyValue("IpAddress", self.ip)
        # set camera parameters
        self.camera = pylon.InstantCamera(
            pylon.TlFactory.GetInstance().CreateFirstDevice(self.pylon_info))
        self.camera.Open()
        print("camera model: %s" % self.camera.DeviceModelName.GetValue())
        print("AOI: %d x %d" %
              (self.camera.Width.GetValue(), self.camera.Height.GetValue()))
        print("payload size: %d\n" % self.camera.PayloadSize.GetValue())
        # self.camera.GainRaw.SetValue(int(self.gain))
        self.camera.OutputQueueSize = 1
        self.camera.MaxNumBuffer = 1
        #set image format
        self.camera.PixelFormat.SetValue("Mono8")
        # set exposure time
        # self.camera.ExposureTimeRaw.SetValue(self.exposure)
        # self.camera.AcquisitionFrameRateEnable.SetValue(True)
        # self.camera.AcquisitionFrameRate.SetValue(self.fps)
        # set camera resolution
        self.camera.Width.SetValue(int(self.resolution[0]))
        self.camera.Height.SetValue(int(self.resolution[1]))
        
        self.converter = pylon.ImageFormatConverter()
        self.converter.OutputPixelFormat = pylon.PixelType_Mono8
        self.converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
        print("camera model: %s" % self.camera.DeviceModelName.GetValue())
        print("AOI: %d x %d" %
              (self.camera.Width.GetValue(), self.camera.Height.GetValue()))
        print("payload size: %d\n" % self.camera.PayloadSize.GetValue())
        # self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
        self.camera.StartGrabbing(pylon.GrabStrategy_OneByOne)
        

    def get_frame(self):
        """
        get frame from camera
        """
        
        if self.camera.IsGrabbing():
            
            # if self.camera.WaitForFrameTriggerReady(200, pylon.TimeoutHandling_ThrowException):
            # self.camera.ExecuteSoftwareTrigger()
        
            # 
            try:
                self.grabResult = self.camera.RetrieveResult(
                    300, pylon.TimeoutHandling_ThrowException)
                self.grabResult.Release()
            except Exception as e:
                print(e)
            QThread.msleep(100)
            try:
                self.grabResult = self.camera.RetrieveResult(
                    300, pylon.TimeoutHandling_ThrowException)
                if self.grabResult.GrabSucceeded():
                    image = self.converter.Convert(self.grabResult)
                    self.current_frame = image.GetArray()
                    self.current_frame = cv2.resize(self.current_frame, None, 
                                                    fx=0.4, fy=0.4, interpolation = cv2.INTER_CUBIC)

                else:
                    print("Error: {}".format(self.grabResult.ErrorCode))
                    self.current_frame = None
            except Exception as e:
                print(e)

            
        else:
            self.current_frame = None
        # self.signal.image.emit(self.current_frame)
        self.grabResult.Release()
        return self.current_frame

    @pyqtSlot()
    def run(self, ):
        self.threadactive = True
        
        while self.threadactive:
            QThread.msleep(200)

    def save_frame(self, path):
        """
        save frame to path
        """
        if self.current_frame is not None:
            cv2.imwrite(path, self.current_frame)
            print("saved frame to {}".format(path))

    def release(self, ):
        """
        Stop camera and release resources
        """
        self.camera.StopGrabbing()
        self.camera.Close()

    def stop_thread(self, ):
        self.threadactive = False
        self.release()
        self.quit()
        self.terminate()

This works fine for some period of time, however after some random interval I get this error and camera stops working.

Grab timed out. Possible reasons are: The image transport from the camera device is not working properly, e. g., all GigE network packets for streaming are dropped; The camera uses explicit triggering (see TriggerSelector for more information) and has not been triggered; Single frame acquisition mode is used and one frame has already been acquired; The acquisition has not been started or has been stopped. TimeoutException thrown (file 'instantcameraimpl. h', line 1037

If I stop the program and try to run the program again, The program keep throwing the same error. But if I remove the RJ45 cable from camera and reconnect it then run the program, it starts acquiring images again. So far, I have only figured out that the connection is lost randomly after 2 hours of normal operations. I am looking for a way to solve this problem and make the connection more stable. Is there anything I can change in the program to make it more stable or reconnect if the connection is lost? because physically removing and reinserting the cable is not feasible for my application.

nexus1203 avatar Jul 26 '23 08:07 nexus1203

  1. do you power the camera via PoE or AUX?
  2. check with your local support team if your camera model has got any firmware update

SMA2016a avatar Aug 27 '23 03:08 SMA2016a

  1. do you power the camera via PoE or AUX? Answer: Camera is powered by PoE.

  2. check with your local support team if your camera model has got any firmware update. Answer: The local support team (Taiwan) asked me to ask for help on this github repo.

nexus1203 avatar Aug 28 '23 05:08 nexus1203

could be your camera is overheating...

hlacikd avatar Sep 28 '23 13:09 hlacikd

What is the fps value that you set the camera to?

thiesmoeller avatar Sep 28 '23 16:09 thiesmoeller

Thanks for the values. So you get 25fps? If not, can you output

print(self.camera.ResultingFrameRateAbs.GetValue())

just before start grabbing to see the final framerate in your configuration. I'm asking because with 300ms timeout you might be at some border to be triggered in your application.

And you could also output https://docs.baslerweb.com/device-temperature while running to see if you leave the operating temperature range.

thiesmoeller avatar Sep 28 '23 19:09 thiesmoeller

@thiesmoeller i am sorry, i have responded to wrong bug issue, please discard my message about fps ( i was reacting to my own issue report, which is already solved)

hlacikd avatar Sep 29 '23 10:09 hlacikd