콘텐츠로 바로 가기
STAGING SERVER
DEVELOPMENT SERVER

오류 처리 및 복구#

이 항목에서는 오류 처리가 중요한 이유를 설명합니다.

산업용 카메라 시스템은 오류 발생이 가능할 뿐만 아니라 충분히 예상되는 환경에서 작동합니다. 일반적인 데스크톱 응용 프로그램과 달리 이러한 시스템은 종종 수 시간 또는 수 일 동안 지속적으로 실행되며 외부 하드웨어와 상호 작용합니다. 이로 인해 오류 처리는 선택 사항이 아니라 시스템 디자인의 핵심 요소입니다.

일반적인 오류 원인은 다음과 같습니다.

  • 네트워크 중단(특히 GigE 카메라 사용 시)
  • USB 연결 해제
  • 누락되었거나 불안정한 트리거 신호
  • CPU 과부하 또는 느린 이미지 처리
  • 대역폭 제한
  • 잘못되었거나 상태에 종속된 카메라 구성

다음 시각 자료는 오류 처리가 중요한 이유를 보여줍니다.

System starts → runs normally → transient failure occurs

적절한 처리가 없는 경우:

Unhandled exception → application crashes → acquisition stops

적절한 처리가 있는 경우:

Failure → detect → recover → continue

목표는 가능한 모든 장애를 방지하는 것이 아닙니다. 목표는 장애를 가시적이고 제어 가능하며 복구할 수 있도록 만드는 것입니다.

pypylon의 오류 유형#

오류 유형에 따라 서로 다른 처리 전략이 필요합니다.

그랩 오류#

그랩 오류는 그랩 결과가 반환되었지만 이미지 자체는 유효하지 않음을 의미합니다.

with camera.RetrieveResult(2000) as grab_result:
    if grab_result.GrabSucceeded():
        image = grab_result.Array
    else:
        print(grab_result.ErrorCode)
        print(grab_result.ErrorDescription)

주요 원인:

  • GigE 연결 중 패킷 손실
  • 대역폭 부족
  • 일시적인 전송 계층 문제
  • 카메라 또는 드라이버 불안정

이러한 유형의 오류는 대개 단일 프레임에만 영향을 미칩니다. 애플리케이션은 일반적으로 문제를 기록하고, 해당 프레임을 건너뛴 후 취득을 계속할 수 있습니다.

Timeout Errors#

A timeout occurs while RetrieveResult() waits for an image but no image arrives within the timeout configured.

with camera.RetrieveResult(
    1000,
    pylon.TimeoutHandling_ThrowException
) as grab_result:
    image = grab_result.Array

주요 원인:

  • Trigger Mode이(가) 활성화되어 있으나 Trigger Signal이 도착하지 않음
  • 카메라가 그래빙하지 않음
  • 예상보다 긴 Exposure Time
  • 너무 짧은 타임아웃 값
  • 일관되지 않은 카메라 구성

타임아웃은 특히 트리거 시스템에서 흔히 발생합니다. 타임아웃이 반드시 카메라 고장을 의미하는 것은 아닙니다. 응용 프로그램이 발생하지 않은 이벤트를 기다리고 있음을 의미하는 경우가 많습니다.

런타임 예외#

런타임 예외는 단일 프레임 획득을 넘어선 문제를 나타냅니다.

예시는 다음과 같습니다:

  • 카메라 연결 해제됨
  • 네트워크 연결 끊김
  • 디바이스 재설정
  • 잘못된 카메라 상태
  • 잘못된 파라미터 액세스
try:
    # acquisition code
    pass
except Exception as e:
    print("Camera error:", e)

이러한 오류는 일반적으로 획득 중지, 대기, 카메라 재열거(re-enumeration) 또는 디바이스 재개와 같은 복구 로직이 필요합니다.

오류 처리 전략#

견고한 시스템은 일반적으로 여러 전략을 결합합니다.

프레임별 처리#

카메라는 계속 작동 중이지만 개별 프레임에 실패가 발생할 수 있는 경우에 이를 사용하십시오.

with camera.RetrieveResult(2000) as grab_result:
    if grab_result.GrabSucceeded():
        process(grab_result.Array)
    else:
        log_error(grab_result.ErrorDescription)

이 접근 방식은 간헐적인 프레임 손실이 허용되는 경우에 유용합니다. 획득 루프를 유지하고 하나의 잘못된 이미지로 인해 전체 시스템이 중단되는 것을 방지합니다.

일반적인 사용 사례:

  • 라이브 디스플레이
  • 모니터링 시스템
  • 중요하지 않은 이미지 스트림

예외 처리#

설정하려는 속성을 식별하려면 try/except 런타임에 실패할 수 있는 작업 주변에 적용합니다.

try:
    with camera.RetrieveResult(
        2000,
        pylon.TimeoutHandling_ThrowException
    ) as grab_result:
        if grab_result.GrabSucceeded():
            process(grab_result.Array)

except Exception as e:
    print("Error:", e)

이렇게 하면 응용 프로그램이 즉시 중단되는 것을 방지할 수 있습니다. 그러나 예외를 포착하는 것만으로는 충분하지 않습니다. 응용 프로그램은 계속 진행할지, 재시도할지, 획득을 재설정할지, 아니면 안전하게 종료할지 여부도 결정해야 합니다.

