Skip to content

Repository files navigation

V2X Safety Agent

TCP/IP 기반 차량용 지능형 V2X 안전 분석 시스템

V2X Safety Agent는 차량-사물 통신(V2X) 환경에서 실시간 위험을 분석하고, AI 기반 운전자 브리핑을 제공하는 end-to-end 지능형 안전 서비스입니다. React Cockpit UI, FastAPI HTTP-to-TCP Bridge, Python TCP Client/Server, Agent Controller, MCP Tool 체인, Gemini AI 대화 엔진을 결합하여 실제 실행 가능한 시스템으로 구성되어 있습니다.

GitHub: https://github.com/deephoon/V2X_Agent.git


목차

  1. 프로젝트 개요
  2. 핵심 기능
  3. 기술 스택
  4. 시스템 아키텍처
  5. TCP/IP 통신 프로토콜
  6. 디렉터리 구조
  7. 모듈 상세 설명
  8. MCP Tool 체인
  9. 위험도 분석 알고리즘
  10. Gemini AI 대화 엔진
  11. Fallback 전략
  12. 시나리오 데이터
  13. 실행 방법
  14. 테스트
  15. 시연 시나리오: S002
  16. 알려진 한계

1. 프로젝트 개요

V2X Safety Agent의 목적은 V2X 인프라 센서가 감지한 사각지대 보행자, 교차 교통 차량, 통신 품질 저하 등의 위험 상황을 실시간으로 분석하고, 그 결과를 운전자에게 설명 가능한 AI(XAI) 브리핑으로 전달하는 것입니다.

시스템의 모든 분석 요청은 Python TCP Socket 통신을 경유합니다. React UI가 직접 MCP Tool이나 Gemini를 호출하지 않으며, FastAPI는 HTTP 요청을 TCP 요청으로 변환하는 브릿지 역할만 수행합니다. 실제 AI Agent 로직과 MCP Tool 호출은 TCP Server 내부에서 실행됩니다.

주요 흐름

사용자가 시나리오 선택 → React UI → FastAPI Bridge → TCP Client → TCP Server
→ Agent Controller → MCP Tool 체인 → Gemini Briefing → TCP Response → React UI 렌더링

2. 핵심 기능

기능 설명
다중 MCP Tool 체인 차량 정보, 날씨, 교통, 위험도, 네트워크 QoS, EV 충전소 등 7개 Tool을 순차적으로 호출하여 종합 분석
다단계 위험도 분석 TTC, 거리, 객체 유형, 통신 상태 기반 base score 산출 후 차량·날씨·교통 보정 계수를 곱한 adjusted score로 최종 판정
Gemini AI XAI 브리핑 분석 결과를 종합하여 운전자에게 즉각 조치, 판단 근거, 음성 브리핑, 능동적 제안을 한국어로 생성
운전자-AI 실시간 대화 분석 이후 운전자가 AI에게 추가 질문·응답할 수 있는 TCP 경유 채팅 기능
TTS 음성 출력 Web Speech API로 AI 브리핑을 한국어 음성으로 자동 읽어줌
차량 레이더 뷰 자차와 감지 객체의 상대 위치를 실시간 시각화
TCP 통신 안정성 <END> marker 기반 message boundary 처리로 partial recv 문제 해결
전 계층 Fallback 외부 API 실패, Gemini 호출 실패, TCP 오류 시에도 시스템이 안정적으로 동작
국내 공개 API 확장 구조 기상청, 한국도로공사, 에어코리아 등 API Key만 설정하면 실제 데이터로 전환 가능

3. 기술 스택

Backend (Python)

구성 요소 기술
TCP Server Python socket (순수 TCP/IP)
HTTP Bridge FastAPI + Uvicorn
AI Agent Google Gemini API (google-genai)
외부 API 호출 requests
데이터 처리 pandas
환경변수 관리 python-dotenv
스키마 검증 pydantic
테스트 pytest

Frontend (TypeScript)

구성 요소 기술
Framework React 19
Build Tool Vite 8
언어 TypeScript 6
아이콘 Lucide React
TTS Web Speech API
스타일링 Vanilla CSS (커스텀 디자인 시스템)

4. 시스템 아키텍처

