genicam/harvesters

_gentl.ResourceInUseException when trying to restart camera after unable to fetch buffer with try_fetch()

AndreaMazzoleniOOI opened this issue · 1 comments

Describe the Issue
I have a GeniNano camera acquiring images every 60s. The applications runs on a RaspberryPi 4, with Harvester installation performed as in #254. The camera start acquiring data when the GenieNanoCamera object is initialized and a Kivy app calls a try_fetch() every 60s. try_fecth() is implemented in the GenieNanoCamera.grab_image() method. After some time, the camera is unable to fetch the buffer, thus None is returned. If i try to stop and restart the camera I get the _gentl.ResourceInUseException and it stays in this state.

Sample Code
I have a callback managed by the KIvy Clock object where I try to stop and restart the camera:

    def callback(self):
        img = Cam.grab_image(show=False)
        # Couldn't fetch img --> img = None --> restart camera
        if img is None:
            Cam.camera.stop()
            Cam.start()
            return
       # Some other code here
      return

Cam is a GenieNanoCamera object defined as below:

class GenieNanoCamera(Camera):

    def __init__(self):
        super().__init__()
        self.h = Harvester()
        self.h.reset()
        self.h.add_file('/opt/mvIMPACT_Acquire/lib/arm64/mvGenTLProducer.cti')  # path to your GenTLProducer.cti file
        self.h.update()
        self.camera = self.h.create(0)
        # self.set_parameters(image_format='Mono8', exposure_time=50000, gain_raw=0, fps=9)
        self.connect()

    def connect(self):
        self.camera.start()

    def disconnect(self):
        self.camera.stop()
        self.camera.destroy()
        self.h.reset()

    def grab_image(self, show=False):
        """Fetch  buffer and returns the image. If unable to fetch the buffer, a None object is returned"""
        buffer = self.camera.try_fetch(timeout=10)
        if buffer is None:
            return None # return empty image to Kivy app

        payload = buffer.payload
        component = payload.components[0]
        width = component.width
        height = component.height
        data_format = component.data_format

        # Reshape the image so that it can be drawn on the VisPy canvas:
        if data_format in mono_location_formats:
            img = component.data.reshape(height, width)
        else:
            # The image requires you to reshape it to draw it on the canvas:
            if data_format in rgb_formats or data_format in rgba_formats or data_format in bgr_formats or data_format in bgra_formats:
                img = component.data.reshape(height, width,
                                             int(component.num_components_per_pixel))  # Set of R, G, B, and Alpha
                if data_format in bgr_formats:
                    # Swap every R and B:
                    img = img[:, :, ::-1]
            elif data_format == 'BayerRG8':
                img = component.data.reshape(height, width)
                cv2.cvtColor(src=img, code=cv2.COLOR_BayerRG2GRAY, dst=img)
        image = img.copy()
        if show:
            win_name = 'debug'
            cv2_open_resized_window(img=image, win_name=win_name, width=WIDTH, height=HEIGHT)
            cv2.setWindowProperty(win_name, cv2.WND_PROP_TOPMOST, 1)
            cv2.imshow(win_name, image)
            cv2.waitKey(0)
            cv2.destroyWindow(win_name)
        buffer.queue()
        return image

    def set_parameters(self, image_format, exposure_time, gain_raw, fps):
        self.camera.remote_device.node_map.autoBrightnessMode.value = 'Off'
        self.camera.remote_device.node_map.PixelFormat.value = image_format
        self.camera.remote_device.node_map.AcquisitionFrameRate.value = fps
        self.camera.remote_device.node_map.GainRaw.value = gain_raw
        self.camera.remote_device.node_map.ExposureTime.value = exposure_time

Complete Traceback error:

>>> self.camera.stop()
 Traceback (most recent call last):
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/kivy/base.py", line 574, in runTouchApp
     EventLoop.mainloop()
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/kivy/base.py", line 339, in mainloop
     self.idle()
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/kivy/base.py", line 379, in idle
     Clock.tick()
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/kivy/clock.py", line 733, in tick
     self.post_idle(ts, self.idle())
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/kivy/clock.py", line 776, in post_idle
     self._process_events()
   File "kivy/_clock.pyx", line 620, in kivy._clock.CyClockBase._process_events
   File "kivy/_clock.pyx", line 653, in kivy._clock.CyClockBase._process_events
   File "kivy/_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events
   File "kivy/_clock.pyx", line 218, in kivy._clock.ClockEvent.tick
   File "/home/pi/Desktop/GUIv2/ChainTrakingGUI.py", line 73, in callback
     Cam.connect()
   File "/home/pi/Desktop/GUIv2/src/monocular_marker_tracking/camera.py", line 64, in connect
     self.camera.start()
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/harvesters/core.py", line 2120, in start
     ACQ_START_FLAGS_LIST.ACQ_START_FLAGS_DEFAULT, -1)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/harvesters/core.py", line 214, in m
     return getattr(self._source_object, attribute)(*args)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/gentl.py", line 3838, in start_acquisition
     return _gentl.DataStream_start_acquisition(self, *args)
 _gentl.ResourceInUseException: GenTL exception: Requested resource is already in use. (Message from the source: ) (ID: -1004)

Expected Behavior
Being able to restart the camera when needed in order to restart acquire images properly.

Configuration

  • OS: Raspbian 32 bit
  • Python: Python 3.7
  • Harvester: 1.3.8
  • GenTL Producer: static.matrix-vision.com/mvIMPACT_Acquire/2.46.2/install_mvGenTL_Acquire_ARM.sh
  • Camera: Teledyne DALSA Nano - M2420

Reproducibility

