This commit is contained in:
edo-neo 2025-08-21 13:52:45 +02:00
parent 1127dc99ea
commit f2aa761ad9

View File

@ -261,13 +261,25 @@ class HikrobotSmartCamera(Component):
# Command to refresh module list
nRet = mv_lib.MV_VS_SetCommandValue(handle, b"CommandRefreshModuleList")
if nRet != MV_VS_OK:
self.log.error("Failed to refresh module list")
error_code = nRet & 0xFFFFFFFF
self.log.error(f"Failed to refresh module list, error code: 0x{error_code:x}")
# Special handling for 0x80030100 (MV_VS_E_GC_GENERIC)
if error_code == 0x80030100:
self.log.warning("Detected MV_VS_E_GC_GENERIC error (0x80030100) during module list refresh")
self.log.info("This is a non-critical error, continuing operation")
# We'll return True here to avoid treating this as a fatal error
return True
return False
self.log.info("Module list refreshed successfully")
return True
except Exception as e:
self.log.error(f"Error refreshing module list: {e}")
# Log the full exception traceback for debugging
import traceback
self.log.error(f"Exception traceback: {traceback.format_exc()}")
return False
def switch_scheme(self, solution_name, retry_count=0, max_retries=2):
@ -606,47 +618,142 @@ class HikrobotSmartCamera(Component):
return
concat_frame = None
concat_results = []
rot = self.rotations.split(",")
for cam_idx in range(self.num_cameras):
cam = self.cam_list[cam_idx]
self.log.info(f"GET FRAME CAMERA # {cam_idx}")
if self.ok_results[cam_idx]:
# keep last good result
frame = self.ok_frames[cam_idx]
res = False
else:
# Trigger acquisition & test execution
nRet = mv_lib.MV_VS_SetCommandValue(cam["handle"], b"AcquisitionStart")
if nRet != MV_VS_OK:
self.log.error(f"CAM{cam_idx} AcquisitionStart failed! [{nRet&0xFFFFFFFF:#x}]")
self.connected = False
frame_res = None
else:
# get frame
frame_res = MV_VS_GetFrame(cam["handle"])
try:
rot = self.rotations.split(",")
for cam_idx in range(self.num_cameras):
try:
cam = self.cam_list[cam_idx]
self.log.info(f"GET FRAME CAMERA # {cam_idx}")
# Initialize default values in case of error
frame = None
res = True # Default to error condition
if self.ok_results[cam_idx]:
# keep last good result
frame = self.ok_frames[cam_idx]
res = False
else:
try:
# Trigger acquisition & test execution
nRet = mv_lib.MV_VS_SetCommandValue(cam["handle"], b"AcquisitionStart")
if nRet != MV_VS_OK:
error_code = nRet & 0xFFFFFFFF
self.log.error(f"CAM{cam_idx} AcquisitionStart failed! [0x{error_code:x}]")
# Special handling for 0x80030100 (MV_VS_E_GC_GENERIC)
if error_code == 0x80030100:
self.log.warning("Detected MV_VS_E_GC_GENERIC error (0x80030100) during acquisition")
self.log.info("This is a non-critical error, using last good frame if available")
# Use last good frame if available
if self.ok_frames[cam_idx] is not None:
frame = self.ok_frames[cam_idx]
res = False
else:
# No good frame available, mark as disconnected
self.log.error("No previous good frame available")
self.connected = False
frame_res = None
else:
# For other errors, mark as disconnected
self.connected = False
frame_res = None
else:
# get frame
frame_res = MV_VS_GetFrame(cam["handle"])
if frame_res is not None:
res = frame_res["res"]["ScDeviceSolutionRunningResult"]
frame = frame_res["frame"]
# rotate frame
if rot[cam_idx] == "1":
frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
if rot[cam_idx] == "2":
frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)
if rot[cam_idx] == "3":
frame = cv2.rotate(frame, cv2.ROTATE_180)
else:
self.connected = False
if frame_res is not None:
try:
# Safely access the result data with error checking
if "res" in frame_res and "ScDeviceSolutionRunningResult" in frame_res["res"]:
res = frame_res["res"]["ScDeviceSolutionRunningResult"]
frame = frame_res["frame"]
# rotate frame
if len(rot) > cam_idx: # Check if rotation info exists for this camera
if rot[cam_idx] == "1":
frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
if rot[cam_idx] == "2":
frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)
if rot[cam_idx] == "3":
frame = cv2.rotate(frame, cv2.ROTATE_180)
else:
self.log.warning(f"CAM{cam_idx} Invalid frame result format")
# Use last good frame if available
if self.ok_frames[cam_idx] is not None:
frame = self.ok_frames[cam_idx]
res = False
else:
self.connected = False
except Exception as e:
self.log.error(f"Error processing frame for CAM{cam_idx}: {e}")
# Use last good frame if available
if self.ok_frames[cam_idx] is not None:
frame = self.ok_frames[cam_idx]
res = False
else:
self.connected = False
else:
self.log.warning(f"CAM{cam_idx} Failed to get frame")
# Use last good frame if available
if self.ok_frames[cam_idx] is not None:
frame = self.ok_frames[cam_idx]
res = False
else:
self.connected = False
except Exception as e:
self.log.error(f"Error during frame acquisition for CAM{cam_idx}: {e}")
# Log the full exception traceback for debugging
import traceback
self.log.error(f"Exception traceback: {traceback.format_exc()}")
# Use last good frame if available
if self.ok_frames[cam_idx] is not None:
frame = self.ok_frames[cam_idx]
res = False
else:
self.connected = False
# Skip this camera if we couldn't get a valid frame
if frame is None:
self.log.warning(f"Skipping CAM{cam_idx} due to missing frame")
continue
# Process the frame
if concat_frame is None:
concat_frame = copy.deepcopy(frame)
else:
try:
concat_frame = cv2.hconcat([concat_frame, frame])
except Exception as e:
self.log.error(f"Error concatenating frames: {e}")
# Use only the first frame if concatenation fails
if concat_frame is None and frame is not None:
concat_frame = copy.deepcopy(frame)
concat_results.append(not res)
if not res:
self.ok_results[cam_idx] = True
self.ok_frames[cam_idx] = copy.deepcopy(frame)
except Exception as e:
self.log.error(f"Error processing camera {cam_idx}: {e}")
# Continue with next camera
continue
# If we couldn't get any frames, return
if concat_frame is None:
concat_frame = copy.deepcopy(frame)
else:
concat_frame = cv2.hconcat([concat_frame, frame])
concat_results.append(not res)
if not res:
self.ok_results[cam_idx] = True
self.ok_frames[cam_idx] = copy.deepcopy(frame)
super()._get([concat_frame, self.ok_results])
self.log.error("No valid frames obtained from any camera")
return
super()._get([concat_frame, self.ok_results])
except Exception as e:
self.log.error(f"Error in _get method: {e}")
# Log the full exception traceback for debugging
import traceback
self.log.error(f"Exception traceback: {traceback.format_exc()}")
# Don't propagate the exception to avoid crashing the application
def resume(self):
self.log.info(f"RESUMING")
@ -660,9 +767,34 @@ class HikrobotSmartCamera(Component):
if len(self.cam_list) == self.num_cameras:
# Dummy acquisition for each camera to avoid reading past images
for cam_idx in range(self.num_cameras):
cam = self.cam_list[cam_idx]
nRet = mv_lib.MV_VS_SetCommandValue(cam["handle"], b"AcquisitionStart")
frame_res = MV_VS_GetFrame(cam["handle"])
try:
cam = self.cam_list[cam_idx]
nRet = mv_lib.MV_VS_SetCommandValue(cam["handle"], b"AcquisitionStart")
if nRet != MV_VS_OK:
error_code = nRet & 0xFFFFFFFF
self.log.warning(f"CAM{cam_idx} AcquisitionStart warning, error code: 0x{error_code:x}")
# Special handling for 0x80030100 (MV_VS_E_GC_GENERIC)
if error_code == 0x80030100:
self.log.warning("Detected MV_VS_E_GC_GENERIC error (0x80030100) during acquisition start")
self.log.info("This is a non-critical error, continuing operation")
# Skip frame acquisition for this camera
continue
# Only try to get a frame if AcquisitionStart was successful
frame_res = MV_VS_GetFrame(cam["handle"])
# Check if frame acquisition was successful
if frame_res is None:
self.log.warning(f"CAM{cam_idx} Failed to get initial frame, but continuing operation")
except Exception as e:
self.log.error(f"Error during camera {cam_idx} initialization: {e}")
# Log the full exception traceback for debugging
import traceback
self.log.error(f"Exception traceback: {traceback.format_exc()}")
# Continue with other cameras
continue
else:
QMessageBox.critical(None, "Errore", f"ERRORE CONNESSIONE TELECAMERE\n")
super().resume()