Commit Graph

260 Commits

Author SHA1 Message Date
dw.jang cac3712b8c BLE: maa throttle을 state-based 게이트로 강화
이전 응답이 완료되기 전에 새 maa가 송신되면 piezoCollector.startMultiChannel(6)이
호출되며 collector가 reset → 큐에 떠다니던 reb 패킷이 폐기되어 BV_FAIL/BV_SKIP가
발생하던 문제 대응.

변경:
- 시간 단독 게이트(800ms) → state + 시간 복합 게이트
- (A) piezoCollector.isMultiChannel && !isComplete 이면 차단
       단 5초 넘으면 강제 통과(영영 deadlock 방지)
- (B) 최소 간격 800ms → 1500ms (펌웨어 응답 시간 ~1.2~1.4s 반영)
- sendAllChannels/sendChannelsOnly가 공유하는 canSendMaa() 헬퍼로 일원화

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:34:51 +09:00
dw.jang 11dd8fb58f chore: version 1.0.0-design (versionCode 24)
문서 변경 이력 (2026-05-12 이후 22 빌드 누적) 적용 완료 마커.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:34:51 +09:00
dw.jang d507b1f447 UI: PiezoMonitoring 누적 업데이트 (108-122)
- 빌드 108: "Void/" → "Voiding/", Toast "Recorded" → 48sp Dialog 오버레이 (1.5초 자동)
- 빌드 109: Donut 캡 제거, 너비×0.85 적응형 (dev 모드는 0.65)
- 빌드 110: useScrollLayout = isDevMode && showDevPanels — 패널 표시될 때만 스크롤 레이아웃
- 빌드 111+115: Volume Text 24→72sp (3× ExtraBold, letterSpacing -1), Bladdy 0.85→0.483, 흰 bg 0.85→0.78, scroll 40/55→46/63dp
- 빌드 113: Voiding 시 Auto Scan 자동 stop + displayMaxVolumeMl/window/timer 정규화
- 빌드 114: Status 배지 dev 모드 한정 탭 → 60~maxVol-50 더미 측정값 랜덤 주입
- 빌드 117: 설정 패널 9개 라벨 14sp→28sp, 행간 spacedBy 6→9dp, HorizontalDivider 9개 padding(vertical=28dp)
- 빌드 122: 측정 상단 좌측 Home 아이콘 추가 (Placement 옆), Placement 진입은 enterPlacementFromMonitoring() 경유

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:34:14 +09:00
dw.jang 898fb77605 UI: PlacementGuide(Sensor Alignment) 리디자인
빌드 107-121 누적 적용:
- 3-stop vertical gradient 배경 (MlTeal 14% / 흰 / MlPrimary 10%) — GREEN 진입 시 단색 톤으로 덮임
- 큰 "Sensor Alignment" 타이틀 38sp ExtraBold 검정 (Maximum Bladder Capacity 톤 통일)
- Hint 텍스트 "pubic bone" 인라인 빨강 ExtraBold 강조 (AnnotatedString)
- Canvas 방향 화살표 4종 제거 — hint 텍스트로만 방향 안내
- Canvas 치골 아치 라인+halo+endpoint 제거 — pubic bone 강조는 hint 인라인 1곳에만
- 실루엣 chestY 16% UP shift (0.06 → 0.09, 비례 유지)
- Body 상단 Spacer 8dp

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:30:50 +09:00
dw.jang 3e1a875b5b UI: PiezoPersonalizationView 전면 리디자인 — 평행 2-카드
빌드 107-119 적용:
- Bladdy 히어로 BoxWithConstraints 동적 사이징, 카드 영역 수직 중앙 정렬
- Card 1 "Maximum Bladder Capacity" 34sp ExtraBold + 500/mL (64+24sp) + 56dp 솔리드 StepperButton + 슬라이더
- Card 2 "Catheter Threshold" 34sp ExtraBold + Level/7/10 3분할(24+64+24sp) + StepperButton + Level 1~10 슬라이더
- 부제 모두 제거, 섹션 간격 64dp
- Slider 값 부동소수점 절삭 버그 fix: it.toInt() → it.roundToInt()

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:28:59 +09:00
dw.jang 975be77126 UI: HomeView Bladdy 220 → 660dp (3×) + BoxWithConstraints 캡
빌드 114 적용: Home의 Bladdy 히어로를 3배 확대하고 BoxWithConstraints로
가용 영역의 90% 캡을 적용해 작은 화면에서 overflow가 나지 않도록 함.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:28:59 +09:00
dw.jang cb8500f6ce ROUTING: Placement 진입 경로 분기 (Personalization vs Monitoring)
빌드 106 적용: placementFromMonitoring 플래그 + enterPlacementFromMonitoring() /
backFromPlacementGuide() 헬퍼 추가. Personalization → Placement → Monitoring 정방향과
Monitoring → Placement 재진입 경로에서 Back 동작이 올바르게 분기되도록 일괄 정리.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:28:59 +09:00
dw.jang 34bb446e0f DEV: 측정 모드 직진입 버튼 + Start 라우팅 fix
빌드 104-105 적용:
- DeviceScanView "No devices found" 화면에 dev 모드 한정 "Enter Measurement Mode" 버튼 추가 (BLE 없이 디자인 작업용)
- AppState.startFromHome() 라우팅 fix — 페어링 후 Personalization → Back → HOME → Start 시 Monitoring 직행 버그를 PIEZO_PERSONALIZATION 부터 시작하도록 변경

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:28:59 +09:00
dw.jang 38c5a3f606 DEMO: PinView 자동통과 + UI 본체 비표시
빌드 101-103 적용: PIN 화면 진입 시 LaunchedEffect로 즉시 appState.pinVerified()
호출(PIN 저장 안 함). 화면 본체는 if(false) {...}로 비표시 — 빈 MlBackground Box만 노출.
원본 UI는 보존하여 데모 후 깨끗한 롤백 가능.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:28:58 +09:00
Charles KWON 833c110d2f feat: 측정 가로모드 대응 + Ant Offset + Scan Log + 다중 sanity check
## 측정 화면 (PiezoMonitoringView)
- BoxWithConstraints + donutFitSize: 가로/작은 화면에서도 donut+Bladdy+buttons
  모두 들어오도록 height-aware sizing (cap 120~360dp)
