我正在开发车队管理系统,其中一项任务是显示代表车辆燃油消耗量的图表(基于来自CANBUS的数据)。
如果数据值介于0和100之间,则表示百分比。因此,如果我得到一个45的整数,则意味着油箱中的燃油为45%。
但是,如果车辆正在移动,由于船舶的物理原因,可能会有不一致的数据。例如,数据系列可能是:
76,76,75,74,73,73,71,70< - 这是一个很好的模式,因为它显示了燃料如何下降。
76,70,75,76,77,76,74,74,73,72,69,72,73,73,72,71< - 这不是一个很好的模式因为跳入燃料坦克不一致,我收到的数据不适合显示给用户。
我希望平滑值,但根据我选择的平均值,结果会有所不同。
关键问题在于,有时我必须在图表中显示耗尽和加油的时刻,并且不能平滑。
我可以使用哪种算法以令人信服的方式分析和表示我的图表?
答案 0 :(得分:2)
有没有办法确定何时加油/排水?如果是这样,那么您可以动态地更改算法。
否则,我建议使用指数平滑。
设d(0 <= d <1)是先前数的权重因子。 所以displayed_number = prev_data * d + new_data *(1-d)
如果有适当的权重系数,似乎会消除“颠簸”,但同时结果会反映燃料事件。
这不是唯一的选择,更像是一个示例算法,但我希望你发现它很有用。
小编辑:我没有意识到指数平滑有一个正确的名称。在我创建的游戏中显示帧率时,我只使用了这种技术。所以,谢谢Kemper。
答案 1 :(得分:1)
据我了解,你希望小变化消失,但保持大跳跃而不平滑。可能moving median正是您正在寻找的,它保留了大跳跃而没有平滑(edge preserving属性)。
我不确定这是最适合您的方法,我必须查看您的数据。
答案 2 :(得分:1)
如果不浪费数据,这或多或少只是一种有根据的猜测...
我会尝试滑动平均值(窗口至少要等于凸点大小),以使凸点平滑,但由于我们不知道此类信号具有什么特性,因此可能会破坏排水。
所以我会尝试这样的事情:
找到颠簸的最大期限
如果它是具有恒定形状的船和坦克,则最大颠簸周期是根据船能够承受的最大波浪大小和船的长度来确定的,并根据坦克的形状和大小进行缩放。如果您不知道该时间段,则可以通过查找一些随后的局部最小值/最大值(偷看)并获取它们之间的最大距离来动态地对其进行测量。
创建一个检测排水的功能
该怎么做?我不能说,因为您不共享数据,我不知道数据的样子。
处理数据(足够多的样本)
因此,我将构造一个大小等于您的滑动平均窗口的FIFO。首先,将整个样本完全填充到FIFO中,然后将样本传递给它。但是,与其存储/显示/绘制输出值,不如使用FIFO中所有值的平均值。
这是FIFO(窗口)大小为9个样本的滑动平均值之前(黑色)和(蓝色)之后的碰撞信号的输出:
请注意,数据与原始信号之间的时间偏移(延迟)为FIFO的一半(我将其移回绘图上,因此绘图彼此对应)。
如果检测到排水并且滑动平均值将其破坏
您需要在排空开始之前暂时禁用滑动平均(仅通过使用较小的滑动窗口大小即可)。您可以在排空之前将大小从原始值线性内插到1 ...然后在其后进行内插,这样信号就不会失去平滑度。但是,滑动平均值可能会完全保留排放信息,而这部分不需要。没有相关数据就无法知道。
如果您需要更高级的信息,那么如果您获得更详细的数据,则可以假定凸块的形状具有特定的形状(由于燃料在其中振荡的罐的形状)。因此,您可以FFT信号,去除特定于凸点的频率,然后通过逆FFT重建。如果您想避免使用复杂的域,可以尝试使用DCT来完成。但是,对于这些任务,我们没有足够的测量数据。