@chendbdb
2026-08-05T08:28:35.000000Z
字数 4715
阅读 3
软件使用说明书 沥青试验仪 沥青
摆动量测量时,设备可能无法保持完全水平。随着设备运动,横向或纵向传感器的读数可能持续增大或持续减小,形成近似线性的基线漂移。
如果直接使用传感器实际值计算峰值,斜面造成的缓慢偏移也会被当成摆动量,导致峰值越来越大。当前程序通过实时拟合线性趋势,并从实际值中减去该趋势,得到真正用于摆动分析的“去趋势值”。
本文说明当前 Android 程序中去趋势值的计算方法、数据流程、峰值处理、图表显示和日志记录逻辑。
本文中的“实际值”不是 Modbus 寄存器中的原始整数,而是传感器值经过协议换算和标定后的测量值,单位为 mm。
横向和纵向分别使用独立的标定配置:
swing1swing2趋势值表示由安装斜面或缓慢漂移造成的线性基线。程序使用本次测量从开始到当前时刻的全部采样点,拟合一条直线:
其中:
mm;mm/s;mm。去趋势值是实际值减去趋势预测值:
其中:
若实际值只包含稳定的线性增长或线性下降,去趋势值应接近 0;若线性趋势上叠加了摆动,去趋势值会保留该摆动部分。
程序使用普通最小二乘法拟合直线。对于 个采样点:
斜率计算公式为:
截距计算公式为:
得到 和 后,任意采样点的去趋势值为:
程序不会在每次新增数据时重新遍历全部采样点计算斜率,而是持续保存以下累计量:
新增一个采样点时,只需更新上述累计量,即可重新计算当前斜率和截距。因此,单次斜率更新的时间复杂度为 。
核心实现位于:
app/src/main/java/com/ttaozi/record/utils/LinearTrendCorrector.java
横向与纵向使用两个互不影响的 LinearTrendCorrector:
trendCorrector1 → 横向摆动量trendCorrector2 → 纵向摆动量
这样可以处理以下情况:
拟合时,相对时间由毫秒转换为秒,因此算法内部斜率单位为:
mm/s
为了便于现场观察,界面和 TXT 日志将斜率乘以 60,显示为:
mm/min
换算公式:
正斜率表示数值随时间上升,负斜率表示数值随时间下降。
在 SwingMeasurementActivity.updateData12() 中,主要处理顺序如下:
界面包含两张独立折线图。
两张图同时显示实际值和去趋势值,可直观看到:
为了保持页面刷新速度,图表仅重新计算和显示最近 30 个采样点。趋势斜率本身仍使用本次测量开始后的全部采样数据计算。
图表数据标签固定显示两位小数;左侧文本框按照“读取设置”中的精度显示。
实时峰值不使用实际值,而使用去趋势值的绝对值:
横向和纵向分别维护各自的最大绝对值。
这意味着持续上升或下降的线性偏移不会直接累加到摆动峰值中。
实时测量过程中,斜率会随着新增采样点逐渐变化。因此,早期数据计算时采用的趋势线可能与最终趋势线略有不同。
为保证最终结果一致,点击“停止”或“保存”时,程序会:
最终峰值计算位于:
SwingMeasurementActivity.recalculateFinalPeaks()
开始新一次测量时会清空:
因此,每次“开始→停止”都是一次独立的趋势拟合过程。
清零会向摆动量设备发送清零命令,同时重置当前页面中的趋势累计量、图表和峰值。若清零时仍处于测量状态,后续采样会从新的基线重新建立趋势。
停止测量后会:
每次测量创建一个独立日志文件。每行格式为:
毫秒时间戳:横向去趋势值,横向实际值,横向斜率,纵向去趋势值,纵向实际值,纵向斜率
示例:
1754352000123:1.250000,10.500000,-0.750000,-2.500000,20.250000,0.500000
字段说明:
| 序号 | 字段 | 单位 | 说明 |
|---|---|---|---|
| 1 | 毫秒时间戳 | ms | Unix 时间戳,精确到毫秒 |
| 2 | 横向去趋势值 | mm | 横向实际值减去横向趋势值 |
| 3 | 横向实际值 | mm | 协议换算并标定后的横向值 |
| 4 | 横向斜率 | mm/min | 当前横向线性趋势斜率 |
| 5 | 纵向去趋势值 | mm | 纵向实际值减去纵向趋势值 |
| 6 | 纵向实际值 | mm | 协议换算并标定后的纵向值 |
| 7 | 纵向斜率 | mm/min | 当前纵向线性趋势斜率 |
日志数值保留 6 位小数。日志记录的是每个时刻基于当时实时趋势线得到的结果,因此可以用于分析斜率随测量过程逐渐稳定的情况。
典型日志目录为:
/storage/emulated/0/Android/data/com.ttaozi.record/files/Documents/log/
假设横向实际值可近似表示为:
其中:
2.0 mm;0.01 mm/s;对应界面斜率为:
在第 20 秒时,趋势值为:
如果传感器实际值为 2.5 mm,则去趋势值为:
因此,峰值计算使用 0.3 mm,而不是包含斜面偏移的 2.5 mm。
只有一个采样点时无法确定斜率,程序将斜率设为 0,截距设为第一个实际值,因此首个去趋势值为 0。
两个点可以确定一条直线,这两个点通常都会落在拟合线上,因此去趋势值可能仍接近 0。
随着样本增加,实际摆动不再能全部被一条直线解释,去趋势值开始体现真实摆动,斜率也逐渐稳定。
因此,测量刚开始时斜率和去趋势值出现短暂变化属于正常现象,不代表传感器异常。
当前算法假设基线偏移近似为线性趋势,适合处理:
需要注意:
开始测量:重置横向趋势拟合器重置纵向趋势拟合器清空实际值、时间、峰值和图表每次采样:timestamp = 当前 Unix 毫秒时间戳relativeTime = timestamp - 测量开始时间horizontalActual = 标定(横向传感器值)verticalActual = 标定(纵向传感器值)horizontalTrend = 横向拟合器.add(relativeTime, horizontalActual)verticalTrend = 纵向拟合器.add(relativeTime, verticalActual)horizontalCorrected = horizontalActual - 横向趋势预测值verticalCorrected = verticalActual - 纵向趋势预测值横向实时峰值 = max(横向实时峰值, abs(horizontalCorrected))纵向实时峰值 = max(纵向实时峰值, abs(verticalCorrected))更新文本和折线图写入 TXT 日志停止或保存:使用最终横向趋势重新校正全部横向历史点使用最终纵向趋势重新校正全部纵向历史点重新计算最终横向和纵向峰值
| 功能 | 文件 |
|---|---|
| 在线线性拟合与去趋势计算 | app/src/main/java/com/ttaozi/record/utils/LinearTrendCorrector.java |
| 摆动量采集、图表和峰值处理 | app/src/main/java/com/ttaozi/record/activity/SwingMeasurementActivity.java |
| TXT 日志写入与解析 | app/src/main/java/com/ttaozi/record/utils/SwingMeasurementLogWriter.java |
| 去趋势算法单元测试 | app/src/test/java/com/ttaozi/record/LinearTrendCorrectorTest.java |
| 日志格式单元测试 | app/src/test/java/com/ttaozi/record/SwingMeasurementLogWriterTest.java |