- nonDevSpacing: available height 기반 단계 (18/22/28/36) — 큰 화면 답답함 해소
- center 4 중 1개라도 missing → 즉시 realign prompt (이전: AutoMeasure 5회 누적)
- 6채널 중 3개 이상 missing 시 위치 이탈 알림 (모드 무관)
- 다이얼로그 문구: "Position Lost or Insufficient Gel"
- V41 결과 후처리 — walls를 PiezoEchoAnalyzer 기준으로 강제 (UI 차트와 일관)
  · ant = analyzer.result.ant
  · post = analyzer.result.lowEnd + 3
- CH3 secondary echo 잡힘 / CH4·CH5 lateral ant too-deep 문제 해결
- Bladdy 3-tap → Developer Mode toggle (측정 화면에서도)

## Placement 가이드 (PlacementGuideView)
- 가로 모드 대응: bodyW = min(w, h*0.7f) — 태블릿 가로에서 portrait 비율 유지
- Sensor 이미지를 Canvas drawImage 로 이동 — bladder oval 좌표계와 정확히 정렬
- Start Alignment 버튼: enabled = true 명시

## Settings overlay
- "Ant Offset" 숫자 입력 필드 (0~20mm, dev mode 전용)
  · BV 계산 시 ant 를 입력값만큼 probe 쪽으로 당김 (chord 증가 → BV 증가)
  · mm→samples 변환은 PiezoHW.distancePerSample
  · V41 SphereFit BV 는 offset≠0 일 때 우회 → 6ch estimate
- "Version" row 추가 (BuildConfig.VERSION_NAME)
- Save 버튼: 실제 UserStorage 영구 저장 + state 재전파
  · AppState.savePiezoSettingsNow() 추가
- 전체 overlay 에 verticalScroll + Card maxHeight 90% — dev 컨텐츠 길어도 Save 도달

## DPS 동기화 (긴급 수정)
설정의 DPS 변경이 V41Detector(Geometry/AnatomicalGate)에 반영 안 되던 문제:
- WdConfig.DPS_DEFAULT: const val → @Volatile @JvmField var
- PiezoHW.distancePerSample setter 가 WdConfig.DPS_DEFAULT 자동 동기화
- 시작 시점 1.968.also { WdConfig.DPS_DEFAULT = it } 로 두 값 일치

## 버전
- versionName: VBTAND0101 → 2026005-101
- versionCode: 2 → 3

## 신규 모듈
- services/ScanLogStore.kt — dev mode 진단 로그 (마지막 Single Scan summary)
  · WALLS CSV (ch,ant,post,urine), DATA CSV (raw ADC), antOffsetMm
- ui/components/ScanLogDialog.kt — 클립보드 복사 다이얼로그
  · xbench (CharlesKWONsLaw) MbbLogDialog 패턴 차용
  · SelectionContainer + monospace + Copy/Clear/Close
- 측정 화면 dev panel 에 "Scan Log (N)" 버튼 추가

## 데이터 모델
- PiezoSettings.antOffsetMm: Int = 0 필드 추가

## 단위 테스트
- V41DetectorCH4Test.kt — 2026-05-06 floating-signal 캡쳐 6채널 raw 를
  V41Detector.detect 에 통과시켜 결과 출력 (CH4 가짜 wall 진단용)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 18:01:33 +09:00
