我正在编写一个C#应用程序,它可以从Wii遥控器以~100Hz的速率连续获取加速度计数据。该数据在到达时存储在列表(每个轴的一个列表)中。 我有一个Timer,它每秒触发一次(所以当它触发列表包含~100个元素时),然后它将低通滤波器应用到列表中(使用Signal Processing Math.NET Neodym库),并写入数据到文件,并清除下一批数据的所有列表。
现在的问题是,输出的滤波器数据在开始时有大的摆动,这种情况发生在应用滤波器的每一次,所以每隔一秒钟,我在数据中有一些错误值,这使得它完全没用。 / p>
我如何解决这个问题,以便过滤器每秒仅应用一次,但可以避免瞬态过载。我怀疑这可以使用重叠窗口完成,但我不太确定如何?
以下是我的过滤器的代码,此代码每秒执行一次:
listXLow = MathNet.SignalProcessing.Filter.OnlineFilter.CreateLowpass(MathNet.SignalProcessing.Filter.ImpulseResponse.Finite, 100, 1, 30).ProcessSamples(listX.ToArray()).ToList();
在参数中,紧跟在ImpulseResponse.Finite之后,100是采样率,1是截止频率,30是滤波器阶数。
以下是显示我的I / O外观的屏幕截图。输入数据是第一个图形,第二个图形显示过滤器输出:
答案 0 :(得分:4)
FIR滤波器具有瞬态长度的顺序。对于30的瞬态长度,您可以保存前100个样本中的最后30个样本,并将它们预先挂起到当前数据,然后在过滤掉掉那个瞬态(130个过滤样本中的前30个)。
答案 1 :(得分:4)
好了,问题解决了,这里留给了其他面临类似问题的人,正如hotpaw2所提到的,这可能是通过重叠窗口完成的,但我发现我根本就没有在Math.NET Neodym库中使用Filter正确的方式。
问题是每次启动计时器时都会创建一个新的过滤器,我通过创建一个全局过滤器对象来解决这个问题,并且每次在Timer tick事件中调用它的ProcessSamples方法。
现在,在程序开始时创建了一个过滤器对象:
MathNet.SignalProcessing.Filter.OnlineFilter XlowFilter = MathNet.SignalProcessing.Filter.FIR.OnlineFirFilter.CreateLowpass(MathNet.SignalProcessing.Filter.ImpulseResponse.Finite, 100, 1.5, 30);
并且只在Timer Tick事件中调用过滤器的方法:
listXLow = XlowFilter.ProcessSamples(listX.ToArray()).ToList();