┌─────────────────────────────────────────────────────────────────────┐
│                         React Cockpit UI                            │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│  │ Scenario │ │ XAI HUD  │ │ Evidence │ │ MCP      │ │ TCP Flow │  │
│  │ Panel    │ │ Panel    │ │ Grid     │ │ Timeline │ │ Panel    │  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘  │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│  │ Weather  │ │ Traffic  │ │ EV       │ │ Vehicle  │ │ Radar    │  │
│  │ Card     │ │ Card     │ │ Charging │ │ Info     │ │ View     │  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘  │
└────────────────────────────┬────────────────────────────────────────┘
                             │ HTTP (fetch)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    FastAPI HTTP-to-TCP Bridge                        │
│  GET /api/health  │  GET /api/scenarios  │  POST /api/analyze       │
│                   │                      │  POST /api/chat          │
└────────────────────────────┬────────────────────────────────────────┘
                             │ TCP Socket (JSON + <END> marker)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      Python TCP Server (9000)                       │
│                              │                                      │
│                     Agent Controller                                │
│                              │                                      │
│  ┌───────────────────────────┼───────────────────────────────┐      │
│  │                     MCP Tool Chain                        │      │
│  │                                                           │      │
│  │  1. VehicleInfoTool ──→ NHTSA vPIC API                    │      │
│  │  2. WeatherContextTool ──→ KMA / Open-Meteo API           │      │
│  │  3. RoadTrafficContextTool ──→ 한국도로공사 / fallback     │      │
│  │  4. RiskAnalysisTool ──→ 위험도 계산 (TTC, 거리, 보정)    │      │
│  │  5. NetworkQoSTool ──→ V2X QoS 평가                       │      │
│  │  6. EVChargingStationTool ──→ HIGH일 때만 호출             │      │
│  └───────────────────────────┼───────────────────────────────┘      │
│                              │                                      │
│                 Gemini Briefing Agent                                │
│                 (XAI 운전자 브리핑 생성)                              │
└─────────────────────────────────────────────────────────────────────┘

역할 분리 원칙

  • React UI — 순수 프레젠테이션 레이어. TCP/MCP/Gemini를 직접 호출하지 않음
  • FastAPI Bridge — HTTP ↔ TCP 프로토콜 변환만 수행
  • TCP Clientsocket.connect()sendall(JSON + <END>)recv 루프
  • TCP Server — TCP 요청 수신 → Agent Controller 실행 → TCP 응답 전송
  • Agent Controller — MCP Tool 호출 순서 오케스트레이션
  • MCP Tools — 각각 독립된 Python 모듈. 외부 API 호출 또는 내부 계산 수행
  • Gemini Agent — MCP Tool 결과를 종합하여 AI 브리핑 생성

5. TCP/IP 통신 프로토콜

Message Boundary 처리

TCP는 stream protocol이므로 단일 recv() 호출로 전체 메시지를 수신할 수 없습니다. 이 문제를 해결하기 위해 공통 프로토콜 모듈 tcp_protocol.py를 도입했습니다.

프로토콜 규격:

[JSON payload bytes][<END>]
  • 모든 요청과 응답은 JSON + <END> marker로 구분됩니다
  • ensure_ascii=False로 직렬화하여 한글이 포함된 JSON도 가독성 있게 전송합니다
  • socket.sendall()로 전체 buffer를 한번에 전송합니다

핵심 함수 3개:

함수 역할
recv_until_marker() bytes 기준으로 <END> marker가 올 때까지 chunk를 누적 수신. UTF-8 문자가 chunk 경계에서 잘리는 문제 방지
send_json_with_marker() dict → JSON 직렬화 → <END> 부착 → sendall()
recv_json_with_marker() marker까지 수신 후 json.loads() 파싱. 실패 시 raw 500자를 로그에 기록

통신 흐름 상세

React UI
  → POST /api/analyze { scenario_id: "S002" }
FastAPI Bridge
  → TCP Client: socket.connect(127.0.0.1:9000)
  → sendall(JSON_REQUEST + "<END>")
TCP Server
  → recv loop until "<END>"
  → json.loads() → Agent Controller 실행
  → sendall(JSON_RESPONSE + "<END>")
TCP Client
  → recv loop until "<END>"
  → json.loads()
FastAPI Bridge
  → HTTP JSON Response (+ tcp_roundtrip_ms 측정값 포함)
React UI
  → Cockpit 렌더링

요청/응답 메시지 구조

분석 요청 (V2X_SAFETY_REQUEST):

