diff --git a/src/components/hikrobot_sc/hikrobot_sc.py b/src/components/hikrobot_sc/hikrobot_sc.py index c55e2f1..64dc3e4 100644 --- a/src/components/hikrobot_sc/hikrobot_sc.py +++ b/src/components/hikrobot_sc/hikrobot_sc.py @@ -67,12 +67,31 @@ class HikrobotSmartCamera(Component): nRet2 = mv_lib.MV_VS_GetEnumValue(handle, b"ScPushState", byref(push_state)) nRet3 = mv_lib.MV_VS_GetIntValue(handle, b"ScPushRate", byref(push_rate)) + # Check for specific error codes + has_generic_error = False + if nRet1 != MV_VS_OK: - self.log.error(f"Failed to get ScPushType, error code: 0x{nRet1&0xFFFFFFFF:x}") + error_code = nRet1 & 0xFFFFFFFF + self.log.error(f"Failed to get ScPushType, error code: 0x{error_code:x}") + if error_code == 0x80030100: # MV_VS_E_GC_GENERIC + has_generic_error = True + if nRet2 != MV_VS_OK: - self.log.error(f"Failed to get ScPushState, error code: 0x{nRet2&0xFFFFFFFF:x}") + error_code = nRet2 & 0xFFFFFFFF + self.log.error(f"Failed to get ScPushState, error code: 0x{error_code:x}") + if error_code == 0x80030100: # MV_VS_E_GC_GENERIC + has_generic_error = True + if nRet3 != MV_VS_OK: - self.log.error(f"Failed to get ScPushRate, error code: 0x{nRet3&0xFFFFFFFF:x}") + error_code = nRet3 & 0xFFFFFFFF + self.log.error(f"Failed to get ScPushRate, error code: 0x{error_code:x}") + if error_code == 0x80030100: # MV_VS_E_GC_GENERIC + has_generic_error = True + + # If we encountered the generic error, log additional information + if has_generic_error: + self.log.warning("Detected MV_VS_E_GC_GENERIC error (0x80030100): General camera error") + self.log.info("This error often occurs during scheme switching when the camera is busy") if nRet1 == MV_VS_OK and nRet2 == MV_VS_OK and nRet3 == MV_VS_OK: self.log.info(f"Push status - Type: {push_type.value}, State: {push_state.value}, Rate: {push_rate.value}") @@ -139,9 +158,15 @@ class HikrobotSmartCamera(Component): # Try to get additional camera status for debugging self._debug_camera_state(handle) - # Send a progress update to the UI - status_message = "Initializing (Status retrieval failed)" - self.progress_signal.emit(5, status_message) + # Check if we have the generic error + if has_generic_error: + # For the generic error, we'll send a more specific status message + status_message = "Initializing (Camera busy)" + self.progress_signal.emit(15, status_message) + else: + # Send a progress update to the UI + status_message = "Initializing (Status retrieval failed)" + self.progress_signal.emit(5, status_message) # After 10 seconds (20 checks at 500ms), force completion if we're still waiting if not hasattr(self, '_progress_check_count'): @@ -189,7 +214,13 @@ class HikrobotSmartCamera(Component): if nRet == MV_VS_OK: self.log.info(f"Device status: {device_status.value}") else: - self.log.info(f"Failed to get device status, error code: 0x{nRet&0xFFFFFFFF:x}") + error_code = nRet & 0xFFFFFFFF + self.log.info(f"Failed to get device status, 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): General camera error") + self.log.info("This error often occurs during scheme switching when the camera is busy") # Try to get the acquisition status acquisition_status = c_uint() @@ -197,7 +228,13 @@ class HikrobotSmartCamera(Component): if nRet == MV_VS_OK: self.log.info(f"Acquisition status: {acquisition_status.value}") else: - self.log.info(f"Failed to get acquisition status, error code: 0x{nRet&0xFFFFFFFF:x}") + error_code = nRet & 0xFFFFFFFF + self.log.info(f"Failed to get acquisition status, 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): General camera error") + self.log.info("This error often occurs during scheme switching when the camera is busy") except Exception as e: self.log.error(f"Error getting debug camera state: {e}") @@ -233,12 +270,14 @@ class HikrobotSmartCamera(Component): self.log.error(f"Error refreshing module list: {e}") return False - def switch_scheme(self, solution_name): + def switch_scheme(self, solution_name, retry_count=0, max_retries=2): """ Switch to a different scheme/solution using the API as described in the documentation. Args: solution_name: The name of the solution to switch to + retry_count: Current retry attempt (used internally for recursion) + max_retries: Maximum number of retry attempts for error recovery Returns: bool: True if the scheme switching process was successfully initiated, False otherwise @@ -268,7 +307,7 @@ class HikrobotSmartCamera(Component): self._debug_camera_state(handle) try: - self.log.info(f"Starting scheme switch to: {solution_name}") + self.log.info(f"Starting scheme switch to: {solution_name} (Attempt {retry_count+1}/{max_retries+1})") # Check if the solution name is valid (not empty) if not solution_name or solution_name.strip() == "": @@ -280,9 +319,18 @@ class HikrobotSmartCamera(Component): self.log.info(f"Setting solution name: {solution_name} (bytes: {solution_name_bytes})") nRet = mv_lib.MV_VS_SetStringValue(handle, b"SrcOperateSolutionName", solution_name_bytes) if nRet != MV_VS_OK: - self.log.error(f"Failed to set solution name: {solution_name}, error code: 0x{nRet&0xFFFFFFFF:x}") + error_code = nRet & 0xFFFFFFFF + self.log.error(f"Failed to set solution name: {solution_name}, error code: 0x{error_code:x}") + # Try to get more information about the error self._debug_camera_state(handle) + + # Check if this is the generic error and we can retry + if error_code == 0x80030100 and retry_count < max_retries: # MV_VS_E_GC_GENERIC + self.log.warning(f"Detected generic error (0x80030100). Waiting 2 seconds before retry {retry_count+1}/{max_retries}") + time.sleep(2) # Wait before retrying + return self.switch_scheme(solution_name, retry_count + 1, max_retries) + return False else: self.log.info(f"Successfully set solution name: {solution_name}") @@ -291,9 +339,18 @@ class HikrobotSmartCamera(Component): self.log.info("Sending CommandProjectLoad command") nRet = mv_lib.MV_VS_SetCommandValue(handle, b"CommandProjectLoad") if nRet != MV_VS_OK: - self.log.error(f"Failed to load project, error code: 0x{nRet&0xFFFFFFFF:x}") + error_code = nRet & 0xFFFFFFFF + self.log.error(f"Failed to load project, error code: 0x{error_code:x}") + # Try to get more information about the error self._debug_camera_state(handle) + + # Check if this is the generic error and we can retry + if error_code == 0x80030100 and retry_count < max_retries: # MV_VS_E_GC_GENERIC + self.log.warning(f"Detected generic error (0x80030100). Waiting 2 seconds before retry {retry_count+1}/{max_retries}") + time.sleep(2) # Wait before retrying + return self.switch_scheme(solution_name, retry_count + 1, max_retries) + return False else: self.log.info("Successfully sent project load command") @@ -312,6 +369,13 @@ class HikrobotSmartCamera(Component): # Log the full exception traceback for debugging import traceback self.log.error(f"Exception traceback: {traceback.format_exc()}") + + # Retry on exception if we haven't exceeded max retries + if retry_count < max_retries: + self.log.warning(f"Exception occurred. Waiting 2 seconds before retry {retry_count+1}/{max_retries}") + time.sleep(2) # Wait before retrying + return self.switch_scheme(solution_name, retry_count + 1, max_retries) + return False def get_ntp_parameters(self): diff --git a/src/ui/test_vision/test_vision.py b/src/ui/test_vision/test_vision.py index 4a52707..dbf9a7e 100644 --- a/src/ui/test_vision/test_vision.py +++ b/src/ui/test_vision/test_vision.py @@ -84,7 +84,10 @@ class SchemeProgressDialog(QDialog): # Update the status label with more detailed information if "Initializing" in status: self.status_label.setText(f"Status: {status}") - self.debug_label.setText(f"Debug info: Camera is initializing. This may take some time.") + if "Camera busy" in status: + self.debug_label.setText(f"Debug info: Camera is busy. Waiting for it to become available...") + else: + self.debug_label.setText(f"Debug info: Camera is initializing. This may take some time.") else: self.status_label.setText(f"Status: {status}") self.debug_label.setText(f"Debug info: Progress update received at {time.strftime('%H:%M:%S')}")