dw.jang a1042b808c 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>
2026-05-11 17:43:39 +09:00
dw.jang ef38aa6eaf UI: 앱 아이콘 교체 + Placement 힌트 텍스트 정리
- 앱 아이콘: 방광이.png로 교체 (webp→png, adaptive-icon 제거)
- Placement: "Centering" → "Checking", "LR balanced. Final check" → "Final check"
- 모든 방향 힌트에 화살표(↑↓←→) 추가 — phaseProtected 시 아이콘 추론 보장
- 디바운스 중에도 directionIcon은 최신 guideResult로 갱신 (화살표 누락 수정)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 17:21:10 +09:00
dw.jang 2cfa56a06d UI: 페어링 다이얼로그 + 태블릿 폰트스케일 + Placement 힌트/버튼 확대
- DeviceScanView: 페어링 안내 다이얼로그 추가 (bonding 완료 대기 중 표시)
- PiezoMonitoringView: fontScale(screenWidth/360) 적용, 도넛 비율 조정,
  버튼 높이/텍스트 확대, InfoCard 폰트스케일, Void/Catheterization 텍스트
- PlacementGuideView: 힌트 카드 28sp + 패딩 확대, Start Alignment/
  Start Scanning 버튼 96dp + 28sp, 센서 BiasAlignment 0.55

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 16:25:01 +09:00
dw.jang ddd2f79380 UI text: revised 문서 반영 — 전체 텍스트 통일
[Placement]
- Alignment Complete → Start Scanning
- sensor → VesiScan (초기 안내)
- Raise/Lower the sensor → Slide up/down
- Move left/right → Slide left/right
- Fine-tune → Optimizing, Checking LR → Centering
- Optimal position! → In position!
- Position lost/detached → Restart above pubic bone.
- Past optimum → Too far, Lost signal → Signal lost

[Donut]
- Void/Catheterize → Voided/Catheterized
- Auto → Auto Scan, Stop → Stop Scan, Spot → Single Scan
- Voiding recorded → Recorded
- 한글 다이얼로그 → 영어 (Disconnect and remove pairing.)
- Sensor Position Issue → Position lost, Go to Alignment → Realign

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 13:58:27 +09:00
dw.jang 75b10c2f77 UI: 힌트 위치 이동 + 버튼 텍스트 + Alignment 비활성 + Bladder Capacity
#1 Placement 힌트 메시지: 몸 아래 → Step 아래/몸 위로 이동
#2 버튼 텍스트: Catheterize→Catheterization, Auto→Automatic, 글자 크기 UP
#3 Alignment Complete: GREEN(Optimal)일 때만 활성 (Skip과 차별화)
#4 Max Volume → Bladder Capacity (설정+Personalization 모두)
- Bladdy 도넛 내 위치 3% 위로 보정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 11:51:27 +09:00
dw.jang fab018f19e UI: 도넛차트 비율 기반 레이아웃 (태블릿 대응)
고정 dp → 화면 너비 비율:
- 도넛: 85% (dev: 65%), 선 두께: 도넛×8%
- Bladdy: 도넛×55% (dev: 30%)
- 볼륨 폰트: 화면×6%
- 패딩: 화면×5%, 간격: 화면×8%
- 버튼: 화면×15% (50~70dp clamp)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 11:02:51 +09:00
dw.jang 6287f21a05 fix: 센서 비율 기반 + LED 깜빡임 + 디바운스 + gated 체크
[Placement]
- 센서 이미지 비율 기반 (너비 35%, BiasAlignment 0.44) — 태블릿 대응
- LED 깜빡임 수정: greenHeld/failCount<3 동안 LED 5 안 보냄
- 디바운스: phaseProtected 중 lastHintChangeMs 안 건드림 (화살표 안 나오던 버그)
- Step 2 전환 힌트 항상 "Checking left/right balance..."
- GREEN에서 ch4/ch5 개별 탈락 시 방향 안내 (lrDev NaN 처리)

[도넛차트]
- Fill 카드: 윗줄 65%, 아랫줄 325/500 mL
- ml → mL 통일
- Spot 완료 시 displayMaxVolumeMl 즉시 갱신
- Auto 윈도우 < 5일 때 Current Measurement "—"

[기타]
- V41 gated 체크 + 최소 len≥3 (ungated 피크 안 보임)
- CCCD 실패(status 133) 500ms 후 1회 재시도
- 기기 스캔 사전순 정렬
- 힌트 점 순환 (./.../...)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 10:07:15 +09:00
dw.jang 5d687f7154 docs: add USER_GUIDE.md — 사용자용 상세 가이드
전체 사용 흐름 (연결→정렬→측정→배뇨기록) 단계별 안내
Placement 3-step 절차, Auto/Spot 측정, 설정, 트러블슈팅 포함

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 09:12:23 +09:00
dw.jang a7133a13ae feat: UI 대량 개선 + Placement 안정성 + BV 수정
[Placement]
- Start 버튼 필수 (자동 스캔 안 함)
- 화면 진입 시 전체 상태 리셋 (Step 2 직행 방지)
- Step 1 완료 조건: ch0~ch3 4개 전부 감지 필수
- Step 2 전환 시 "Checking left/right balance..." 3스캔 보호
- Step 전환 힌트 강제 유지 (phaseHoldHint)
- GREEN hold 7초 + 3회 연속 실패 후 이탈
- GREEN 이탈 시 스캔 중지 + Start 재시작 대기
- Detach 시 스캔 중지 + Start 버튼 표시
- 힌트 점 순환 (Raise.. / Raise... 업데이트 표시)
- 텍스트: "Raise the sensor up" 등 자연어
- 초기/재시작 시 화살표 제거
- Step 2 스킵 제거 (항상 3단계 순서)
- GREEN에서 ch4/ch5 개별 탈락 시 방향 안내
- gradient dead zone에 4채널 필수