{
  "type": "V2X_SAFETY_REQUEST",
  "request_id": "REQ-S002",
  "timestamp": "2026-05-30T14:00:00Z",
  "vehicle_id": "EGO-001",
  "payload": {
    "scenario_id": "S002",
    "scenario_name": "blind_spot_pedestrian",
    "ego": { "speed_mps": 12.5, "accel_mps2": -1.2, "heading_deg": 0 },
    "object": { "object_id": "PED-001", "object_type": "pedestrian", "x": 18, "y": 3, ... },
    "network": { "latency_ms": 120, "packet_loss": 0.048, ... },
    "environment": { "road_friction": 0.3, "visibility_m": 50 },
    "vehicle": { "vin": "1HGCM82633A004352" },
    "location": { "lat": 37.4963, "lon": 126.9572, "name": "Soongsil University" }
  }
}

채팅 요청 (V2X_CHAT_REQUEST):

{
  "type": "V2X_CHAT_REQUEST",
  "request_id": "chat_1717059600000",
  "payload": {
    "message": "네, 감속해 주세요",
    "current_gemini": { "driver_briefing": "...", "proactive_suggestion": "..." },
    "context": { ... }
  }
}

6. 디렉터리 구조

v2x-safety-agent/
├── backend/                          # FastAPI HTTP-to-TCP Bridge
│   ├── api_bridge.py                 #   /api/health, /api/scenarios, /api/analyze, /api/chat
│   └── schemas.py                    #   Pydantic 요청 스키마 (AnalyzeRequest, ChatRequest)
│
├── client/                           # Python TCP Client
│   ├── scenario_loader.py            #   CSV → dict payload 변환
│   └── tcp_client.py                 #   send_v2x_request(), send_chat_request()
│
├── data/
│   └── v2x_scenarios.csv             # 시나리오 데이터 (5개 시나리오)
│
├── frontend/                         # React Vite TypeScript 앱
│   └── src/
│       ├── api/v2xApi.ts             #   FastAPI Bridge HTTP 클라이언트
│       ├── components/               #   13개 UI 컴포넌트
│       │   ├── CockpitHeader.tsx      #     상단 헤더 (Bridge 연결 상태)
│       │   ├── ScenarioPanel.tsx       #     시나리오 선택 + TCP 설정 + Analyze 버튼
│       │   ├── XaiHudPanel.tsx         #     XAI HUD (위험도, AI 브리핑, 채팅, TTS)
│       │   ├── VehicleRadarView.tsx    #     자차-객체 상대 위치 레이더 뷰
│       │   ├── EvidenceGrid.tsx        #     증거 지표 그리드 (TTC, 거리, 통신 등)
│       │   ├── GeminiBriefingCard.tsx   #     Gemini 브리핑 카드
│       │   ├── WeatherCard.tsx         #     날씨 컨텍스트 카드
│       │   ├── TrafficContextCard.tsx   #     교통 컨텍스트 카드
│       │   ├── EVChargingStationCard.tsx #    EV 충전소/안전 정차 카드
│       │   ├── VehicleInfoCard.tsx      #     차량 정보 + 제동 프로필 카드
│       │   ├── RecommendedActions.tsx   #     권장 조치 목록
│       │   ├── McpTimeline.tsx         #     MCP Tool 호출 순서 타임라인
│       │   └── TcpFlowPanel.tsx        #     TCP 통신 흐름 시각화
│       ├── styles/globals.css         #   전체 CSS 디자인 시스템
│       └── types/v2x.ts              #   TypeScript 타입 정의 (225줄)
│
├── mcp_tools/                        # MCP Tool 모듈
│   ├── vehicle_info_tool.py          #   NHTSA vPIC VIN 디코딩 + 제동 프로필 추정
│   ├── weather_context_tool.py       #   KMA → Open-Meteo → fallback 날씨 조회
│   ├── road_traffic_context_tool.py  #   한국도로공사/MOLIT/TOPIS → fallback 교통 조회
│   ├── risk_analysis_tool.py         #   다단계 위험도 계산 (base + adjusted)
│   ├── network_qos_tool.py           #   V2X 통신 품질 평가
│   ├── ev_charging_station_tool.py   #   전기차 충전소/안전 정차 지점 조회
│   └── air_quality_context_tool.py   #   대기질 조회 (확장 후보)
│
├── server/                           # TCP Server + Agent
│   ├── tcp_server.py                 #   TCP 소켓 서버 (127.0.0.1:9000)
│   ├── agent_controller.py           #   MCP Tool 오케스트레이션 + 응답 구성
│   └── gemini_briefing_agent.py      #   Gemini API 호출 + XAI 브리핑 생성 + 채팅
│
├── tests/                            # pytest 테스트
│   ├── test_risk_analysis.py         #   위험도 계산 검증
│   ├── test_vehicle_info_tool.py     #   VIN 디코딩 fallback 검증
│   ├── test_tcp_protocol.py          #   TCP marker 프로토콜 검증
│   └── test_public_api_tools.py      #   날씨/교통/EV/대기질 fallback 검증
│
├── tcp_protocol.py                   # 공통 TCP 프로토콜 (JSON + <END> marker)
├── requirements.txt                  # Python 의존성
├── .env.example                      # 환경변수 템플릿
└── .gitignore

