docs: README 전체 업데이트 (v5, 2026-05-11 기준)

- Pipeline Summary: GREEN 상수 (CV preset별, LR 0.20, 7s hold, 3fail exit),
  힌트 텍스트 표 추가, Spot 5회/Auto 10윈도우, 태블릿 fontScale,
  향후 과제 갱신 (IMU 포팅 예정)
- USER_GUIDE: 전체 재작성 — Start flow, 힌트 화살표(↑↓←→),
  페어링 다이얼로그, Void/Catheterization, Single Scan/Auto Scan,
  Checking/Final check/In position! 텍스트 반영
- ALGORITHM_COMPARISON: Placement 섹션 현행화 — Start 버튼 필수,
  phase protection, 화살표 항상 갱신, GREEN 7s+3fail

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-11 17:43:39 +09:00
parent ef38aa6eaf
commit a1042b808c
3 changed files with 343 additions and 96 deletions
+80 -33
View File
@@ -2,7 +2,7 @@
## 작성일: 2026-04-23
## 작성자: dwjang
## 마지막 업데이트: 2026-05-09 (v4) — VBTAND0101
## 마지막 업데이트: 2026-05-11 (v5) — VBTAND0101
---
@@ -383,34 +383,46 @@ Android: estimateBladderVolume6ch(6채널)
[CH0] 0° ← 가장 위 (배꼽쪽, y=21mm)
```
## 방향 안내 로직 — 3모드 (2026-05-07 업데이트)
## 방향 안내 로직 — 3모드 (2026-05-11 업데이트)
개발자 모드 Settings에서 전환 가능: **Gradient** (기본) / Boundary / **SWEEP**
### 조작 흐름 (Start 버튼 필수)
```
화면 진입 → "Place VesiScan above the pubic bone, then press Start"
↓ Start Alignment 버튼 탭 (96dp 대형)
전체 상태 리셋 → 1초 간격 연속 스캔 시작
↓
VERTICAL → LATERAL → GREEN (순차, 건너뛰기 없음)
↓ GREEN 7초 유지 + 3회 연속 실패 안 하면
Start Scanning 버튼 활성화 (초록색)
```
### Gradient 모드 (기본) — 신호 길이 비교
```
시작: 치골 위 → 위로 올림
시작: 치골 위
1단계 VERTICAL:
0~1채널: ch0/ch1 감지→↑, ch2/ch3 감지→↓
2+채널: weighted center gradient
weightedCenter = Σ(ch_pos × len) / Σ(len)
gradient = weightedCenter - 1.5
gradient > 0 → ↓ (ch3쪽 길다 = 방광 아래)
gradient < 0 → ↑ (ch0쪽 길다 = 방광 위)
|gradient| < 0.4 + lenVariation < 0.5 → 상하 OK
gradient > 0 → "Slide down ↓" (ch3쪽 길다 = 방광 아래)
gradient < 0 → "Slide up ↑" (ch0쪽 길다 = 방광 위)
|gradient| < 0.3 + centerDetected >= 4 → "Checking..." → LATERAL
2단계 LATERAL:
|len4 - len5| ≤ 10 sample → 바로 GREEN
lrSymmetry ≥ 0.5 → GREEN
아니면 len 차이 방향으로 안내
|len4 - len5| ≤ 10 sample → "Final check..." → GREEN
lrSymmetry ≥ 0.5 → "Final check..." → GREEN
아니면 "Slide left ←" / "Slide right →"
3단계 GREEN:
CV ≤ 0.12 (10회마다 +0.03 완화)
|lrDev| ≤ 0.35
둘 다 통과 → Green!
CV만 간당간당 → "Almost there..." (GREEN에 머물며 재시도)
CV ≤ threshold (V0=0.07, V1/V2=0.10, 5회마다 +0.03 완화)
|lrDev| ≤ 0.20
둘 다 통과 → "In position!" (7초 hold)
3회 연속 실패 → "Position lost. Restart above pubic bone." + 스캔 중지
```
### SWEEP 모드 (CKLaw) — 위에서 아래로 쓸어내리기
@@ -446,26 +458,44 @@ Android: estimateBladderVolume6ch(6채널)
| 상수 | 값 | 의미 |
|------|-----|------|
| DEFAULT_CV_THR | 0.12 | 기본 CV 임계 (10회마다 +0.03 완화) |
| DEFAULT_LR_DEV_THR | 0.35 | LR 비대칭 임계 |
| DEFAULT_CV_THR | V0=0.07, V1/V2=0.10, 기타=0.08 | 기본 CV 임계 |
| CV 완화 | +0.03 per 5 scans | 5회마다 임계값 증가 |
| DEFAULT_LR_DEV_THR | 0.20 | LR 비대칭 임계 |
| 절대 LR 차이 | ≤10 sample | LATERAL 즉시 통과 |
| R-peak tolerance | 1.5mm | SWEEP 모드 GREEN gate |
| 디바운스 | 1.5초 | phase 전환은 즉시, 같은 phase 힌트만 디바운스 |
| GREEN hold | 7초 | GREEN 진입 후 최소 유지 시간 |
| GREEN exit | 3회 연속 실패 | hold 이후 이탈 조건 |
| 디바운스 | 1.5초 (같은 phase) / 3초 (phase 전환) | |
| Phase 보호 | 3스캔 | phase 전환 후 힌트 강제 유지 |
### 힌트 텍스트 (모든 방향 힌트에 화살표 포함)
| 상황 | 텍스트 |
|------|--------|
| 상하 이동 | "Slide up ↑" / "Slide down ↓" / "Slide up slightly ↑" / "Slide down slightly ↓" |
| 좌우 이동 | "Slide left ←" / "Slide right →" |
| 확인 중 | "Checking..." |
| 최종 확인 | "Final check..." |
| 최적 위치 | "In position!" |
| 위치 이탈 | "Position lost. Restart above pubic bone." |
| 센서 미부착 | "Sensor detached. Restart above pubic bone." |
## 연속 스캔 동작
```
"Start Scanning" 버튼 탭
"Start Alignment" 버튼 탭 (waitingForStart → false)
↓
전체 상태 리셋 (phase, score, debounce, greenFail 등)
↓
즉시 첫 스캔 (maa 6채널)
↓ 결과: CV, 방향, Score 표시
3초 대기
↓ 결과: CV, 방향, Score 표시 (28sp 대형 힌트)
1초 대기
↓
자동 재스캔 (repeatCount 증가 → threshold 완화)
자동 재스캔 (scanCount 증가 → CV threshold 완화)
↓
... 반복 (사용자가 Stop 누를 때까지)
... 반복 (GREEN 도달 or 이탈 시 자동 중지)
is_pass = true → Lock → "Start Measurement" 활성화
is_pass = true → Lock → 7초 hold → "Start Scanning" 버튼 활성화
```
---
@@ -504,20 +534,22 @@ Spot 버튼 탭
화면에 "305 ml" 표시! (도넛차트 + 레벨 업데이트)
```
## Auto 모드 (2026-05-07 업데이트)
## Auto Scan 모드 (2026-05-11 업데이트)
별도 Auto 버튼으로 자동 반복 측정:
- 1.5초 간격 자동 측정
- 첫 5회: "Measuring... (n/5)" 로딩 표시
- 5회 이상: **sliding window trimmed mean** (10개 윈도우) → 안정된 값 표시
- Stop 버튼으로 종료
"Auto Scan" 버튼으로 자동 반복 측정:
- 최소 800ms 간격 자동 측정 (BLE maa throttle 보장)
- 첫 5회: "—" 표시 (데이터 수집 중)
- 5회 이상: **sliding window trimmed mean** (10개 윈도우, 최대/최소 각 1개 제외 → 8개 평균)
- "Stop Scan" 버튼으로 종료
- Auto fail: 2ch+ missing 5회 연속 → "Position lost. Restart from alignment" 다이얼로그
## Spot 모드 (2026-05-07 업데이트)
## Single Scan 모드 (2026-05-11 업데이트)
Spot 버튼 1탭 → **3회 측정 → median** (중간값 깜빡임 없음):
- 최대 6회까지 재시도 (유효값 3개 수집 목표)
- 측정 간격 300ms (BLE 겹침 방지)
"Single Scan" 버튼 1탭 → **5회 측정 → trimmed mean**:
- 최대 8회까지 재시도 (유효값 5개 수집 목표, 최소 3개)
- 측정 간격: maa 800ms throttle이 간격 보장
- 중간 값 화면 미표시 (isSpotInProgress 플래그)
- 1초 쿨다운 후 재사용 가능
## 측정 실패 시 자동 재시도
@@ -1058,7 +1090,15 @@ Start Scanning (3초 간격 자동 반복)
║ PASS → LED 6 (ALIGN_COMPLETE) + Lock ║
╚═══════════════════════════════════════╝
↓ Green!
"Start Measurement" 버튼 활성화
"Start Scanning" 버튼 활성화 (초록, 96dp)
```
### 태블릿 대응
```
fontScale = (screenWidth / 360f).coerceIn(1.0, 1.8)
→ 폰(360dp)=1.0배, 태블릿(600dp+)=~1.6배
버튼/힌트 텍스트, InfoCard, 배터리/카테터 표시 등 전체 적용
```
### 패킷 드랍 대응
@@ -1267,6 +1307,13 @@ ADC 파싱 시 Big/Little Endian을 자동 감지:
| ADC CSV 저장 | ✅ 완료 | 세션별 파일 |
| Canvas 하복부 실루엣 | ✅ 완료 | PNG 제거, CKLaw Bezier torso |
| i18n (한국어/영어) | ✅ 완료 | strings.xml |
| UI 텍스트 통일 | ✅ 완료 | revised 문서 반영 (Slide up ↑, In position! 등) |
| 태블릿 대응 | ✅ 완료 | fontScale, 비율 기반 레이아웃, 힌트/버튼 확대 |
| 페어링 다이얼로그 | ✅ 완료 | bonding 대기 중 안내 표시 |
| 앱 아이콘 | ✅ 완료 | 방광이 캐릭터 PNG (5 density) |
| Placement 화살표 수정 | ✅ 완료 | 디바운스/보호 중에도 화살표 항상 표시 |
| GREEN 안정성 | ✅ 완료 | 7초 hold + 3회 연속 실패 exit + phase 보호 |
| IMU 모션 감지 | 🔜 예정 | vesiscanbasicAndroid에서 포팅 예정 |
| Placement 팬텀 테스트 | 🔜 예정 | Gradient vs SWEEP 비교 |
| 5-Anchor calibration | 🔜 검토 | CKLaw 전체 포팅 여부 결정 |
| 인체 임상 검증 | 🔜 예정 | 상수 재조정 |