首页 > 解决方案 > 四舍五入的平均值越来越差

问题描述

我正在尝试使用 Arduino 对来自高度传感器的读数进行平均,但随着时间的推移,分辨率变得越来越差,尽管原始输入数据保持不变。

此代码中未明确定义的所有变量都是浮点数。

altTotal = 0.00;
slopeTotal = 0.00;

altitude = ps.readFloatAltitudeMeters();

//=========== Altitude averaging
for (int j = 0.00; j <=(aveNum-2); j++) {
  arrAlt[j] = arrAlt[j+1];
}

arrAlt[aveNum-1] = altitude;

for (i = 0.00; i <= (aveNum-1); i++){
  altTotal = altTotal + arrAlt[i];
}

altAve = altTotal/(i);
//============

f = f+1;
altRd = altRd + altAve;

if (f == 5) {

//======== check cycle time
unsigned long endCycle = micros();
unsigned long delta = endCycle - start;
delta = delta/1000;
unsigned long start = endCycle;


loop1 = loop2;
loop2 = delta;
loopTime = loop2-loop1;
//========

  v0 = v1;
  v1 = v2;
  v2 = altRd/f - v0 - 2*v1;
  altButt = v0 + 2*v1 + v2;

  alt1 = alt2;
  alt2 = altButt;
  climbRate = (alt2 - alt1) * (1000/loopTime); //to convert climb rate to m/s

  //climbRate = -5;

  f = 0;
  altRd = 0;

}

我希望“climbRate”的输出具有一致的分辨率,但随着时间的推移,分辨率会变得更糟,是 2 的倍数。首先它以 0.006 的分辨率开始,然后是 0.012,然后是 0.023,然后是 0.047,然后是 0.094,以此类推。

以下是输出示例:

0.000,m/s ,0,0.10,328ms ,0.00m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,1603.12m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,3206.23m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,4809.35m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,6412.46m altRd ,1603.11m altButt
0.023,m/s ,0,0.10,328ms ,0.00m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,1603.12m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,3206.24m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,4809.37m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,6412.51m altRd ,1603.12m altButt
0.047,m/s ,0,0.10,328ms ,0.00m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,1603.14m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,3206.28m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,4809.42m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,6412.55m altRd ,1603.13m altButt

我不确定问题出在哪里。

我将一些变量设置为不同的类型,但我将它们全部转换为浮点数以尝试提高分辨率但没有成功。

标签: c++arduinoarduino-c++

解决方案


鉴于上面的示例,我无法告诉您错误的确切位置,但我可以告诉您导致问题的原因以及解决问题的方法。

您的代码在数值上不稳定。与大多数其他语言一样,实数值在 C++ 中通过浮点表示(引入了一个新的更准确的标准,但尚未广泛使用)。

float值精度为 23 位,这意味着其精度约为其值的 10^{-7}。下面的所有内容都被截断。

例如:2e7f + 1 == 2e7ftrue因为 1 太小给定浮点精度。

很可能在您的代码中的某个地方,您需要两个越来越大的浮点变量的差异,导致它们的差异随着时间的推移越来越不准确。

要修复它,您可以使用double而不是float. 如果你不能,或者这还不够,那么你必须使你的代码在数字上更稳定......它可能很复杂......这不是可以在简短的答案中轻松解释的东西。寻求有关该问题的教程。


推荐阅读