7. 모듈 상세 설명

7.1 TCP Server (server/tcp_server.py)

  • 127.0.0.1:9000에서 TCP 연결을 대기합니다
  • 연결마다 30초 socket timeout을 설정합니다
  • 요청 type에 따라 V2X_SAFETY_REQUESTrun_agent(), V2X_CHAT_REQUESTrun_agent_chat()을 호출합니다
  • 예외 발생 시에도 서버 프로세스가 종료되지 않고 JSON error response를 반환합니다
  • SO_REUSEADDR 옵션으로 포트 재사용을 허용합니다
  • TCP_SERVER_HOST, TCP_SERVER_PORT 환경변수로 바인딩 주소를 변경할 수 있습니다

7.2 FastAPI Bridge (backend/api_bridge.py)

HTTP-to-TCP 프로토콜 변환 역할만 수행합니다. Bridge가 MCP Tool이나 Gemini를 직접 호출하지 않습니다.

Endpoint 메서드 역할
/api/health GET Bridge 상태 확인
/api/scenarios GET CSV 기반 시나리오 목록 조회
/api/analyze POST TCP Client를 통해 분석 요청 전송 + 응답 반환
/api/chat POST TCP Client를 통해 채팅 요청 전송 + 응답 반환
  • TCP round trip 시간을 tcp_roundtrip_ms로 측정하여 응답에 포함합니다
  • ConnectionRefusedError, socket.timeout, JSONDecodeError 등 예외별로 React가 이해할 수 있는 구조화된 에러 JSON을 반환합니다
  • CORS는 localhost:5173, 127.0.0.1:5173을 허용합니다

7.3 TCP Client (client/tcp_client.py)

  • send_v2x_request(): 시나리오 ID → CSV 로드 → TCP 요청 구성 → socket 연결 → 전송 → 응답 수신
  • send_chat_request(): 채팅 메시지 + 현재 Gemini 상태 + 컨텍스트 → TCP 요청 전송 → 응답 수신
  • build_v2x_request(): CSV 데이터를 표준 TCP 요청 JSON 구조로 변환

7.4 Scenario Loader (client/scenario_loader.py)

data/v2x_scenarios.csv에서 시나리오 데이터를 로드하고, TCP 요청에 필요한 구조화된 dict로 변환합니다.

변환 결과에는 ego (자차 상태), object (감지 객체), network (V2X 통신), environment (도로 환경), vehicle (VIN), location (위치) 정보가 포함됩니다.

7.5 Agent Controller (server/agent_controller.py)

MCP Tool의 호출 순서를 관리하고 최종 TCP 응답 JSON을 구성합니다.

분석 실행 순서 (run_agent):

1. VehicleInfoTool       → 차량 정보 + 제동 프로필
2. WeatherContextTool    → 날씨 + weather_risk_multiplier
3. RoadTrafficContextTool → 교통 + traffic_risk_multiplier
4. RiskAnalysisTool      → 위험도 계산 (위 3개 Tool 결과를 입력으로 받음)
5. NetworkQoSTool        → V2X 통신 품질 평가
6. EVChargingStationTool → risk_level이 HIGH일 때만 호출
7. GeminiBriefingAgent   → XAI 운전자 브리핑 생성
8. Recommendations 생성  → 위험도, QoS, 날씨, 교통 기반 최대 4개

VehicleInfoTool, WeatherContextTool, RoadTrafficContextTool을 RiskAnalysisTool보다 먼저 호출하는 이유: 제동거리 보정 계수, 날씨 위험 보정 계수, 교통 위험 보정 계수를 위험도 계산에 반영해야 하기 때문입니다.

채팅 실행 (run_agent_chat):

운전자 메시지 + 현재 AI 상태 + 센서 컨텍스트를 Gemini에 전달하여 대화 응답을 생성합니다.

서버 로그 출력 예시:

