From 86a9c79681cbe8658cca009dfde5d4246ba2c0e5 Mon Sep 17 00:00:00 2001 From: dongliang Date: Thu, 30 Apr 2026 17:50:48 +0930 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8A=A0=E9=80=9F=E5=BA=A6=E8=AE=A1?= =?UTF-8?q?=E8=A6=81=E6=B1=82=E8=BF=9E=E7=BB=AD3=E4=B8=AA=E9=AB=98?= =?UTF-8?q?=E5=80=BC=E6=89=8D=E8=A7=A6=E5=8F=91=EF=BC=8C=E9=98=B2=E6=91=86?= =?UTF-8?q?=E5=8A=A8=E5=B0=96=E5=B3=B0=E8=AF=AF=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实测小幅摆动时Z在-2~10间剧烈跳动,单个尖峰Z=10就触发了。 改为要求连续3个采样≥8(约0.6秒持续高值)才触发: - 真正抬手:Z稳定在8-9多个采样 → 连续3个≥8 ✅ - 小幅摆动:尖峰后立即回落 → 连续不到3个 ❌ Co-Authored-By: Claude Opus 4.6 (1M context) --- .../device/sensor/FiseAccelerometerWake.kt | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/xiaoqu/watch/device/sensor/FiseAccelerometerWake.kt b/app/src/main/java/com/xiaoqu/watch/device/sensor/FiseAccelerometerWake.kt index d8cc74e..45d19fa 100644 --- a/app/src/main/java/com/xiaoqu/watch/device/sensor/FiseAccelerometerWake.kt +++ b/app/src/main/java/com/xiaoqu/watch/device/sensor/FiseAccelerometerWake.kt @@ -42,6 +42,8 @@ class FiseAccelerometerWake @Inject constructor( private const val Z_MIN_THRESHOLD = 3f /** 方案C:当前值阈值,超过此值认为"手臂已明确抬起"(实测:放下过程Z≈5-7,抬起稳定Z≈8-9) */ private const val Z_CURRENT_THRESHOLD = 8f + /** 方案C:连续高值计数要求(需连续N个采样≥阈值才触发,防摆动尖峰误触发) */ + private const val HIGH_COUNT_REQUIRED = 3 /** 方案C:触发后冷却采样数(防连续触发,10个≈2秒) */ private const val COOLDOWN_SAMPLES = 10 } @@ -64,6 +66,8 @@ class FiseAccelerometerWake @Inject constructor( private var windowFilled = false /** 触发后冷却计数器 */ private var cooldownCount = 0 + /** 连续高值计数器(Z >= 阈值的连续采样数) */ + private var highCount = 0 /** * 开始监听传感器 @@ -138,13 +142,15 @@ class FiseAccelerometerWake @Inject constructor( // === 方案C 核心逻辑 === /** - * 最小值跳变检测 - * 追踪近期(最近5个采样≈1秒)的最小Z值: - * - 如果近期最小值 < 5(说明手臂曾经放下过) - * - 并且当前Z值 ≥ 7(说明手臂已抬起) - * → 判定为"抬手"动作 + * 最小值 + 连续高值检测 * - * 优点:只需一个低值采样即可触发,比均值方案灵敏得多 + * 两个条件同时满足才触发: + * 1. 近期5个采样中有值 < 3(手臂曾明确下垂) + * 2. 当前连续 3 个采样都 ≥ 8(手臂已抬起并稳定,非瞬间尖峰) + * + * 连续高值要求可区分: + * - 真正抬手:Z 稳定在 8-9 持续多个采样 → 连续 3 个 ≥ 8 ✅ + * - 小幅摆动:Z 在 0-10 间剧烈跳动,尖峰后立即回落 → 连续不到 3 个 ❌ */ private fun detectWristRaise(z: Float) { // 冷却期:刚触发过,等待冷却结束 @@ -153,7 +159,7 @@ class FiseAccelerometerWake @Inject constructor( return } - // 写入环形缓冲区 + // 写入环形缓冲区(追踪近期最小值) val pos = windowIndex % MIN_WINDOW_SIZE zWindow[pos] = z windowIndex++ @@ -163,6 +169,13 @@ class FiseAccelerometerWake @Inject constructor( } if (!windowFilled) return + // 更新连续高值计数 + if (z >= Z_CURRENT_THRESHOLD) { + highCount++ + } else { + highCount = 0 + } + // 找近期最小值 var recentMin = Float.MAX_VALUE for (i in 0 until MIN_WINDOW_SIZE) { @@ -170,14 +183,15 @@ class FiseAccelerometerWake @Inject constructor( } // DEBUG: 输出每次计算结果,用于调参(正式发布时删除) - Timber.v("抬手亮屏: Z=%.1f recentMin=%.1f (阈值: min<%.0f AND cur>=%.0f)", - z, recentMin, Z_MIN_THRESHOLD, Z_CURRENT_THRESHOLD) + Timber.v("抬手亮屏: Z=%.1f recentMin=%.1f highCount=%d (阈值: min<%.0f AND %d连续>=%.0f)", + z, recentMin, highCount, Z_MIN_THRESHOLD, HIGH_COUNT_REQUIRED, Z_CURRENT_THRESHOLD) - // 判断:近期有低值(手臂曾下垂)且当前值高(手臂已抬起) - if (recentMin < Z_MIN_THRESHOLD && z >= Z_CURRENT_THRESHOLD) { + // 判断:近期有低值(手臂曾下垂)且连续高值达标(手臂已稳定抬起) + if (recentMin < Z_MIN_THRESHOLD && highCount >= HIGH_COUNT_REQUIRED) { wakeScreenIfOff() - // 触发后进入冷却期 + 清空窗口 + // 触发后进入冷却期 + 清空状态 cooldownCount = COOLDOWN_SAMPLES + highCount = 0 resetWindow() } }