[도넛차트]
- Max Volume 5초 간격 갱신
- Current Measurement / Fill 카드 (Fill = 65% + 325/500 mL)
- Auto 윈도우 < 5일 때 Current Measurement "—"
- Spot 완료 시 displayMaxVolumeMl 즉시 갱신
- ml → mL 통일
- Sensor Detached 상단 문구 제거
- 카테터 기본값 15개

[기능]
- Auto 2ch 미수신 5회 연속 → Realign 팝업
- Spot 간격 800ms→100ms (throttle이 보장)
- Auto Stop 버튼 깜빡임 해결
- Plot fallback 제거 (allWalls null이면 피크 안 보임)
- Pairing 미완료 시 다음 화면 차단
- 설정 패널 Save/Cancel 버튼
- 뒤로가기 앱 종료 확인

[코드 품질]
- Thread → coroutine (measureScope + Dispatchers.Default)
- mutableStateOf 메인 스레드 보장
- measureDoneSignal var→val mutableStateOf
- @Volatile (BleManager, GreenZoneConstants, PiezoHW)
- maa throttle deadlock 방지 (Boolean 반환)
- channelLogs allWalls 기준 통일

README v4 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 20:20:34 +09:00
dw.jang b97d3d8052 feat: 10건 UI 피드백 + Auto fail 팝업 + 텍스트 정리
#1 Sensor Detached 상단 문구 삭제 (urgency 메시지 항상 유지)
#2 Max Volume 5초 간격 갱신 (displayMaxVolumeMl)
#3 Fill/Level → Current Measurement/Fill
#4 detach 시 팝업→Placement 이동 (showRealignPrompt)
#5 Auto 2ch 이상 미수신 연속 5회 → 팝업 (바로 이동 아님)
#6 팝업 텍스트 "Sensor Position Issue" + 안내 문구
#7 Step2 진입 시 "Checking left/right balance..."
#8 detach 후 waitingForStart=true → Start 버튼 표시
#9 초기/재시작 안내 시 화살표 제거 (directionIcon="")
#10 Raise/Lower 텍스트 → "Raise the sensor up" 등 자연어

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 17:21:11 +09:00
dw.jang 8f2eb15af3 feat: Placement Start flow + Auto fail redirect + Spot 800ms
#1 Placement: 초기 "Place sensor, then press Start" 안내
   Start Alignment 버튼으로 스캔 시작 (자동 시작 안 함)
#2 GREEN 이탈 시 스캔 중지 + "Position lost, press Start" 재시작 대기
#3 Auto: 3회 연속 실패(채널 미수신/BV 불가) → Auto 중지 +
   "Sensor Alignment Required" 다이얼로그 → Go to Alignment
#4 Spot 간격 1500ms → 800ms (총 ~5초로 단축)

기타:
- Auto Stop 깜빡거림 해결 (enabled에서 isMeasuring 제거)
- 미부착 시 상단 배지 "Sensor detached" 빨간 표시
- 카테터 수 상단 바 표시 (탭→추가 팝업)
- Void 버튼 → 즉시 기록+감소 (팝업 없이)
- ch4/ch5 하나라도 빠지면 GREEN 해제 (lrPass 기본 false)
- GREEN hold 5초 + 이탈 시 Start over
- Placement Post Max 슬라이더 추가 (개발자 설정)
- 설정 패널 Save/Cancel 버튼

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 14:46:04 +09:00
dw.jang 38ab74369e UI: 8건 피드백 반영 + Spot 봉인 + 페어링 체크
[Placement]
#1 센서 위치 타원 중앙 (offset y=65dp)
#5 skin 색 항상 동일 (greenZone 분기 제거)
#6 화살표 센서 밖으로 (sensorHalfH + 20f 간격)
#8 GREEN 체크마크 제거
센서 크기 192x120dp (80%)

[Donut]
#2 상단 버튼 1.5배 (48/56dp)
#3 배터리 아이콘 Canvas 그리기 (충전량 바)
#4 도넛-카드 간격 2배 (32/40dp)
#7 Bladdy 정중앙 (matchParentSize + Arrangement.Center)

[기능]
- Spot 중 Auto/Void 버튼 봉인 (enabled=false)
- BLE 페어링(bonding) 완료 확인 후 다음 화면 (30초 대기)
- R-peak gate Gradient 모드 비활성화
- GREEN 디버그 로그 (cv/lrPass/rPeakOk)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 17:27:34 +09:00
dw.jang 72ccbdf102 fix: Thread→coroutine, PlacementGuideView 메인스레드 보장
- #2: PiezoMonitoringView raw Thread → measureScope.launch + Dispatchers.Default
  withContext(Main)으로 state 변경 보장, composable 떠나면 자동 취소
- #22: PlacementGuideView onMultiChannelComplete 콜백 → handler.post 감싸기
  BLE Binder 스레드에서 Compose state 직접 변경 → 메인 스레드 보장
- nested handler.post 제거, throttle 시 직접 state 리셋

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 16:30:19 +09:00
dw.jang 758930796f fix: critical code review — thread safety, state management
CRITICAL fixes:
- #1: lastMultiChannelResult 변경을 handler.post로 (메인 스레드 보장)
- #3: measureDoneSignal var=remember → val mutableStateOf (recomposition 안전)
- #34,35: BleManager bluetoothGatt/tx/rxCharacteristic/lastRxTimestamp @Volatile
- #66: GreenZoneConstants 모든 mutable var @Volatile
- #56: PiezoHW.distancePerSample @Volatile
- nested handler.post 제거 (불필요한 프레임 지연)
- maa throttle deadlock 방지 (Boolean 반환 + state 리셋)
- Plot/Log 불일치 수정 (channelLogs를 allWalls 기준으로 통일)
- Placement 센서 위치/화살표 조정, gradient dead zone, CV relaxation
- 개발자 모드 CV 표시, 가이드 상자 항상 표시

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 16:25:06 +09:00
dw.jang 0e0e04b6f5 fix: cross-channel outlier 제거 + placement 강화 + UI 수정
- Cross-channel urine length outlier: median의 1.35x 초과 또는 0.5x 미만 → 제거
  (CH3 바닥반사 urine=50 vs 정상 ~35 → 480ml↔223ml 편차 해결)
- Placement CV: V0=0.07, V1/V2=0.10 (기기별 분기)
- Placement 기준 강화: LR dev 0.20, gradient 0.3, lenVariation 0.35
- "방향OK→무조건GREEN" 제거, CV 미달시 "Fine-tune position"
- GREEN CV가이드/Hold steady 제거, ch별 len 분석 방향 안내
- 가이드 텍스트 상자 항상 표시
- 센서 이미지 topview 교체 (240×150dp)
- 앱 버전 VBTAND0101
- Plot/Log allWalls 통일 (선택 Method 기준)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 15:36:38 +09:00
dw.jang 6dd0ec5058 UI: 피드백 반영 — Placement/Donut/뒤로가기/토스트
[Placement]
- 복부 높이: 500dp→weight(1f) 유동, 스크롤 제거
- 화살표 크기: 50→70, head 20→28, stroke 7→9
- 6/6, 60% 비개발자 모드에서 제거
- Step indicator를 이미지 위로 이동

[Donut]
- Bladdy 크기: 80/110dp→120/150dp (비개발자)
- 도넛 크기: 260/320dp→300/360dp (비개발자)
- 볼륨 텍스트 배경 제거 (투명)
- 원 내부 흰색 반투명 배경 추가
- measuring 메시지 제거 (Auto 대기 중 표시 안 함)
- 배터리 옆 초록 connection dot 제거
- Volume 카드 제거, Fill/Level만 유지 (maxVolumeMl 기준)
- "빠른 저장"→"Quick Save" 영어 통일
- 측정 부족/미감지 토스트 제거

[기타]
- HOME 뒤로가기 → "Exit App?" 확인 다이얼로그

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 12:36:41 +09:00
dw.jang 414ce940a2 fix: maa 1초 throttle — BLE 계층에서 이중 전송 물리 차단
handler.post로 isMeasuring 갱신해도 Compose state 레이스 해결 안 됨.
BleManager에서 lastMaaSentMs 타임스탬프로 1초 이내 재전송 무조건 차단.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 12:27:58 +09:00
dw.jang 54bca199af fix: maa 이중 전송 방지 (BV_FAIL 근본 원인)
- isMeasuring=false를 handler.post로 메인 스레드 갱신
  (Thread 내 설정 → Compose state 지연 → 다음 measure() 통과 → maa 이중 전송)
- measure() 진입 시 isMeasuring 가드 추가 (중복 호출 방어)
- 채널 수신 로그 추가 (RECEIVED N channels)
- MTU 247 negotiation 추가 (reb: 208B 분할 전송 최소화)
- Spot 6ch 필터 추가 (allChannelsReceived)
- Auto Stop 시 값 유지 (재계산 안 함)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 11:59:13 +09:00
dw.jang c819d615d0 fix: LR 방향 수정 + Almost there 제거 + postMaxIdx 슬라이더
- 좌우 방향 전면 수정: ch4(왼쪽)길다→←, ch5(오른쪽)길다→→
  ch4만 감지→← (기기 오른쪽 치우침), ch5만→→
