Commit Graph

20 Commits

Author SHA1 Message Date
dw.jang 45242f8256 tune(walking): default Start Wmean 4→15, Start Hold 1s→6s (사용자 실측 기준)
증상: 앉아있다 일어서기만 해도 walking false-trigger.

원인: 사용자 실측 데이터 분석 — stand-up + 자세 조정 motion 이 wmean
      5-10 dps 로 약 3-5초 지속. 이전 default (Start Wmean=4, Hold=1s) 는
      이 motion 을 walking 으로 잡음.

수정:
  Start Wmean: 4 → 15  (stand-up 의 typical wmean 보다 위)
  Start Hold:  1초 → 6초 (stand-up settling 보다 김)

근거:
  - 사용자 측정 stand-up motion: wmean 5-10 (저강도) ~ 100 (spike)
  - 진짜 보행 (body-mounted, 예상): wmean 50+ 지속
  - Hold 6초 — 정상 보행은 무한 지속이라 자동 만족, stand-up 은 5초 미만

비고:
  - 임계는 여전히 dev slider 로 조정 가능 (이전 commit 18a4cee)
  - 사용자별 / 디바이스별 튜닝 가능
  - 향후 periodicity check (FFT) 추가 시 임계 다시 완화 가능

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 12:29:14 +09:00
dw.jang 18a4cee00d feat(dev): 자세/walking 모든 임계 슬라이더 추가 (튜닝용)
사용자: walking 이 너무 예민하게 뜸. 모든 임계를 dev settings 에서 조절하고 싶음.

추가된 슬라이더 (Pitch Threshold 아래에 그룹별 정렬):

1) Posture
   - Pitch Threshold (lying ↔ non-lying)         기존
   - Poll Interval                                 기존

2) Walking Thresholds
   - Min Pitch (walking 인정 최소 pitch)           기존
   - Start Wmean (시작 평균 gyro)                  기존
   - Start Wstd (시작 표준편차)                    기존
   - Keep Wmean (유지 평균) — range 0.5~30 (이전 10) 신규 범위↑
   - **Start Hold** (시작 조건 hold 시간, 0.2~5초)  ⭐신규
   - **Keep Grace** (종료 grace 시간, 0.5~10초)     ⭐신규
   - **Window** (sliding window 크기, 0.5~5초)     ⭐신규

3) Acc Magnitude Gate
   - **Min** (UNKNOWN 하한, 0.3~1.0g)              ⭐신규
   - **Max** (UNKNOWN 상한, 1.0~3.0g)              ⭐신규

내부 변경:
  - GreenZoneConstants 에 postureAccMagMin/Max 추가
  - ImuPostureClassifier 의 const ACC_MAG_MIN/MAX → GreenZoneConstants 참조
    (런타임 변경 가능)

총 11개 슬라이더 — 사용자가 실측하며 튜닝 가능.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 11:37:46 +09:00
dw.jang ecdec7c97c feat(posture): Walking detector (flowchart Path B) + 2단계 알람
새 flowchart 의 walking 검출 추가:

1) Posture enum: UNKNOWN/LYING/NON_LYING + **WALKING** (4-state)

2) WalkingDetector.kt 신규 (flowchart Path B 구현)
   - Sliding window (default 1.5초) buffer 에 gyro magnitude 누적
   - 매 cycle 마다 wmean (이동평균) + wstd (이동표준편차) 계산
   - State machine:
     IDLE → WALKING:
       |pitch| > 45° AND wmean > 4 AND wstd > 2
       → 1초 이상 연속 만족 시 전이
     WALKING → IDLE:
       |pitch| > 45° AND wmean > 2
       → 미달 후 2초 grace 지나면 전이

3) GreenZoneConstants 에 walking 임계 7개 추가 (모두 dev 조정 가능):
   - walkingMinPitchDeg=45, walkingStartWmean=4, walkingStartWstd=2,
     walkingStartHoldMs=1000, walkingKeepWmean=2, walkingKeepHoldMs=2000,
     walkingWindowMs=1500

4) PiezoMonitoring:
   - walkingDetector 인스턴스
   - imuCollector.onComplete: classifier + detector 동시 호출,
     composite posture (WALKING > NON_LYING > LYING) 결정
   - NON_WALKING → WALKING 전이 시 critical 알람 trigger

5) UI:
   - 상단 status bar: Walking 아이콘 (DirectionsWalk, 빨강) 추가
   - 기존 wakeup 팝업 색: 빨강 → 주황 (warning level)
   - 신규 walking 팝업: 빨강 + DirectionsWalk + "환자가 걷고 있습니다 — fall risk"

6) Dev settings: walking 임계 슬라이더 4개 추가
   (Min Pitch / Start Wmean / Start Wstd / Keep Wmean)
   sliding window / hold 시간은 default 유지 (필요 시 추가)

2단계 알람 체계 (의료적):
  - 주황 (warning): LYING N초 → NON_LYING/WALKING 전이 (일어남 감지)
  - 빨강 (critical): NON_WALKING → WALKING 전이 (보행 시작 — fall risk 최고)

Tag phase2-pre-walking (28a8769) 이전 상태로 복원 가능.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 10:28:43 +09:00
dw.jang 28a8769fa3 tune(posture): default polling 3s → 1s (실시간 자세 감지)
낙상 예방 시나리오상 자세 변화 즉시 감지 중요 → 1초 polling 으로 단축.
canSendMaa() 500ms throttle + mtb 응답 ~400ms 이라 1초가 사실상 한계.
사용자가 slider 로 더 늦출 수도 있음 (1~15초 범위).

BLE 부담: device active ~40% (mtb 한 cycle ≈ 400ms × 매초).
배터리 영향은 짧은 모니터링 세션 (수십분~수시간) 수준에선 무시 가능.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 09:20:32 +09:00
dw.jang 0bb484ae45 feat(posture): Poll Interval 슬라이더 + default 10s → 3s
증상: 자세 갱신이 10초마다라 너무 느림. 빠르게 테스트하고 싶음.

수정:
  1) GreenZoneConstants.posturePollIntervalMs (default 3000ms) 신규
     - polling loop 의 delay(10000) → delay(GreenZoneConstants.posturePollIntervalMs)
     - 슬라이더 변경 즉시 다음 iteration 부터 적용

  2) PiezoMonitoring dev settings: Poll Interval 슬라이더 추가
     - 위치: Lying Duration 슬라이더 바로 아래
     - 범위: 1초 ~ 15초 (연속)
     - 표시: "X.X초"
     - 변경 시 GreenZoneConstants 에 즉시 반영

default 변경: 10초 → 3초.
  - mtb 한 cycle ≈ 400ms, 3초 polling = device 활동 ≈ 13% (가벼움)
  - 1초까지 줄여도 캐싱/throttle 충돌 거의 없음 (canSendMaa 500ms gate)

BLE 부담 vs 응답성 trade-off:
  | interval | 1시간 device 사용 | 자세 변화 최대 지연 |
  |   1초    |     ~24분 (40%)   |     ~1초           |
  |   3초    |     ~8분 (13%)    |     ~3초           |
  |   5초    |     ~5분 (8%)     |     ~5초           |
  |   10초   |     ~2.5분 (4%)   |     ~10초          |

낙상 예방엔 1-3초가 적정. 평상시 사용엔 5-10초.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 09:14:32 +09:00
dw.jang af469558e6 feat(posture): Phase 2 — 기상 알람 (LYING/NON_LYING + Settings 토글 + 빨간 팝업)
요구사항: 설정 탭에서 알람 on/off → on 상태에서 일어남 감지 시 빨간 팝업.

변경:

1) ImuPostureClassifier 2-state 단순화
   - 기존: SUPINE/SITTING/STANDING (3 state)
   - 신규: LYING / NON_LYING (2 state) + UNKNOWN
   - sitting/standing 구분 불필요 (낙상 예방엔 "누웠나/일어났나" 만 중요)
   - 분류: |pitch| > threshold → LYING, ≤ → NON_LYING

2) GreenZoneConstants.pitchLyingThreshold (default 25°)
   - @Volatile var — runtime 변경 가능
   - dev 모드 설정에서 slider 로 조정 (10~70°, 11 steps)

3) WakeupAlarmPrefs — SharedPreferences 저장
   - isEnabled (default false)
   - lyingDurationSec (default 180 = 3분)

