2. 相机连接与设备枚举
在 pylon 平台上开发机器视觉应用,第一步永远不是写采集逻辑,而是让软件“看见”相机。Basler 相机主要通过两种接口接入:GigE Vision 与 USB3 Vision。它们都建立在 GenICam 标准之上,因此 pylon 可以用统一的 API 访问不同接口的相机,但底层发现机制、带宽特性与配置方式差异明显,理解这些差异是稳定连接多相机系统的基础。
两种协议的本质差异
GigE Vision 基于千兆以太网,使用 GVCP 协议在 UDP 端口 3956 上进行设备发现与控制,图像数据则通过 GVSP 流传输。它的优势是线缆长(可达 100 米)、支持 PoE 供电、天然适合多相机分布式部署;代价是带宽受限于网卡与交换机,且需要正确配置 IP 才能通信。USB3 Vision 基于 USB 3.0 总线,采用 SuperSpeed 传输,控制器通过 USB 设备描述符和 U3V 协议枚举相机,带宽高、延迟低、即插即用,但线缆长度通常限制在 3 米左右,且多相机共享主机控制器带宽。
在 pylon 中,这两种相机都通过 GenICam 的传输层(Transport Layer)抽象为统一设备。GigE 使用 PylonGigE 传输层,USB 使用 PylonUsb 传输层。枚举时 pylon 会同时加载已注册的传输层,因此一次枚举即可列出所有接口上的相机。
设备发现机制
GigE 相机的发现依赖广播:主机向子网广播 GVCP Discovery 报文,相机回应自身信息(厂商、型号、序列号、当前 IP、MAC 等)。这意味着如果主机与相机不在同一子网,且没有配置持久化 IP 或 DHCP 服务器,相机可能无法被发现。pylon 提供了“自动发现”与“手动指定 IP”两种方式。USB 相机则通过 USB 总线枚举,主机控制器在设备插入时读取描述符,pylon 直接获取设备列表,无需网络配置。
实际开发中,一个常见问题是 GigE 相机被枚举到但无法打开,原因往往是 IP 不在同一网段。此时 pylon 的枚举结果中会显示相机的当前 IP 与子网掩码,开发者可以据此判断是否需要修改主机网卡 IP 或为相机分配持久化 IP。
pylon 设备枚举 API
pylon 的 C++ API 中,设备枚举通过 CTlFactory 完成。典型代码如下:
#include <pylon/PylonIncludes.h>
using namespace Pylon;
CTlFactory& tlFactory = CTlFactory::GetInstance();
DeviceInfoList_t devices;
tlFactory.EnumerateDevices(devices);
for (size_t i = 0; i < devices.size(); ++i) {
std::cout << "Device " << i << ": "
<< devices[i].GetModelName() << " | "
<< devices[i].GetSerialNumber() << " | "
<< devices[i].GetDeviceClass() << " | "
<< devices[i].GetIpAddress() << std::endl;
}
DeviceInfoList_t 中的每个 CDeviceInfo 对象包含设备类(GigE 或 USB)、型号、序列号、用户 ID、IP 地址等。开发者可以按序列号或用户 ID 筛选目标相机,避免多相机环境下选错设备。C# 中对应 EnumerateDevices 与 DeviceInfo 类,逻辑一致。
多相机连接与用户 ID
当系统中有多台同型号相机时,仅靠型号无法区分。Basler 相机支持设置“设备用户 ID”(Device User ID),这是一个可写入相机内部持久存储的字符串。通过 pylon API 可以在打开相机后设置:
camera.DeviceUserID.SetValue("Line1_Top");
设置后,该 ID 会出现在后续枚举的 DeviceInfo 中。这样在代码里就可以按用户 ID 精确匹配相机,而不是依赖枚举顺序或序列号硬编码。对于多相机系统,建议在部署阶段为每台相机写入有意义的用户 ID,例如“工位1_上相机”“工位1_下相机”,并在配置文件中维护用户 ID 与逻辑角色的映射。
IP 配置与持久化 IP
GigE 相机的 IP 配置有三种模式:DHCP、AutoIP(链路本地地址,169.254.x.x)和静态 IP。在工业现场,通常使用静态 IP 以保证确定性。pylon 提供了 CGigECamera 的 ChangeIpConfiguration 方法,也可以在 pylon IP Configurator 工具中手动设置。持久化 IP 的关键是:设置后相机会将 IP 写入非易失存储,断电重启后仍生效。如果相机与主机不在同一网段,枚举可能失败,此时需要临时将主机网卡改为与相机同网段,完成 IP 修改后再恢复。
一个实用的部署流程是:先用 AutoIP 让相机与主机自动协商到 169.254.x.x 网段,枚举到相机后,将其改为规划好的静态 IP(如 192.168.1.10),同时设置用户 ID,最后将主机网卡也改为 192.168.1.x 网段。这样后续每次上电,相机与主机都在同一子网,枚举稳定。
连接状态监控与异常处理
相机连接不是一次性的,运行中可能因网线松动、供电波动、USB 重新枚举而断开。pylon 提供了连接状态监控机制:Camera.IsConnected() 可查询当前连接状态;对于 GigE,还可以注册 ConnectionLost 事件回调。当连接丢失时,采集线程会抛出 GenericException 或 TimeoutException,应用应捕获并进入重连流程。
重连的典型策略是:停止采集、释放相机对象、重新枚举设备、按用户 ID 匹配目标相机、重新打开并恢复参数配置。注意,相机参数(曝光、增益、ROI)在断开后可能丢失,因此建议在应用启动时从配置文件加载参数,重连后重新下发。对于多相机系统,重连应逐台进行,避免同时重连导致带宽或 USB 控制器瞬时过载。
多相机系统的工程建议
对于 4 台以上 GigE 相机的系统,建议使用独立网卡或工业交换机,并开启巨帧(Jumbo Frame,通常 9000 字节)以降低 CPU 负载。每台相机分配固定静态 IP,主机网卡也使用静态 IP,避免 DHCP 租约变化导致枚举失败。USB 多相机则要注意主机控制器数量:一台主机通常有多个 USB 控制器,将相机分散到不同控制器上可以避免带宽争抢。pylon 的 DeviceInfo 中不直接暴露控制器信息,但可以通过系统工具(如 Windows 设备管理器)确认拓扑。
连接状态监控应作为应用的标准模块。建议在采集线程之外单独运行一个监控线程,周期性调用 IsConnected(),并在检测到断开时触发重连。重连成功后,除了恢复参数,还应重新启动采集流。对于需要高可用性的场景,可以记录断开时间、重连次数和失败原因,便于现场排查。