[AGENT] Start V2X Safety Analysis
[MCP] Tool Called: VehicleInfoTool
[MCP] VehicleInfoTool Result: { ... }
[MCP] Tool Called: WeatherContextTool
[MCP] WeatherContextTool Result: { ... }
[MCP] Tool Called: RoadTrafficContextTool
[MCP] RoadTrafficContextTool Result: { ... }
[MCP] Tool Called: RiskAnalysisTool
[MCP] RiskAnalysisTool Result: { ... }
[MCP] Tool Called: NetworkQoSTool
[MCP] NetworkQoSTool Result: { ... }
[MCP] Tool Called: EVChargingStationTool
[MCP] EVChargingStationTool Result: { ... }
[AGENT] Calling Gemini Briefing Agent
[AGENT] Final safety briefing generated

7.6 React Cockpit UI (frontend/)

13개 컴포넌트로 구성된 차량 안전 대시보드입니다. FastAPI Bridge의 /api/analyze/api/chat만 호출합니다.

컴포넌트 역할
CockpitHeader 상단 헤더. FastAPI Bridge 연결 상태 표시
ScenarioPanel 시나리오 목록, TCP 설정(host/port), Analyze 버튼
XaiHudPanel 핵심 HUD. 위험도 레벨/점수, AI 브리핑, 채팅 UI, TTS 토글, 레이더 뷰
VehicleRadarView SVG 기반 자차-객체 상대 위치 시각화 (거리, TTC 표시)
EvidenceGrid 증거 지표 그리드 (TTC, 거리, 가속도, 마찰계수, latency, packet loss 등)
WeatherCard 날씨 컨텍스트 (기온, 강수, 풍속, 위험 보정 계수)
TrafficContextCard 교통 컨텍스트 (도로명, 평균속도, 혼잡도, 위험 보정 계수)
EVChargingStationCard EV 충전소/안전 정차 후보 (HIGH 위험 시에만 표시)
VehicleInfoCard 차량 정보 + 제동 프로필 (category, multiplier, confidence)
GeminiBriefingCard Gemini 브리핑 상세 (source, model, 요약)
RecommendedActions 시스템 권장 조치 목록 (최대 4개)
McpTimeline MCP Tool 호출 순서 타임라인 시각화
TcpFlowPanel TCP 통신 흐름 다이어그램 (host, port, roundtrip, request ID, status)

XAI HUD 기능:

  • 위험 수준별 glowing 애니메이션 (HIGH: 빨강, MEDIUM: 노랑, LOW: 시안)
  • base score / adjusted score / 보정 계수 실시간 표시
  • AI 브리핑 + 채팅 히스토리 (버블 UI)
  • TTS 음성 출력 on/off 토글
  • 운전자 입력 → TCP 경유 → Gemini 응답 → 채팅 히스토리 업데이트

8. MCP Tool 체인

8.1 VehicleInfoTool

파일: mcp_tools/vehicle_info_tool.py
외부 API: NHTSA vPIC API

VIN(Vehicle Identification Number)을 디코딩하여 make, model, model_year, vehicle_type, body_class, fuel_type을 조회합니다. 이 정보를 기반으로 **제동 프로필(braking profile)**을 추정합니다.

제동 프로필 분류 규칙:

vehicle_type / body_class 키워드 category braking_distance_multiplier
TRUCK, SUV, MULTIPURPOSE suv_or_truck 1.15
BUS bus 1.25
MOTORCYCLE motorcycle 0.95
PASSENGER, SEDAN passenger_sedan 1.00
알 수 없음 unknown_vehicle 1.10

참고: NHTSA vPIC는 실제 제동거리나 제동 성능 데이터를 직접 제공하지 않습니다. braking_distance_multiplier는 vehicle type/body class에서 추정한 보수적(conservative) 보정 계수입니다.

API 실패 시 status="fallback"unknown_vehicle 기준 1.1x multiplier를 반환합니다.

8.2 WeatherContextTool

파일: mcp_tools/weather_context_tool.py
외부 API: 기상청(KMA) API → Open-Meteo API → fallback

조회 우선순위:

  1. KMA API (환경변수 KMA_API_KEY, KMA_API_URL 설정 시)
  2. Open-Meteo API (무료, API Key 불필요)
  3. Deterministic fallback

날씨 위험 보정 계수:

조건 weather_status weather_risk_multiplier
강수 > 0 RAIN_RISK 1.12
풍속 ≥ 10 m/s WIND_RISK 1.08
정상 NORMAL 1.00

8.3 RoadTrafficContextTool

파일: mcp_tools/road_traffic_context_tool.py
외부 API: 한국도로공사 / 국토교통부(MOLIT) / 서울 TOPIS → fallback

