跳转到内容

BATCAM FX 概述

BATCAM FX 开发概述

1. 简介

BATCAM FX 是 SM Instruments 的实时声学相机。它同时提供 1600×1200 分辨率的光学图像与 40×30 波束成形(BF)图,可将发出声音的位置可视化地叠加在图像上。

本文档是 BATCAM FX 对接开发的起点。这里一览式地介绍设备提供的接口,并说明最具代表性的对接工作——叠加图像合成的数据流与连接方法。参数控制、ROS 2 集成、固件更新等详细主题将链接到各自的详细文档。关于开发者中心的整体结构以及其他产品(BATCAM FX2、FX Viewer)的文档,请参阅开发者中心入门

2. 提供的接口一览

接口用途相关文档
RTSP接收相机原始视频流。在固件 1.0.3 及以上版本中,设备也可以通过 RTSP 提供由其自行合成的叠加图像。Overlay 参数
WebSocket + Protobuf波束成形(BF Map)、音频、AI 局部放电(PRPD)分类结果的实时流式传输本文档、Python Protobuf 示例
REST API账户管理、设备设置(网络、固件、重启、设备信息)、事件触发、波束成形与叠加参数、ROS Domain IDBATCAM FX API 演练场
ROS 2基于话题/动作的数据接收与设置(自 v1.0.3b 开发固件起支持)ROS Integration
固件更新通过网页或 Shell(SSH)安装固件Web 更新Shell 更新

REST API 的完整端点规范可在 API 演练场中查看,并可在浏览器中直接调用试用。关于通过 WebSocket 发送的消息格式,请参阅 fx-stream-protocol SchemaPython Protobuf 示例文档。

3. 叠加图像合成的数据流

BATCAM FX 的数据通过 RTSP 发送相机原始视频数据,并通过 WebSocket 发送以 Protobuf 协议编码的数据。如果希望直接获取叠加后的图像,请按以下顺序合成图像。

BATCAM FX 叠加图像合成数据流示意图:将 RTSP 原始视频与 WebSocket/Protobuf 波束成形数据组合

  1. 从 RTSP(rtsp://{device_ip}/raw)接收原始视频。

  2. 通过 WebSocket 接收以 Protobuf 格式编码的 Beamforming 消息,并将其解码为由总计 1200 个 Float 值构成的数组(Float Array)。该数组是把 40x30 结构的 BF Map 展开为 1x1200 结构的结果,以 25Hz 的周期发送。

  3. 对 Float Array 进行插值,生成用于叠加的图像。40×30 的 BF Map 会映射到 1600×1200 的光学图像上。

  4. 将 RTSP 视频流与接收到的声源数据组合,即可实时生成 Beamforming 叠加图像。

💡 参考:在固件 1.0.3 及以上版本中,BATCAM FX 支持提供由设备自行合成叠加图像的 RTSP 流,因此也可以采用不自行合成的构成方式。设置方法请参阅Overlay 参数文档,BF Map 的坐标系与 Listening Point 的指定方法请参阅 Listening Point 坐标文档。

4. 连接信息与认证

下表中的 {device_ip} 是设备的 IP 地址。IP 设置可通过 REST API(/setting/ip)查询和更改,设备的固件版本可通过设备信息查询 API(/setting/status)确认。详细规范请参阅 API 演练场

项目备注
RTSP 视频流rtsp://{device_ip}/raw需要用户认证
WebSocket 流式传输ws://{device_ip}/ws必须指定 SubProtocol
WebSocket SubProtocolSubscribe根据示例的不同,也会使用小写的 subscribe 写法
REST APIhttp://{device_ip}由设备直接提供 API 服务
固件更新页面http://{device_ip}/firmware请参阅 Web 更新
固件更新日志ws://{device_ip}/firmware/ws接收更新进度日志
认证方式HTTP BasicREST、RTSP、WebSocket 通用

BATCAM FX 默认预先设置了 adminuser 两个账户。账户创建使用 /auth/create,查询全部账户列表使用 /auth/all,单个账户的查询、删除与密码重置通过 /auth/account 端点执行。

⚠️ 注意:出厂默认密码请务必修改后再使用。

Authorization 标头的构成 — 如果您使用的 WebSocket 库支持认证,请提供 Username 和 Password;如果不支持,则在请求 WebSocket 连接的 Header 中添加 Authorization 键,并将 {username}:{password} 字符串以 base64 编码后包含在其中。

Authorization: Basic base64({username}:{password})
# 示例:username=admin, password=password 时
Authorization: Basic YWRtaW46cGFzc3dvcmQ=

开始订阅(Subscribe) — WebSocket 连接建立后并不会立即接收到消息,需要使用 Protobuf 预生成代码中提供的 Subscribe 对象,向相机发送对所需数据流的订阅。各数据流的 Subscribe ID 如下。

Subscribe ID消息内容发送频率
0Beamforming40×30 BF Map(1×1200 Float 数组)25 Hz
1WsAudio8000 采样 Float 音频(200 kHz × 40 ms)25 Hz
2LPointAudioListening Point 3 通道波束成形音频25 Hz
3PrpdAI 局部放电分类结果(固件 v1.0.3c 及以上,请参阅 AI PRPD 分类4 Hz

5. 示例代码与 Protobuf Schema

使用 Protobuf 与 WebSocket 收发数据的示例已公开在本公司的 GitHub(C# 示例)上。该示例完整包含了上述叠加合成过程,并且还包含 GUI 示例。

以下是展示从 WebSocket 连接、发送订阅到解码首条消息这一流程的 Python 示例。

import asyncio
import base64
import websockets
import fx_protocol_pb2 as pb # fx-stream-protocol 的预生成文件
async def stream(ip: str, user: str, password: str):
cred = base64.b64encode(f"{user}:{password}".encode()).decode()
headers = {
"Authorization": f"Basic {cred}",
"Sec-WebSocket-Protocol": "subscribe",
}
uri = f"ws://{ip}/ws"
async with websockets.connect(uri, additional_headers=headers, subprotocols=["subscribe"]) as ws:
# 开始订阅 Beamforming(ID 0)
sub = pb.Subscribe()
sub.id = 0
sub.type = pb.Subscribe.SUBSCRIBE
await ws.send(sub.SerializeToString())
async for raw in ws:
event = pb.Event()
event.ParseFromString(raw)
if event.WhichOneof("data") == "beamforming":
bf = event.beamforming
print(f"bf count={len(bf.bf)} gain={bf.gain}") # bf count=1200
asyncio.run(stream("192.168.0.30", "admin", "password"))

环境配置、Python 绑定生成、各消息类型的详细示例,将在 Python Protobuf 示例文档中分步骤说明。

编码/解码 Protobuf 所需的 Schema 与预生成文件可在本公司的 OSS GitLab(fx-stream-protocol)中查看。本文档以 v0.0.2 标签的预生成文件为准进行说明,其他版本请在仓库的标签列表中查看。

6. 常见问题(Troubleshooting)

现象原因解决方法
WebSocket 连接无法建立未指定 SubProtocol连接时必须将 WebSocket SubProtocol 指定为 Subscribe(库的 subprotocols 选项)。
连接成功但收不到消息未发送订阅(Subscribe)消息连接后立即发送 Subscribe 对象(id、type)以开始订阅。(C# 参考链接
因认证错误(401)导致连接被拒绝认证信息缺失或账户信息有误向库的认证功能提供 Username/Password(C# 参考链接),或按上述格式直接构造 Authorization 标头。请确认账户与密码是否正确。

7. 后续步骤