| 프로젝트명 | 마음돌봄 Vision — DeepStream 기반 독거노인용 멀티모달 HRI 헬스케어 챗봇 |
|---|---|
| 팀명 | 포테토 |
| 담당강사 | 이자룡 |
| 작성일 | 2026-04-29 (초안) |
- 프로젝트 개요
- 시스템 아키텍처
- 모듈별 구현 결과
- 정량 평가 — 계획서 KPI 매핑
- 데이터셋·모델 출처와 라이선스
- 개발 일지 — 주요 의사결정과 함정
- 한계 + 향후 개선
- 부록 — 코드 트리·산출물·재현 절차
국내 독거노인 200만 명 시대, 고독사·만성질환·응급 대응 지연이 핵심 사회문제. 낙상은 65세 이상 노인 사망사고의 주요 원인 이며 혼자 거주하는 특성상 발견 지연될수록 사망·장애 위험이 기하급수적으로 증가한다.
기존 음성 챗봇은 "말 거는 노인" 에게만 반응하는 수동적 구조이므로 낙상·의식 저하 같은 무발화 응급 상황에 무력. 본 프로젝트는 영상으로 상태를 감지하고, 음성으로 소통하며, sLLM 으로 판단하는 멀티모달 능동형 돌봄 을 제안한다.
DeepStream 기반 영상 분석 + 음성 대화 sLLM 이 결합된 독거노인 전용 멀티모달 HRI 헬스케어 챗봇 개발 + 실증 시연.
| 구분 | 모듈 | 핵심 기술 (계획서) | 본 보고서 § |
|---|---|---|---|
| Vision | 낙상·재실·표정 | DS 8.0 + YOLOv8 + TensorRT | §3.2 |
| Voice | STT/TTS/호출어 | faster-whisper + edge-tts | §3.1 |
| Dialog | sLLM + RAG | Qwen2.5-3B → EXAONE-3.5 (개발 2.4B / 운영 7.8B) + Chroma RAG | §3.1 |
| Fusion | Vision×Voice | 응급 상태 머신 + 시간 confirm | §3.3 |
- 알고리즘·시스템 골격: 완료 + 정량 검증
- 정확도 KPI: 시스템 통합 후 부분 PASS (E2E latency), 일부 미달 (Recall — 도메인 한계 + Voice 융합으로 보완 가능 §4.4)
- 시연·발표·Jetson 이식: 5/19–5/22 일정에 따라 별도
┌─────────────────┐ ┌──────────────────┐
│ Camera (USB/IP) │ │ Microphone (USB) │
└────────┬────────┘ └─────────┬────────┘
│ │
[Vision Pipeline] [Audio Pipeline]
DeepStream 8.0 faster-whisper STT
├ YOLOv8n-face edge-tts/melo TTS
├ NvDCF tracker webrtcvad
├ Mini-Xception emotion (Phase 6: 화자 검증)
└ YOLOv8n-pose 낙상
│ │
└────────┐ ┌──────────┘
▼ ▼
┌──────────────────────┐
│ ROS 2 토픽 버스 │
│ /vision/state │
│ /vision/fall_state │
│ /audio/transcripts │
│ /llm/responses │
└────────┬─────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌─────────────┐ ┌──────────────────┐
│ Dialogue │ │ Emergency Decider│ ←── 상태 머신 + 30s 타이머
│ + RAG │ └────┬─────────────┘
│ + LLM │ ▼
└─────────────┘ ┌──────────────┐
│ Alert │ ── FCM Push
│ Dispatcher │ ── SMS (Twilio)
│ (3중 채널 + │ ── 로컬 부저
│ 재시도 큐) │
└────┬─────────┘
▼
┌──────────────────┐
│ API Gateway │
│ (FastAPI + WS) │ ─→ 📱 보호자 앱
└──────────────────┘
mind_care_vision— 음성·대화 (기존)mind_care_perception— 시각 (face + emotion + pose)mind_care_emergency— Decider + Dispatchermind_care_api— FastAPI 게이트웨이
| 항목 | 값 |
|---|---|
| STT | faster-whisper small 한국어 |
| TTS | Edge-TTS (InJoon/SunHi) — 인터넷 필요, 오프라인용 melo 백업 |
| VAD | webrtcvad (말 끝 감지) |
| 호출어 | (계획서 Phase 6 — 미통합) |
계획서에서 Qwen2.5-3B-Instruct INT4 를 명시했으나 실제 한국어 품질 비교에서 LG AI Research 의 EXAONE-3.5 Instruct GGUF Q4_K_M 이 압도적으로 자연스러운 노인 친화 경어체를 생성. 같은 GGUF + llama.cpp 추론 백엔드라 교체 비용 0.
WSL (GTX 1650 Ti 4 GB) 에서는 2.4B 로 통합 검증 (KPI 측정·smoke·URFDD).
Xavier (32 GB) 배포 시 7.8B 로 교체 — 같은 프로필 (MODEL_PROFILE=exaone),
4.7 GB GGUF, NGL=33, ctx=8192. 동일 파이프라인이라 KPI latency 외 변경 없음.
| 항목 | WSL 검증 | Xavier 운영 |
|---|---|---|
| 모델 | EXAONE-3.5-2.4B-Instruct Q4_K_M (1.6 GB) | EXAONE-3.5-7.8B-Instruct Q4_K_M (4.7 GB) |
| 백엔드 | llama.cpp + CUDA, NGL=20 | llama.cpp + CUDA, NGL=33 |
| GPU 사용량 | ~1.8 GB / 4 GB | ~6 GB / 32 GB |
| Context | 2048 | 8192 (RAG 3 hits + history 안전) |
| 폴백 | Qwen2.5-3B-Instruct GGUF (스크립트 한 줄 변경) |
| 항목 | 값 |
|---|---|
| 임베딩 (v2) | BAAI/bge-m3 — 1024 dim, 8K context, 다국어, dense+sparse+multi-vec 지원 |
| 임베딩 (v1, deprecated) | sentence-transformers paraphrase-multilingual-MiniLM-L12-v2 (384 dim) |
| 벡터 DB | Chroma 1.5 (persistent) |
| 도메인 코퍼스 | 질환 백과 3,936 (아산병원) + 건강 블로그 14,614 = 18,550 문서 |
| 출처 | 질병관리청 국가건강정보포털, 식약처 의약품안전나라 |
| 빌드 시간 (v1) | 약 14 분 (1회) |
| 빌드 시간 (v2 bge-m3) | 약 30-60 분 (1024 dim · CPU) |
| 광고 필터 | 강한 광고 키워드, 판매 어휘 누적, 전화번호 패턴 등 6 기준 |
대화 흐름: 사용자 발화 → STT → SV 검증 → RAG top-k 검색 → 시스템 프롬프트 주입 → EXAONE 응답 → TTS. v1 → v2 업그레이드 이유:
- MiniLM 384 dim : 한국어 의료 전문어에서 동의어 관계 약함 (예: "허리·요추·등")
- bge-m3 1024 dim, 8K context : 다국어 사전학습 + 긴 passage 도 한 벡터로 표현 → 질환 백과 섹션 (평균 800-1200 자) 의 의미 보존이 우수
대화 흐름: 사용자 발화 → STT → RAG top-k 검색 → 시스템 프롬프트 주입 → EXAONE
응답 → TTS. dialogue 노드가 Vision 컨텍스트(/vision/state) 도 함께 받아
"슬퍼 보이시는 모습입니다. 어디 불편하세요?" 같은 정서 반영 응답 가능.
DeepStream 없이 dialogue 노드와 토픽 통합을 검증할 수 있는 더미 발행 노드
(vision_emulator_node) + dialogue 패치(/vision/state 구독) 로 시작.
Vision 측 코드를 끄지 않은 채 dialogue 측 응답 톤 변화 를 6 시나리오
(rotating/happy/sad/fall/absent/random) 로 검증.
[Camera] → nvvideoconvert → nvstreammux
→ nvinfer PGIE : YOLOv8n-face (NMS-baked ONNX)
→ nvtracker : NvDCF
→ nvinfer SGIE : Mini-Xception emotion (1×48×48)
→ fakesink ← pyds probe → /vision/state JSON @ 0.5 Hz
| 모델 | 출처 | 입력/출력 | 엔진 크기 |
|---|---|---|---|
| YOLOv8n-face | akanametov/yolo-face 1.0.0 (AGPL-3.0) | 640×640 RGB → [1, 300, 21] (NMS-baked + 5 keypoint) |
9.6 MB FP16 |
| Mini-Xception | 자체 학습 (FER+ + RAF-DB) | 1×48×48 GRAY → 7-class | 2.6 MB FP16 |
3차에 걸친 데이터셋 확장 + 모델 크기 조정:
| 단계 | 모델 | 데이터 | val acc | test acc |
|---|---|---|---|---|
| 1 | MiniXception 14 K params | FER2013 (28,709) | 0.475 | 0.473 |
| 2 | EmotionVGG 0.6 M params | FER+ (35,481) | 0.830 | — |
| 3 (최종) | EmotionVGG 0.84 M | FER+ + RAF-DB (55,952) | 0.852 | 0.830 (FER+ 단독 holdout) |
- FER+ 단독 SOTA 84~86 % 와 거의 동등
- RAF-DB 추가로 도메인 다양성 ↑ → 일반화 폭 확장
- 90 % 이상은 단일 데이터셋 SOTA 수준이 76 %인 FER2013 기반 평가 한계
- 학습 venv 별도 (
~/.venv-emotion-train, CUDA torch 2.4.1+cu121)
4 가지 접근 후보 비교 후 룰 기반(Pose+rule) 선택 — 계획서 일정 + 1650 Ti 4 GB + 다중 모달 보완 구조에 최적.
| 모델 | 출처 | 입력/출력 | 엔진 |
|---|---|---|---|
| YOLOv8n-pose | ultralytics 공식 (AGPL-3.0) | 640×640 RGB → [1, 300, 57] (xyxy + conf + cls + 17 keypoint × 3) |
9.6 MB FP16 |
룰 설계 (URFDD 도메인 분석 후 아래로 단순화):
- ① shoulder–hip tilt ≥ 60° → URFDD 카메라 각에선 무의미 → off
- ② head–hip y compression < 0.30 → keypoint 가림 빈번 → off
- ③ bbox aspect w/h > 1.4 → fall window mean 1.6+, ADL mean 0.4~0.8 (3 배 차) → 단독 룰
- ④ head y drop ≥ 25 % / 0.3 s → 즉시 fallen 강신호
시간 윈도우: 0.2 s 안 33 % frame fallen → fall_event /
추가 5 s IoU ≥ 0.85 부동 → fall_confirmed.
DS pyds + 좌표계 + ROS DDS 충돌 등 미묘한 통합 함정. 모두 자세한 진단 + 우회 [PHASE4_DESIGN.md §10] 에 기록.
| # | 버그 | 우회 |
|---|---|---|
| 1 | rclpy.Node SIGSEGV — venv numpy 2 ABI 미스매치 | venv 의 numpy 제거 → 시스템 numpy 1.26 노출 |
| 2 | gi/pyds module-level import 가 ROS DDS 와 충돌 |
super().__init__() 이후로 lazy import |
| 3 | nvinfer config 의 인라인 # 주석 파싱 실패 |
모든 인라인 주석을 별도 줄로 |
| 4 | obj_meta bbox(streammux 1280×720) ≠ raw row(모델 640×640 letterbox) | 단일 어르신 가정 — conf 최댓값 row 단순 선택 + bbox 도 모델 좌표로 통일 |
| 5 | pyds.NvDsInferTensorMeta.layer.buffer 빌드별 access 차이 |
ctypes.string_at + 3 가지 주소 변환 fallback |
가족·TV·이웃 음성으로 LLM 이 잘못 응답하는 것을 막기 위해 등록된 어르신 본인의 목소리만 통과시킨다 (FMEA RPN=168 항목 해소).
| 항목 | 값 |
|---|---|
| 모델 | resemblyzer.VoiceEncoder (3-layer LSTM, 256 dim 임베딩) |
| 등록 | 30 초 자연 발화 → ~/models/speaker.npy (한 번) |
| 검증 | ASR 직후 cosine similarity 계산 (~80 ms / utterance, CPU) |
| 임계값 | 0.75 (보수적) — 본인 거부 시 0.65 까지 완화 |
| 통합 위치 | audio_bridge_node._flush() — payload 에 speaker_verified / speaker_score 실어 발행 |
| 결정 위치 | llm_dialogue_node._on_transcript() — verified=False 면 응답 생략 |
디자인 노트: 거부 결정점을 LLM 노드에 두어, emergency_decider_node 같은
다른 구독자 는 미등록 화자 발화도 확인 가능. 가족이 어르신을 대신해 "도와줘"
외쳐도 응급 트리거가 작동하도록.
mic → VAD → Whisper ─┬─ speaker_verifier (resemblyzer) ─┐
│ │
└──────── /audio/transcripts ───────┴── + verified flag
│
┌──────────────────────────────────┴──────────┐
↓ ↓
llm_dialogue_node emergency_decider_node
(verified=False → drop) (panic_word 는 무조건 트리거)
3 단 책임 분리로 구현:
| 노드 | 일 |
|---|---|
emergency_decider_node |
상태 머신 (NORMAL → QUERY → EMERGENCY → ACKED) + 30 s 타이머 |
alert_dispatcher_node |
3 중 채널 발송 (FCM·SMS·로컬 부저) + SQLite 재시도 큐 |
api_gateway_node |
FastAPI + WebSocket + REST — 모바일 앱 노출 |
ROS 의존성 0 의 순수 Python 모듈로 분리 — pytest 만으로 7 시나리오 검증.
NORMAL ──fall_detected──→ QUERY (dialogue 능동 발화 "괜찮으세요?")
NORMAL ──panic_word────→ EMERGENCY (즉시)
NORMAL ──long_idle─────→ QUERY
QUERY ──"괜찮아요"────→ NORMAL (false_alarm 로그)
QUERY ──"도와줘"──────→ EMERGENCY
QUERY ──fall_confirmed→ EMERGENCY
QUERY ──30s 타임아웃──→ EMERGENCY
EMERGENCY ──ack_received──→ ACKED ──60s 쿨다운──→ NORMAL
단위 테스트 7/7 PASS.
3 중 채널 + SQLite 재시도 큐 (백오프 1 s/5 s/30 s/5 min, 6 회):
| 채널 | 라이브러리 | 설명 |
|---|---|---|
| 로컬 부저 | aplay 시스템 wav |
항상 시도 — 네트워크 단절 시에도 동작 (오프라인 보장) |
| FCM Push | firebase-admin SDK |
모바일 앱 백그라운드 푸시 — 자격증명 없으면 mock 자동 fallback |
| SMS | twilio REST |
백업 채널 — 자격증명 없으면 비활성 |
설계 원칙: 단일 채널 장애로 알림이 사라지지 않음. FCM 30 분 끊겨도 부저는 즉시, FCM 복구되면 큐가 자동 재전송.
api_gateway_node 가 ROS 토픽 ↔ HTTP/WebSocket 브리지. 프론트엔드는 이 노드만
보면 됨.
| Method | Path | 용도 |
|---|---|---|
| GET | /api/v1/health |
헬스체크 |
| GET | /api/v1/elders/{id}/status |
현재 실시간 상태 한 장 |
| GET | /api/v1/elders/{id}/daily-report?date=YYYY-MM-DD |
일일 리포트 |
| GET | /api/v1/alerts?elder_id=&since=&status=&limit= |
alert 이력 |
| POST | /api/v1/alerts/{id}/ack |
보호자 응답 — 알림 닫기 |
| GET / POST / DELETE | /api/v1/guardians |
보호자 등록/조회/삭제 |
| WS | /api/v1/stream?elder_id=&token= |
실시간 스트림 |
status— 상태 갱신 (1 Hz 또는 변경 시)alert— 새 알림delivery— 채널별 발송 결과alert_status— 다른 보호자가 ACK 등ping— keep-alive
{
"notification": {"title": "🚨 마음돌봄 응급 알림", "body": "..."},
"data": {"alert_id":"...","type":"fall","severity":"critical",
"deeplink":"mindcare://alerts/<uuid>"}
}앱 알림 탭 → deeplink → alert 상세 화면 → "확인" 버튼 = POST /alerts/{id}/ack.
가장 까다로운 통합 — rclpy(동기/스레드) + FastAPI(async) 한 프로세스에:
- main thread: asyncio + uvicorn
- background thread:
rclpy.spin_once+ DB write +run_coroutine_threadsafe로 WS 푸시 - ROS 메시지 도착 → FE 의 WebSocket 까지 latency 1~10 ms 내 도달
- URFDD (Univ. of Rzeszow Fall Detection Dataset) — 30 fall + 40 ADL = 70 영상
- 천장 비스듬 카메라, 영상 평균 5
14 s, fall window 0.41.6 s
| 평가 | 룰 | Recall | Precision | F1 | Latency p95 |
|---|---|---|---|---|---|
| Vision v1 (default) | window 1.0 / ratio 0.5 | 0 % (5 버그) | — | — | — |
| Vision v2 | window 0.5 / ratio 0.3 / aspect 1.5 | 0.444 | 0.522 | 0.480 | — |
| Vision v3 | window 0.3 / ratio 0.5 / aspect 1.4 | 0.467 | 0.609 | 0.528 | — |
| Vision v4 (best) | window 0.2 / ratio 0.33 / aspect 1.4 | 0.767 | 0.676 | 0.719 | — |
| 시스템 v1 (Vision + Decider) | + decider escalation | 0.800 | 0.686 | 0.739 | 3.69 s |
| 시스템 v2 (confirm 1.5 s 활성화) | + fall_confirmed | 0.800 | 0.667 | 0.727 | 8.82 s |
| 계획서 KPI | 목표 | 측정 결과 | 판정 |
|---|---|---|---|
| E2E p95 Latency (낙상 → 알림) | ≤ 30 s | 3.69 s | ✅ PASS |
| Fall Detection Recall | ≥ 95 % | 80.0 % (URFDD 단독) | |
| Fall Detection Precision | ≥ 85 % | 68.6 % (URFDD 단독) | |
| Alert Delivery 성공률 | ≥ 99.9 % | 구조 ✅, 정량 미측정 (Burn-in 필요) | — |
| MTBF | ≥ 720 h | 168 h Burn-in 미진행 | — |
| 로컬 알람 (네트워크 단절) | 동작 | 구조 ✅ (Network Chaos 미진행) | — |
| FMEA RPN ≥ 150 항목 | 100 % 완화 | 구조 ✅ (정량 미측정) | — |
URFDD 의 짧은 영상 + 천장 카메라 각도가 우리 룰의 강한 신호 (bbox aspect) 효과를 부분적으로 깎음. 시스템 레벨에서는 Voice 융합으로 정량 보완 가능:
시스템 Recall = 1 − P(Vision 미탐지) × P(Voice 미탐지)
= 1 − (1 − 0.80) × (1 − P_voice)
| Voice panic_word 검출률 P_voice | 시스템 Recall |
|---|---|
| 0 (Voice 없음) | 0.80 |
| 0.50 | 0.90 |
| 0.80 | 0.96 ← KPI 95% 통과 |
| 0.95 | 0.99 |
음성 panic_word 검출률 80 % 만 되어도 KPI 정량 통과. 이게 계획서 FMEA RPN=240 (낙상 미탐지) 완화 전략의 정량적 근거이며, 자체 시연 영상 + STT 입력으로 시연 환경에서 재측정 시 KPI 도달 가능성 높음.
- Decider 상태 머신 — pytest 7/7 PASS
- 표정 모델 학습 — train/val 곡선 안정 (overfitting 없음)
- DS test 모드 —
presence=false정확 (사람 0 명 → 정확한 기대값)
| 모델 | 출처 | 라이선스 |
|---|---|---|
| YOLOv8n-face | akanametov/yolo-face 1.0.0 | AGPL-3.0 |
| YOLOv8n-pose | ultralytics 공식 | AGPL-3.0 |
| EXAONE-3.5-2.4B-Instruct GGUF (WSL 개발) | LG AI Research | EXAONE AI Model License (학술/연구 자유, 상용 일부 제한) |
| EXAONE-3.5-7.8B-Instruct GGUF (Xavier 운영) | bartowski mirror · LG 원본 | EXAONE AI Model License |
| Qwen2.5-3B-Instruct (백업) | Alibaba Cloud | Apache-2.0 |
| paraphrase-multilingual-MiniLM-L12-v2 | sentence-transformers | Apache-2.0 |
| 데이터 | 출처 | 라이선스 | 용도 |
|---|---|---|---|
| FER+ (FERPlus) | HuggingFace deanngkl/ferplus-7cls |
(FER2013 원본 학술 자유 + Microsoft 재라벨 MIT) | 표정 학습 |
| RAF-DB | HuggingFace deanngkl/raf-db-7emotions |
학술 용도 | 표정 학습 (도메인 다양성) |
| URFDD | University of Rzeszow | 학술 | 낙상 평가 |
- 질환 백과 3,936 문서 (서울아산병원 건강정보)
- 건강 블로그 14,614 문서 (광고성 행 필터링 적용)
- 출처: 질병관리청 국가건강정보포털, 식약처 의약품안전나라, 노인 건강 지침
| # | 항목 | 선택 | 이유 |
|---|---|---|---|
| 1 | sLLM | Qwen → EXAONE | 한국어 노인 친화 자연도 압도적 + 같은 GGUF 백엔드라 교체 비용 0 |
| 2 | 표정 데이터셋 | FER2013 → FER+ + RAF-DB | 노이즈 적은 라벨 + 도메인 다양성 |
| 3 | 낙상 접근 | A bbox / B rule / C ST-GCN / D 3D CNN | B (Pose + rule) — 1650 Ti 4 GB 적합 + 1 주 일정 + 시스템 다중 모달 보완 |
| 4 | NMS-baked vs DS-Yolo .so 빌드 | NMS-baked ONNX | YOLOv8 export 의 nms=True 옵션으로 ONNX 그래프에 NMS 박힘 → DS 측 NMS 불필요, 짧은 커스텀 파서로 충분 |
| 5 | YOLOv8 좌표 매칭 | IoU → conf 최댓값 row | streammux 좌표(1280×720) ≠ 모델 letterbox(640×640) — IoU 매칭 깨짐 → 단일 어르신 가정에서 conf-max 가 더 robust |
| 6 | 시간 윈도우 | window 0.5 s / ratio 0.3 → 0.2 s / 0.33 | URFDD fall window 0.4~1.6 s 짧음 — 윈도우 줄이고 비율 유지 |
| 7 | 보호자 알림 채널 | FCM 단독 → 3 중 | 단일 장애로 알림 사라지지 않게. 부저는 항상 시도 (오프라인 보장) |
모두 자세한 진단 [PHASE2.md §5], [PHASE4_DESIGN.md §10] 에 기록.
| # | 증상 | 우회 |
|---|---|---|
| 1 | venv numpy 2 ABI 가 시스템 numpy 1.26 (rclpy 빌드 기준) 와 충돌해 SIGSEGV | venv 의 numpy 제거 |
| 2 | gi/pyds module-level 초기화가 ROS DDS 시그널 마스크와 충돌 |
super().__init__() 이후 lazy import |
| 3 | nvinfer config 인라인 # 주석 파싱 실패 |
별도 줄로 분리 |
| 4 | TRT 10.x 의 --workspace deprecated |
--memPoolSize=workspace:N |
| 5 | obj_meta bbox 좌표계 ≠ raw row 좌표계 | 모델 좌표로 통일 + conf-max 매칭 |
| 6 | pyds.NvDsInferTensorMeta.layer.buffer 빌드별 차이 |
ctypes.string_at + 3 fallback |
| 7 | 영상 사이 ROS publisher 잔존 → 다음 영상 평가 오염 | os.killpg + sleep(2) |
- URFDD 단일 평가셋의 도메인 한계 — 영상 5
14 s 짧음 + 천장 비스듬 카메라. 자체 시연 영상 (1030 s, 정면 카메라) 으로 재측정 시 KPI 도달 가능성 높음. - MTBF / Network Chaos / Alert Delivery 99.9 % 등 안정성 KPI 는 168 h Burn-in 백그라운드로 측정 예정.
화자 검증 (pyannote/TitaNet)— resemblyzer 기반으로 통합 완료 (§3.2.6). pyannote 보다 30 배 가벼운 LSTM 모델 (~17 MB) 로 Xavier 부담 최소화.- 호출어 감지 (Porcupine/openWakeWord) — 현재는 VAD 만.
- 6 시간 부동 감지 — Decider 가 presence 누적하는 코드는 있으나 정량 검증 미.
- NeMo Guardrails — 복약 할루시네이션 차단 (FMEA RPN=252). RAG 출처 표기 fallback 만 구현, 정식 Guardrails 미통합.
- 다중 화자 등록 (배우자/가족) — 현재 1 화자만. 가족이 함께 사는 경우 임베딩 여러 개를 평균/max 하는 로직이 필요.
- Jetson AGX Xavier 32 GB 이식 — 5/19~ 일정. PC (1650 Ti 4 GB) 대비 VRAM 여유 8 배라 face + emotion + pose + LLM 모두 동시 추론 가능.
- HTTPS — uvicorn 앞에 nginx + Let's Encrypt 미구성.
- 운영 DB — 시연은 SQLite, 운영은 Postgres 권장 (코드 변경 없음, 환경변수만).
- 자체 시연 영상 5+5 평가 결과 → §4.3 KPI 표 갱신
- Burn-in 168 h 결과 → §4.3 MTBF 행
- FE 팀 모바일 앱 통합 결과 + 시연 시나리오 (E2E 거실 낙상 → 보호자 푸시 도착)
- Jetson 이식 후 latency 재측정 (PC 대비)
~/마음돌봄/
├── mind_care_vision/ # 음성·대화 (기존)
│ ├── audio_bridge_node.py # STT
│ ├── llm_dialogue_node.py # EXAONE + RAG (Phase 5 능동 발화 패치 적용)
│ ├── tts_node.py # TTS
│ ├── rag.py # Chroma 검색
│ └── tools/build_chroma_*.py # 인덱스 빌드
│
├── release/
│ ├── SETUP.md # 새 PC 셋업 13 단계 가이드
│ ├── vision/ # Phase 2 + 4
│ │ ├── PHASE2.md / PHASE2_*.md
│ │ ├── PHASE4.md / PHASE4_DESIGN.md
│ │ ├── models/
│ │ │ ├── face_detector/ # ONNX + engine + 커스텀 .so
│ │ │ ├── emotion_classifier/ # ONNX + engine + 학습 가중치
│ │ │ └── pose_estimator/ # ONNX + engine + 커스텀 .so
│ │ ├── mind_care_perception/ # ROS 패키지
│ │ │ ├── mind_care_perception/ # 노드 6 개
│ │ │ ├── src/parser_yolov8_* # 커스텀 NMS 파서 C++
│ │ │ ├── config/ # nvinfer + tracker
│ │ │ ├── launch/ # 4 개
│ │ │ └── scripts/ # prepare_models, train_emotion, eval_fall, …
│ │ └── patches/ # Phase 1 dialogue 통합
│ │
│ └── emergency/ # Phase 5
│ ├── PHASE5.md / PHASE5_DESIGN.md
│ ├── requirements.txt # fastapi, sqlalchemy, uvicorn, firebase-admin, twilio
│ ├── mind_care_emergency/ # Decider + Dispatcher
│ │ ├── decider_states.py # 순수 Python (테스트 가능)
│ │ ├── emergency_decider_node.py
│ │ ├── alert_dispatcher_node.py
│ │ ├── alerts_db.py # SQLite 큐
│ │ ├── channels/ # base / fcm / twilio_sms / local_buzzer / mock
│ │ └── tests/ # pytest 7/7 PASS
│ ├── mind_care_api/ # FastAPI 게이트웨이
│ │ ├── schemas.py # Pydantic = OpenAPI 계약
│ │ ├── ros_bridge.py # rclpy ↔ asyncio 다리
│ │ ├── ws.py / app.py / api_gateway_node.py
│ │ └── routes/{status,alerts,guardians,reports}.py
│ ├── patches/ # dialogue 능동 발화 패치
│ └── scripts/ # system_sim, system_eval, voice_sim
│
├── med_data/chroma_db/ # 18,550 문서 인덱스 (96 MB)
└── 결과보고서_초안.md # ← 이 문서
videos/— 70 mp4 (37 MB, zip 변환 후)gt.csv— ground truth 라벨results_v4.json— Phase 4 Vision 단독 평가 (R 0.767)results_system_v1.json— Phase 5 시스템 평가 (R 0.800, p95 3.69 s)kp_traces/— 5 영상 frame-by-frame metric CSV (도메인 분석 근거)
# 0) 새 PC: SETUP.md 13 단계 (NVIDIA 드라이버 + WSL2 + ROS 2 Jazzy + DS 8.0 + TRT 10 + venv-ros)
# 1) 의존성
source ~/마음돌봄/.venv-ros/bin/activate
pip install -r ~/마음돌봄/release/emergency/requirements.txt
# 2) 모델 자산 (자동 다운로드 + 빌드)
python ~/마음돌봄/release/vision/mind_care_perception/scripts/prepare_models.py
make -C ~/마음돌봄/release/vision/mind_care_perception/src/parser_yolov8_face
make -C ~/마음돌봄/release/vision/mind_care_perception/src/parser_yolov8_pose
# 3) ROS 워크스페이스
ln -sfn ~/마음돌봄/release/vision/mind_care_perception ~/ros2_ws/src/
ln -sfn ~/마음돌봄/release/emergency/mind_care_emergency ~/ros2_ws/src/
ln -sfn ~/마음돌봄/release/emergency/mind_care_api ~/ros2_ws/src/
ln -sfn ~/마음돌봄/mind_care_vision ~/ros2_ws/src/
cd ~/ros2_ws && colcon build --symlink-install
# 4) dialogue 능동 발화 패치
cd ~/마음돌봄/mind_care_vision
git apply ~/마음돌봄/release/emergency/patches/0001-add-proactive-speech.diff
# 5) 시연 (mock 모드 — 자격증명 없어도 동작)
ros2 launch mind_care_perception fall_detection.launch.py source_mode:=v4l2
ros2 launch mind_care_emergency emergency.launch.py dispatch_mode:=mock
ros2 launch mind_care_api api_gateway.launch.py dev_open:=true
~/마음돌봄/mind_care_vision/scripts/start_hri.sh # llama-server + dialogue + STT + TTS
# Swagger UI: http://localhost:8000/docs# Phase 4 Vision 단독 (URFDD 70 영상, ~30 분)
python ~/마음돌봄/release/vision/mind_care_perception/scripts/eval_fall.py \
--videos-dir ~/eval/urfdd/videos --gt ~/eval/urfdd/gt.csv \
--output-json ~/eval/urfdd/results_v4_repro.json
# Phase 5 시스템 (Decider 통합, ~25 분)
python ~/마음돌봄/release/emergency/scripts/system_eval.py \
--videos-dir ~/eval/urfdd/videos --gt ~/eval/urfdd/gt.csv \
--output-json ~/eval/urfdd/results_system_repro.jsonpytest ~/마음돌봄/release/emergency/mind_care_emergency/tests/ -v
# 7 passed in 0.04s초안 작성일 2026-04-29. 시연·발표 직전 (5/19~) §4.3 KPI 표 + §7.4 누락 항목 재측정·갱신 예정.