This commit is contained in:
@@ -111,6 +111,22 @@ namespace MembranePoreTester.ViewModels
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
double pressure = Math.Round(rawPressure * _plcConfig.PressureFactor, 2);
|
||||
|
||||
|
||||
|
||||
|
||||
// 2. 读取当前工位的加压上限(实时)
|
||||
ushort upperLimitAddress = StationId == 1 ? _plcConfig.PressureUpperLimit
|
||||
: StationId == 2 ? _plcConfig.PressureUpperLimit2
|
||||
: _plcConfig.PressureUpperLimit3;
|
||||
double pressureUpperLimit = await _plcService.ReadFloatAsync(upperLimitAddress);
|
||||
|
||||
// 3. 如果压力已达到或超过上限,停止采集
|
||||
if (pressure >= pressureUpperLimit - 3)
|
||||
{
|
||||
StopCollecting();
|
||||
return; // 不再添加当前数据点
|
||||
}
|
||||
|
||||
// 2. 读取当前模式对应的流量
|
||||
double flow = 0;
|
||||
if (TestMode.Contains("湿膜"))
|
||||
@@ -550,11 +566,18 @@ namespace MembranePoreTester.ViewModels
|
||||
}
|
||||
|
||||
|
||||
// 修改 Calculate 方法:
|
||||
//修改 Calculate 方法:
|
||||
private void Calculate()
|
||||
{
|
||||
// 先清洗数据并替换到绑定的集合中,确保DataGrid和曲线显示清洗后的数据
|
||||
var originalPoints = Record.DataPoints.ToList();
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("=== 清洗前的数据点 ===");
|
||||
foreach (var p in originalPoints)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"P={p.Pressure}, Wet={p.WetFlow}, Dry={p.DryFlow}");
|
||||
}
|
||||
|
||||
var cleanedPoints = CleanDataPoints(originalPoints);
|
||||
|
||||
if (cleanedPoints.Count < 2)
|
||||
@@ -587,22 +610,105 @@ namespace MembranePoreTester.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
//private void Calculate()
|
||||
//{
|
||||
// // 直接使用原始数据,不清洗
|
||||
// if (Record.DataPoints.Count < 2)
|
||||
// {
|
||||
// MessageBox.Show("有效数据点不足,至少需要 2 个数据点进行计算。");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 注意:不清洗,也不改变 Record.DataPoints 的顺序(但计算函数内部会自己排序)
|
||||
// // 直接计算
|
||||
// AveragePoreSize = PoreDistributionAnalysis.CalculateAveragePore(
|
||||
// Record.DataPoints, Record.PressureUnit, Record.Liquid);
|
||||
|
||||
// RangePercentage = PoreDistributionAnalysis.CalculatePoreRangePercentage(
|
||||
// Record.DataPoints, Record.PressureUnit, Record.Liquid, LowerPore, UpperPore);
|
||||
|
||||
// // 可选:提示用户当前使用了原始数据(不清洗)
|
||||
// // MessageBox.Show("已使用原始数据(未清洗)进行计算");
|
||||
//}
|
||||
|
||||
//private List<Models.DataPoint> CleanDataPoints(IEnumerable<Models.DataPoint> points)
|
||||
//{
|
||||
// return points
|
||||
// .Where(p => p.Pressure > 0.001) // 移除压力接近0的点
|
||||
// .Where(p => !(Math.Abs(p.WetFlow) < 0.001 && Math.Abs(p.DryFlow) < 0.001)) // 移除双零流量点
|
||||
// .GroupBy(p => Math.Round(p.Pressure, 2)) // 按压力四舍五入分组(避免重复压力)
|
||||
// .Select(g => new Models.DataPoint
|
||||
// {
|
||||
// Pressure = g.Key,
|
||||
// WetFlow = g.Max(x => x.WetFlow), // 取最大值(避免0覆盖有效值)
|
||||
// DryFlow = g.Max(x => x.DryFlow)
|
||||
// })
|
||||
// .OrderBy(p => p.Pressure)
|
||||
// .ToList();
|
||||
//}
|
||||
|
||||
|
||||
|
||||
private List<Models.DataPoint> CleanDataPoints(IEnumerable<Models.DataPoint> points)
|
||||
{
|
||||
return points
|
||||
.Where(p => p.Pressure > 0.001) // 移除压力接近0的点
|
||||
.Where(p => !(Math.Abs(p.WetFlow) < 0.001 && Math.Abs(p.DryFlow) < 0.001)) // 移除双零流量点
|
||||
.GroupBy(p => Math.Round(p.Pressure, 2)) // 按压力四舍五入分组(避免重复压力)
|
||||
// 第一步:基础清洗(移除压力≤0、双零流量、合并相同压力取最大流量)
|
||||
var cleaned = points
|
||||
.Where(p => p.Pressure > 0.001)
|
||||
.Where(p => !(Math.Abs(p.WetFlow) < 0.001 && Math.Abs(p.DryFlow) < 0.001))
|
||||
.GroupBy(p => Math.Round(p.Pressure, 2))
|
||||
.Select(g => new Models.DataPoint
|
||||
{
|
||||
Pressure = g.Key,
|
||||
WetFlow = g.Max(x => x.WetFlow), // 取最大值(避免0覆盖有效值)
|
||||
WetFlow = g.Max(x => x.WetFlow),
|
||||
DryFlow = g.Max(x => x.DryFlow)
|
||||
})
|
||||
.OrderBy(p => p.Pressure)
|
||||
.ToList();
|
||||
|
||||
if (cleaned.Count < 4) return cleaned; // 点数太少,不进行高级剔除
|
||||
|
||||
// 第二步:仅对湿膜流量进行异常孤立点剔除(干膜保持原样,因为干膜可能有很多0和少量非零)
|
||||
var result = new List<Models.DataPoint>();
|
||||
const double threshold = 3.0; // 孤立高点阈值(倍),比之前放宽
|
||||
|
||||
for (int i = 0; i < cleaned.Count; i++)
|
||||
{
|
||||
var current = cleaned[i];
|
||||
bool isAbnormal = false;
|
||||
|
||||
// 仅检查中间的点(非首尾),且只检查湿膜流量
|
||||
if (i > 0 && i < cleaned.Count - 1)
|
||||
{
|
||||
double prevWet = cleaned[i - 1].WetFlow;
|
||||
double nextWet = cleaned[i + 1].WetFlow;
|
||||
double maxNeighbor = Math.Max(prevWet, nextWet);
|
||||
double minNeighbor = Math.Min(prevWet, nextWet);
|
||||
|
||||
// 如果当前湿膜流量远大于前后邻居的最大值(孤立高峰),且前后邻居都不为0
|
||||
if (maxNeighbor > 0 && current.WetFlow > maxNeighbor * threshold)
|
||||
isAbnormal = true;
|
||||
|
||||
// 如果当前湿膜流量远小于前后邻居的最小值(孤立低谷),一般很少见,但保留
|
||||
if (minNeighbor > 0 && current.WetFlow < minNeighbor / threshold)
|
||||
isAbnormal = true;
|
||||
}
|
||||
|
||||
// 不剔除干膜中的非零点(即使孤立也不删)
|
||||
if (!isAbnormal)
|
||||
result.Add(current);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 如果全部被误判为异常,则回退到原始清洗结果
|
||||
return result.Count == 0 ? cleaned : result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//private void GenerateReport()
|
||||
//{
|
||||
// ReportGenerator.GeneratePoreDistributionReport(Record);
|
||||
|
||||
Reference in New Issue
Block a user