feat: Placement 판정 결과 BLE 디버그 로거에 기록 + README 대폭 업데이트

BLE 로그 추가:
- DETACHED mean=12.3 std=8.7
- PLACEMENT_SEARCHING cv=0.234 dir=MOVE UP moderate score=35
- PLACEMENT_PASS cv=0.112 lr_dev=0.089 score=78

README 추가 섹션:
- 17. 미부착 감지 알고리즘 상세 (DetachmentDetection)
  - 원리, 상수, 실측 안전 마진 설명
- 18. Placement 전체 파이프라인 흐름도
  - Detachment → Echo → CV → LR → LED 판정
  - BLE 로그 출력 예시
- 향후 과제에 미부착 감지 완료 항목 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 15:27:39 +09:00
parent ea19b74c00
commit 1beb0737c6
2 changed files with 146 additions and 10 deletions
+143 -10
View File
@@ -965,21 +965,153 @@ CRC16.buildCommandASCII("mid", " ") // → "mid? " + CRC
| 6 | ALIGN_COMPLETE | 정렬 모드 탐지 완료 |
| 7 | ERROR | 오류 발생 |
### Placement Guide 연동
### Placement Guide 연동 (3단계 판정)
```
Start Scanning → mls?(5) ALIGN_SEARCHING (LED 탐지 모드)
↓
3초 간격 스캔 중...
↓
CV PASS → mls?(6) ALIGN_COMPLETE (LED 완료)
↓
Stop Scanning → mls?(0) OFF
매 3초 스캔 →
│
├─ [1단계] 미부착 감지 (DetachmentDetection)
│ mean(|y|) < 100 AND std(y) < 100 → 미부착
│ → LED 4 (DETACH_WARNING)
│ → "Sensor detached — check contact"
│
├─ [2단계] Placement 판정 (CV threshold)
│ CV > 0.15 또는 |lr_dev| > 0.15 → 부적절
│ → LED 5 (ALIGN_SEARCHING)
│ → 방향 가이드 (MOVE UP/DOWN/LEFT/RIGHT)
│
└─ [3단계] 최적 위치
CV ≤ 0.15 AND |lr_dev| ≤ 0.15 → PASS
→ LED 6 (ALIGN_COMPLETE)
→ "Best Placement!"
Stop Scanning → LED 0 (OFF)
```
---
# 17. 향후 과제
# 17. 미부착 감지 (Detachment Detection)
### 원본: detachment_detection.py (원은지님, 2026-04-24)
### 알고리즘
```
입력: 6채널 ADC raw 데이터 (100 samples × 6ch)
1. Center 채널 추출 (CH0~CH3, 4채널)
2. Baseline 제거:
baseline = median(signal[80:100]) ← 끝부분 20개 샘플의 중앙값
y = signal[20:80] - baseline ← 중간 60개 샘플에서 baseline 차감
3. 특징 계산 (채널별):
mean_abs = mean(|y|) ← 절대값 평균 (신호 크기)
std = std(y) ← 표준편차 (신호 변동성)
4. 4채널 평균:
mean_abs = avg(mean_abs_ch0, ..., mean_abs_ch3)
std_val = avg(std_ch0, ..., std_ch3)
5. 판정 ("and" rule):
미부착 = mean_abs < 100 AND std_val < 100
```
### 왜 이 방식인가?
```
부착된 경우: 미부착된 경우:
초음파가 조직을 통과 → 반사 공기 중 → 신호 거의 없음
signal[20:80] 구간에 변동 있음 signal[20:80] 구간이 평탄
mean_abs >> 100, std >> 100 mean_abs < 100, std < 100
실측 데이터 (원은지님):
미부착 max: mean=33.7, std=43.4 ← threshold 100보다 훨씬 낮음
부적절 min: mean=254.8, std=234.7 ← threshold 100보다 훨씬 높음
→ ~2.5배 안전 마진
```
### 상수
| 상수 | 값 | 의미 |
|------|-----|------|
| `WINDOW_START` | 20 | 분석 구간 시작 (ringdown 이후) |
| `WINDOW_END` | 80 | 분석 구간 끝 |
| `BASELINE_WINDOW_START` | 80 | baseline 구간 시작 |
| `BASELINE_WINDOW_END` | 100 | baseline 구간 끝 |
| `THR_MEAN` | 100 | mean(|y|) 임계값 |
| `THR_STD` | 100 | std(y) 임계값 |
---
# 18. Placement 전체 파이프라인 (CV threshold + Detachment + LED)
### 원본: placement.py (원은지님, 2026-04-24)
### 전체 흐름도
```
Start Scanning (3초 간격 자동 반복)
↓
[매 스캔]
↓
6채널 ADC 수신 (maa? → reb:×6 → raa:)
↓
┌───────────────────────────────────────┐
│ 1. Detachment Detection │
│ signal[20:80] - median([80:100]) │
│ mean(|y|) < 100 AND std < 100? │
│ → YES: LED 4 (미부착) → 다음 스캔 │
└───────────────────────────────────────┘
↓ NO (부착됨)
┌───────────────────────────────────────┐
│ 2. Echo Analysis (6채널) │
│ SG denoise → Low-echo detection │
│ → ant/post wall 위치 (mm) │
└───────────────────────────────────────┘
↓
┌───────────────────────────────────────┐
│ 3. CV Threshold (Center CH0~CH3) │
│ depth_mm = (post-ant) × DPS × cos(θ)│
│ CV = std(depths) / mean(depths) │
│ CV ≤ 0.15? → PASS │
└───────────────────────────────────────┘
↓
┌───────────────────────────────────────┐
│ 4. LR Deviation (CH4 vs CH5) │
│ lr_dev = (depth4-depth5) / mean │
│ |lr_dev| ≤ 0.15? → PASS │
└───────────────────────────────────────┘
↓
┌───────────────────────────────────────┐
│ 5. 최종 판정 │
│ CV PASS AND LR PASS │
│ → YES: LED 6 (최적 위치) → Lock │
│ → NO: LED 5 (탐색 중) │
│ + 방향 가이드 │
│ (MOVE UP/DOWN/LEFT/RIGHT) │
│ + severity (slight/moderate/severe) │
└───────────────────────────────────────┘
↓
Threshold Relaxation (반복 시):
CV_thr = 0.15 + scanCount × 0.02
→ 오래 조절해도 안 되면 기준 완화
Lock → "Start Measurement" 버튼 활성화
```
### BLE 디버그 로그 출력 예시
```
13:45:39 WARN DETACHED mean=12.3 std=8.7
13:45:42 INFO PLACEMENT_SEARCHING cv=0.234 dir=MOVE UP moderate score=35
13:45:45 INFO PLACEMENT_SEARCHING cv=0.180 dir=MOVE DOWN slight score=52
13:45:48 INFO PLACEMENT_PASS cv=0.112 lr_dev=0.089 score=78
```
---
# 19. 향후 과제
| 항목 | 상태 | 비고 |
|------|------|------|
@@ -994,7 +1126,8 @@ Stop Scanning → mls?(0) OFF
| BLE 디버그 로거 | ✅ 완료 | TX/RX 파싱 + Downloads 내보내기 |
| ADC 로그 저장 | ✅ 완료 | 6ch raw ADC → JSONL |
| 기기 정보 조회 (mid?) | ✅ 완료 | 연결 시 자동 (HW/SN/FW) |
| LED 모드 (mls?) | ✅ 완료 | Placement 연동 (5→6→0) |
| 미부착 감지 (DetachmentDetection) | ✅ 완료 | mean/std < 100 → LED 4 |
| LED 모드 (mls?) | ✅ 완료 | Placement 3단계 (4→5→6→0) |
| IMU 쿼리 (msp?) | ✅ 완료 | 1초 간격, 자동측정 루프 |
| 자동측정 (IMU 1s + 측정 10s) | ✅ 완료 | |
| iOS 동기화 (UI) | ✅ 완료 | 알림, Quick Save, 일지 |