3개 국내 교통 API 제공자를 순차적으로 시도하며, 모두 실패하거나 API Key가 없으면 시나리오별 fallback을 사용합니다.

교통 위험 보정 계수:

평균 속도 traffic_status traffic_risk_multiplier
< 25 km/h CONGESTED 1.08
< 45 km/h SLOW 1.05
≥ 45 km/h FREE_FLOW 1.00

8.4 RiskAnalysisTool

파일: mcp_tools/risk_analysis_tool.py

위험도 분석의 핵심 모듈입니다. 자세한 알고리즘은 9장을 참고하세요.

8.5 NetworkQoSTool

파일: mcp_tools/network_qos_tool.py

V2X 통신 품질을 평가합니다. 외부 API 호출 없이 시나리오 데이터 기반으로 판정합니다.

WARNING 발생 조건:

지표 임계값 의미
latency_ms > 100ms 메시지 지연
packet_loss > 3% 패킷 손실
message_age_ms > 150ms 메시지 노후

하나라도 초과하면 qos_status = "WARNING", 모두 정상이면 "NORMAL".

8.6 EVChargingStationTool

파일: mcp_tools/ev_charging_station_tool.py
외부 API: 전국전기차충전소표준데이터 / 한국환경공단 API → fallback

risk_levelHIGH일 때만 Agent Controller가 호출합니다. API Key가 없으면 Soongsil Univ EV Safe Stop fallback을 반환합니다.

8.7 AirQualityContextTool (확장 후보)

파일: mcp_tools/air_quality_context_tool.py
외부 API: 에어코리아 실시간 대기오염정보 API → fallback

현재 Agent Controller의 기본 호출 순서에는 포함되어 있지 않습니다. PM10 ≥ 80 또는 PM2.5 ≥ 35일 때 시야 저하 위험(VISIBILITY_RISK)을 반환하는 구조만 갖추고 있습니다.


9. 위험도 분석 알고리즘

9.1 기본 계산

distance = √(object_x² + object_y²)
relative_speed = max(ego_speed - object_speed, 0.1)
TTC (Time-To-Collision) = distance / relative_speed

9.2 Base Risk Score 가산

조건 가산 점수 근거
객체가 보행자 (pedestrian) +0.25 취약 도로 사용자
감지 출처가 인프라 (infrastructure) +0.15 자차 센서 미감지 사각지대 객체
거리 < 20m +0.20 근접 위험
TTC < 3초 +0.25 임박한 충돌 위험
latency > 100ms +0.10 V2X 메시지 지연
packet_loss > 3% +0.10 패킷 손실로 정보 신뢰도 저하
message_age > 150ms +0.10 수신 데이터 노후화

base_risk_score = min(합계, 1.0)

9.3 Adjusted Risk Score

adjusted_risk_score = min(
  base_risk_score × braking_multiplier × weather_risk_multiplier × traffic_risk_multiplier,
  1.0
)

9.4 최종 위험 수준 판정

adjusted_risk_score risk_level
≥ 0.75 HIGH
≥ 0.45 MEDIUM
< 0.45 LOW

9.5 응답 필드

{
  "distance_m": 18.25,
  "ttc_sec": 1.64,
  "base_risk_score": 1.0,
  "adjusted_risk_score": 1.0,
  "braking_multiplier": 1.0,
  "weather_risk_multiplier": 1.0,
  "traffic_risk_multiplier": 1.08,
  "risk_score": 1.0,
  "risk_level": "HIGH",
  "reasons": [
    "보행자 객체가 감지됨",
    "인프라 센서가 감지한 객체",
    "객체와의 거리가 20m 미만 (18.25m)",
    "TTC가 3초 미만 (1.64초)",
    "V2X 메시지 latency가 100ms 초과 (120ms)",
    "packet loss가 3% 초과 (4.8%)",
    "message age가 150ms 초과 (180ms)",
    "교통 흐름 위험 보정 계수 적용 (1.08x)"
  ]
}

10. Gemini AI 대화 엔진

10.1 XAI 브리핑 생성 (generate_gemini_briefing)

MCP Tool 결과 전체를 Gemini에 전달하여 4개 필드를 생성합니다:

필드 설명 예시
Immediate_Action AI가 수행한 즉각 조치 "긴급 제동 (AEB) 개입 및 조향 보조 활성화"
Agent_Reasoning AI 판단 근거 1문장 "V2X 통신 지연으로 로컬 센서 데이터를 우선 적용하여..."
Voice_Briefing 운전자 음성 브리핑 1~2문장 "보행자가 접근 중입니다. 충돌 방지를 위해..."
Proactive_Suggestion 능동적 질문/제안 "관제 센터에 위험 알림을 전송할까요?"

