说明文档及下载链接
一、加速度信号处理优化(MainActivity.kt)
1.1 滑动窗口缩小
windowSize: 10 → 6
缩小滑动窗口至约 120ms(6 帧),最大限度保留不到 1s 的轨道冲击峰值。
1.2 全局增益(baseGain)
在 InspectorState 中新增 baseGain 参数,默认值 1.5,可持久化到 SharedPreferences。在传感器计算中:
val totalGainV = s.scaleZ * s.baseGain
val totalGainH = s.scaleX * s.baseGain
与 Scale 参数叠加,增益可独立调节。
1.3 filterAlpha 默认值提高
filterAlpha: 0.6 → 0.65
加速指数平滑的响应速度,使 UI 显示值更接近真实峰值。
1.4 UI 峰值保持机制
新增 uiPeakV / uiPeakH 变量,500ms 窗口内保持加速度峰值:
// 500ms 重置一次
if (currentTime - lastPeakResetTime > 500) {
uiPeakV = abs(filteredZ); uiPeakH = abs(filteredX)
lastPeakResetTime = currentTime
} else {
uiPeakV = max(uiPeakV, abs(filteredZ))
uiPeakH = max(uiPeakH, abs(filteredX))
}
仪表盘显示峰值而非瞬时值。
二、坐标库清理算法修复(MainActivity.kt: autoCleanupLibrary)
2.1 去重 Key 增加方向维度 + 放宽精度
修复前:"%.6f,%.6f"(6位小数,无方向)
修复后:
val key = String.format(Locale.US, "%s|%s|%.5f,%.5f",
ref.lineName, ref.lineDirection, ref.latitude, ref.longitude)
- 增加
lineName和lineDirection→ 双向共用车站不误删 - 6 位小数 → 5 位小数(约 1m) → 隧道航推坐标可正确去重
2.2 锚点优先保留策略
if (ref.isAnchor && !existing.isAnchor) {
toDelete.add(existing.id) // 锚点替换非锚点
seenCoords[key] = ref
} else {
toDelete.add(ref.id) // 否则删除当前
}
同坐标点中锚点优先保留,非锚点重复删后到的。
2.3 上行方向单调性修复 + 反转遍历
修复前:不分方向,ORDER BY mileageValue ASC 遍历,上行 K0→K141 递增 → 反向数据全误删
修复后:
val isUpbound = (direction == "上行")
var lastValidMileage = if (isUpbound) Double.MAX_VALUE else -1.0
val pointsToProcess = if (isUpbound) refs.reversed() else refs // 反转遍历
上行反转后按 K141→K0(递减)遍历,检查逻辑变为"里程变大则为污染"。下行/单线逻辑不变(递增检查)。
2.4 增加无效坐标检查
val isInvalid = (point.latitude == 0.0) || ...
2.5 单线处理
单线走下行分支(isUpbound = false),里程递增检查通过即可。正反采集数据都能保留,去重由第一遍坐标去重兜底。
三、GPS 丢失-恢复校正(InspectorService.kt)
3.1 修复 GPS 恢复纠偏算法
修复前:用速度×时间推算里程差(恒速假设,加减速→误差累积)
val estimatedAtRestore = if (s.lineDirection == "上行")
gpsLostStartMileage - (lastValidSpeed * 3.6f * dtHours)
else
gpsLostStartMileage + (lastValidSpeed * 3.6f * dtHours)
updateSavedRecordsWithOffset(..., mVal - estimatedAtRestore, ...)
修复后:直接对比 GPS 恢复后的真实里程与最后一个航推值
val totalOffset = mVal - lastValidMileage
updateSavedRecordsWithOffset(..., totalOffset, ...)
3.2 新增加速度积分航推(UI 显示用)
新增 5 个变量:
| 变量 | 作用 |
|---|---|
gpsSpeedAtLoss |
GPS 丢失时的末次速度(m/s) |
estimatedIntegralSpeed |
积分推定速度(m/s) |
filteredLongitudinalAcc |
低通滤波后的纵向加速度(m/s²) |
longitudinalAccAlpha |
低通系数 0.12 |
lastAccelTimestamp |
上次加速度时间戳 |
逻辑:GPS 丢失时在 onSensorChanged 中,用带符号的横向加速度 finalH × 9.81 经 α=0.12 滤波后积分更新速度:
filteredLongitudinalAcc = (1 - α) × filteredLongitudinalAcc + α × (finalH × 9.81)
estimatedIntegralSpeed += filteredLongitudinalAcc × dt
速度限制在 0120m/s(0432km/h)。
3.3 航推定时器使用积分速度
if (lastValidSpeed > 0.5f || (isGpsLost && estimatedIntegralSpeed > 0.5f)) {
val currentSpeed = if (isGpsLost) estimatedIntegralSpeed.toDouble() else lastValidSpeed.toDouble()
val displacementMeters = currentSpeed * (dtMillis / 1000.0)
...
}
GPS 丢失期间 UI 显示的里程基于积分速度而非恒速,能反映加减速趋势。
3.4 GPS 丢失时记录速度初值
if (!isGpsLost) {
isGpsLost = true
gpsLostStartTime = lastValidTime
gpsLostStartMileage = lastValidMileage
gpsSpeedAtLoss = lastValidSpeed // 新增
estimatedIntegralSpeed = lastValidSpeed // 积分初值
filteredLongitudinalAcc = 0f
lastAccelTimestamp = System.currentTimeMillis()
}
3.5 匀加速模型重算隧道记录(核心改进)
GPS 恢复后使用匀加速模型替代线性时间分摊:
a = (v恢复 - v丢失) / Δt
m(t) = m_start + v0 × t + ½ × a × t²
两端严格对齐真实里程和速度。
if (dtTotal > 1.0) {
val accel = (v1 - v0) / dtTotal
recalculateLostRecords(sessionId, startTime, endTime, startMileage, v0, accel)
}
**极短中断(<1s)**走原线性校正回退路径。
3.6 recalculateLostRecords 函数
private suspend fun recalculateLostRecords(
sessionId: Long, startTime: Long, endTime: Long,
startMileage: Double, v0: Double, accel: Double
) {
val records = database.detectionDao().getLostRecordsInRange(sessionId, startTime, endTime)
records.forEach { record ->
val dt = (record.timestamp - startTime) / 1000.0
val correctedKm = startMileage + (v0 * dt / 1000.0) + (0.5 * accel * dt * dt / 1000.0)
database.detectionDao().updateRecordMileage(record.id, correctedKm, formatMileage(correctedKm))
}
}
四、数据库 DAO 新增(InspectorDatabase.kt)
4.1 更新单条记录里程
@Query("UPDATE detection_records SET mileageValue = :mileageVal, mileage = :mileageText WHERE id = :id")
suspend fun updateRecordMileage(id: Long, mileageVal: Double, mileageText: String)
4.2 查询丢失区间记录
@Query("SELECT * FROM detection_records WHERE sessionId = :sessionId " +
"AND timestamp >= :startTime AND timestamp <= :endTime AND isEstimated = 1 " +
"ORDER BY timestamp ASC")
suspend fun getLostRecordsInRange(sessionId: Long, startTime: Long, endTime: Long): List<DetectionRecord>
五、编译器警告修复
5.1 冗余限定符
java.util.ArrayDeque<Float>() → ArrayDeque<Float>()
5.2 一元运算符警告
行首的 + 被解析为一元正号而非二元加法,已移至上一行末尾:
filteredLongitudinalAcc = (1 - longitudinalAccAlpha) * filteredLongitudinalAcc +
longitudinalAccAlpha * (finalH * 9.81f)
六、受影响的文件清单
| 文件 | 改动位置 | 改动量 |
|---|---|---|
InspectorService.kt |
变量区、onSensorChanged、航推定时器、GPS恢复、新增函数 | ~80 行 |
InspectorDatabase.kt |
DAO 接口末尾 | 2 个方法 |
MainActivity.kt |
autoCleanupLibrary、窗口/增益参数、峰值保持 | ~50 行 |
暂无评论