4) WakeupDetector — state machine
   - LYING 진입 시 timestamp 기록
   - LYING → NON_LYING 전이 시 elapsed 측정
   - elapsed ≥ lyingDurationSec 이면 onWakeup 콜백
   - 1회 발동 후 LYING 복귀까지 재무장 안 됨 (스팸 방지)
   - UNKNOWN 은 무시 (motion artifact 흔들림 영향 X)

5) PiezoMonitoringView
   - posture 아이콘 매핑 LYING (Hotel, 파랑) / NON_LYING (AccessibilityNew, 초록) / UNKNOWN
   - imuCollector.onComplete 콜백에서 wakeupDetector.update(posture) 호출
   - showWakeupAlarm Boolean state + 빨간 Dialog (Color 0xFFD32F2F)
     · Warning 아이콘 + "환자가 일어났습니다" 메세지
     · 누운 시간 표시
     · 확인 버튼 (사용자 dismiss 필수, 자동 닫힘 X)
     · dismissOnBackPress/ClickOutside = false (실수 dismiss 방지)
   - Demo 모드: posture LYING 고정 (BLE 없음)

6) PiezoPersonalizationView — WakeupAlarmCard 신규
   - 빨간 톤 카드 + Switch
   - "기상 알람 — 환자가 일어나면 빨간 팝업으로 알림 (낙상 예방)"
   - 토글 즉시 WakeupAlarmPrefs.setEnabled

7) Dev 설정 (PiezoMonitoringView 의 dev panel)
   - "Pitch Threshold" 슬라이더 추가 (10°~70°)
   - GreenZoneConstants.pitchLyingThreshold 직접 조정
   - 실시간 반영 — 다음 cycle 부터 적용

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 17:17:58 +09:00
dw.jang 718016af7a feat: V2 alignment (Method D + alignment.py) demo-final 에 이식
feature/tab-navigation 의 V2 코드를 demo-final 로 가져와 임상 alignment session
에서 V1/V2 둘 다 선택 가능하도록.

복사된 파일 (feature/tab-navigation 그대로):
  walldetect/algo/SgSmoothGeneric.kt
  walldetect/algo/methodd/MethodDParams.kt
  walldetect/algo/methodd/MethodDPreprocessing.kt
  walldetect/algo/methodd/MethodDSpan.kt
  walldetect/algo/methodd/MethodDWallSelect.kt
  walldetect/algo/methodd/MethodDTgc.kt
  walldetect/MethodDDetector.kt
  walldetect/MethodDRunner.kt
  managers/AlignmentAdvisorV2.kt
    (RollingAligner + AlignGuide4Stage + AlignmentAdvice — alignment.py 1:1)

확장:
  walldetect/algo/Otsu.kt
    + otsu1dWithSeparability(values) — Python otsu_1d 의 (threshold, sep) tuple 호환
    method_d span fallback gate 에서 사용

  managers/GreenZoneConstants.kt
    + enum AlignmentAlgo { V1, V2 }
    + @Volatile var alignmentAlgo: AlignmentAlgo = V1 (default = legacy)

  ui/views/monitoring/PlacementGuideView.kt
    + val v2Aligner = remember { RollingAligner() }
    + V2 분기 (alignmentAlgo == V2 시): raw 6ch → push → state(accum/commit)
      → directionHint/directionIcon/placementScore/LED 설정
      → bleManager.debugLogger.info("ALIGN_V2 phase=... state=... bestSet=...")
    + ⚙ Settings overlay 에 V1 (legacy) / V2 (new) 토글 (보라색)
    + addAlignmentFrame 호출 시 V2 활성이면 v2Aligner.phase.name 사용 (4-stage)

  ui/views/clinical/ClinicalHomeView.kt
    + ClinicalSession.alignmentAlgo 를 현재 GreenZoneConstants.alignmentAlgo 값으로 채움
      (이전 demo-final 은 "V1" 하드코딩)
    → V2 토글 후 Sensor Alignment 진입 시 alignment_algo="V2" 가 json 에 기록

영향:
  - 기존 V1 동작 그대로 (default 가 V1, 토글 안 하면 동일)
  - V2 선택 시 demo-final 에서도 4-stage 진행 가능 + json 라벨 V2 명시
  - 알고리즘 토글은 dev 모드 (⚙ 버튼) 에서만 가능 — 일반 사용자 노출 X

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-17 14:03:34 +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 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 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 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 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 e528bc6761 fix: Python 대조 CRITICAL 10건 수정 (Method A/B 완전 동기화)
Method B:
- #1 Otsu: limit 제거 → 전체 신호로 계산
- #2 detectLowEcho: 2단계 fallback (Otsu→None이면 고정1250 재시도)
- #3 LOW_ECHO_AMP: 1150 → 1250
- #4 low mask: analysisLimit 제한 제거 → 전체 신호 마스킹
- #5 postH >= threshold 체크 제거 (Python에 없음)
- #6 merge gap < 3: 무조건 병합 (peak_check_min_gap=3)
- #7 TGC: raw fit → log 압축 후 fit (Python fit_attenuation_lines 동일)
- #8 Back reflection: 다채널 consensus → 채널별 개별 (Python pipeline.py 동일)

Method A:
- #9 sliding_scores_1d low quantile: floor index → np.quantile 선형 보간
- #10 score_thr: 중간값 근사 → np.quantile(0.5) 선형 보간
- npQuantile() 헬퍼 함수 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 14:33:58 +09:00
dw.jang 6614e915d6 feat: Method B TGC+FP필터, Placement UI 리디자인, 네비게이션 개선
Method B 알고리즘 (Python 동기화):
- TGC 파이프라인: applyTgc (감쇠 보상, adaptive ratio)
- 후면반사 제거: findBackReflectionIdx + suppressBackReflection
- 멀티채널 합의: findBackReflectionMultichannel (median)
- FP 필터: wallMin/lowMean < 1.15, score < 3000
- peakMin: max(lowMean+margin, threshold)
- Otsu: separability 반환 + OTSU_RATIO(0.85) + fallback(sep<0.3)
- urineLen: post-ant → post-ant-1 (Python 동기화)
- ant fallback: span 시작 직전 (단조 감소 대응)

Placement UI 리디자인:
- 상반신 일러스트 (Canvas: 몸통+배꼽+치골+방광+센서+화살표)
- Green Zone: 배경 animateColorAsState 전환 + 체크마크
- 가이드 순서: 치골→위로→CH0 안잡히면 아래로→좌우 대칭
- 디바운스 4초 유지, 힌트 텍스트 Green시 초록
- 좌우 힌트: CH4/CH5 비교 기반 방향 제시
- 설정 톱니바퀴 + floating 패널 (Method A/B/C + Otsu)
- 채널 dot row 별도 배치
- Green score: CV 0.10, LR dev 0.25 (엄격화)

도넛차트 UI:
- Max Vol 카드 제거 (4→3칸), InfoCard 높이 통일
- Void/Catheterize 버튼 (2줄, 56dp)
- Quick Save: 실제 측정값 표시 + volume 0 리셋
- 기본 Method C

네비게이션:
- Placement 뒤로가기 → 연결중이면 Monitoring (Home 안감)
- Home Start → 연결중이면 바로 Monitoring (DeviceScan 스킵)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 16:56:51 +09:00
dw.jang c9cd3cb3ce feat: Method C (V4.1 CharlesKWON) 통합 + Placement 설정 패널
Method C (walldetect/ 패키지, 38파일):
- V41Detector: OS-CFAR threshold + wavelet denoise + anatomical gate + B-mode score
- Multi-method BV dispatch: frustum(≥2ch) / Verathon(1ch) / sphere fit(cross-check)
- Kasa→LM sphere fitting, sub-sample parabolic refinement
- 패키지 이동: com.medithings.charleskwonslaw → com.example.medilightv2android

통합:
- 설정 UI: A/B 스위치 → A/B/C 버튼 그룹 (A=보라, B=파랑, C=주황)
- Monitoring: Method C 선택 시 V41Detector.detect() → BV dispatch 결과 사용
- Placement: 선택된 Method(A/B/C) 반영 + 톱니바퀴 설정 패널 추가

Placement 그래프 개선:
- Threshold 수평선 (주황 점선)
- Y축 눈금 (0, 1k, 2k)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 11:06:22 +09:00
dw.jang c849943b4e feat: Otsu adaptive threshold, Method A 포팅, BV ellipse cap, UI 정리
Algorithm:
- Otsu 1D adaptive threshold 포팅 (span_utils.py otsu_1d, 기본 ON)
- Method A 벽 검출 포팅 (PiezoEchoAnalyzerA.kt: plateau score + prominence)
- Method A cross-validation (채널간 중앙값/gradient 보정)
- BV cap 높이: parabolic → ellipse 피팅 (8점 축정렬 타원)
- Bottom cap: sphere, Top cap: cone (Python bv_estimation.py 동기화)
- 설정에 Method A/B 토글 (왼쪽=A, 오른쪽=B)

Logging:
- BLE 로그 + CSV에 otsu threshold 값 기록
- 측정 로그에 method label (A/B) 표시

UI:
- 설정 패널: floating overlay로 변경 + MaxVolume 슬라이더 추가
- Onboarding: 1페이지로 단순화 (Pager/indicator 제거)
- Registration: 한 페이지에 전체 입력 + Skip 버튼
- Placement: 로딩 인디케이터/스캔 텍스트 삭제

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:43:56 +09:00
dw.jang f391f404b4 feat: Settings에 Low Echo Threshold + Distance/Sample 슬라이더 추가
1. Low Echo Threshold: 800~2000 슬라이더 (기본 1150, 주황색)
   → GreenZoneConstants.lowEchoAmp 런타임 변경
   → CH4/CH5 threshold 조절로 lateral 감지 개선

2. Distance/Sample: 1.5~2.5mm 슬라이더 (기본 1.771, 초록색)
   → PiezoHW.distancePerSample 런타임 변경
   → 기기별 캘리브레이션 가능

3. 도넛차트 ml 실시간 표시: estimatedVolume → lastVolumeMl 직접 표시
   → 측정 즉시 정확한 ml 반영 (기존: 레벨 변환 후 재계산으로 지연)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 16:50:31 +09:00
dw.jang 98d3b11a46 docs: Python↔Android 1:1 검증 결과 + BLE 재연결 시스템 상세 문서화
- 전수 상수 비교 테이블 (V0/V1/V2 좌표, 각도, 음향 상수, lr_ratio)
- 알고리즘 수준 비교 (전처리, low-echo, lr_ratio, BV 추정)
- 결론: 모든 항목 완벽 일치 (Adaptive TGC는 Python에도 미포함)
- BLE 재연결 시스템 흐름도 + Watchdog + GATT 에러 경로 설명
- BLE 디버그 로거 사용법
- GreenZoneConstants.kt 주석 오류 수정 (1600→1150)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 16:18:49 +09:00
dw.jang c114592ab1 feat: 6ch 알고리즘 포팅 + urineLen 기반 정밀 Placement Guide
6ch 알고리즘 (config_6ch.py / bv_estimation.py 포팅):
- PiezoHW: V0/V1/V2 프리셋 (Snell's law 굴절 각도)
- computeLrRatio(): CH4/CH5 lateral에서 타원 단면 비율 동적 계산
- estimateBladderVolume6ch(): center 4ch + lateral lr_ratio
- denoise(): TVD 제거, SG 필터만 사용
- LOW_ECHO_AMP: 1600→1150, distancePerSample: 1.771

Placement Guide 2단계:
- 1단계: 이진 판정 (잡힘/안잡힘) → 기본 방향
- 2단계: urineLen 기반 정밀 가이드 (대칭+균형+크기)
  - 세로: CH0/CH3 비율 1.5배 이상이면 방향 제시
  - 가로: CH4/CH5 차이 5칸 이상이면 방향 제시
- Placement Score = 세로대칭(30%) + 가로균형(30%) + 중앙크기(40%)
- 각 채널에 urineLen 숫자 표시

VesiScan_Android_Pipeline_Summary.md 문서 작성

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 10:22:57 +09:00
dwjang c1c6dfc16a feat: port algorithm core from iOS (4 files)
GreenZoneConstants.kt — all 16 constants (thresholds, physical)
UrinAI.kt — urine gatekeeper (binary threshold detection)
PiezoEchoAnalyzer.kt — low-echo detection with prominence-based wall selection
PiezoBVEstimator.kt — Frustum BV estimation with device presets

1:1 port from Swift, same logic, same constants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 16:14:07 +09:00