- Almost there 제거: 방향OK+CV미달 → 그냥 GREEN 통과
- postMaxIdx 런타임 슬라이더 (개발자 설정, 기본 80, 범위 50-95)
  Method A/B 공통 적용 — 바닥반사 peak 무시

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 09:41:44 +09:00
dw.jang b1ca5bfd66 fix: Auto Stop 최종 trimmedMean 반영 + Placement 채널소실 멘트
- Auto Stop 시 윈도우 전체 trimmed mean 계산 후 표시
- LATERAL/GREEN 중 center 채널 소실 → "Start over from above the pubic bone"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 18:04:24 +09:00
dw.jang e5b252b314 feat: Detection/BV 분리 설정 + Spot 5회 trimmedMean + UI 여유
- Detection(A/B/C)과 BV(Frustum/V41) 독립 설정 (개발자 모드)
  기본값: Detection=C, BV=V41
- Spot: 3회 median → 5회 1.5초간격 trimmed mean (Auto와 동일)
  최대 8회 재시도, 최소 유효 3개
- 일반 모드 도넛 320dp, 간격 28dp, 버튼 62dp (화면 여유)
- Placement mm 표시 제거 — 방향만 안내

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 17:28:04 +09:00
dw.jang 1b70ec809d fix: preset 감지 오류 (BV 2배 차이 근본원인) + 도넛 비율 + placement 자동통과
- autoDetectPreset: 기기이름 뒤에서 3번째 글자로 각도타입 판별
  VBT26050301 → '3' → V2 (기존: VBT2604 매칭 실패 → V0 → 각도 0° → BV 절반)
