2

我正在编写一个 C# 应用程序,它以 ~100Hz 的速率从 Wii 遥控器连续获取加速度计数据。此数据在到达时存储在一个列表中(每个轴一个列表)。我有一个计时器,它每隔一秒触发一次,(所以当它触发时列表包含~100 个元素),然后它对列表应用一个低通滤波器(使用信号处理 Math.NET Neodym 库),并写入将数据保存到文件中,并清除下一批数据的所有列表。

现在的问题是,输出的过滤器数据在开始时波动很大,每次应用过滤器时都会发生这种情况,所以每隔一秒,我的数据中就会出现一些错误值,这使得它完全没用。

我该如何解决这个问题,以便过滤器仍然每秒钟应用一次,但可以避免瞬变。我怀疑这可以使用重叠窗口来完成,但不太确定如何?

这是我的过滤器的代码,此代码每秒执行一次:

 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 外观的屏幕截图。输入数据是第一个图,第二个显示过滤器输出: 显示输入和输出数据的图表

4

2 回答 2

4

FIR 滤波器具有瞬态阶的长度。对于 30 的瞬态长度,您可以保存前 100 个样本中的最后 30 个样本,并将它们预先添加到当前数据中,然后在过滤后丢弃该瞬态(130 个过滤样本中的前 30 个)。

于 2013-01-07T03:05:21.813 回答
4

好的,问题解决了,把这个留给其他面临类似问题的人,正如 hotpaw2 所提到的,这可以通过重叠窗口来完成,但我发现我根本没有以正确的方式使用 Math.NET Neodym 库中的过滤器。

问题是每次触发计时器时都会创建一个新过滤器,我通过创建一个全局过滤器对象来解决这个问题,并在每次 Timer 滴答事件中调用它的 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();
于 2013-01-07T10:34:45.647 回答