diff --git a/app/src/main/java/com/example/medilightv2android/managers/ImuPostureClassifier.kt b/app/src/main/java/com/example/medilightv2android/managers/ImuPostureClassifier.kt index fbfcbdd..e35b9f4 100644 --- a/app/src/main/java/com/example/medilightv2android/managers/ImuPostureClassifier.kt +++ b/app/src/main/java/com/example/medilightv2android/managers/ImuPostureClassifier.kt @@ -59,20 +59,22 @@ object ImuPostureClassifier { val accMag = sqrt(ax * ax + ay * ay + az * az) val gyroMag = sqrt(gx * gx + gy * gy + gz * gz) + // Pitch 는 acc gate 통과 여부와 무관하게 항상 계산 (walking detector 가 사용). + val pitchPre = (atan(ax / sqrt(ay * ay + az * az)) * 180.0 / Math.PI).toFloat() + if (accMag < ACC_MAG_MIN || accMag > ACC_MAG_MAX) { - return Result(Posture.UNKNOWN, 0f, accMag, gyroMag, + return Result(Posture.UNKNOWN, pitchPre, accMag, gyroMag, "acc mag out of range (%.2f)".format(accMag)) } // Gyro gate 제거 — bias 큰 디바이스에서 영구 fail 문제 (위 주석 참조) - val pitch = (atan(ax / sqrt(ay * ay + az * az)) * 180.0 / Math.PI).toFloat() - val absPitch = abs(pitch) + val absPitch = abs(pitchPre) val thr = GreenZoneConstants.pitchLyingThreshold // Pitch 의미: AX 가 중력과 일치할수록 큰 값 (≈90°), AZ 가 중력과 일치하면 작은 값 (≈0°). // 사용자 직관: 센서 평평하게 둠 (AZ up) = LYING, 세움 (AX up) = NON_LYING (upright). // → 작은 pitch → LYING, 큰 pitch → NON_LYING val posture = if (absPitch <= thr) Posture.LYING else Posture.NON_LYING - return Result(posture, pitch, accMag, gyroMag, "ok") + return Result(posture, pitchPre, accMag, gyroMag, "ok") } } 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 a13c319..7e25a64 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 @@ -725,10 +725,10 @@ fun PiezoMonitoringView(appState: AppState) { val walkSnap = walkingDetector.update(samples, r.pitchDeg, nowMs) val isWalkingNow = walkSnap.isWalking - // Composite posture — WALKING 이 NON_LYING 보다 우선 + // Composite posture — WALKING 이 UNKNOWN/NON_LYING 보다 우선 (자체 게이트 신뢰) val composite = when { - r.posture == com.example.medilightv2android.managers.Posture.UNKNOWN -> com.example.medilightv2android.managers.Posture.UNKNOWN isWalkingNow -> com.example.medilightv2android.managers.Posture.WALKING + r.posture == com.example.medilightv2android.managers.Posture.UNKNOWN -> com.example.medilightv2android.managers.Posture.UNKNOWN else -> r.posture // LYING or NON_LYING }