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:
@@ -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, 일지 |
|
||||
|
||||
Reference in New Issue
Block a user