diff --git a/app/src/main/java/com/example/medilightv2android/managers/GreenZoneConstants.kt b/app/src/main/java/com/example/medilightv2android/managers/GreenZoneConstants.kt index e5376eb..282ea23 100644 --- a/app/src/main/java/com/example/medilightv2android/managers/GreenZoneConstants.kt +++ b/app/src/main/java/com/example/medilightv2android/managers/GreenZoneConstants.kt @@ -41,6 +41,17 @@ object GreenZoneConstants { @Volatile var detectionMethod: DetectionMethod = DetectionMethod.METHOD_C @Volatile var bvMethod: BvMethod = BvMethod.V41 + + /** + * lr_ratio 강제 override (algorithm 팀 최신 표준: piezophantomtest 4830e7c). + * - null : computed (기존 Python `compute_lr_ratio` 알고리즘) + * - Double : 강제 값 (algorithm 팀 default = 1.0) + * + * Phantom 실측 검증: computed lr=0.68 → BV -38%. lr=1.0 fixed → -1.6% (APP 일치). + * 6채널 hardware LR 분해능 한계로 computed lr 신뢰도 낮음. Dev toggle 전환 가능. + */ + @Volatile var lrRatioOverride: Double? = 1.0 + @Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE @Volatile var alignmentAlgo: AlignmentAlgo = AlignmentAlgo.V1 // default V1 (일반 사용자). V2 (Method D) 는 clinical alignment session 전용. diff --git a/app/src/main/java/com/example/medilightv2android/managers/PiezoBVEstimator.kt b/app/src/main/java/com/example/medilightv2android/managers/PiezoBVEstimator.kt index 3c173ac..9bc385d 100644 --- a/app/src/main/java/com/example/medilightv2android/managers/PiezoBVEstimator.kt +++ b/app/src/main/java/com/example/medilightv2android/managers/PiezoBVEstimator.kt @@ -398,7 +398,10 @@ fun estimateBladderVolume6ch( var centerWalls = PiezoHW.centerCh.map { if (it < allWalls.size) allWalls[it] else null } centerWalls = repairCenterWallsFor6ch(centerWalls) val lateralWalls = PiezoHW.lateralCh.map { if (it < allWalls.size) allWalls[it] else null } - val lrRatio = computeLrRatio(centerWalls, lateralWalls, sensorZMm = PiezoHW.sensorZMmAll) + // 2026-07-01: algorithm 팀 최신 표준 (piezophantomtest 4830e7c) — lr_ratio_override=1.0 + // Phantom 검증: computed lr 은 6채널 HW 한계로 -38% 오차. Dev panel 로 전환 가능. + val lrRatio = com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride + ?: computeLrRatio(centerWalls, lateralWalls, sensorZMm = PiezoHW.sensorZMmAll) return estimateBladderVolume( walls = centerWalls, lrRatio = lrRatio, diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index ee32b4d..3f637d2 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -1905,6 +1905,24 @@ fun PiezoMonitoringView(appState: AppState) { HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding)) + // 2026-07-01: lr_ratio override (algorithm 팀 4830e7c 표준) + var lrFixed by remember { + mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride != null) + } + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { + Text("lr=1.0 fixed", fontSize = labelSize, fontWeight = FontWeight.SemiBold) + Spacer(modifier = Modifier.weight(1f)) + Switch(checked = lrFixed, + onCheckedChange = { + lrFixed = it + com.example.medilightv2android.managers.GreenZoneConstants.lrRatioOverride = + if (it) 1.0 else null + }, + colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary)) + } + + HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding)) + // SG Filter var sgEnabled by remember { mutableStateOf(analyzer.useSgFilter) } Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {