跳转到内容
STAGING SERVER
DEVELOPMENT SERVER

错误处理与恢复#

本主题解释了为什么错误 handling 非常重要。

工业相机系统运行的环境中,故障不仅可能发生,而且是在预料之中的。与典型的桌面应用程序不同,这些系统通常连续运行数小时甚至数天,并与外部硬件进行交互。因此,错误处理并非可有可无,而是系统设计中的核心要素。

典型的错误来源包括:

  • 网络中断,特别是使用 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

常见原因:

  • 已启用 Trigger Mode,但没有触发信号到达
  • 相机未在抓取图像
  • Exposure Time 长于预期
  • Timeout 值过短
  • 相机配置不一致

超时在触发系统中尤为常见。超时并不一定意味着相机损坏,通常意味着应用程序正在等待一个未发生的事件。

运行时异常#

运行时异常表示超出了单帧采集范围的问题。

示例如下:

  • 相机已拔出
  • 网络连接丢失
  • 设备重置
  • 相机状态无效
  • 参数访问无效
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")

Logging 可为长时间运行的系统提供 Timestamp、严重性级别、持久化文件以及更好的诊断功能。

可恢复错误与致命错误#

并非所有错误都应以相同的方式处理。

错误 典型处理方式
单帧失败 记录日志并继续
Trigger Mode 超时 检查触发配置或重试
临时带宽问题 记录日志、减少负载、继续
相机断开连接 停止、重新枚举、重新连接
启动时缺少必需的相机 快速失败
无效配置 停止并报告错误

生产应用程序应明确区分可重试的错误与需要人工干预的错误。

核心要点#

  • 在工业环境中,错误是正常的。
  • 同时处理帧级错误和系统级异常。
  • 考虑使用超时机制并指定合适的长度。
  • 使用 with 以确保资源清理。
  • 为无人值守系统实现恢复循环。
  • 在生产环境中使用 logging 并进行清晰的错误分类。

设计良好的错误处理策略可确保相机应用程序稳定且自主地运行。