콘텐츠로 건너뛰기
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#

다음과 같은 경우 타임아웃이 발생합니다. RetrieveResult() 이미지를 기다리지만 설정된 타임아웃 내에 이미지가 도착하지 않습니다.

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

일반적인 원인:

  • Trigger Mode가 활성화되었지만 트리거 신호가 도착하지 않음
  • 카메라가 그래빙하지 않음
  • 예상보다 긴 Exposure Time
  • 너무 짧은 타임아웃 값
  • 일관되지 않은 카메라 설정

타임아웃은 트리거 시스템에서 특히 흔히 발생합니다. 타임아웃이 발생했다고 해서 반드시 카메라가 고장난 것은 아닙니다. 대개 애플리케이션이 발생하지 않은 이벤트장을 기다리고 있음을 의미합니다.

Runtime Exceptions#

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

예시는 다음과 같습니다.

  • 카메라 플러그가 분리됨
  • 네트워크 연결 끊김
  • 장치 재설정
  • 잘못된 카메라 상태
  • 잘못된 Property 접근
try:
    # acquisition code
    pass
except Exception as e:
    print("Camera error:", e)

이러한 오류는 일반적으로 취득 중지, 대기, 카메라 재열거 또는 장치 재개와 같은 복구 로직이 필요합니다.

오류 처리 전략#

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

프레임별 처리#

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

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. 액퀴지션이 정상적으로 실행됩니다.
  2. 오류가 발생합니다.
  3. 예외가 발생합니다.
  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, 심각도 수준, 지속성 파일 및 더 나은 진단 기능을 제공합니다.

복구 가능한 오류와 치명적인 오류#

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

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

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

주요 내용 요약#

  • 산업용 환경에서 오류 발생은 자연스러운 현상입니다.
  • 프레임 수준의 오류와 시스템 수준의 예외를 모두 처리하세요.
  • 타임아웃 사용을 고려하고 적절한 길이를 지정하세요.
  • 사용 with 리소스 정리를 보장하기 위해.
  • 무인 시스템을 위한 복구 루프를 구현하세요.
  • 프로덕션 환경에서는 로깅과 명확한 오류 분류를 사용하세요.

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