프롬프트 설계 특징:

  • Gemini를 "차량용 초지능형 V2X Safety Agent" 페르소나로 설정
  • 단순 데이터 요약이 아니라 능동적으로 판단하고 보고하는 톤 지시
  • response_mime_type: "application/json" 으로 구조화된 JSON 응답 강제
  • Gemini 2.5 모델 사용 시 thinking_budget=0으로 빠른 응답 확보

10.2 대화 모드 (generate_chat_response)

분석 완료 후 운전자가 AI에게 추가 질문하거나 제안에 응답할 수 있습니다.

운전자: "네, 감속해 주세요"
   ↓ TCP 경유
AI: "네, 알겠습니다. 현재 30km/h로 속도를 낮춰 결빙 구간을 통과하겠습니다."
    + "관제 센터에 위험 알림을 전송할까요?"

이전 AI 브리핑 + 운전자 응답 + 현재 센서 컨텍스트를 종합하여 자연스러운 대화를 이어갑니다.

10.3 에러 분류 및 Fallback

Gemini API 오류는 3가지로 분류하여 각각 다른 fallback 메시지를 제공합니다:

분류 조건 Fallback 메시지
rate_limit HTTP 429, quota 초과 "Gemini API 무료 티어 한도 초과로 AI 통신망 응답이 지연..."
overload HTTP 5xx, 서버 과부하 "Gemini API 서버 과부하로 AI 통신망 응답이 지연..."
unknown 기타 "통신 상태가 불안정하여 자체 로컬 데이터로 상황을 판단..."

overload 에러 시 0.8초 대기 후 1회 재시도합니다.


11. Fallback 전략

시스템은 어떤 외부 의존성이 실패하더라도 안정적으로 동작하도록 설계되었습니다.

실패 지점 Fallback 동작
NHTSA vPIC API 실패 status="fallback", unknown 차량 기준 braking multiplier 1.1x 반환
KMA API 실패 또는 미설정 Open-Meteo API로 자동 전환
Open-Meteo API 실패 status="fallback", 기본 안전 수칙 메시지 반환
국내 교통 API 미설정 시나리오별 deterministic fallback 교통 컨텍스트 반환
EV 충전소 API 미설정 Soongsil Univ EV Safe Stop fallback 반환
Gemini API Key 미설정 Deterministic fallback 브리핑 생성 (위험 수준별 즉각 조치 + 기본 근거)
Gemini API 호출 실패 에러 종류별 fallback 메시지 + 기본 브리핑 구조 반환
TCP Server 요청 처리 예외 서버 프로세스 유지, status="error" JSON 응답 반환
TCP Server 미실행 FastAPI Bridge가 tcp_server_unavailable 에러 JSON 반환
TCP 응답 timeout FastAPI Bridge가 tcp_timeout 에러 JSON 반환
TCP 응답 JSON 파싱 실패 FastAPI Bridge가 tcp_invalid_json 에러 JSON 반환

12. 시나리오 데이터

data/v2x_scenarios.csv에 5개 시나리오가 정의되어 있습니다.

ID 이름 객체 유형 감지 출처 핵심 특징
S001 normal_following vehicle vehicle 정상 차량 추종. 낮은 위험도
S002 blind_spot_pedestrian pedestrian infrastructure 사각지대 보행자. 높은 위험도, 통신 품질 저하
S003 cross_traffic_vehicle vehicle infrastructure 교차 교통 차량. 중간 위험도
S004 stale_v2x_message pedestrian infrastructure 극심한 통신 지연 (230ms, 7.5% loss, 320ms age)
S005 low_confidence_object unknown infrastructure 낮은 감지 신뢰도 (0.52)

13. 실행 방법

13.1 Python 환경 준비

cd v2x-safety-agent
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

13.2 환경변수 설정

cp .env.example .env

최소 설정 (Gemini 브리핑 사용 시):

GEMINI_API_KEY=your_actual_api_key
GEMINI_MODEL=gemini-2.5-flash

국내 공개 API 확장 (선택사항):

KMA_API_KEY=your_kma_key
KMA_API_URL=https://...
KOREA_EXPRESSWAY_API_KEY=your_key
KOREA_EXPRESSWAY_API_URL=https://...
MOLIT_TRAFFIC_API_KEY=your_key
MOLIT_TRAFFIC_API_URL=https://...
SEOUL_TOPIS_API_KEY=your_key
SEOUL_TOPIS_API_URL=https://...
KOREA_EV_CHARGING_API_KEY=your_key
KOREA_EV_CHARGING_API_URL=https://...
AIRKOREA_API_KEY=your_key
AIRKOREA_API_URL=https://...