복구 루프 패턴#

복구 루프는 오류 감지와 자동 복구를 결합합니다. 다음 코드 샘플은 복구 루프를 구성하기 위한 권장 패턴을 보여줍니다.

import time

with pylon.InstantCamera(pylon.FirstFound) as camera:
    while True:
        try:
            if not camera.IsGrabbing():
                camera.StartGrabbing()

            with camera.RetrieveResult(
                2000,
                pylon.TimeoutHandling_ThrowException
            ) as grab_result:

                if grab_result.GrabSucceeded():
                    image = grab_result.Array
                    process(image)
                else:
                    log_error(grab_result.ErrorDescription)

        except Exception as e:
            log_error(f"Acquisition error: {e}")

            if camera.IsGrabbing():
                camera.StopGrabbing()

            time.sleep(0.5)

복구 루프를 사용할 때의 이벤트 시퀀스는 다음과 같습니다.

  1. 인수(Acquisition)가 정상적으로 실행됩니다.
  2. 오류가 발생합니다.
  3. 예외(Exception)가 발생합니다.
  4. 예외 처리기가 문제를 기록합니다.
  5. StopGrabbing() 인수 파이프라인을 재설정합니다.
  6. 애플리케이션이 잠시 대기합니다.
  7. 루프가 인수를 재시도합니다.

이 패턴을 통해 시스템은 수동 개입 없이 일시적인 장애로부터 복구할 수 있습니다.

인수 오류가 발생한 후에는 내부 버퍼나 그랩 상태가 더 이상 깨끗한 인수 파이프라인을 나타내지 않을 수 있습니다.

Error → uncertain acquisition state → reset required

그렇기 때문에 호출하는 것은 StopGrabbing() 복구 루프의 필수적인 부분입니다. 이는 다음 작업에 도움이 됩니다.

  • 현재 인수 작업 중지
  • 내부 버퍼 해제 또는 재활용
  • 깔끔한 재시작을 위한 카메라 준비

이 방법으로 가능한 모든 하드웨어 오류를 해결할 수는 없지만, 대개 첫 번째로 안전한 복구 단계입니다.

카메라 연결 해제 처리#

물리적 연결 끊김은 가장 흔한 실제 장애 사례 중 하나입니다.

Camera unplugged → communication lost → exception

견고한 애플리케이션이라면 하드웨어가 언제든지 사라질 수 있다고 가정해야 합니다.

전형적인 복구 시퀀스는 다음과 같습니다.

Detect error
   ↓
Stop acquisition
   ↓
Wait briefly
   ↓
Re-enumerate cameras if needed
   ↓
Reconnect or report fatal failure

프로덕션 시스템의 경우, 재연결 로직은 일반적으로 기본 그랩 루프보다 더 상위 수준에서 구현됩니다.

리소스 안전성#

사용 with 그랩 결과에 필수적입니다.

with camera.RetrieveResult(...) as grab_result:
    image = grab_result.Array

이렇게 하면 블록 내부에 예외가 발생하더라도 그랩 결과가 확실히 해제됩니다.

적절한 정리 작업이 없으면 인수가 중단될 수 있습니다.

Unreleased grab results → buffers unavailable → acquisition stalls

이것이 이 가이드의 모든 예제에서 그랩 결과에 컨텍스트 관리자를 사용하는 이유입니다.

출력 대신 로깅 사용#

예를 들어, print() 간단하고 가독성이 좋습니다. 프로덕션 환경에서는 Python logging 모듈을 사용하는 것이 좋습니다.

import logging

logging.exception("Camera acquisition failed")

로깅은 장기 실행 시스템에 대해 Timestamp, 심각도 수준, 지속성 파일 및 더 나은 진단 기능을 제공합니다.

복구 가능 오류 vs. 치명적 오류#

모든 오류를 동일한 방식으로 처리해서는 안 됩니다.

Error 일반적인 처리 방식
단일 프레임 실패 로그 기록 후 계속 진행
Trigger Mode에서의 시간 초과(Timeout) 트리거 구성 확인 또는 재시도
일시적인 대역폭 문제 로그 기록, 부하 감소, 계속 진행
카메라 연결 끊김 중지, 재열거(re-enumerate), 재연결
시작 시 필수 카메라 누락 빠른 실패(Fail fast)
잘못된 구성 중지 및 오류 보고

프로덕션 애플리케이션은 재시도할 수 있는 오류와 작업자의 개입이 필요한 오류를 명확하게 구분해야 합니다.

주요 핵심 사항#

  • 산업 현장에서는 오류 발생이 자연스럽습니다.
  • 프레임 수준의 오류와 시스템 수준의 예외를 모두 처리하세요.
  • 시간 초과(Timeout) 사용을 고려하고 적절한 길이를 지정하세요.
  • 설정하려는 속성을 식별하려면 with 리소스 정리를 보장하기 위해서입니다.
  • 무인 시스템을 위한 복구 루프를 구현하세요.
  • 프로덕션 환경에서는 로깅과 명확한 오류 분류를 사용하세요.

잘 설계된 오류 처리 전략은 안정적이고 자율적인 카메라 애플리케이션을 보장합니다.