- 도넛차트: level 단계별 → maxVolumeMl/maxVolume 연속 비율로 변경
- Placement "Almost there" 3회 연속 → 자동 GREEN 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 16:13:13 +09:00
dw.jang b73921eb2b fix: UX feedback + BV ellipse outlier (#22) + README v3 update
- #1 배터리 최적화 페이지 이동 제거 (ForegroundService+WakeLock만)
- #2 Auto 첫 측정 대기 시 "Measuring... (n/5)" loading 표시
- #3 Placement 멘트 정리 — 방향만 남기기 (CH 언급 제거)
- #4 CH0~CH5 dot row 개발자 모드 전용
- #5 Spot 재시도 로직 (최대 6회, 유효 3개 목표, 300ms 간격)
- LR 좌우 조건 완화: ±8mm, symmetry≥0.5, lrDev≤0.35
- |len4-len5|≤10 → LATERAL 건너뛰고 바로 GREEN
- GREEN 미달 시 CV만 간당간당하면 GREEN 유지 ("Almost there...")
- CV 기본 임계 0.08→0.12, 디바운스 3초→1.5초
- BV 타원 피팅 outlier 반복 제거 (appshare #22)
- README v3 업데이트 (3모드 placement, BV 파이프라인, 상태표)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 15:36:14 +09:00
dw.jang 139ebcbbb1 refactor: BV estimation — y-z/x-z ellipse fitting, wall repair, outlier removal
Port of appshare #21 merge (bv_estimation.py):
- repairCenterWallsFor6ch: gap=1 보간, gap>=2 top 그룹 제거
- computeLrRatio: chord 비율 → x-z 6점 타원 피팅 (b_lr/a_ap)
- Post-median outlier 제거 (median ±25%, ≥3ch)
- Cap 높이: ellipseCapHeights 삭제 → y-z 8점 타원 피팅 inline
- Top cap 상한: 미검출 상위 채널 빔 y좌표 기준 제한

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 12:06:41 +09:00
dw.jang 53a07195f8 feat: developer mode, SWEEP placement, gradient guide, spot flicker fix
- Developer mode: 캐릭터 3탭 토글, dev-only settings/graphs/logs
- SWEEP placement (CKLaw): BladderSphereSeek circle fit + RTracker
  + argmax + coronal lateral + R-peak gate GREEN lock
- Gradient placement: weighted center gradient 기반 상하 판정,
  방향 로직 수정 (ch0=위, ch3=아래), 초기 멘트 "치골 위에 배치"
- Spot 측정: isSpotInProgress 플래그로 중간값 화면 깜빡임 제거
- 좌우 애매한 ↔ 멘트 제거 → 구체적 방향 또는 상태 안내

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 11:32:03 +09:00
dw.jang 4b74b88f76 refactor: placement body PNG → Canvas 실루엣 (CKLaw Bezier torso)
placement_body.png 제거, CKLaw BladderSeekScreen의 해부학적
Canvas 실루엣으로 교체 (갈비뼈, 배꼽, 치골 아치, hourglass torso).
sensor_device.png는 유지. 센서 위치 방광 타원 안쪽으로 조정.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 16:38:44 +09:00
dw.jang 9d64faf8cf UX: Placement UI 대폭 개선 — 센서 사진, 영어 멘트, 화살표 강화
이미지:
- 센서 사진(vesiscanbasicimage.png) 오버레이 (200×125dp)
- 전체 영역 500dp로 확대
- 타원 높이 절반 + 위쪽 경계 고정
- 센서 위치 미세 조정 (x+5dp)

화살표:
- 타원 바깥 경계에 부착 (gap=12)
- 두께 5→7, 머리 18→20, 색상 #FF5722
- 상하좌우 타원 경계 기준 위치

텍스트:
- 전체 영어화 (Gradually raise/lower, Move right/left 등)
- "Sensor Placement" → "Sensor Alignment"
- "Placement Complete" → "Alignment Complete"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 14:12:04 +09:00
dw.jang b4e2b21306 fix: 배터리 최적화 제외 요청 (Doze 면제, 삼성 대응)
- BLE 연결 시 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 다이얼로그 표시
- 이미 제외 상태면 스킵
- Manifest에 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 권한 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 12:30:54 +09:00
dw.jang 4357cb359a fix: 도넛 차트 maxVolume 복원 (최대값 유지, Volume 카드는 실시간)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 12:22:07 +09:00
dw.jang f3d3a9ce54 feat: 6ch 필터 + 도넛 확대 + Fill/Level 기준 변경 + 슬라이딩 윈도우
BV 계산:
- 6채널 모두 수신(buffer>=20) 시에만 BV 계산 (불완전 데이터 제외)

도넛 차트:
- 크기: compact 180→220dp, normal 240→280dp
- 선 두께: 20→22, 28→30dp
- 캐릭터: 70→80, 100→110dp
- 볼륨 텍스트: 16→18sp, maxVolumeMl → lastVolumeMl 표시

Info Cards:
- Fill: appState.fillPercentage → lastVolumeMl/maxVolume×100 (실측 기준)
- Level: appState.bladderLevel → lastVolumeMl/maxVolume×MAX_LEVEL
- 미측정 시 "—" 표시

Auto 측정:
- 배치 윈도우 → 슬라이딩 윈도우 (최대 10개 유지, 오래된 것 제거)
- 5개 이상이면 매 측정마다 trimmed mean 업데이트
- 이전: 10개 모이면 한 번에 업데이트 → clear
- 변경: [1,2,3,4,5]→출력, [2,3,4,5,6]→출력 (실시간 반영)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 12:13:10 +09:00
dw.jang 802b9b1822 feat: Placement 하복부 일러스트 이미지 + UI 개선
Placement:
- Canvas 실루엣 → 하복부 일러스트 PNG 배경 (투명 배경 처리)
- 방광+센서+화살표는 Canvas 오버레이 유지
- GREEN 진입/이탈 즉시 반영 (디바운스 무시)
- 좌측 라벨(가슴/배꼽/치골) 제거

Spot 측정:
- 3회 측정 중 화면 깜빡임 방지 (이전 값 유지, 최종 median만 표시)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 11:52:32 +09:00
dw.jang 4dd8d5382f fix: BLE 로그 실시간 파일 기록 (화면 잠금/앱 종료에도 보존)
BleDebugLogger:
- 매 entry마다 즉시 Downloads/VesiScan_BLE_*.log에 append
- 새 BLE 연결 시 새 파일 생성 + 헤더 기록
- 기존 메모리 내 로그 + UI 표시는 동일 유지
- 화면 잠금/Doze/앱 종료에도 로그 보존

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 18:06:55 +09:00
dw.jang 231ae1bf6d fix: Placement GREEN CV 기준 strict화
- DEFAULT_CV_THR: 0.10 → 0.08
- 완화: 0.05/8회 → 0.03/10회 (max 0.14)
- 초기 0.08, 10회 후 0.11, 20회 후 0.14

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 17:51:29 +09:00
dw.jang 502151b967 feat: Spot 3회 median + Placement 가이드 딜레이 3초
Spot:
- 1회 즉시 → 3회 연속 측정(200ms 간격) → median 표시
- 측정 중 로딩 인디케이터
- 2회 이상 유효 시 median 적용

Placement:
- 가이드 텍스트 최소 유지시간 4초 → 3초

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 17:20:32 +09:00
dw.jang 82634c2107 feat: Method C (V4.1) 대규모 업데이트 — 2-pass pipeline + ChordConsensus
새 알고리즘 모듈 (7개):
- ImpulseReject: 2-pass Hampel filter (lumen 내 impulse 제거)
- MedianFilter: running-median pre-filter (window=7, speckle 제거)
- MorphClose: morphological closing on lumen mask (disabled)
- StaLta: STA/LTA impulse detector (Allen 1978, wall edge vs reverberation)
- ChordConsensus: Tukey MAD outlier + Fischler-Bolles pair test
- DetectionSanity: detection sanity checks
- SweepStabilizer: sweep temporal stability

변경된 모듈 (9개):
- V41Detector: 2-pass pipeline (ImpulseReject.detectWithLumenClean),
  BModeScore V41_WEIGHTS (wamp+stalta), ChordConsensus filtering
- BvEstimation: ChordConsensus filter → trusted channel only
- DetectLumenFirst: running-median pre-filter, V41_PARAMS,
  mergeGapMax=5, Kremkau half-amplitude ant fallback
- AnatomicalGate: antDepthMin 22→10mm, strict threshold 제거
- BModeScore: V41_WEIGHTS (far=0.15, dark=0.10, wamp=0.45, stalta=0.20)
- WallSelect: MAX_PEAK_CANDIDATES_POST=64
- SpanUtils, Otsu, BvDispatchResult 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 17:01:55 +09:00
dw.jang d6e981e1d2 feat: 채널별 빔 각도 보정 (Python PR#20 동기화)
Method B:
- 채널별 otsu_ratio = OTSU_RATIO × cos(θ) 보정
- 큰 각도 채널은 threshold 완화 → 약한 후위벽 감지 개선
- detectLowEcho에 otsuRatioOverride 파라미터 추가
- analyzeMultiChannelWithTgc: initial + rerun 모두 각도 보정 적용

Method A:
- 채널별 min_wall_contrast_ratio = 1.2 × cos(θ) 보정
- detectMethodA에 contrastRatioOverride 파라미터 추가
- analyzeChannel에서 PiezoHW.degreeAll 기반 자동 계산

Monitoring:
- Detachment LED: 상태 변경 시에만 전송 (wasDetached 추적)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 16:32:31 +09:00
dw.jang 258bad9a26 feat: Foreground Service + Detachment 개선 + Placement 가이드 모드
Foreground Service (BleForegroundService.kt):
- BLE 연결 시 자동 시작, 해제 시 자동 중단
- PARTIAL_WAKE_LOCK (최대 4시간)
- Notification: "VesiScan - BLE 기기 연결 중..."
- connectedDevice foregroundServiceType
- Doze 모드에서도 BLE 통신 유지
- keepScreenOn도 유지 (추가 안전장치)

Detachment 개선:
- THR_MEAN/STD 100→30 (완전 탈착만 감지, 거리 약화 무시)
- 6채널 모두 수신됐을 때만 체크 (BLE 거리 문제와 구분)
- Placement: if(false) 제거 → 활성화 + "센서가 부착되지 않았습니다"
- Monitoring: 정상 복귀 시 LED OFF

Placement 가이드 모드:
- Simple (기본): 3+채널 → 바로 좌우 (기존)
- Boundary: 올라갔다 내려오기 패턴 (경계 감지 → 최적점 복귀)
- 설정 톱니바퀴에 Simple/Boundary 스위치

BLE 로그:
- 역순 표시 (최신이 위) — 스크롤 위치 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 16:09:54 +09:00
dw.jang 48df4370bc fix: Placement 그래프를 선택된 Method 결과로 통일
- 그래프 벽 표시: analyzer.analyzeChannel(B 고정) → lastWallResults(선택 Method)
- lastWallResults state 추가: 콜백에서 allWalls 저장 → 그래프에서 참조
- Method C 선택 시에도 V41Detector의 ant/post가 그래프에 정확히 표시
- dot 색상 + 그래프 벽 + depth mm 모두 동일 Method 결과 사용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 18:04:01 +09:00
dw.jang 3370fd8087 fix: 후면반사 오판방지 수정 + 1채널 구 BV 추가
BackReflection.kt (Python 동기화):
- consensusIdx: min_votes=3 (후보 3개 미만이면 None)
- buildCandidate: post≈global_br이면 None 반환 (post를 BR로 판단 안함)
- isSuspiciousPostPeak: post>ant → post>ant×1.5 (amp_ratio=1.5)
- isReflectionOnlyMultichannel: post>ant → post>ant×1.5

BV Estimation:
- 1채널 구(sphere) 계산 추가 (Python _single_channel_bv)
  - V = (4/3)πR³, R = D/2 (cos 보정)
  - centerWallCount >= 1이면 BV 계산 (기존 3 → 1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 17:42:30 +09:00
dw.jang 002a99d163 fix: Placement LED 단계별 1회만 + 화살표 확대 + 도넛뷰 detachment LED
Placement:
- LED 명령: 매 스캔 → 단계 변경 시 1회만 (lastLedMode 추적)
  - 5=SEARCHING, 6=COMPLETE, 화면 나갈 때 0=OFF
- 화살표 크기: arrowLen 40→60, arrowHead 12→18, strokeWidth 4→5

Monitoring (도넛뷰):
- 매 측정마다 DetachmentDetection.detect() 실행
- 미부착 감지 시 LED 4 (DETACH_WARNING) 전송 + 로그

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 17:29:37 +09:00