Commit 23d8f843 authored by 潘栩锋's avatar 潘栩锋 🚴

修改取样的滤波方法,使用时间滤波。 界面添加查看原始AD 与滤波后的AD

parent e6bcbe0b
...@@ -146,6 +146,19 @@ namespace FLY.Thick.Base.Client ...@@ -146,6 +146,19 @@ namespace FLY.Thick.Base.Client
/// </summary> /// </summary>
public int Window { get; set; } public int Window { get; set; }
/// <summary>
/// 使用%方式检查异常
/// </summary>
public bool IsCheckByPercent { get; set; } = true;
/// <summary>
/// 异常% 单位%
/// </summary>
public double ErrPercent { get; set; } = 2;
/// <summary>
/// 异常值
/// </summary>
public int ErrValue { get; set; } = 200;
/// <summary> /// <summary>
/// 样品 /// 样品
/// </summary> /// </summary>
...@@ -179,7 +192,10 @@ namespace FLY.Thick.Base.Client ...@@ -179,7 +192,10 @@ namespace FLY.Thick.Base.Client
velocity = Velocity, velocity = Velocity,
range = Range, range = Range,
window = Window, window = Window,
samples = new GETSAMPLE_OBJ_INTERFACE.Pack_Params_SampleCell[Samples.Count()], IsCheckByPercent = IsCheckByPercent,
ErrPercent =ErrPercent,
ErrValue = ErrValue,
samples = new GETSAMPLE_OBJ_INTERFACE.Pack_Params_SampleCell[Samples.Count()],
search = Search, search = Search,
features = new GETSAMPLE_OBJ_INTERFACE.Pack_Params_SampleFeature[Features.Count()] features = new GETSAMPLE_OBJ_INTERFACE.Pack_Params_SampleFeature[Features.Count()]
}; };
...@@ -212,11 +228,11 @@ namespace FLY.Thick.Base.Client ...@@ -212,11 +228,11 @@ namespace FLY.Thick.Base.Client
p.ToBytes() p.ToBytes()
); );
} }
#endregion #endregion
#region INotifyPropertyChanged 成员 #region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
...@@ -262,6 +278,10 @@ namespace FLY.Thick.Base.Client ...@@ -262,6 +278,10 @@ namespace FLY.Thick.Base.Client
Velocity = p.velocity; Velocity = p.velocity;
Range = p.range; Range = p.range;
Window = p.window; Window = p.window;
IsCheckByPercent = p.IsCheckByPercent;
ErrPercent = p.ErrPercent;
ErrValue = p.ErrValue;
for (int i = 0; i < Samples.Count() && i < p.samples.Count(); i++) for (int i = 0; i < Samples.Count() && i < p.samples.Count(); i++)
{ {
Samples[i].Enable = p.samples[i].enable; Samples[i].Enable = p.samples[i].enable;
...@@ -303,6 +323,23 @@ namespace FLY.Thick.Base.Client ...@@ -303,6 +323,23 @@ namespace FLY.Thick.Base.Client
{ {
PushGetValue(from, srcid, infoid, infodata); PushGetValue(from, srcid, infoid, infodata);
} }
public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState)
{
switch (funcid) {
case GETSAMPLE_OBJ_INTERFACE.CALL_GET_TEMPDATAS:
{
string json = Misc.Converter.BytesToString(retdata);
var reponse = Newtonsoft.Json.JsonConvert.DeserializeObject<List<List<TempFilterData>>>(json);
(AsyncDelegate as AsyncCBHandler)(AsyncState, reponse);
}
break;
}
}
public void GetTempFilterDatas(AsyncCBHandler asyncCB, object asyncContext)
{
CurrObjSys.CallFunctionEx(mConn, mServerID, ID, GETSAMPLE_OBJ_INTERFACE.CALL_GET_TEMPDATAS, null, asyncCB, asyncContext);
}
} }
} }
...@@ -4,6 +4,7 @@ using System.Linq; ...@@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using FLY.Thick.Base.Common; using FLY.Thick.Base.Common;
using System.ComponentModel; using System.ComponentModel;
using FObjBase;
namespace FLY.Thick.Base.IService namespace FLY.Thick.Base.IService
{ {
...@@ -34,7 +35,18 @@ namespace FLY.Thick.Base.IService ...@@ -34,7 +35,18 @@ namespace FLY.Thick.Base.IService
/// </summary> /// </summary>
int Window { get; set; } int Window { get; set; }
/// <summary>
/// 使用%方式检查异常
/// </summary>
bool IsCheckByPercent { get; set; }
/// <summary>
/// 异常%
/// </summary>
double ErrPercent { get; set; }
/// <summary>
/// 异常值
/// </summary>
int ErrValue { get; set; }
/// <summary> /// <summary>
/// 参数:样品点参数 /// 参数:样品点参数
/// </summary> /// </summary>
...@@ -58,6 +70,20 @@ namespace FLY.Thick.Base.IService ...@@ -58,6 +70,20 @@ namespace FLY.Thick.Base.IService
/// 应用 /// 应用
/// </summary> /// </summary>
void Apply(); void Apply();
/// <summary>
/// 返回 List(List(TempFilterData))
/// </summary>
/// <param name="asyncCB"></param>
/// <param name="asyncContext"></param>
void GetTempFilterDatas(AsyncCBHandler asyncCB, object asyncContext);
}
public class TempFilterData
{
public DateTime Time { get; set; }
public int Ad { get; set; }
public int FilterAd { get; set; }
public bool IsReset { get; set; }
} }
public interface ISampleCell : INotifyPropertyChanged public interface ISampleCell : INotifyPropertyChanged
{ {
......
...@@ -101,6 +101,9 @@ namespace FLY.Thick.Base.OBJ_INTERFACE ...@@ -101,6 +101,9 @@ namespace FLY.Thick.Base.OBJ_INTERFACE
public UInt32 velocity; public UInt32 velocity;
public int range; public int range;
public int window; public int window;
public bool IsCheckByPercent;
public double ErrPercent;
public int ErrValue;
public Pack_Params_SampleCell[] samples; public Pack_Params_SampleCell[] samples;
public int search; public int search;
public Pack_Params_SampleFeature[] features; public Pack_Params_SampleFeature[] features;
...@@ -115,6 +118,10 @@ namespace FLY.Thick.Base.OBJ_INTERFACE ...@@ -115,6 +118,10 @@ namespace FLY.Thick.Base.OBJ_INTERFACE
buf.AddRange(BitConverter.GetBytes(velocity)); buf.AddRange(BitConverter.GetBytes(velocity));
buf.AddRange(BitConverter.GetBytes(range)); buf.AddRange(BitConverter.GetBytes(range));
buf.AddRange(BitConverter.GetBytes(window)); buf.AddRange(BitConverter.GetBytes(window));
buf.AddRange(BitConverter.GetBytes(IsCheckByPercent));
buf.AddRange(BitConverter.GetBytes(ErrPercent));
buf.AddRange(BitConverter.GetBytes(ErrValue));
buf.AddRange(BitConverter.GetBytes(search)); buf.AddRange(BitConverter.GetBytes(search));
buf.AddRange(BitConverter.GetBytes(samples.Length)); buf.AddRange(BitConverter.GetBytes(samples.Length));
...@@ -135,7 +142,7 @@ namespace FLY.Thick.Base.OBJ_INTERFACE ...@@ -135,7 +142,7 @@ namespace FLY.Thick.Base.OBJ_INTERFACE
public bool TryParse(byte[] value) public bool TryParse(byte[] value)
{ {
int cnt = 1 + 4 * 4 +4 + 4 + 4; int cnt = 1 + 4 * 4 + 4 + 4 + 4 + (1 + 8 + 4);
if (value.Length < cnt) if (value.Length < cnt)
return false; return false;
int idx = 0; int idx = 0;
...@@ -150,6 +157,12 @@ namespace FLY.Thick.Base.OBJ_INTERFACE ...@@ -150,6 +157,12 @@ namespace FLY.Thick.Base.OBJ_INTERFACE
window = BitConverter.ToInt32(value, idx); window = BitConverter.ToInt32(value, idx);
idx += 4; idx += 4;
IsCheckByPercent = BitConverter.ToBoolean(value, idx);
idx++;
ErrPercent = BitConverter.ToDouble(value, idx);
idx += 8;
ErrValue = BitConverter.ToInt32(value, idx);
idx += 4;
search = BitConverter.ToInt32(value, idx); search = BitConverter.ToInt32(value, idx);
idx += 4; idx += 4;
...@@ -389,5 +402,13 @@ namespace FLY.Thick.Base.OBJ_INTERFACE ...@@ -389,5 +402,13 @@ namespace FLY.Thick.Base.OBJ_INTERFACE
public const UInt16 PUSH_PARAMS = 0; public const UInt16 PUSH_PARAMS = 0;
public const UInt16 PUSH_STATE = 1; public const UInt16 PUSH_STATE = 1;
#endregion #endregion
#region CallFunction
/// <summary>
/// request:null
/// reponse:List(List(TempFilterData))
/// </summary>
public const UInt16 CALL_GET_TEMPDATAS = 0;
#endregion
} }
} }
...@@ -99,7 +99,9 @@ namespace FLY.Thick.Base.Server.OBJProxy ...@@ -99,7 +99,9 @@ namespace FLY.Thick.Base.Server.OBJProxy
(e.PropertyName == "Velocity") || (e.PropertyName == "Velocity") ||
(e.PropertyName == "Range") || (e.PropertyName == "Range") ||
(e.PropertyName == "Window") || (e.PropertyName == "Window") ||
(e.PropertyName == "OnePointIsOffset") || (e.PropertyName == "IsCheckByPercent") ||
(e.PropertyName == "ErrPercent") ||
(e.PropertyName == "ErrValue") ||
(e.PropertyName == "Search")) (e.PropertyName == "Search"))
{ {
push_params(); push_params();
...@@ -124,6 +126,9 @@ namespace FLY.Thick.Base.Server.OBJProxy ...@@ -124,6 +126,9 @@ namespace FLY.Thick.Base.Server.OBJProxy
range = mGetSampleService.Range, range = mGetSampleService.Range,
velocity = mGetSampleService.Velocity, velocity = mGetSampleService.Velocity,
window = mGetSampleService.Window, window = mGetSampleService.Window,
IsCheckByPercent = mGetSampleService.IsCheckByPercent,
ErrPercent = mGetSampleService.ErrPercent,
ErrValue = mGetSampleService.ErrValue,
search = mGetSampleService.Search search = mGetSampleService.Search
}; };
...@@ -192,6 +197,9 @@ namespace FLY.Thick.Base.Server.OBJProxy ...@@ -192,6 +197,9 @@ namespace FLY.Thick.Base.Server.OBJProxy
mGetSampleService.Range = p.range; mGetSampleService.Range = p.range;
mGetSampleService.Velocity = p.velocity; mGetSampleService.Velocity = p.velocity;
mGetSampleService.Window = p.window; mGetSampleService.Window = p.window;
mGetSampleService.IsCheckByPercent = p.IsCheckByPercent;
mGetSampleService.ErrPercent = p.ErrPercent;
mGetSampleService.ErrValue = p.ErrValue;
mGetSampleService.Search = p.search; mGetSampleService.Search = p.search;
for(int i=0;i<mGetSampleService.Samples.Count() && i<p.samples.Count();i++) for(int i=0;i<mGetSampleService.Samples.Count() && i<p.samples.Count();i++)
...@@ -212,5 +220,20 @@ namespace FLY.Thick.Base.Server.OBJProxy ...@@ -212,5 +220,20 @@ namespace FLY.Thick.Base.Server.OBJProxy
} break; } break;
} }
} }
public override void CallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] infodata)
{
switch (funcid) {
case GETSAMPLE_OBJ_INTERFACE.CALL_GET_TEMPDATAS:
{
mGetSampleService.GetTempFilterDatas((context,retdata) =>
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(retdata);
CurrObjSys.PushCallFunctionEx(from, srcid, ID, magic, funcid, Misc.Converter.StringToBytes(json));
}, null);
}break;
}
}
} }
} }
...@@ -59,7 +59,7 @@ namespace FLY.Thick.Base.Server ...@@ -59,7 +59,7 @@ namespace FLY.Thick.Base.Server
/// <summary> /// <summary>
/// 滤波 /// 滤波
/// </summary> /// </summary>
public TempFilter TempF=new TempFilter(); public TempFilter2 TempF=new TempFilter2();
#region ISaveToXml 成员 #region ISaveToXml 成员
...@@ -179,10 +179,21 @@ namespace FLY.Thick.Base.Server ...@@ -179,10 +179,21 @@ namespace FLY.Thick.Base.Server
/// <summary> /// <summary>
/// 滤波窗口 /// 滤波窗口,单位 min
/// </summary> /// </summary>
public int Window { get; set; } public int Window { get; set; }
/// <summary>
/// 使用%方式检查异常
/// </summary>
public bool IsCheckByPercent { get; set; } = true;
/// <summary>
/// 异常% 单位%
/// </summary>
public double ErrPercent { get; set; } = 2;
/// <summary>
/// 异常值
/// </summary>
public int ErrValue { get; set; } = 200;
/// <summary> /// <summary>
/// 样品 /// 样品
...@@ -230,6 +241,10 @@ namespace FLY.Thick.Base.Server ...@@ -230,6 +241,10 @@ namespace FLY.Thick.Base.Server
Range = 100;//样品范围 Range = 100;//样品范围
Velocity = 200;//取样速度 Velocity = 200;//取样速度
Window = 3;//移动窗口 Window = 3;//移动窗口
IsCheckByPercent = true;
ErrPercent = 2;
ErrValue = 200;
Samples[0] = new SampleCell() Samples[0] = new SampleCell()
{ {
Enable = true, Enable = true,
...@@ -252,8 +267,8 @@ namespace FLY.Thick.Base.Server ...@@ -252,8 +267,8 @@ namespace FLY.Thick.Base.Server
Direction = Misc.DIRECTION.FORWARD Direction = Misc.DIRECTION.FORWARD
}; };
foreach (SampleCell sample in Samples) //foreach (SampleCell sample in Samples)
sample.TempF.SetWindow(Window); // sample.TempF.SetWindow(Window);
Search = 100; Search = 100;
...@@ -266,13 +281,13 @@ namespace FLY.Thick.Base.Server ...@@ -266,13 +281,13 @@ namespace FLY.Thick.Base.Server
void GSample_PropertyChanged(object sender, PropertyChangedEventArgs e) void GSample_PropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "Window") //if (e.PropertyName == "Window")
{ //{
foreach(SampleCell sample in Samples) // foreach(SampleCell sample in Samples)
{ // {
sample.TempF.SetWindow(Window); // sample.TempF.SetWindow(Window);
} // }
} //}
} }
public bool Load() public bool Load()
...@@ -301,7 +316,7 @@ namespace FLY.Thick.Base.Server ...@@ -301,7 +316,7 @@ namespace FLY.Thick.Base.Server
else else
sample.Direction = Misc.DIRECTION.FORWARD; sample.Direction = Misc.DIRECTION.FORWARD;
sample.AD = -1; sample.AD = -1;
sample.TempF.ResetSampleFailure(); sample.TempF.Reset();
} }
Timer = Interval; Timer = Interval;
...@@ -311,7 +326,7 @@ namespace FLY.Thick.Base.Server ...@@ -311,7 +326,7 @@ namespace FLY.Thick.Base.Server
foreach (SampleCell sample in Samples) foreach (SampleCell sample in Samples)
{ {
sample.AD = -1; sample.AD = -1;
sample.TempF.ResetSampleFailure(); sample.TempF.Reset();
} }
Timer = Interval; Timer = Interval;
} }
...@@ -459,28 +474,29 @@ namespace FLY.Thick.Base.Server ...@@ -459,28 +474,29 @@ namespace FLY.Thick.Base.Server
} }
/// <summary> /// <summary>
/// 样品取样,推送给thickm, 参数一定合法,不用检测 /// 样品取样,推送给thickm, 参数一定合法,不用检测
/// </summary> /// </summary>
/// <param name="direction"></param> /// <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) public virtual void Do(Misc.DIRECTION direction, int grid_start, int[] buf)
{ {
bool isFailure = false;//取样失败了 //取样结果,isFailure=true, 取样失败,全部复位!!!
bool isFailure = false;
if(CheckParamIsValid() == false) if(CheckParamIsValid() == false)
return; return;
int grid_offset = 0;//经过相识性计算后的偏移量 int grid_offset = 0;//经过相识性计算后的偏移量
//在这里处理gsample->m_timer //在这里处理gsample->m_timer
int dir_idx = 0; int dir_idx = (direction == Misc.DIRECTION.FORWARD) ? 0 : 1;
if (direction == Misc.DIRECTION.FORWARD)
dir_idx = 0;
else
dir_idx = 1;
//数据在 gsample -> gagedata[0] //数据在 gsample -> gagedata[0]
SampleFeature psr = Features[dir_idx] as SampleFeature; SampleFeature psr = Features[dir_idx] as SampleFeature;
//这个方向的特征查找使能了,位置修正!!!!!!
if (psr.Enable) if (psr.Enable)
{ {
//检测机架数据,当为空时,不能作相识性计算 //检测机架数据,当为空时,不能作相识性计算
...@@ -495,18 +511,15 @@ namespace FLY.Thick.Base.Server ...@@ -495,18 +511,15 @@ namespace FLY.Thick.Base.Server
int grid2 = pos2 / posOfGrid; int grid2 = pos2 / posOfGrid;
int grid_searchtol = Search / posOfGrid; int grid_searchtol = Search / posOfGrid;
int[] gagedata; //获取相同方向的机架信息数据
if (direction == Misc.DIRECTION.FORWARD) int[] gagedata = ((direction == Misc.DIRECTION.FORWARD) ? mGageInfo.ForwData : mGageInfo.BackwData).ToArray();
gagedata = mGageInfo.ForwData.ToArray();
else
gagedata = mGageInfo.BackwData.ToArray();
//合格,查找最大相识性的点 //合格,查找最大相识性的点
int grid_b = grid1 - grid_searchtol; int grid_b = grid1 - grid_searchtol;
int grid_e = grid2 + grid_searchtol; int grid_e = grid2 + grid_searchtol;
int grid_len = grid_e - grid_b + 1; int grid_len = grid_e - grid_b + 1;
psr.ScanData = new int[grid_len]; psr.ScanData = new int[grid_len];//这个方向的需要 特征查找范围内的数据,不用考虑 buf 不够 grid_len
Array.Copy(buf, grid_b - grid_start, psr.ScanData, 0, grid_len); Array.Copy(buf, grid_b - grid_start, psr.ScanData, 0, grid_len);
double max_relvency = 0; double max_relvency = 0;
...@@ -525,7 +538,7 @@ namespace FLY.Thick.Base.Server ...@@ -525,7 +538,7 @@ namespace FLY.Thick.Base.Server
psr.MaxOffset = max_grid_offset * posOfGrid; psr.MaxOffset = max_grid_offset * posOfGrid;
if (max_relvency > 0.8) //相识度必须高于0.8 if (max_relvency > 0.8) //相识度必须高于0.8
grid_offset = max_grid_offset; grid_offset = max_grid_offset;//位置修正
else else
{ {
//相似性太低,取样失败!!! //相似性太低,取样失败!!!
...@@ -538,11 +551,11 @@ namespace FLY.Thick.Base.Server ...@@ -538,11 +551,11 @@ namespace FLY.Thick.Base.Server
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] as SampleCell;
TempFilter tempre = sample.TempF; var tempre = sample.TempF;
if ((sample.Direction == direction) && (sample.Enable) ) if ((sample.Direction == direction) && (sample.Enable) )
{ {
ad=-1; ad=-1;
if (!isFailure) if (!isFailure)//不修要位置修正
{ {
//获取grid 数据 //获取grid 数据
int posOfGrid = flyad.PosOfGrid; int posOfGrid = flyad.PosOfGrid;
...@@ -562,16 +575,35 @@ namespace FLY.Thick.Base.Server ...@@ -562,16 +575,35 @@ namespace FLY.Thick.Base.Server
} }
else else
{ {
ad = tempre.CalSampleAD(ad);//ad filter int orgAd = ad;
if (tempre.IsSampleFailure())//AD突变。。。异常,复位 ad = tempre.CalSampleAD(orgAd, TimeSpan.FromMinutes(Window));//ad 滤波
int diff = Math.Abs(orgAd - ad);
if (IsCheckByPercent)
{ {
isFailure = true; 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) if (isFailure)
{ {
tempre.ResetSampleFailure(); tempre.Reset();
ad = -1; ad = -1;
} }
...@@ -579,10 +611,7 @@ namespace FLY.Thick.Base.Server ...@@ -579,10 +611,7 @@ namespace FLY.Thick.Base.Server
} }
} }
SampleChangedEvent?.Invoke(this);
if (SampleChangedEvent != null)
SampleChangedEvent(this);
if (isFailure)//样品获取失败,下次继续!!! if (isFailure)//样品获取失败,下次继续!!!
...@@ -628,8 +657,8 @@ namespace FLY.Thick.Base.Server ...@@ -628,8 +657,8 @@ namespace FLY.Thick.Base.Server
SampleCell sample = Samples[idx] as SampleCell; SampleCell sample = Samples[idx] as SampleCell;
sample.AD = avg; sample.AD = avg;
if (SampleChangedEvent != null)
SampleChangedEvent(this); SampleChangedEvent?.Invoke(this);
//只有当所有都成功,Timer=0 //只有当所有都成功,Timer=0
...@@ -658,7 +687,9 @@ namespace FLY.Thick.Base.Server ...@@ -658,7 +687,9 @@ namespace FLY.Thick.Base.Server
"Interval", "Interval",
"Range", "Range",
"Window", "Window",
"OnePointIsOffset", "IsCheckByPercent",
"ErrPercent",
"ErrValue",
"Samples", "Samples",
"Search", "Search",
"Features" "Features"
...@@ -675,13 +706,7 @@ namespace FLY.Thick.Base.Server ...@@ -675,13 +706,7 @@ namespace FLY.Thick.Base.Server
#region INotifyPropertyChanged 成员 #region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion #endregion
...@@ -691,5 +716,23 @@ namespace FLY.Thick.Base.Server ...@@ -691,5 +716,23 @@ namespace FLY.Thick.Base.Server
//通知上层 //通知上层
Save(); Save();
} }
/// <summary>
/// 返回 List(List(TempFilterData))
/// </summary>
/// <param name="asyncCB"></param>
/// <param name="asyncContext"></param>
public void GetTempFilterDatas(AsyncCBHandler asyncCB, object asyncContext)
{
List<List<TempFilterData>> ret = new List<List<TempFilterData>>();
foreach (SampleCell sample in Samples)
{
if(sample.Enable)
ret.Add(sample.TempF.GetDatas());
}
asyncCB(asyncContext, ret);
}
} }
} }
using System; using FLY.Thick.Base.IService;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace FLY.Thick.Base.Server namespace FLY.Thick.Base.Server
{ {
/// <summary>
/// 样品修正 滤波
/// </summary>
public class TempFilter public class TempFilter
{ {
DateTime sampleTime; DateTime sampleTime;
int sampleFailure; int sampleFailure;
int swfilterCnt; int swfilterCnt;
/// <summary>
/// 滤波器
/// </summary>
class SWFilter class SWFilter
{ {
/// <summary>
/// 缓存区
/// </summary>
int[] buffer; int[] buffer;
/// <summary>
/// 缓存区大小
/// </summary>
int bufferSize; int bufferSize;
/// <summary>
/// 队列尾
/// </summary>
int lastData; int lastData;
/// <summary>
/// 默认值
/// </summary>
int initvalue; int initvalue;
public SWFilter(int buffersize) public SWFilter(int buffersize)
...@@ -44,7 +63,7 @@ namespace FLY.Thick.Base.Server ...@@ -44,7 +63,7 @@ namespace FLY.Thick.Base.Server
window--; window--;
} }
if (cnt == 0) return initvalue; if (cnt == 0) return initvalue;
return (int)(sum / cnt + 0.5); return (int)Math.Round(sum / cnt);
} }
public void Clear(int initvalue) public void Clear(int initvalue)
...@@ -65,7 +84,7 @@ namespace FLY.Thick.Base.Server ...@@ -65,7 +84,7 @@ namespace FLY.Thick.Base.Server
public void SetSize(int buffersize) public void SetSize(int buffersize)
{ {
if (buffersize != this.bufferSize) if (this.bufferSize != buffersize)
{ {
this.bufferSize = buffersize; this.bufferSize = buffersize;
...@@ -78,8 +97,14 @@ namespace FLY.Thick.Base.Server ...@@ -78,8 +97,14 @@ namespace FLY.Thick.Base.Server
SWFilter swfilter; SWFilter swfilter;
int tempBIndex; int tempBIndex;
int[] tempBuf = new int[3]; int[] tempBuf = new int[3];
/// <summary>
/// 前一个AD值
/// </summary>
int preValue; int preValue;
/// <summary>
///
/// </summary>
public TempFilter() public TempFilter()
{ {
sampleFailure = 0; sampleFailure = 0;
...@@ -90,20 +115,40 @@ namespace FLY.Thick.Base.Server ...@@ -90,20 +115,40 @@ namespace FLY.Thick.Base.Server
preValue = -1; preValue = -1;
} }
/// <summary>
/// 复位失败次数
/// </summary>
public void ResetSampleFailure() public void ResetSampleFailure()
{ {
sampleFailure = 0; sampleFailure = 0;
} }
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsSampleFailure() public bool IsSampleFailure()
{ {
if (sampleFailure < 0) return true; if (sampleFailure < 0) return true;
return false; return false;
} }
/// <summary>
/// 输入原始AD值,输出滤波后AD值
/// </summary>
/// <param name="ad"></param>
/// <returns></returns>
public int CalSampleAD(int ad) public int CalSampleAD(int ad)
{ {
int originAD; return CalSampleAD(ad, out int originAD);
return CalSampleAD(ad, out originAD);
} }
/// <summary>
/// 输入原始AD值,输出滤波后AD值
/// </summary>
/// <param name="ad"></param>
/// <param name="originAD"></param>
/// <returns></returns>
public int CalSampleAD(int ad, out int originAD) public int CalSampleAD(int ad, out int originAD)
{ {
originAD = 0; originAD = 0;
...@@ -137,7 +182,7 @@ namespace FLY.Thick.Base.Server ...@@ -137,7 +182,7 @@ namespace FLY.Thick.Base.Server
if (delta > 0.01 * Math.Abs(preValue))//跳到超过 1% ,有问题 if (delta > 0.01 * Math.Abs(preValue))//跳到超过 1% ,有问题
{ {
if (tempBIndex < 1) // Sudden Changed! Need 3 times to confirm. if (tempBIndex < 1) // 突变!! 需要2次确认 因为可能只是很大的噪声
{ {
tempBIndex++; tempBIndex++;
tempBuf[tempBIndex] = ad; tempBuf[tempBIndex] = ad;
...@@ -173,10 +218,93 @@ namespace FLY.Thick.Base.Server ...@@ -173,10 +218,93 @@ namespace FLY.Thick.Base.Server
preValue = swfilter.CalValue(swfilterCnt); preValue = swfilter.CalValue(swfilterCnt);
return preValue; return preValue;
} }
/// <summary>
/// 移动滤波窗口大小
/// </summary>
/// <param name="window"></param>
public void SetWindow(int window) public void SetWindow(int window)
{ {
if (window < 50) if (window < 50)
swfilterCnt = window; swfilterCnt = window;
} }
} }
/// <summary>
/// 样品修正 滤波, 返回N分钟内数据的均值。
/// 如果波动较大,提示异常
/// </summary>
public class TempFilter2
{
List<TempFilterData> Datas = new List<TempFilterData>();
TimeSpan keepTime = TimeSpan.FromMinutes(6);
/// <summary>
///
/// </summary>
public TempFilter2()
{
}
/// <summary>
///
/// </summary>
/// <param name="ad">原始AD</param>
/// <param name="filterTime">滤波时间</param>
/// <returns>滤波后Ad</returns>
public int CalSampleAD(int ad, TimeSpan filterTime)
{
if (filterTime.TotalSeconds <= 0)
{
filterTime = TimeSpan.Zero;
}
keepTime = TimeSpan.FromMinutes(Math.Max(6, filterTime.TotalMinutes * 3));
var now = DateTime.Now;
Datas.RemoveAll(d => d.Time < now - keepTime);
Datas.Add(new TempFilterData()
{
Ad = ad,
FilterAd = ad,
Time = now
});
double sum = 0;
int cnt = 0;
for (int i = 0; i < Datas.Count(); i++)
{
var d = Datas[Datas.Count()-1-i];
if (d.Time >= (now - filterTime) && d.IsReset == false)
{
sum += d.Ad;
cnt++;
}
else {
break;
}
}
if (cnt > 0)
{
Datas.Last().FilterAd = (int)Math.Round(sum / cnt);
}
return Datas.Last().FilterAd;
}
/// <summary>
///
/// </summary>
public void Reset()
{
var now = DateTime.Now;
Datas.RemoveAll(d => d.Time < now - keepTime);
Datas.Add(new TempFilterData() { IsReset = true, Time = DateTime.Now });
}
public List<TempFilterData> GetDatas()
{
return Datas;
}
}
} }
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