API Key가 없어도 모든 Tool은 fallback으로 동작하므로 시스템 전체 실행에 지장이 없습니다.

13.3 터미널 1 — TCP Server 실행

python -m server.tcp_server
==================================================
V2X Safety Agent - TCP Server
==================================================
[SERVER] Listening on 127.0.0.1:9000

포트 변경이 필요한 경우:

TCP_SERVER_PORT=9001 python -m server.tcp_server

13.4 터미널 2 — FastAPI Bridge 실행

uvicorn backend.api_bridge:app --reload --host 127.0.0.1 --port 8000

Bridge 상태 확인:

curl http://127.0.0.1:8000/api/health
# {"status":"ok","service":"V2X Safety FastAPI Bridge"}

13.5 터미널 3 — React UI 실행

cd frontend
npm install
npm run dev

브라우저에서 http://localhost:5173 접속

13.6 사용 순서

  1. React UI에서 시나리오를 선택합니다 (기본: S002 blind_spot_pedestrian)
  2. Analyze 버튼을 클릭합니다
  3. TCP Server 터미널에서 MCP Tool 호출 로그를 확인합니다
  4. React UI에 위험도, AI 브리핑, 증거 지표가 표시됩니다
  5. AI 브리핑이 TTS로 읽어집니다 (브라우저 TTS 지원 시)
  6. AI의 제안에 대해 채팅으로 응답할 수 있습니다

14. 테스트

Python 단위 테스트

python -m pytest
테스트 파일 검증 내용
test_risk_analysis.py S002 입력 시 risk_level == "HIGH" 확인, braking multiplier 적용 시 adjusted >= base 확인
test_vehicle_info_tool.py NHTSA API timeout fallback 시에도 braking_profile 존재 확인
test_tcp_protocol.py <END> marker 기반 chunked JSON 수신 검증, 한글 JSON roundtrip 검증
test_public_api_tools.py Weather/RoadTraffic/EVCharging/AirQuality fallback 동작 및 multiplier 검증

Frontend 빌드 검증

cd frontend
npm run build

API 직접 테스트

# Health check
curl http://127.0.0.1:8000/api/health

# 시나리오 목록
curl http://127.0.0.1:8000/api/scenarios

# S002 분석 요청
curl -X POST http://127.0.0.1:8000/api/analyze \
  -H "Content-Type: application/json" \
  -d '{"scenario_id":"S002","tcp_host":"127.0.0.1","tcp_port":9000}'

15. 시연 시나리오: S002

S002 blind_spot_pedestrian은 인프라 센서가 사각지대 보행자를 감지하고, V2X 통신 품질 저하와 도로 환경을 종합하여 HIGH 위험으로 판단하는 시나리오입니다.

HIGH 위험 판정 근거

조건 가산
보행자 객체 pedestrian +0.25
인프라 센서 감지 infrastructure +0.15
거리 < 20m ~18.25m +0.20
TTC < 3초 ~1.64초 +0.25
latency > 100ms 120ms +0.10
packet_loss > 3% 4.8% +0.10
message_age > 150ms 180ms +0.10

base_risk_score = 1.0 (상한)

보정 계수 적용:

  • braking_multiplier: 1.00 (passenger sedan)
  • weather_risk_multiplier: 현재 날씨에 따라 결정
  • traffic_risk_multiplier: 1.08 (CONGESTED fallback)

adjusted_risk_score ≥ 0.75 → risk_level = HIGH


16. 알려진 한계

항목 설명
제동 프로필 NHTSA vPIC는 실제 제동거리/성능 데이터를 제공하지 않음. braking_distance_multiplier는 차량 유형 기반 추정값
날씨/교통 API 국내 API Key 미설정 시 fallback 사용. 실제 실시간 데이터와 차이 가능
Gemini 의존성 API Key 미설정 또는 google-genai 패키지 문제 시 deterministic fallback 브리핑 사용
외부 API 가용성 네트워크 상태에 따라 success/fallback이 달라질 수 있음
TTS 브라우저 Web Speech API 지원 및 한국어 음성 엔진 유무에 따라 동작 여부가 달라짐
동시 접속 TCP Server는 순차 처리 방식. 동시 다수 요청 시 대기 발생 가능

About

V2X_Agent 프로젝트 입니다.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages