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>
This commit is contained in:
@@ -38,7 +38,7 @@ object GreenZoneConstants {
|
|||||||
* UrinAI의 liquidThrLoose(raw 기준)와 다름 — 여기는 TVD+SG 적용 후 신호 기준.
|
* UrinAI의 liquidThrLoose(raw 기준)와 다름 — 여기는 TVD+SG 적용 후 신호 기준.
|
||||||
* Python 원본: 1150 (low_echo_detection_method_b.py LOW_ECHO_AMP, 6ch 버전)
|
* Python 원본: 1150 (low_echo_detection_method_b.py LOW_ECHO_AMP, 6ch 버전)
|
||||||
* 영향: PiezoEchoAnalyzer → low-echo span 탐지, 벽 찾기의 기반 */
|
* 영향: PiezoEchoAnalyzer → low-echo span 탐지, 벽 찾기의 기반 */
|
||||||
const val lowEchoAmp: Float = 1150f
|
var lowEchoAmp: Float = 1150f
|
||||||
|
|
||||||
/** 구조 이진화 임계값: raw < 이 값 → 액체(liquid), ≥ → 조직(tissue).
|
/** 구조 이진화 임계값: raw < 이 값 → 액체(liquid), ≥ → 조직(tissue).
|
||||||
* 낮출수록 엄격 (더 확실한 액체만 인정), 높일수록 관대.
|
* 낮출수록 엄격 (더 확실한 액체만 인정), 높일수록 관대.
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ object PiezoHW {
|
|||||||
val degree: DoubleArray get() = centerCh.map { degreeAll[it] }.toDoubleArray()
|
val degree: DoubleArray get() = centerCh.map { degreeAll[it] }.toDoubleArray()
|
||||||
val degreeLR: DoubleArray get() = centerCh.map { degreeLRAll[it] }.toDoubleArray()
|
val degreeLR: DoubleArray get() = centerCh.map { degreeLRAll[it] }.toDoubleArray()
|
||||||
|
|
||||||
/** Acoustic calibration */
|
/** Acoustic calibration (런타임 조절 가능) */
|
||||||
const val distancePerSample: Double = 1.771 // mm/sample
|
var distancePerSample: Double = 1.771 // mm/sample
|
||||||
const val delayOffsetMm: Double = 6.85
|
const val delayOffsetMm: Double = 6.85
|
||||||
|
|
||||||
/** Volume model */
|
/** Volume model */
|
||||||
|
|||||||
+45
-3
@@ -42,6 +42,8 @@ import com.example.medilightv2android.ble.BleManager
|
|||||||
import com.example.medilightv2android.ble.PiezoChannelData
|
import com.example.medilightv2android.ble.PiezoChannelData
|
||||||
import com.example.medilightv2android.managers.PiezoEchoAnalyzer
|
import com.example.medilightv2android.managers.PiezoEchoAnalyzer
|
||||||
import com.example.medilightv2android.managers.PiezoConstants
|
import com.example.medilightv2android.managers.PiezoConstants
|
||||||
|
import com.example.medilightv2android.managers.GreenZoneConstants
|
||||||
|
import com.example.medilightv2android.managers.PiezoHW
|
||||||
import com.example.medilightv2android.managers.estimateBladderVolume6ch
|
import com.example.medilightv2android.managers.estimateBladderVolume6ch
|
||||||
import com.example.medilightv2android.models.BladderLevel
|
import com.example.medilightv2android.models.BladderLevel
|
||||||
import com.example.medilightv2android.models.UrgencyLevel
|
import com.example.medilightv2android.models.UrgencyLevel
|
||||||
@@ -624,7 +626,8 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
colors = CardDefaults.cardColors(containerColor = MlCardBackground),
|
colors = CardDefaults.cardColors(containerColor = MlCardBackground),
|
||||||
modifier = Modifier.shadow(8.dp, RoundedCornerShape(16.dp), spotColor = Color.Black.copy(alpha = 0.06f))
|
modifier = Modifier.shadow(8.dp, RoundedCornerShape(16.dp), spotColor = Color.Black.copy(alpha = 0.06f))
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding(20.dp)) {
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
// Catheterization Threshold
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Catheterization Threshold", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Catheterization Threshold", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
@@ -637,8 +640,47 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
steps = 8,
|
steps = 8,
|
||||||
colors = SliderDefaults.colors(thumbColor = MlPrimary, activeTrackColor = MlPrimary)
|
colors = SliderDefaults.colors(thumbColor = MlPrimary, activeTrackColor = MlPrimary)
|
||||||
)
|
)
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
// Low Echo Threshold
|
||||||
|
var currentThreshold by remember { mutableStateOf(GreenZoneConstants.lowEchoAmp) }
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text("Low Echo Threshold", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Text("${"%.0f".format(currentThreshold)}", fontSize = 14.sp, fontWeight = FontWeight.Bold, color = Color(0xFFFF9500))
|
||||||
|
}
|
||||||
|
Slider(
|
||||||
|
value = currentThreshold,
|
||||||
|
onValueChange = {
|
||||||
|
currentThreshold = it
|
||||||
|
GreenZoneConstants.lowEchoAmp = it
|
||||||
|
},
|
||||||
|
valueRange = 800f..2000f,
|
||||||
|
colors = SliderDefaults.colors(thumbColor = Color(0xFFFF9500), activeTrackColor = Color(0xFFFF9500))
|
||||||
|
)
|
||||||
|
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
// Distance Per Sample
|
||||||
|
var currentDps by remember { mutableStateOf(PiezoHW.distancePerSample.toFloat()) }
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text("Distance/Sample", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Text("${"%.3f".format(currentDps)} mm", fontSize = 14.sp, fontWeight = FontWeight.Bold, color = Color(0xFF4CAF50))
|
||||||
|
}
|
||||||
|
Slider(
|
||||||
|
value = currentDps,
|
||||||
|
onValueChange = {
|
||||||
|
currentDps = it
|
||||||
|
PiezoHW.distancePerSample = it.toDouble()
|
||||||
|
},
|
||||||
|
valueRange = 1.5f..2.5f,
|
||||||
|
colors = SliderDefaults.colors(thumbColor = Color(0xFF4CAF50), activeTrackColor = Color(0xFF4CAF50))
|
||||||
|
)
|
||||||
|
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
Text("Max Volume", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Max Volume", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
@@ -673,7 +715,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
BladdyRiveView(urgency = urgency, size = if (isCompact) 70.dp else 100.dp)
|
BladdyRiveView(urgency = urgency, size = if (isCompact) 70.dp else 100.dp)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
"${appState.estimatedVolume} ml",
|
if (lastVolumeMl > 0) "${"%.0f".format(lastVolumeMl)} ml" else "${appState.estimatedVolume} ml",
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
color = urgency.accentColor,
|
color = urgency.accentColor,
|
||||||
|
|||||||
Reference in New Issue
Block a user