I have been working with multiple ZED2 cameras, having threads to handle each camera stream in python, that involves grabbing frames and processing them. When I start the camera capture process, and unplug the USB connection of a ZED2, and then plug it back again, the observation is that the main thread gets stuck at the camera frame grabbing phase. Another observation is when we plug back the camera, the camera grab process does not startup automatically where I would assume it to start, does that mean when we plug the USB out during a running process trying to access the camera feed the camera object dies or gets deleted?
When you call grab and you previously enabled async_grab_camera_recovery in the initialization structure, you can check the returned error message to handle grab failures due to camera disconnections.
Read the documentation of the returned ERROR_CODE for more information
Hi @Myzhar, thank you for the welcome. Thank you for the pointers, I have two follow up questions -
Once the USB is plugged back in, once we get the message : [ZED][INFO] [Grab] Automatically recover from image capture failure → SUCCESS, I am not getting any subsequent grab messages after that until I restart the camera app (restarting the software)
Once I plugout the USB for one camera why aren’t the other threads running grab executing?
Would you recommend an pointers for the 1st challenge (question no. 1)
Looking forward to hearing back from you and a bunch of thanks in advance!
When you call grab and you previously enabled async_grab_camera_recovery in the initialization structure, you can check the returned error message to handle grab failures due to camera disconnections.
We didn’t enable async_grab_camera_recovery.
As per the same documentation
When async_grab_camera_recovery is false, the sl::grab() method is blocking and will return only once the camera communication is restored or the timeout is reached.
Default: false
Adding a logging call right after camera.grab(…) showed that camera.grab(…) never returned.
Shouldn’t we expect the camera.grab(…) to still return after the timeout duration?
We’ll try enabling async_grab_camera_recovery and see if this solves our recovery issue.
We are using ZED SDK version 5.0.2, and these are the lines of code that we are executing and we are getting stuck at -
grab_error_code = self.camera.grab(self.runtime_depth_params)
self.logger.debug(
f’Zed grab attempt #{frame_request_count} with error code {grab_error_code.name}’
)
After plugging out and plugging in the USB, we never get to the debug message
We experimented with changing the ZED SDK version to 5.0.5, we see the same observations. Once we plug out the camera USB and replug it back again with both async_grab_camera_recovery True and False, we are not getting any subsequent grab messages, and it seems that the main thread gets stuck with the grab method still not able to recover. Is there anything else would you recommend for us regarding this?
→ I do see an unexpected behavior (a crash occuring at the moment the camera got re-plugged and finished to reboot) which has been logged for fixing and to be part of the next release. We’ll keep you posted regarding that.
However, I did not manage to see the lock you described, would it be possible for you to send a minimalist script that would help us to reproduce the issue so that we can diagnose? Maybe fixing the issue above will also fix yours, but having a reproducible script will help us ensure that.
Potential temporary fix:
If you want to use init.async_grab_camera_recovery = True and only need the sensor data and not the Depth or other module output, I would recommend using cam.read() instead of cam.grab(). In our tests, everything worked fine using the read method and unplugging/re-plugging the camera while the sample is running.
More info on the read method here.
I was only mentioning about the crash occurring at the moment the camera got re-plugged and finished to reboot, can you point out and describe the “lock” that you mentioned in the last comment?
We did further testing, setting init.async_grab_camera_recovery = True, indeed resolved our issues of the process being deadlocked.
Setting it to true, we can disconnect the camera a few times and they reconnect