| | |
| | | package com.flightfeather.uav.model.epw |
| | | |
| | | import com.flightfeather.uav.common.utils.DateUtil |
| | | import com.flightfeather.uav.common.utils.GsonUtils |
| | | import com.flightfeather.uav.lightshare.bean.CompanySOP |
| | | import com.flightfeather.uav.lightshare.bean.DataVo |
| | | import com.flightfeather.uav.model.BaseDataPrep |
| | | import com.flightfeather.uav.model.BaseSOP |
| | | import com.flightfeather.uav.socket.bean.AirData |
| | | import com.flightfeather.uav.socket.bean.AirDataPackage |
| | | import com.flightfeather.uav.socket.eunm.FactorType |
| | | import com.flightfeather.uav.socket.eunm.UWDeviceType |
| | | import kotlin.math.max |
| | | import kotlin.math.min |
| | | import kotlin.math.round |
| | | import kotlin.math.sqrt |
| | | |
| | | class EPWDataPrep : BaseDataPrep<DataVo, BaseSOP>() { |
| | | /** |
| | | * 数据平滑预处理 |
| | | * 对于最新的一组数据,根据其之前连续的若干数据,进行数据平滑处理 |
| | | * @Date 2024.5.16 |
| | | */ |
| | | class EPWDataPrep(val deviceType: UWDeviceType? = UWDeviceType.GRID) : BaseDataPrep<DataVo, BaseSOP>() { |
| | | |
| | | // 向前检索的数据记录数 |
| | | private val ncal = 15 |
| | | |
| | | // 标准差倍数参数 |
| | | private val nstd = 3 |
| | | |
| | | // 均值倍数参数 |
| | | private val xratio = 3 |
| | | |
| | | // 连续数据的合理最大增长倍率 |
| | | private val multiplier = 20 |
| | | |
| | | // 需要处理的因子类型 |
| | | private val calTypes = |
| | | // emptyList<String>() |
| | | WeightType.prep |
| | | private var calTypes = when (deviceType) { |
| | | UWDeviceType.VEHICLE, |
| | | UWDeviceType.UAV, |
| | | UWDeviceType.BOAT, |
| | | -> WeightType.prepUnderWay |
| | | UWDeviceType.GRID -> WeightType.prepFixed |
| | | else -> WeightType.prepFixed |
| | | } |
| | | |
| | | private val lastData = mutableListOf<DataVo>() |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // val newDataList = mutableListOf<DataVo>() |
| | | // mDataList.forEach { |
| | | // newDataList.add(it.copy()) |
| | | // } |
| | | |
| | | var i = ncal |
| | | if (lastData.isNotEmpty()) { |
| | |
| | | return sopList |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 实时数据平滑处理 |
| | | */ |
| | | fun mDataPrep2(dataPackage: AirDataPackage): List<DataVo> { |
| | | val vo = dataPackage.toDataVo() |
| | | return mDataPrep2(listOf(vo)) |
| | | } |
| | | |
| | | /** |
| | | * 实时数据平滑处理 |
| | | */ |
| | | fun mDataPrep2(mDataList: List<DataVo>): List<DataVo> { |
| | | var i = ncal |
| | | if (lastData.isNotEmpty()) { |
| | |
| | | while (i < mDataList.size) { |
| | | for (y in mDataList[i].values?.indices ?: 0..0) { |
| | | val it = mDataList[i].values?.get(y) ?: continue |
| | | |
| | | if (!calTypes.contains(it.factorName)) continue |
| | | val vMax = FactorType.getVMax(it.factorName) ?: continue |
| | | // it.factorData ?: continue |
| | | it.factorData ?: continue |
| | | |
| | | if (it.factorData!! > vMax) { |
| | | val lastDataIndex = i |
| | |
| | | // 合理最小值 |
| | | val min = min(avg.first - std * nstd, avg.first / (1 + xratio)) |
| | | |
| | | // 判断监测因子是否需要进行平滑处理, |
| | | // 若不需要,则判断量级是否在合理范围内以及变化倍率是否在合理范围内 |
| | | if (!calTypes.contains(it.factorName)) { |
| | | if (isInRange(it) != true || excessiveChange(it) == true) { |
| | | // 采用计算所得均值代替原始值 |
| | | it.factorData = avg.first |
| | | } |
| | | } else { |
| | | // 数据不处于合理范围并且有效个数达标时,采用计算所得均值代替原始值 |
| | | if (avg.second > max(ncal / 5, 2) |
| | | && (it.factorData!! < min || it.factorData!! > max) |
| | | ) { |
| | | // 原始数据 |
| | | // it.factorData = null |
| | | it.factorData = avg.first |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | if (f?.factorName == factorName) { |
| | | val range = FactorType.getRange(f?.factorName) ?: continue |
| | | //判断数据是否在合理范围内 |
| | | if (f?.factorData ?: 0.0 in range.first..range.second) { |
| | | if ((f?.factorData ?: 0.0) in range.first..range.second) { |
| | | t += f?.factorData!! |
| | | c++ |
| | | } |
| | |
| | | sqrt(t / (c - 1)) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断数据是否在正常量程内 |
| | | */ |
| | | private fun isInRange(airData: AirData): Boolean? { |
| | | val range = FactorType.getRange(airData.factorName) ?: return null |
| | | //判断数据是否在合理范围内 |
| | | return (airData.factorData ?: 0.0) in range.first..range.second |
| | | } |
| | | |
| | | /** |
| | | * 判断连续的数据量级上升幅度是否过大 |
| | | */ |
| | | private fun excessiveChange(airData: AirData): Boolean? { |
| | | airData.factorData ?: return null |
| | | if (lastData.isEmpty()) return false |
| | | val latestData = lastData.last() |
| | | // 结果倍率 |
| | | var m = 1.0 |
| | | for (i in latestData.values?.indices ?: 0..0) { |
| | | val f = latestData.values?.get(i) |
| | | if (f?.factorName == airData.factorName) { |
| | | m = airData.factorData!!.div(f?.factorData ?: airData.factorData!!) |
| | | break |
| | | } |
| | | } |
| | | return m > multiplier |
| | | } |
| | | } |