컨텐츠로 건너뛰기

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로 제공할 수 있습니다.오버레이 파라미터
WebSocket + Protobuf빔포밍(BF Map)·오디오·AI 부분방전(PRPD) 분류 결과의 실시간 스트리밍이 문서, Python Protobuf 예제
REST API계정 관리, 장비 설정(네트워크·펌웨어·재부팅·기기정보), 이벤트 트리거, 빔포밍·오버레이 파라미터, ROS Domain IDBATCAM FX API 플레이그라운드
ROS 2토픽/액션 기반 데이터 수신 및 설정 (v1.0.3b 개발 펌웨어부터 지원)ROS Integration
펌웨어 업데이트웹페이지 또는 쉘(SSH)을 통한 펌웨어 설치웹 업데이트, 쉘 업데이트

REST API의 전체 엔드포인트 명세는 API 플레이그라운드에서 확인하고, 브라우저에서 직접 호출해 볼 수 있습니다. WebSocket으로 전송되는 메시지의 포맷은 fx-stream-protocol 스키마Python 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 스트림 제공을 지원하므로, 직접 합성하지 않는 구성도 가능합니다. 설정 방법은 오버레이 파라미터 문서를, 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}/wsSubProtocol 지정 필수
WebSocket SubProtocolSubscribe예제에 따라 소문자 subscribe 표기도 사용됩니다
REST APIhttp://{device_ip}장비가 API를 직접 서빙
펌웨어 업데이트 페이지http://{device_ip}/firmware웹 업데이트 참고
펌웨어 업데이트 로그ws://{device_ip}/firmware/ws업데이트 진행 로그 수신
인증 방식HTTP BasicREST·RTSP·WebSocket 공통

BATCAM FX에는 기본적으로 admin, user 두 개의 계정이 미리 설정되어 있습니다. 계정 생성은 /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 스키마

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를 인코딩/디코딩하기 위해 필요한 스키마와 사전 생성 파일은 당사 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. 다음 단계