SECTION 01
시스템 아키텍처
FPV ICS는 현재 서버 사이드 시뮬레이션으로 동작합니다.
실제 Edge 디바이스가 연결되면 시뮬레이터 대신 동일한 소켓 채널로 실측 데이터가 유입되어
HUD는 수정 없이 그대로 동작합니다.
물리 센서
카메라·소나·MAG 등
→
Edge 디바이스
Jetson / RPi · AI 추론
→
광섬유 테더 / RF
WebSocket JSON
→
FastAPI 서버
:8010 Socket.IO
→
HUD 브라우저
/drone /ugv /usv /uuv /mcm
📌 설계 원칙
Edge 디바이스는 JSON 메시지를 WebSocket으로 push하기만 하면 됩니다.
서버는 이를 받아 HUD에 브로드캐스트합니다. Edge에서 직접 HUD에 접근하지 않습니다.
⚠ 현재 상태 (시뮬레이션)
ics_mcm_engine.py, ics_uuv_engine.py 등 서버 사이드 엔진이
실제 Edge 역할을 대신합니다. Edge 연동 시 해당 엔진을 비활성화하고
Edge WebSocket 클라이언트를 등록하면 됩니다.
🚁 DRONE
UAV
EdgeJetson Orin Nano
통신5.8GHz RF / LTE
채널telemetry, ar_overlay
주기10 Hz (telemetry)
🤖 UGV
지상
EdgeJetson AGX Orin
통신WiFi 6 / LTE / RF
채널ics2_state
주기5 Hz
⚓ USV
수상
EdgeJetson Xavier NX
통신LTE / 위성 / RF
채널usv_state
주기2 Hz
🤿 UUV
수중
Edge내압 Jetson TX2
통신광섬유 테더 전용
채널uuv_state
주기1 Hz
💣 MCM
기뢰탐지
Edge내압 Jetson TX2
통신광섬유 테더 전용
채널mcm_state
주기1 Hz
SECTION 02
전송 프로토콜
Edge → 서버 간 WebSocket (Socket.IO), 서버 → HUD 브로드캐스트 동일 채널 사용.
| 항목 | 값 | 비고 |
|---|---|---|
| 프로토콜 | WebSocket (Socket.IO v4) | HTTP fallback 지원 |
| 서버 주소 | ws://<SERVER_IP>:8010 |
운용 시 wss:// 사용 권장 |
| 인증 | 접속 시 auth.token 헤더 |
현재 미구현 (개발 단계) |
| 데이터 포맷 | JSON | UTF-8, 압축 미적용 |
| 최대 메시지 크기 | 64 KB | 이미지 데이터는 별도 HTTP 스트림 |
| ping interval | 10 s | timeout 20 s |
| UUV/MCM 전용 | 광섬유 테더 → TCP/IP 브리지 | RF 수중 불가 — 테더 필수 |
Python · Edge 클라이언트 예시
# Edge 디바이스에서 서버로 데이터 push import socketio sio = socketio.Client() sio.connect('http://SERVER_IP:8010') # 플랫폼별 채널에 emit sio.emit('edge_drone_state', payload_dict) # DRONE sio.emit('edge_ugv_state', payload_dict) # UGV sio.emit('edge_usv_state', payload_dict) # USV sio.emit('edge_uuv_state', payload_dict) # UUV sio.emit('edge_mcm_state', payload_dict) # MCM
SECTION 03
공통 메시지 구조
모든 플랫폼 메시지에 반드시 포함되어야 하는 공통 필드입니다.
JSON Schema · 공통 헤더
{
"platform": "DRONE", // REQUIRED — DRONE | UGV | USV | UUV | MCM
"unit_id": "UGV-01", // REQUIRED — 유닛 식별자
"timestamp": 1712900000.123, // REQUIRED — Unix epoch (초, 소수점 ms)
"tick": 1042, // REQUIRED — 단조 증가 프레임 카운터
"fw_version": "1.0.0", // OPTIONAL — Edge 펌웨어 버전
"health": { // OPTIONAL — Edge 자기진단
"cpu_pct": 42.5,
"ram_pct": 61.0,
"temp_c": 58.2,
"uptime_s": 3600
},
// ... 플랫폼별 페이로드 (아래 각 섹션 참조)
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | REQUIRED | 플랫폼 식별자 (대문자 고정값) |
| unit_id | string | REQUIRED | 유닛 고유 ID (예: UGV-01, MCM-03) |
| timestamp | float | REQUIRED | Unix epoch 초 (소수점 이하 ms) |
| tick | int | REQUIRED | 단조 증가 프레임 번호 (패킷 손실 감지용) |
| fw_version | string | optional | Edge 소프트웨어 버전 (SemVer) |
| health | object | optional | Edge 디바이스 자기진단 데이터 |
SECTION 04
🚁 DRONE — UAV FPV
Socket.IO 채널:
Edge: Jetson Orin Nano · 통신: 5.8GHz RF / LTE · 주기: 10 Hz
edge_drone_state → 서버가 telemetry 로 브로드캐스트Edge: Jetson Orin Nano · 통신: 5.8GHz RF / LTE · 주기: 10 Hz
JSON Payload · DRONE
{
/* ── 공통 헤더 ── */
"platform": "DRONE",
"unit_id": "UAV-01",
"timestamp": 1712900000.0,
"tick": 1042,
/* ── 비행 상태 ── */
"lat": 37.123456, // 위도 (°)
"lon": 127.123456, // 경도 (°)
"alt": 85.3, // 고도 MSL (m)
"alt_rel": 82.1, // 지면 기준 상대 고도 (m)
"heading": 275.4, // 기수 방위 (°, 0~360)
"speed": 12.5, // 지면 속도 (m/s)
"vspeed": -0.3, // 수직 속도 (m/s, 하강 음수)
"pitch": -2.1, // 피치 (°)
"roll": 5.8, // 롤 (°)
"flight_mode": "GUIDED", // 비행 모드
"armed": true, // 시동 여부
/* ── 배터리 ── */
"battery_pct": 78.5, // 배터리 잔량 (%)
"voltage_v": 22.1, // 셀 전압 (V)
/* ── AI 탐지 결과 (YOLO 온디바이스) ── */
"detections": [
{
"id": "TGT-001",
"class": "vehicle", // 탐지 클래스
"confidence": 0.92,
"bbox": [120, 80, 200, 160], // [x1,y1,x2,y2] px
"distance_m": 340.0, // 추정 거리 (m)
"bearing": 280.5 // 방위각 (°)
}
],
/* ── FPV 영상 ── */
"video_url": "rtsp://192.168.1.10:8554/fpv" // RTSP 스트림 URL
}
| 필드 | 타입 | 단위 | 필수 | 설명 |
|---|---|---|---|---|
| lat / lon | float | ° | REQUIRED | WGS84 좌표 |
| alt | float | m | REQUIRED | 해발 고도 (MSL) |
| heading | float | ° | REQUIRED | 0~360, 북=0 |
| speed | float | m/s | REQUIRED | 지면 속도 |
| battery_pct | float | % | REQUIRED | 0.0 ~ 100.0 |
| flight_mode | string | — | REQUIRED | MAVLink 비행 모드 문자열 |
| detections | array | — | optional | YOLO 탐지 결과 배열 |
| video_url | string | — | optional | RTSP / HLS 스트림 주소 |
SECTION 05
🤖 UGV — 지상 무인 차량
Socket.IO 채널:
Edge: Jetson AGX Orin · 통신: WiFi 6 / LTE / RF 메시 · 주기: 5 Hz
edge_ugv_state → 서버가 ics2_state 로 브로드캐스트Edge: Jetson AGX Orin · 통신: WiFi 6 / LTE / RF 메시 · 주기: 5 Hz
JSON Payload · UGV
{
"platform": "UGV",
"unit_id": "UGV-01",
"timestamp": 1712900000.0,
"tick": 512,
/* ── 위치·이동 ── */
"lat": 37.123456,
"lon": 127.123456,
"heading": 90.0, // 진행 방위 (°)
"speed_ms": 3.2, // 이동 속도 (m/s)
"mode": "PATROL", // PATROL | INVESTIGATE | EVADE | STANDBY
/* ── 센서 융합 ── */
"sensors": {
"eoir": { "active": true, "confidence": 0.88 }, // EO/IR 카메라
"lidar": { "active": true, "confidence": 0.92 }, // LiDAR
"audio": { "active": false, "confidence": 0.10 }, // 음향 탐지
"rf": { "active": false, "confidence": 0.05 } // RF 신호 탐지
},
"fused_confidence": 0.84, // 가중 융합 신뢰도
"threat_class": "Personnel", // 위협 분류
"threat_level": "HIGH", // NONE|LOW|MEDIUM|HIGH|CRITICAL
"threat_distance_m":45.0,
"threat_bearing": 120.0,
/* ── 시스템 ── */
"battery_pct": 68.0,
"motor_temp_c": 52.3,
"lidar_range_m":0.5 // LiDAR 최근접 장애물 거리
}
| 필드 | 타입 | 단위 | 필수 | 설명 |
|---|---|---|---|---|
| sensors.* | object | — | REQUIRED | EO/IR, LiDAR, Audio, RF 각 센서 상태 |
| fused_confidence | float | 0~1 | REQUIRED | 온디바이스 센서 융합 결과 |
| threat_level | string | — | REQUIRED | NONE / LOW / MEDIUM / HIGH / CRITICAL |
| threat_distance_m | float | m | optional | 탐지 위협까지의 거리 |
| lidar_range_m | float | m | optional | LiDAR 최근접 반환 거리 (충돌 방지) |
SECTION 06
⚓ USV — 무인 수상함
Socket.IO 채널:
Edge: Jetson Xavier NX · 통신: LTE / 위성 / RF · 주기: 2 Hz
edge_usv_state → 서버가 usv_state 로 브로드캐스트Edge: Jetson Xavier NX · 통신: LTE / 위성 / RF · 주기: 2 Hz
JSON Payload · USV
{
"platform": "USV",
"unit_id": "USV-01",
"timestamp": 1712900000.0,
"tick": 210,
/* ── 항법 ── */
"lat": 36.5000,
"lon": 126.5000,
"heading": 045.0,
"speed_kts": 8.5, // 노트
"depth_m": 0.0, // 수상 = 0
"mode": "PATROL",
/* ── 해상 센서 ── */
"sensors": {
"radar": { "active": true, "confidence": 0.90, "range_m": 5000 },
"ais": { "active": true, "contacts": 3 },
"eoir": { "active": true, "confidence": 0.75 },
"sonar": { "active": false, "confidence": 0.0 } // 수상에서는 미사용
},
"fused_confidence": 0.80,
"threat_class": "Surface_Vessel",
"threat_level": "MEDIUM",
"threat_distance_m":1200.0,
"threat_bearing": 280.0,
/* ── 환경 ── */
"wave_height_m": 0.8,
"wind_speed_ms": 5.2,
"sea_state": 2, // Beaufort 해상 상태 (0~12)
"battery_pct": 85.0
}
SECTION 07
🤿 UUV — 수중 드론
Socket.IO 채널:
Edge: 내압 하우징 Jetson TX2 · 통신: 광섬유 테더 전용 (RF 수중 불가) · 주기: 1 Hz
edge_uuv_state → 서버가 uuv_state 로 브로드캐스트Edge: 내압 하우징 Jetson TX2 · 통신: 광섬유 테더 전용 (RF 수중 불가) · 주기: 1 Hz
🚫 수중 무선통신 불가
RF / WiFi / 5.8GHz FPV / 위성 — 전파는 수 cm 이내에서 해수에 완전 흡수됩니다.
UUV는 광섬유 테더 케이블을 통해 TCP/IP로 서버와 연결합니다.
음향통신(USBL)은 수백 bps로 JSON 스트리밍에 부적합합니다.
JSON Payload · UUV
{
"platform": "UUV",
"unit_id": "UUV-01",
"timestamp": 1712900000.0,
"tick": 88,
/* ── 항법 (GPS 없음 → INS+DVL) ── */
"depth_m": 55.0, // 수압계 측정 수심
"heading": 045.0,
"speed_kts": 4.0,
"pitch_deg": -1.5,
"roll_deg": 2.3,
"wp_idx": 3, // 현재 웨이포인트 인덱스
/* ── 수중 센서 4종 ── */
"sensors": {
"sonar": { "active": true, "confidence": 0.84 }, // 음파
"hydro": { "active": true, "confidence": 0.78 }, // 음파 (수동청음)
"dvl": { "active": true, "confidence": 0.95 }, // 음파 (속도계)
"optical": { "active": false, "confidence": 0.10 } // 레이저 광학
},
"fused_confidence": 0.72,
"threat_class": "Enemy_Sub",
"threat_level": "HIGH",
"threat_distance_m":2400.0,
"threat_bearing": 280.0,
"threat_elev_m": -120.0, // 위협 고도 (수심, 음수=수중)
/* ── 환경 (CTD) ── */
"water_temp_c": 12.5,
"salinity_ppt": 34.5, // 염도 → 음속 보정
"battery_pct": 87.0,
/* ── 광섬유 테더 ── */
"tether": {
"connected": true,
"length_m": 68.75, // 전개 길이 (depth × 1.25)
"tension_n": 42.0, // 케이블 장력 (N)
"data_gbps": 1.0,
"latency_ms": 4.8,
"winch": "HOLDING" // STANDBY|DEPLOYING|HOLDING|REELING
}
}
| 필드 | 타입 | 단위 | 필수 | 설명 |
|---|---|---|---|---|
| depth_m | float | m | REQUIRED | 수압계 측정값 (GPS 없음) |
| sensors.sonar | object | — | REQUIRED | 주 탐지 센서 — 음파 |
| salinity_ppt | float | ppt | REQUIRED | CTD 염도 (소나 음속 보정) |
| tether.connected | bool | — | REQUIRED | 광섬유 테더 연결 상태 |
| tether.length_m | float | m | REQUIRED | 전개된 케이블 길이 |
| tether.tension_n | float | N | optional | 케이블 장력 (단선 예방 모니터링) |
SECTION 08
💣 MCM — 기뢰 탐지 전용
Socket.IO 채널:
Edge: 내압 하우징 Jetson TX2 · 통신: 광섬유 테더 전용 · 주기: 1 Hz
edge_mcm_state → 서버가 mcm_state 로 브로드캐스트Edge: 내압 하우징 Jetson TX2 · 통신: 광섬유 테더 전용 · 주기: 1 Hz
JSON Payload · MCM
{
"platform": "MCM",
"unit_id": "MCM-01",
"timestamp": 1712900000.0,
"tick": 44,
/* ── MCM 항법 ── */
"depth_m": 25.0,
"heading": 090.0,
"speed_kts": 2.0, // MCM은 저속 탐색 (1~3 kts)
"mode": "Search", // Search|Classify|Investigate|Neutralize|Mark
"scan_coverage_pct": 34.5, // 누적 탐색 커버리지
/* ── MCM 4종 센서 ── */
"sensors": {
"sss": { "active": true, "confidence": 0.88, "range_m": 200 }, // 음파
"fls": { "active": true, "confidence": 0.82, "range_m": 80 }, // 음파
"optical": { "active": false, "confidence": 0.10 }, // 레이저 광학
"mag": { "active": false, "confidence": 0.05 } // 자기장
},
"fused_confidence": 0.0, // 탐지 없음
"mine_type": "None", // None|Moored|Bottom|Limpet|Influence|Drift
"threat_level": "NONE",
/* ── 탐지된 기뢰 목록 ── */
"mines": [
{
"mine_id": "MINE-001",
"mine_type": "Moored",
"status": "CONFIRMED", // POSSIBLE|PROBABLE|CONFIRMED|NEUTRALIZED
"confidence": 0.94,
"distance_m": 140.0,
"bearing": 45.0,
"depth_m": 18.0,
"neutralize_method": "와이어 절단기"
}
],
"mines_detected": 1,
"mines_confirmed": 1,
"mines_neutralized": 0,
/* ── 지휘관 승인 루프 ── */
"need_commander": false,
"action_text": "저속 래스터 탐색 중 (SSS 전개)",
/* ── 광섬유 테더 ── */
"tether": {
"connected": true,
"length_m": 31.25,
"tension_n": 18.0,
"data_gbps": 1.0,
"latency_ms": 4.1,
"winch": "DEPLOYING"
},
/* ── 환경 ── */
"water_temp_c": 14.2,
"salinity_ppt": 34.5,
"battery_pct": 94.0
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| mine_type | string | REQUIRED | None / Moored / Bottom / Limpet / Influence / Drift |
| mines[] | array | optional | 탐지된 기뢰 목록 (최대 20개) |
| mines[].status | string | REQUIRED | POSSIBLE / PROBABLE / CONFIRMED / NEUTRALIZED |
| need_commander | bool | REQUIRED | 지휘관 승인 요청 여부 (고위협 기뢰 무력화 시) |
| scan_coverage_pct | float | optional | 누적 탐색 커버리지 0~100% |
SECTION 09
서버 → Edge 명령
HUD 운용자가 내리는 명령을 서버가 Edge로 전달하는 채널입니다. Edge는
cmd 이벤트를 구독합니다.
JSON · 명령 구조
{
"target": "UGV-01", // 대상 유닛 ID
"cmd": "SET_MODE", // 명령 종류
"params": {
"mode": "PATROL"
},
"issued_by": "OPERATOR-1",
"timestamp": 1712900000.0
}
| cmd | 플랫폼 | params | 설명 |
|---|---|---|---|
| SET_MODE | 전체 | mode: string | 운용 모드 전환 |
| WAYPOINT | 전체 | lat, lon, alt/depth | 웨이포인트 지정 |
| RTB | 전체 | — | 귀환 명령 (Return To Base) |
| WINCH_REEL | UUV/MCM | action: DEPLOY/REEL/HOLD | 광섬유 윈치 제어 |
| NEUTRALIZE | MCM | mine_id: string | 기뢰 무력화 실행 (지휘관 승인 후) |
| SURFACE | UUV/MCM | — | 수면 부상 명령 |
| EMERGENCY_STOP | 전체 | — | 즉시 정지 (최우선 처리) |
SECTION 10
시나리오 주입 API
실제 Edge 없이 특정 시나리오를 강제 주입하여 HUD·파이프라인을 테스트하는 REST API입니다.
| Method | Path | Body | 설명 |
|---|---|---|---|
| POST | /api/ics/inject | {"scenario":"suicide_drone"} | 드론 위협 시나리오 |
| POST | /api/usv/inject | {"scenario":"enemy_sub"} | USV 위협 주입 |
| POST | /api/uuv/inject | {"scenario":"torpedo"} | UUV 위협 주입 |
| POST | /api/mcm/inject | {"scenario":"moored_mine"} | 기뢰 탐지 시나리오 |
| GET | /api/mcm/state | — | MCM 현재 상태 폴링 |
| GET | /api/uuv/state | — | UUV 현재 상태 폴링 |
| GET | /api/usv/state | — | USV 현재 상태 폴링 |
cURL 예시
# 계류기뢰 탐지 시나리오 주입 curl -X POST https://fpv.exko.kr/api/mcm/inject \ -H "Content-Type: application/json" \ -d '{"scenario":"moored_mine"}' # 현재 MCM 상태 조회 curl https://fpv.exko.kr/api/mcm/state | python3 -m json.tool
SECTION 11
Edge 디바이스 하드웨어
플랫폼별 권장 탑재 컴퓨터와 핵심 사양입니다.
| 플랫폼 | 디바이스 | AI 성능 | 전력 | 특이사항 |
|---|---|---|---|---|
| 🚁 DRONE | NVIDIA Jetson Orin Nano 8GB | 40 TOPS | 7~15 W | 경량, YOLO v8 실시간 30fps+ |
| 🤖 UGV | NVIDIA Jetson AGX Orin 64GB | 275 TOPS | 15~60 W | 고성능, LiDAR 포인트클라우드 처리 |
| ⚓ USV | NVIDIA Jetson Xavier NX 16GB | 21 TOPS | 10~20 W | 방수 인클로저, AIS 수신기 연동 |
| 🤿 UUV | NVIDIA Jetson TX2 4GB | 1.33 TFLOPS | 7.5 W | 내압 하우징 필수 (수심 200m 이상) |
| 💣 MCM | NVIDIA Jetson TX2 4GB | 1.33 TFLOPS | 7.5 W | 내압 하우징, SSS/FLS 인터페이스 보드 |
✅ 대안 — Raspberry Pi 5 (저비용 프로토타이핑)
AI 추론 없이 센서 데이터 수집·포맷·전송만 담당할 경우 RPi 5 (4~8GB)로 충분합니다.
AI 추론은 서버 사이드로 오프로드합니다. UGV/USV 프로토타입에 적합합니다.
SECTION 12
🔌 광섬유 테더 규격
UUV/MCM의 유일한 현실적 통신 수단입니다. RF는 수중에서 물리적으로 작동하지 않습니다.
📡 수중 물리적 한계 — RF 통신 불가 이유
전자기파(RF)는 전도성 해수(염분)에 의해 수 cm 이내에서 지수적으로 감쇠됩니다.주파수가 높을수록 감쇠 더 심각: 2.4GHz WiFi ≈ 수cm, 5.8GHz FPV ≈ 수mm 투과
위성 통신(GPS/Iridium)은 수면 부상 시에만 가능. 음향통신(USBL)은 수백 bps 한계.
| 항목 | 규격값 | 비고 |
|---|---|---|
| 케이블 유형 | 중립부력 광섬유 복합 케이블 | 내압 + 인장 보강재 포함 |
| 광섬유 코어 | 단일모드 (SMF-28) | 저손실, 장거리 적합 |
| 데이터율 | 1 Gbps (양방향) | FPV 영상 + 텔레메트리 동시 |
| 지연 (전기적) | < 5 ms | 빛의 유리 내 전파속도 기준 |
| 최대 길이 | 500 m (시스템 기준) | 운용 수심 × 1.25 이상 확보 |
| 최대 운용 수심 | 400 m | 내압 커넥터 한계 |
| 인장 강도 | 200 kg 이상 | 조류·드래그 대응 |
| 전력 공급 | DC 48~300 V (POF) | 모함 → UUV 전력 공급 (선택) |
| 윈치 | 자동 장력 제어 윈치 | STANDBY / DEPLOYING / HOLDING / REELING |
| 인터페이스 | TCP/IP over Ethernet (RJ45 → 광 변환) | Edge에서 일반 이더넷 포트 사용 |
광섬유 테더 → Edge 연결 구성
모함 (서버) │ │ 광섬유 케이블 (≤500m, 1Gbps) │ + 전력선 (DC 48V, 선택) │ 윈치 / 슬립링 │ 내압 관통 커넥터 │ 광전 변환기 (Media Converter) SFP → RJ45 Ethernet │ Edge 디바이스 (Jetson TX2) eth0: 1 Gbps │ 소나 인터페이스 보드 카메라 / MAG 센서
SECTION 13
Quick Start — Edge 연동 3단계
실제 Edge 디바이스를 FPV ICS 서버에 연결하는 최소 절차입니다.
Step 1 · Edge에 클라이언트 설치
# Jetson / RPi Edge 디바이스에서
pip install python-socketio[client] requests
Step 2 · Edge 에이전트 최소 구현
""" fpv_edge_agent.py — 최소 Edge 에이전트 플랫폼에 맞는 채널명과 페이로드로 수정하여 사용 """ import socketio, time, json SERVER = "http://192.168.1.100:8010" # 서버 IP 수정 UNIT = "MCM-01" CHAN = "edge_mcm_state" # 플랫폼별 채널 sio = socketio.Client() @sio.event def connect(): print("✅ 서버 연결됨") @sio.on("cmd") # 서버 → Edge 명령 수신 def on_cmd(data): print(f"CMD: {data}") # 명령 처리 로직 구현 sio.connect(SERVER) tick = 0 while True: payload = { "platform": "MCM", "unit_id": UNIT, "timestamp": time.time(), "tick": tick, # ─── 실제 센서 데이터로 교체 ─── "depth_m": 25.0, "heading": 90.0, "speed_kts": 2.0, "tether": { "connected": True, "length_m": 31.2 } } sio.emit(CHAN, payload) tick += 1 time.sleep(1.0) # 1 Hz
Step 3 · 서버에서 Edge 채널 수신 등록 (main.py)
# backend/main.py에 추가 @sio.on("edge_mcm_state") async def edge_mcm(sid, data): """Edge → 서버 수신 후 HUD로 브로드캐스트""" await sio.emit("mcm_state", data) # HUD 채널로 전달 # 선택: mcm_pipeline.apply_edge_data(data) 시뮬 엔진 교체
✅ 완료
Edge가 edge_mcm_state로 push → 서버가 mcm_state로 브로드캐스트 →
fpv.exko.kr/mcm HUD 자동 업데이트.
HUD 코드 수정 불필요.