콘텐츠로 바로 가기
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 연결 중 패킷 손실
  • 대역폭 부족
  • 일시적인 전송 계층 문제
  • 카메라 또는 드라이버의 불안정성

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

타임아웃 오류#

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

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

일반적인 원인:

  • 트리거 모드가 활성화되어 있지만 트리거 신호가 수신되지 않습니다.
  • 카메라가 영상을 인식하지 못합니다
  • 노출 시간이 예상보다 길다
  • 타임아웃 값이 너무 짧습니다.
  • 일관성 없는 카메라 설정

타임아웃은 트리거 방식의 시스템에서 특히 흔히 발생합니다. 타임아웃이 발생한다고 해서 항상 카메라가 고장난 것은 아닙니다. 대개는 애플리케이션이 결코 발생하지 않은 이벤트를 기다리고 있다는 것을 의미합니다.

런타임 예외#

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

예를 들면 다음과 같습니다:

  • 카메라 전원 연결 해제됨
  • 네트워크 연결이 끊어졌습니다
  • 기기 초기화
  • 카메라 상태가 올바르지 않습니다.
  • 잘못된 매개변수 액세스
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")

로깅은 장시간 실행되는 시스템에 대해 타임스탬프, 심각도 수준, 영구 저장 파일 및 향상된 진단 기능을 제공합니다.

복구 가능한 오류 대 치명적 오류#

모든 오류를 똑같은 방식으로 처리해야 하는 것은 아닙니다.

Error 일반적인 취급 방법
단일 프레임 오류 로그 기록 후 계속
트리거 모드에서 타임아웃 트리거 설정을 확인하거나 다시 시도하십시오.
일시적인 대역폭 문제 로그 기록, 부하 감소, 계속
카메라 연결 해제됨 중지, 재열거, 재연결
시작 시 필수 카메라가 없습니다 빨리 실패하라
잘못된 구성 중지하고 오류를 보고하세요

실제 운영 환경의 애플리케이션은 재시도가 가능한 오류와 운영자의 개입이 필요한 오류를 명확히 구분해야 합니다.

주요 핵심 사항#

  • 산업 현장에서는 오류가 흔히 발생합니다.
  • 프레임 수준의 오류와 시스템 수준의 예외를 모두 처리하십시오.
  • 타임아웃을 사용하는 것을 고려하고 적절한 시간을 지정하십시오.
  • 설정하려는 속성을 식별하려면 with 자원 정리를 보장하기 위해.
  • 무인 시스템에 대한 복구 루프를 구현합니다.
  • 실제 운영 환경에서는 로깅 기능을 사용하고 오류를 명확하게 분류하십시오.

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