Commit 9671ddff authored by 潘栩锋's avatar 潘栩锋 🚴

还在修改 样品采集,添加很多报警

parent 7e126e15
...@@ -64,16 +64,10 @@ namespace FLY.Thick.Base.UI ...@@ -64,16 +64,10 @@ namespace FLY.Thick.Base.UI
/// </summary> /// </summary>
public bool Enable { get; set; } public bool Enable { get; set; }
/// <summary>
/// 参数:速度
/// </summary>
public UInt32 Velocity { get; set; }
/// <summary> /// <summary>
/// 参数:样品点范围 /// 参数:样品点范围
/// </summary> /// </summary>
public int Range { get; set; } public int SampleRange { get; set; }
/// <summary> /// <summary>
/// 参数:移动滤波 ,窗口值 /// 参数:移动滤波 ,窗口值
...@@ -92,6 +86,18 @@ namespace FLY.Thick.Base.UI ...@@ -92,6 +86,18 @@ namespace FLY.Thick.Base.UI
/// 异常值 /// 异常值
/// </summary> /// </summary>
public int ErrValue { get; set; } public int ErrValue { get; set; }
/// <summary>
/// 当前 样品X_AD/样品0_AD 与 上一次比较 差异比例 单位不是%
/// </summary>
public double CrossErrPercent { get; set; }
/// <summary>
/// 异常比较 时间间隔范围;
/// 两次时间点比较, 时间点的间隔最大时长。 大于它无效,不能比较
/// </summary>
public int ErrIntervalMin { get; set; }
/// <summary> /// <summary>
/// 参数:样品点参数 /// 参数:样品点参数
/// </summary> /// </summary>
...@@ -99,7 +105,7 @@ namespace FLY.Thick.Base.UI ...@@ -99,7 +105,7 @@ namespace FLY.Thick.Base.UI
/// <summary> /// <summary>
/// 参数:特征查找范围 /// 参数:特征查找范围
/// </summary> /// </summary>
public int Search { get; set; } public int SearchRange { get; set; }
/// <summary> /// <summary>
/// 参数:特征参数 /// 参数:特征参数
/// </summary> /// </summary>
...@@ -133,13 +139,12 @@ namespace FLY.Thick.Base.UI ...@@ -133,13 +139,12 @@ namespace FLY.Thick.Base.UI
this.getSampleService = getSampleService; this.getSampleService = getSampleService;
this.gageInfoService = gageInfoService; this.gageInfoService = gageInfoService;
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Enable), this, nameof(Enable)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Enable), this, nameof(Enable));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Velocity), this, nameof(Velocity)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.SampleRange), this, nameof(SampleRange));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Range), this, nameof(Range));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Window), this, nameof(Window)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Window), this, nameof(Window));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.IsCheckByPercent), this, nameof(IsCheckByPercent)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.IsCheckByPercent), this, nameof(IsCheckByPercent));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrPercent), this, nameof(ErrPercent)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrPercent), this, nameof(ErrPercent));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrValue), this, nameof(ErrValue)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrValue), this, nameof(ErrValue));
Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Search), this, nameof(Search)); Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.SearchRange), this, nameof(SearchRange));
Samples = new SampleCell[this.getSampleService.Samples.Count()]; Samples = new SampleCell[this.getSampleService.Samples.Count()];
Features = new SampleFeature[this.getSampleService.Features.Count()]; Features = new SampleFeature[this.getSampleService.Features.Count()];
...@@ -173,7 +178,7 @@ namespace FLY.Thick.Base.UI ...@@ -173,7 +178,7 @@ namespace FLY.Thick.Base.UI
this.getSampleService.Enable = this.Enable; this.getSampleService.Enable = this.Enable;
this.getSampleService.Range = this.Range; this.getSampleService.SampleRange = this.SampleRange;
this.getSampleService.Velocity = this.Velocity; this.getSampleService.Velocity = this.Velocity;
this.getSampleService.Window = this.Window; this.getSampleService.Window = this.Window;
this.getSampleService.IsCheckByPercent = this.IsCheckByPercent; this.getSampleService.IsCheckByPercent = this.IsCheckByPercent;
...@@ -190,7 +195,7 @@ namespace FLY.Thick.Base.UI ...@@ -190,7 +195,7 @@ namespace FLY.Thick.Base.UI
sample_desp.OrgAD = sample_src.OrgAD; sample_desp.OrgAD = sample_src.OrgAD;
sample_desp.Position = sample_src.Position; sample_desp.Position = sample_src.Position;
} }
this.getSampleService.Search = this.Search; this.getSampleService.SearchRange = this.SearchRange;
for (int i = 0; i < Features.Count(); i++) for (int i = 0; i < Features.Count(); i++)
{ {
var feature_src = this.Features[i]; var feature_src = this.Features[i];
......
...@@ -15,14 +15,14 @@ namespace FLY.Thick.Base.Client ...@@ -15,14 +15,14 @@ namespace FLY.Thick.Base.Client
/// 边界查找服务 构造 /// 边界查找服务 构造
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
public GetSampleServiceClient(UInt32 id) : base(id) { init(); } public GetSampleServiceClient(UInt32 id) : base(id) { }
/// <summary> /// <summary>
/// 边界查找服务 构造 /// 边界查找服务 构造
/// </summary> /// </summary>
/// <param name="serviceId">服务id</param> /// <param name="serviceId">服务id</param>
/// <param name="connName">连接器</param> /// <param name="connName">连接器</param>
public GetSampleServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { init(); } public GetSampleServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { }
...@@ -41,7 +41,7 @@ namespace FLY.Thick.Base.Client ...@@ -41,7 +41,7 @@ namespace FLY.Thick.Base.Client
/// <summary> /// <summary>
/// 参数:样品点范围 /// 参数:样品点范围
/// </summary> /// </summary>
public int Range { get; set; } public int SampleRange { get; set; }
/// <summary> /// <summary>
...@@ -65,19 +65,23 @@ namespace FLY.Thick.Base.Client ...@@ -65,19 +65,23 @@ namespace FLY.Thick.Base.Client
/// <summary> /// <summary>
/// 样品 /// 样品
/// </summary> /// </summary>
public SampleCell[] Samples { get; set; } = new SampleCell[3]; public SampleCell[] Samples { get; set; } = new SampleCell[] {
new SampleCell(),new SampleCell(),new SampleCell()
};
/// <summary> /// <summary>
/// 查找公差 /// 查找公差
/// </summary> /// </summary>
public int Search { get; set; } public int SearchRange { get; set; }
/// <summary> /// <summary>
/// 特征 相识度 0 正, 1 反 /// 特征 相识度 0 正, 1 反
/// </summary> /// </summary>
public SampleFeature[] Features { get; set; } = new SampleFeature[2]; public SampleFeature[] Features { get; set; } = new SampleFeature[] {
new SampleFeature(),new SampleFeature()
};
public double CrossErrPercent { get; set; }
public int ErrIntervalMin { get; set; }
/// <summary> /// <summary>
/// ///
...@@ -88,16 +92,6 @@ namespace FLY.Thick.Base.Client ...@@ -88,16 +92,6 @@ namespace FLY.Thick.Base.Client
} }
#endregion #endregion
void init()
{
for (int i = 0; i < Samples.Count(); i++)
Samples[i] = new SampleCell();
for (int i = 0; i < Features.Count(); i++)
Features[i] = new SampleFeature();
}
} }
} }
...@@ -24,43 +24,64 @@ namespace FLY.Thick.Base.IService ...@@ -24,43 +24,64 @@ namespace FLY.Thick.Base.IService
/// <summary> /// <summary>
/// 参数:速度 /// 参数:速度
/// </summary> /// </summary>
UInt32 Velocity { get; set; } UInt32 Velocity { get; }
/// <summary> /// <summary>
/// 参数:样品点范围 /// 参数:样品点范围 单位:脉冲
/// 样品点直径为 Range*2
/// </summary> /// </summary>
int Range { get; set; } int SampleRange { get; set; }
/// <summary> /// <summary>
/// 参数:移动滤波 ,窗口值 /// 参数:移动滤波 ,窗口值 单位:min
/// </summary> /// </summary>
int Window { get; set; } int Window { get; set; }
/// <summary> /// <summary>
/// 使用%方式检查异常 /// 使用%方式检查异常
/// 1.滤波前AD 与 滤波后AD比较
/// 2.当前样品AD 与 上一次样品AD比较
/// 3.当前 样品X_AD/样品0_AD 与 上一次比较
/// </summary> /// </summary>
bool IsCheckByPercent { get; set; } bool IsCheckByPercent { get; set; }
/// <summary> /// <summary>
/// 异常% /// 异常比例 单位不是%
/// </summary> /// </summary>
double ErrPercent { get; set; } double ErrPercent { get; set; }
/// <summary> /// <summary>
/// 异常值 /// 异常值
/// </summary> /// </summary>
int ErrValue { get; set; } int ErrValue { get; set; }
/// <summary>
/// 当前 样品X_AD/样品0_AD 与 上一次比较 差异比例 单位不是%
/// </summary>
double CrossErrPercent { get; set; }
/// <summary>
/// 异常比较 时间间隔范围;
/// 两次时间点比较, 时间点的间隔最大时长。 大于它无效,不能比较
/// </summary>
int ErrIntervalMin { get; set; }
/// <summary> /// <summary>
/// 参数:样品点参数 /// 参数:样品点参数
/// </summary> /// </summary>
[PropertyPush] [PropertyPush]
SampleCell[] Samples { get; } SampleCell[] Samples { get; }
/// <summary> /// <summary>
/// 参数:特征查找范围 /// 参数:特征查找范围 单位:脉冲
/// 取样范围 会扩大为 -SearchRange ~ +SearchRange
/// </summary> /// </summary>
int Search { get; set; } int SearchRange { get; set; }
/// <summary> /// <summary>
/// 参数:特征参数 /// 参数:特征参数 0:正方向, 1:反方向
/// </summary> /// </summary>
[PropertyPush] [PropertyPush]
SampleFeature[] Features { get; } SampleFeature[] Features { get; }
......
...@@ -39,37 +39,53 @@ namespace FLY.Thick.Base.Server ...@@ -39,37 +39,53 @@ namespace FLY.Thick.Base.Server
/// <summary> /// <summary>
/// 参数:样品点范围 /// 参数:样品点范围 单位:脉冲
/// 样品点直径为 Range*2
/// </summary> /// </summary>
public int Range { get; set; } = 100; public int SampleRange { get; set; } = 100;
/// <summary> /// <summary>
/// 滤波窗口,单位 min /// 滤波窗口,单位 min
/// </summary> /// </summary>
public int Window { get; set; } public int Window { get; set; }
/// <summary> /// <summary>
/// 使用%方式检查异常 /// 使用%方式检查异常
/// </summary> /// </summary>
public bool IsCheckByPercent { get; set; } = true; public bool IsCheckByPercent { get; set; } = true;
/// <summary> /// <summary>
/// 异常% 单位% /// 异常比例 单位不是%
/// </summary> /// </summary>
public double ErrPercent { get; set; } = 2; public double ErrPercent { get; set; } = 0.02;
/// <summary> /// <summary>
/// 异常值 /// 异常值
/// </summary> /// </summary>
public int ErrValue { get; set; } = 200; public int ErrValue { get; set; } = 200;
/// <summary>
/// 当前 样品X_AD/样品0_AD 与 上一次比较 差异比例 单位不是%
/// </summary>
public double CrossErrPercent { get; set; } = 0.02;
/// <summary>
/// 异常比较 时间间隔范围;
/// 两次时间点比较, 时间点的间隔最大时长。 大于它无效,不能比较
/// </summary>
public int ErrIntervalMin { get; set; } = 30;
/// <summary> /// <summary>
/// 样品 /// 样品
/// </summary> /// </summary>
public SampleCell[] Samples { get; set; } public SampleCell[] Samples { get; set; }
/// <summary> /// <summary>
/// 查找公差 /// 参数:特征查找范围 单位:脉冲
/// 取样范围 会扩大为 -SearchRange ~ +SearchRange
/// </summary> /// </summary>
public int Search { get; set; } = 100; public int SearchRange { get; set; } = 100;
/// <summary> /// <summary>
/// 特征 相识度 0 正, 1 反 /// 特征 相识度 0 正, 1 反
...@@ -78,6 +94,8 @@ namespace FLY.Thick.Base.Server ...@@ -78,6 +94,8 @@ namespace FLY.Thick.Base.Server
#endregion #endregion
TempFilter2[] tempFilters; TempFilter2[] tempFilters;
DIRECTION[] directions; DIRECTION[] directions;
IGageInfoService mGageInfo; IGageInfoService mGageInfo;
...@@ -106,7 +124,7 @@ namespace FLY.Thick.Base.Server ...@@ -106,7 +124,7 @@ namespace FLY.Thick.Base.Server
tempFilters[i] = new TempFilter2(); tempFilters[i] = new TempFilter2();
Enable = true; Enable = true;
Range = 100;//样品范围 SampleRange = 100;//样品范围
Velocity = 200;//取样速度 Velocity = 200;//取样速度
Window = 3;//移动窗口 Window = 3;//移动窗口
IsCheckByPercent = true; IsCheckByPercent = true;
...@@ -137,7 +155,7 @@ namespace FLY.Thick.Base.Server ...@@ -137,7 +155,7 @@ namespace FLY.Thick.Base.Server
}; };
directions[2] = DIRECTION.FORWARD; directions[2] = DIRECTION.FORWARD;
Search = 100; SearchRange = 100;
Features[0] = new SampleFeature() { StartPos = 0, EndPos = 0 }; Features[0] = new SampleFeature() { StartPos = 0, EndPos = 0 };
Features[1] = new SampleFeature() { StartPos = 2000, EndPos = 2100 }; Features[1] = new SampleFeature() { StartPos = 2000, EndPos = 2100 };
...@@ -247,8 +265,8 @@ namespace FLY.Thick.Base.Server ...@@ -247,8 +265,8 @@ namespace FLY.Thick.Base.Server
SampleCell sample = Samples[i]; SampleCell sample = Samples[i];
if ((sample.Enable) && (directions[i] == direction)) if ((sample.Enable) && (directions[i] == direction))
{ {
int _b = sample.Position - Range; int _b = sample.Position - SampleRange;
int _e = sample.Position + Range; int _e = sample.Position + SampleRange;
if (!valid) if (!valid)
{ {
...@@ -274,8 +292,8 @@ namespace FLY.Thick.Base.Server ...@@ -274,8 +292,8 @@ namespace FLY.Thick.Base.Server
{ {
if (Features[r_idx].Enable) if (Features[r_idx].Enable)
{ {
b -= Search; b -= SearchRange;
e += Search; e += SearchRange;
} }
start = b; start = b;
end = e; end = e;
...@@ -296,7 +314,7 @@ namespace FLY.Thick.Base.Server ...@@ -296,7 +314,7 @@ namespace FLY.Thick.Base.Server
{ {
if (sample.Enable) if (sample.Enable)
{ {
if(((sample.Position - Range)<0) || ((sample.Position+Range)>= flyad.PosLen)) if(((sample.Position - SampleRange)<0) || ((sample.Position+SampleRange)>= flyad.PosLen))
return false; return false;
} }
} }
...@@ -304,7 +322,7 @@ namespace FLY.Thick.Base.Server ...@@ -304,7 +322,7 @@ namespace FLY.Thick.Base.Server
{ {
if (feature.Enable) if (feature.Enable)
{ {
if(((feature.StartPos - Search)<0) || ((feature.EndPos+Search)>= flyad.PosLen)) if(((feature.StartPos - SearchRange)<0) || ((feature.EndPos+SearchRange)>= flyad.PosLen))
return false; return false;
} }
} }
...@@ -323,163 +341,293 @@ namespace FLY.Thick.Base.Server ...@@ -323,163 +341,293 @@ namespace FLY.Thick.Base.Server
Do(direction, 0, dat); Do(direction, 0, dat);
} }
bool CalGridOffset(SampleFeature psr, Misc.DIRECTION direction,int grid_start, int[] buf, out int grid_offset)
/// <summary>
/// 样品取样,推送给thickm, 参数一定合法,不用检测
/// </summary>
/// <param name="direction">方向</param>
/// <param name="grid_start">开始grid序号</param>
/// <param name="buf">grid数据</param>
public virtual void Do(Misc.DIRECTION direction, int grid_start, int[] buf)
{ {
//取样结果,isFailure=true, 取样失败,全部复位!!! grid_offset = 0;
bool isFailure = false; //检测机架数据,当为空时,不能作相识性计算
if (!mGageInfo.DataOK)
if (CheckParamIsValid() == false) return true;
return;
int grid_offset = 0;//经过相识性计算后的偏移量
//在这里处理gsample->m_timer int pos1 = psr.StartPos;
int dir_idx = (direction == Misc.DIRECTION.FORWARD) ? 0 : 1; int pos2 = psr.EndPos;
int posOfGrid = flyad.PosOfGrid;
//数据在 gsample -> gagedata[0] int grid1 = pos1 / posOfGrid;
SampleFeature psr = Features[dir_idx] as SampleFeature; int grid2 = pos2 / posOfGrid;
int grid_searchtol = SearchRange / posOfGrid;
//这个方向的特征查找使能了,位置修正!!!!!! //获取相同方向的机架信息数据
if (psr.Enable) int index = (direction == Misc.DIRECTION.FORWARD) ? 0 : 1;
int[] gagedata = null;
mGageInfo.GetGageInfo(index, (asyncContext, retData) =>
{ {
//检测机架数据,当为空时,不能作相识性计算 var reponse = retData as GetGageInfoResponse;
if (!mGageInfo.DataOK) gagedata = reponse.Data;
goto _corr_end; }, this);
int pos1 = psr.StartPos;
int pos2 = psr.EndPos;
int posOfGrid = flyad.PosOfGrid;
int grid1 = pos1 / posOfGrid; //合格,查找最大相识性的点
int grid2 = pos2 / posOfGrid; int grid_b = grid1 - grid_searchtol;
int grid_searchtol = Search / posOfGrid; int grid_e = grid2 + grid_searchtol;
int grid_len = grid_e - grid_b + 1;
int[] scanData = new int[grid_len];//这个方向的需要 特征查找范围内的数据,不用考虑 buf 不够 grid_len
//获取相同方向的机架信息数据 Array.Copy(buf, grid_b - grid_start, scanData, 0, grid_len);
int index = (direction == Misc.DIRECTION.FORWARD) ? 0 : 1;
int[] gagedata = null; double max_relvency = 0;
mGageInfo.GetGageInfo(index, (asyncContext, retData) => int max_grid_offset = 0;
for (int i = 0; i < grid_searchtol * 2; i++)
{
double r = Misc.MyMath.Correl(gagedata, grid1, scanData, i, grid2 - grid1 + 1);
if (r > max_relvency)
{ {
var reponse = retData as GetGageInfoResponse; max_relvency = r;
gagedata = reponse.Data; max_grid_offset = i - grid_searchtol;
}, this); }
}
psr.MaxRelevancy = max_relvency;
psr.MaxOffset = max_grid_offset * posOfGrid;
if (max_relvency > 0.8) //相识度必须高于0.8
//合格,查找最大相识性的点 {
int grid_b = grid1 - grid_searchtol; grid_offset = max_grid_offset;//位置修正
int grid_e = grid2 + grid_searchtol; return true;
int grid_len = grid_e - grid_b + 1; }
int[] scanData = new int[grid_len];//这个方向的需要 特征查找范围内的数据,不用考虑 buf 不够 grid_len else
{
//相似性太低,取样失败!!!
return false;
}
}
Array.Copy(buf, grid_b - grid_start, scanData, 0, grid_len); /// <summary>
/// 设置这个方向 全部样品为失败
/// </summary>
/// <param name="direction"></param>
void SetFailure(Misc.DIRECTION direction)
{
for (int i = 0; i < Samples.Count(); i++)
{
SampleCell sample = Samples[i];
var tempre = tempFilters[i];
if ((directions[i] == direction) && (sample.Enable))
{
tempre.Reset();
sample.IsFailure = true;
}
}
}
double max_relvency = 0; enum GetSampleAdResult
int max_grid_offset = 0; {
OK,
/// <summary>
/// 没有采集数据
/// </summary>
Invalid,
/// <summary>
/// AD值为0
/// </summary>
Zero,
/// <summary>
/// 滤波 异常
/// </summary>
FilterErr,
/// <summary>
/// 与上一个比较,变化太大
/// </summary>
TimeCompareErr
}
GetSampleAdResult GetSampleAd(SampleCell sample, TempFilter2 tempre, int grid_start, int[] buf, int grid_offset, out int ad)
{
//获取grid 数据
int posOfGrid = flyad.PosOfGrid;
int grid = sample.Position / posOfGrid + grid_offset;
int grid_range = SampleRange / posOfGrid;
int grid1 = grid - grid_range;
int grid_len = grid_range * 2;
int grid_b = grid1 - grid_start;
int grid_e = grid_b + grid_len - 1;
//计算平均值
ad = Misc.MyMath.Avg(buf, grid_b, grid_e);
if (!Misc.MyBase.ISVALIDATA(ad))//AD无效。。。异常,复位
{
ad = -1;
for (int i = 0; i < grid_searchtol * 2; i++) return GetSampleAdResult.Invalid;
}
else
{
int orgAd = ad;
ad = tempre.CalSampleAD(orgAd, TimeSpan.FromMinutes(Window));//ad 滤波
double diff = Math.Abs(orgAd - ad);
if (IsCheckByPercent)
{ {
double r = Misc.MyMath.Correl(gagedata, grid1, scanData, i, grid2 - grid1 + 1); if (diff == 0)
if (r > max_relvency) {
}
else if (ad == 0)
{ {
max_relvency = r; ad = -1;
max_grid_offset = i - grid_searchtol; return GetSampleAdResult.Zero;
}
else if (diff / ad >= ErrPercent) //大于2% 异常
{
return GetSampleAdResult.FilterErr;
} }
} }
psr.MaxRelevancy = max_relvency;
psr.MaxOffset = max_grid_offset * posOfGrid;
if (max_relvency > 0.8) //相识度必须高于0.8
grid_offset = max_grid_offset;//位置修正
else else
{ {
//相似性太低,取样失败!!! if (diff >= ErrValue)
isFailure = true; {
return GetSampleAdResult.FilterErr;
}
}
//获取以前的Ad
int lastAd = tempre.GetLastAd(GetErrIntervalTime);
if (lastAd != -1) {
//找到了
diff = Math.Abs(ad - lastAd);
if (diff / ad >= ErrPercent) //大于2% 异常
{
return GetSampleAdResult.TimeCompareErr;
}
} }
} }
return GetSampleAdResult.OK;
}
DateTime GetErrIntervalTime => DateTime.Now - TimeSpan.FromMinutes(ErrIntervalMin);
_corr_end: GetSampleAdResult SetSampleAds(Misc.DIRECTION direction, int grid_start, int[] buf, int grid_offset)
int ad = -1; {
for (int i = 0; i < Samples.Count(); i++) for (int i = 0; i < Samples.Count(); i++)
{ {
SampleCell sample = Samples[i] as SampleCell; SampleCell sample = Samples[i];
var tempre = tempFilters[i]; var tempre = tempFilters[i];
if ((directions[i] == direction) && (sample.Enable)) if ((directions[i] == direction) && (sample.Enable))
{ {
ad = -1; //获取滤波后的AD值
if (!isFailure)//不修要位置修正 var ret = GetSampleAd(sample, tempre, grid_start, buf, grid_offset, out int ad);
if(ret == GetSampleAdResult.OK)
{ {
//获取grid 数据 sample.AD = ad;
int posOfGrid = flyad.PosOfGrid; sample.IsFailure = false;
int grid = sample.Position / posOfGrid + grid_offset;
int grid_range = Range / posOfGrid;
int grid1 = grid - grid_range;
int grid_len = grid_range * 2;
int grid_b = grid1 - grid_start;
int grid_e = grid_b + grid_len - 1;
//计算平均值
ad = Misc.MyMath.Avg(buf, grid_b, grid_e);
if (!Misc.MyBase.ISVALIDATA(ad))//AD无效。。。异常,复位
{
isFailure = true;
}
else
{
int orgAd = ad;
ad = tempre.CalSampleAD(orgAd, TimeSpan.FromMinutes(Window));//ad 滤波
int diff = Math.Abs(orgAd - ad);
if (IsCheckByPercent)
{
if (diff == 0)
{
}
else if (ad == 0)
{
isFailure = true;
}
else if (diff / ad >= ErrPercent * 0.01) //大于2% 异常
{
isFailure = true;
}
}
else {
if (diff >= ErrValue)
{
isFailure = true;
}
}
}
} }
if (isFailure) else
{ {
tempre.Reset();
ad = -1; return ret;
} }
else }
}
if (Samples[0].AD > 0 && Samples[0].IsFailure == false)
{
//交叉比较
for (int i = 1; i < Samples.Count(); i++)
{
SampleCell sample = Samples[i];
if ((directions[i] == direction) && (sample.Enable))
{ {
sample.AD = ad; double p = 1.0 * Samples[i].AD / Samples[0].AD;
if (p <= 0)
break;
int lastAdi = tempFilters[i].GetLastAd(GetErrIntervalTime);
int lastAd0 = tempFilters[0].GetLastAd(GetErrIntervalTime);
if (lastAd0 == 0)
break;
double last_p = 1.0 * lastAdi / lastAd0;
double diff = Math.Abs(last_p - p);
if (diff / p >= CrossErrPercent) //大于2% 异常
{
//TODO
//TODO
return GetSampleAdResult.TimeCompareErr;
}
} }
sample.IsFailure = isFailure;
} }
} }
return GetSampleAdResult.OK;
}
/// <summary>
/// 样品取样,推送给thickm, 参数一定合法,不用检测
/// </summary>
/// <param name="direction">方向</param>
/// <param name="grid_start">开始grid序号</param>
/// <param name="buf">grid数据</param>
public virtual void Do(Misc.DIRECTION direction, int grid_start, int[] buf)
{
SampleChangedEvent?.Invoke(this); if (CheckParamIsValid() == false)
return;
int grid_offset = 0;//经过相识性计算后的偏移量
if (isFailure)//样品获取失败,下次继续!!! //数据在 gsample -> gagedata[0]
SampleFeature psr = Features[(direction == Misc.DIRECTION.FORWARD) ? 0 : 1];
//这个方向的特征查找使能了,位置修正!!!!!!
if (psr.Enable)
{ {
//通过特征 计算样品偏移,
this.warningSystem.Add( //当没有机架信息,会返回 true
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Code, //成功 计算出偏移 返回 true
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Descrption); //相关性太低,返回 false
if (!CalGridOffset(psr, direction, grid_start, buf, out grid_offset))
{
//有问题,全部复位
SetFailure(direction);
this.warningSystem.Update(
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Code,
$"{ERRNOs.Instance.SAMPLE_ERRNO_Failure.Descrption}:特征查找失败");
goto _end;
}
} }
//获取这个方向全部样品AD
var ret = SetSampleAds(direction, grid_start, buf, grid_offset);
switch (ret)
{
case GetSampleAdResult.Zero:
{
this.warningSystem.Update(
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Code,
$"{ERRNOs.Instance.SAMPLE_ERRNO_Failure.Descrption}:AD值为0");
}
break;
case GetSampleAdResult.Invalid:
{
this.warningSystem.Update(
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Code,
$"{ERRNOs.Instance.SAMPLE_ERRNO_Failure.Descrption}:没有采集数据");
}
break;
case GetSampleAdResult.FilterErr:
{
this.warningSystem.Update(
ERRNOs.Instance.SAMPLE_ERRNO_Failure.Code,
$"{ERRNOs.Instance.SAMPLE_ERRNO_Failure.Descrption}:滤波异常");
}
break;
}
if(ret != GetSampleAdResult.OK)
{
//有问题,全部复位
SetFailure(direction);
}
_end:
SampleChangedEvent?.Invoke(this);
} }
/// <summary> /// <summary>
...@@ -494,7 +642,7 @@ namespace FLY.Thick.Base.Server ...@@ -494,7 +642,7 @@ namespace FLY.Thick.Base.Server
{ {
if (sample.Enable) if (sample.Enable)
{ {
if ((sample.AD < 0)) if ((sample.AD <= 0))
return false; return false;
} }
} }
...@@ -515,7 +663,7 @@ namespace FLY.Thick.Base.Server ...@@ -515,7 +663,7 @@ namespace FLY.Thick.Base.Server
{ {
if (sample.Enable) if (sample.Enable)
{ {
if ((sample.AD < 0) || (sample.IsFailure)) if ((sample.AD <= 0) || (sample.IsFailure))
return true; return true;
} }
} }
...@@ -542,17 +690,7 @@ namespace FLY.Thick.Base.Server ...@@ -542,17 +690,7 @@ namespace FLY.Thick.Base.Server
SampleChangedEvent?.Invoke(this); SampleChangedEvent?.Invoke(this);
} }
/// <summary>
/// 重新获取样品
/// </summary>
//public void Reset()
//{
// foreach (SampleCell sample in Samples)
// {
// TempFilter tempre = sample.TempF;
// tempre.ResetSampleFailure();
// }
//}
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
......
...@@ -239,8 +239,10 @@ namespace FLY.Thick.Base.Server ...@@ -239,8 +239,10 @@ namespace FLY.Thick.Base.Server
public class TempFilter2 public class TempFilter2
{ {
List<TempFilterData> Datas = new List<TempFilterData>(); List<TempFilterData> Datas = new List<TempFilterData>();
const int KeepTimeMin = 6;
const int KeepCount = 9;
TimeSpan keepTime = TimeSpan.FromMinutes(KeepTimeMin);
TimeSpan keepTime = TimeSpan.FromMinutes(6);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
...@@ -261,50 +263,91 @@ namespace FLY.Thick.Base.Server ...@@ -261,50 +263,91 @@ namespace FLY.Thick.Base.Server
{ {
filterTime = TimeSpan.Zero; filterTime = TimeSpan.Zero;
} }
keepTime = TimeSpan.FromMinutes(Math.Max(6, filterTime.TotalMinutes * 3));
var now = DateTime.Now; var now = DateTime.Now;
Datas.RemoveAll(d => d.Time < now - keepTime); keepTime = TimeSpan.FromMinutes(Math.Max(KeepTimeMin, filterTime.TotalMinutes * 3));
KeepSize();
Datas.Add(new TempFilterData() Datas.Add(new TempFilterData()
{ {
Ad = ad, Ad = ad,
FilterAd = ad, FilterAd = ad,
Time = now Time = now
}); });
double sum = 0; double sum = ad;
int cnt = 0; int cnt = 1;
for (int i = 0; i < Datas.Count(); i++) for (int i = 1; i < Datas.Count(); i++)
{ {
var d = Datas[Datas.Count()-1-i]; int index = Datas.Count() - 1 - i;
if (d.Time >= (now - filterTime) && d.IsReset == false) var d = Datas[index];
{ if (d.IsReset) {
sum += d.Ad; //这个是reset 信号,退出
cnt++; break;
} }
else { if (d.Time < (now - filterTime))
{
//太久了,退出
break; break;
} }
sum += d.Ad;
cnt++;
} }
if (cnt > 0)
{ ad = (int)Math.Round(sum / cnt);
Datas.Last().FilterAd = (int)Math.Round(sum / cnt); Datas.Last().FilterAd = ad;
}
return Datas.Last().FilterAd; return ad;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public void Reset() public void Reset()
{
KeepSize();
if (Datas.Count > 0 && !Datas.Last().IsReset)
{
//上一次是复位信号,就不需要再添加一个复位信号了
Datas.Add(new TempFilterData() { IsReset = true, Time = DateTime.Now });
}
}
void KeepSize()
{ {
var now = DateTime.Now; var now = DateTime.Now;
Datas.RemoveAll(d => d.Time < now - keepTime); int index = Datas.FindIndex(d => d.Time >= now - keepTime);
Datas.Add(new TempFilterData() { IsReset = true, Time = DateTime.Now }); if (index <= 0)
return;
//小于index, 都是要删除的
//但必须保证删除后 Datas.Length >=10
int len = Datas.Count() - index;
if (len < KeepCount)
index = Datas.Count() - KeepCount;
if (index <= 0)
return;
Datas.RemoveRange(0, index);
} }
public List<TempFilterData> GetDatas() public List<TempFilterData> GetDatas()
{ {
return Datas; return Datas;
} }
public int GetLastAd(DateTime time)
{
for (int i = 1; i < Datas.Count; i++)
{
int index = Datas.Count() - 1 - i;
var d = Datas[index];
if (d.Time < time)
return -1;//时间太早了,没有数据
if (Datas[index].IsReset)
continue;
return d.Ad;
}
return -1;//没有数据
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment