| | |
| | | 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.socket.bean.AirData |
| | | import com.flightfeather.uav.socket.bean.AirDataPackage |
| | | import com.flightfeather.uav.socket.eunm.FactorType |
| | | import kotlin.math.max |
| | | import kotlin.math.min |
| | | import kotlin.math.round |
| | | import kotlin.math.sqrt |
| | | |
| | | class EPWDataPrep : BaseDataPrep<DataVo, CompanySOP>() { |
| | |
| | | private val calTypes = |
| | | // emptyList<String>() |
| | | WeightType.prep |
| | | |
| | | private val lastData = mutableListOf<DataVo>() |
| | | |
| | | override fun mDataPrep(mDataList: List<DataVo>): List<DataVo> { |
| | | mDataList.forEach { |
| | |
| | | // } |
| | | |
| | | var i = ncal |
| | | if (lastData.isNotEmpty()) { |
| | | i = 0 |
| | | } |
| | | while (i < mDataList.size) { |
| | | for (y in mDataList[i].values?.indices ?: 0..0) { |
| | | val it = mDataList[i].values?.get(y) ?: continue |
| | |
| | | it.factorData ?: continue |
| | | |
| | | if (it.factorData!! > vMax) { |
| | | val list = mDataList.subList(i - ncal, i) |
| | | val lastDataIndex = i |
| | | val thisIndex = if (i-ncal<0) 0 else i - ncal |
| | | val list = mutableListOf<DataVo>() |
| | | if (lastDataIndex < lastData.size) { |
| | | list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1)) |
| | | } |
| | | list.addAll(mDataList.subList(thisIndex, i)) |
| | | |
| | | // 去除无效值的平均 |
| | | val avg = average(list, it.factorName) |
| | | val avg = average(list, it.factorName) ?: continue |
| | | // 去除无效值的标准差 |
| | | val std = standardDeviation(avg.first, list, it.factorName) |
| | | // 合理最大值 |
| | |
| | | i++ |
| | | } |
| | | |
| | | lastData.clear() |
| | | val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1 |
| | | mDataList.subList(s, mDataList.lastIndex + 1).forEach { |
| | | lastData.add(it.copy()) |
| | | } |
| | | |
| | | return mDataList |
| | | } |
| | | |
| | |
| | | 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()) { |
| | | i = 0 |
| | | } |
| | | 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 |
| | | |
| | | if (it.factorData!! > vMax) { |
| | | val lastDataIndex = i |
| | | val thisIndex = if (i-ncal<0) 0 else i - ncal |
| | | val list = mutableListOf<DataVo>() |
| | | if (lastDataIndex < lastData.size) { |
| | | list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1)) |
| | | } |
| | | list.addAll(mDataList.subList(thisIndex, i)) |
| | | |
| | | // 去除无效值的平均,当所有数据都是无效值时,暂不做处理 |
| | | average(list, it.factorName)?.let { avg -> |
| | | // 去除无效值的标准差 |
| | | val std = standardDeviation(avg.first, list, it.factorName) |
| | | // 合理最大值 |
| | | val max = max(avg.first + std * nstd, avg.first + avg.first * xratio) |
| | | // 合理最小值 |
| | | val min = min(avg.first - std * nstd, avg.first / (1 + xratio)) |
| | | |
| | | // 数据不处于合理范围并且有效个数达标时,采用计算所得均值代替原始值 |
| | | if (avg.second > max(ncal / 5, 2) |
| | | && (it.factorData!! < min || it.factorData!! > max) |
| | | ) { |
| | | // 原始数据 |
| | | // it.factorData = null |
| | | it.factorData = avg.first |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | i++ |
| | | } |
| | | |
| | | // 将新数据的至多最后15个保存下来(已经过预处理),用于下一次的判断 |
| | | val newList = mutableListOf<DataVo>() |
| | | val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1 |
| | | mDataList.subList(s, mDataList.lastIndex + 1).forEach { |
| | | newList.add(it.copy()) |
| | | } |
| | | // 当新数据与旧数据采样时间差超过1分钟时,认为两组数据已无关联性,清空旧数据 |
| | | if (lastData.isNotEmpty() && newList.isNotEmpty()) { |
| | | val lastTime = DateUtil.instance.StringToDate(lastData.last().time) |
| | | val thisTime = DateUtil.instance.StringToDate(newList.first().time) |
| | | if (thisTime?.time?.minus(lastTime?.time ?: 0) ?: 0 >= (60 * 1000)) { |
| | | lastData.clear() |
| | | } |
| | | } |
| | | lastData.addAll(newList) |
| | | // 确保保存的数据最多只有最新的15个 |
| | | while (lastData.size > ncal) { |
| | | lastData.removeAt(0) |
| | | } |
| | | |
| | | return mDataList |
| | | } |
| | | |
| | | /** |
| | | * 去除无效值的平均 |
| | | * @param list 监测数据 |
| | | * @return 均值和有效数据个数 |
| | | */ |
| | | private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int> { |
| | | private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int>? { |
| | | var t = 0.0 |
| | | var c = 0 |
| | | list.forEach { |
| | | for (i in it.values?.indices ?: 0..0) { |
| | | val f = it.values?.get(i) |
| | | if (f?.factorName == factorName) { |
| | | if (f?.factorData != null) { |
| | | t += f.factorData!! |
| | | val range = FactorType.getRange(f?.factorName) ?: continue |
| | | //判断数据是否在合理范围内 |
| | | if (f?.factorData ?: 0.0 in range.first..range.second) { |
| | | t += f?.factorData!! |
| | | c++ |
| | | } |
| | | break |
| | |
| | | val avg = if (c == 0) { |
| | | 0.0 |
| | | } else { |
| | | t / c |
| | | round(t / c * 1000) / 1000 |
| | | } |
| | | |
| | | return Pair(avg, c) |
| | | return if (c == 0) { |
| | | null |
| | | } else { |
| | | Pair(avg, c) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | for (i in it.values?.indices ?: 0..0) { |
| | | val f = it.values?.get(i) |
| | | if (f?.factorName == factorName) { |
| | | if (f?.factorData != null) { |
| | | t += (f.factorData!! - avg) * (f.factorData!! - avg) |
| | | val range = FactorType.getRange(f?.factorName) ?: continue |
| | | if (f?.factorData ?: 0.0 in range.first..range.second) { |
| | | t += (f?.factorData!! - avg) * (f.factorData!! - avg) |
| | | c++ |
| | | } |
| | | break |