This phenomenon can be stably reproduced:

  • [X ] Yes
  • No.

Actions You Have Taken

  • Since the try_fetch() returns None, I tried to skip a callback when the buffer is not returned with a try except. However, the camera stays in the same state and cannot fetch a buffer anymore.

  • I tried to clear the buffer as in #383 but it does not seem to work.


    def set_parameters(self, image_format, exposure_time, gain_raw, fps):


        self.camera.remote_device.node_map.BalanceWhiteAuto.value = 'Off'

        self.camera.remote_device.node_map.AcquisitionMode.value = "Continuous"
        self.camera.remote_device.node_map.TriggerSelector.value = 'FrameStart'
        self.camera.remote_device.node_map.TriggerActivation.set_value('RisingEdge')
        self.camera.remote_device.node_map.TriggerMode.value = 'On'
        self.camera.remote_device.node_map.TriggerSource.value = 'Software'
        
        self.camera.remote_device.node_map.autoBrightnessMode.value = 'Off'

        self.camera.remote_device.node_map.PixelFormat.value = image_format
        self.camera.remote_device.node_map.AcquisitionFrameRate.value = fps
        self.camera.remote_device.node_map.GainRaw.value = gain_raw
        self.camera.remote_device.node_map.ExposureTime.value = exposure_time
  • I tried to reset the device getting the following:
Traceback (most recent call last):
  File "/opt/pycharm/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 2796, in execute
    return _genapi.ICommand_execute(self, Verify)
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/harvesters/_private/core/port.py", line 54, in write
    self.port.write(address, value)
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/gentl.py", line 5016, in write
    return _gentl.Port_write(self, address, buffer)
_gentl.AccessDeniedException: GenTL exception: Requested operation is not allowed. (Message from the source: No write access to device Nano-M2420(00:01:0d:c6:2c:c5)(current access DEVICE_ACCESS_STATUS_OPEN_READONLY)) (ID: -1005)
  • If I force the stop of the program and restart it the camera is reset to its original status.

  • I've read the Harvester FAQ page.

Additional context
I am running my code on a Kivy (version 2.1.0) app. try_fetch() is called with a callback managed by the Clock class implemented in Kivy every 60 seconds.

EDIT:
Actions You Have Taken

  • Since the try_fetch() returns None, I tried to skip a callback when the buffer is not returned with a try-except. However, the camera stays in the same state and cannot fetch a buffer anymore.

  • I tried to clear the buffer as in #383 but it does not seem to work.

    def set_parameters(self, image_format, exposure_time, gain_raw, fps):

        self.camera.remote_device.node_map.BalanceWhiteAuto.value = 'Off'

        self.camera.remote_device.node_map.AcquisitionMode.value = "Continuous"
        self.camera.remote_device.node_map.TriggerSelector.value = 'FrameStart'
        self.camera.remote_device.node_map.TriggerActivation.value = 'RisingEdge'
        self.camera.remote_device.node_map.TriggerMode.value = 'On'
        self.camera.remote_device.node_map.TriggerSource.value = 'Software'
        
        self.camera.remote_device.node_map.autoBrightnessMode.value = 'Off'

        self.camera.remote_device.node_map.PixelFormat.value = image_format
        self.camera.remote_device.node_map.AcquisitionFrameRate.value = fps
        self.camera.remote_device.node_map.GainRaw.value = gain_raw
        self.camera.remote_device.node_map.ExposureTime.value = exposure_time

Which raise the following:

  Traceback (most recent call last):
   File "/home/pi/Desktop/GUIv2/ChainTrakingGUI.py", line 304, in <module>
     Cam = init_camera(config)
   File "/home/pi/Desktop/GUIv2/ChainTrakingGUI.py", line 281, in init_camera
     cam = GenieNanoCamera()
   File "/home/pi/Desktop/GUIv2/src/monocular_marker_tracking/camera.py", line 58, in __init__
     self.set_parameters(image_format='Mono8', exposure_time=50000, gain_raw=0, fps=9)
   File "/home/pi/Desktop/GUIv2/src/monocular_marker_tracking/camera.py", line 127, in set_parameters
     self.camera.remote_device.node_map.TriggerActivation.value = 'RisingEdge'
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 2650, in <lambda>
     __setattr__ = lambda self, name, value: _swig_setattr(self, IEnumeration, name, value)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 101, in _swig_setattr
     return _swig_setattr_nondynamic(self, class_type, name, value, 0)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 93, in _swig_setattr_nondynamic
     object.__setattr__(self, name, value)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 2714, in _set_value
     self.from_string(value)
   File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 1437, in from_string
     return _genapi.IValue_from_string(self, ValueStr, Verify)
 _genapi.AccessException: Node is not writable. : AccessException thrown in node 'TriggerActivation' while calling 'TriggerActivation.FromString()' (file 'ValueT.h', line 86)
  • I tried to reset the device with remote_device.node_map.DeviceReset.execute() getting the following:
  File "/opt/pycharm/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/genapi.py", line 2796, in execute
    return _genapi.ICommand_execute(self, Verify)
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/harvesters/_private/core/port.py", line 54, in write
    self.port.write(address, value)
  File "/home/pi/.local/share/virtualenvs/GUIv2-HIklSUks/lib/python3.7/site-packages/genicam/gentl.py", line 5016, in write
    return _gentl.Port_write(self, address, buffer)
_gentl.AccessDeniedException: GenTL exception: Requested operation is not allowed. (Message from the source: No write access to device Nano-M2420(00:01:0d:c6:2c:c5)(current access DEVICE_ACCESS_STATUS_OPEN_READONLY)) (ID: -1005)
  • If I force the stop of the program and restart it the camera is reset to its original status.