一年前,我
描述了一个带有测风仪
的气象站,用于风向和风速。 根据两个工作季节的经验,对其进行了一些更改和改进,其中在正文中进行了部分描述。
这些变化之一涉及平均风向的计算。 令我惊讶的是,我在网络上没有找到关于此主题的任何明智信息,只有在一个论坛上,人们自己才几乎想到了矢量平均的方法(但几乎,他们并没有解决一般问题)。 因此,我发现将此主题放在单独的出版物中很有用-突然会有其他人派上用场。 该方法可用于平均任何矢量量,而不仅仅是风或水。
请注意,进行风的气象测量的规范方法如下:在10分钟内平均矢量(即速度和方向)(在俄罗斯和世界上大多数国家,他们说,美国和其他一些国家以不同的方式接受这种方式)。 在这种情况下,应在距地球表面10 m的高度进行测量。 要确保所有这些条件在膝盖条件下都是非常困难的:不能在开放空间中达到10 m的高度(不要在远离扭曲风流的房屋和树木的地方建造特殊的塔),相反,应在阴凉处和附近测量湿度和温度从表面。 便携式传感器从紧凑型设备转变为整个测量系统(请参阅基洛夫市气象站区域的照片)。

结果(平均10分钟)将很少提供信息。 在地表附近,风比在海拔高得多,风在10分钟内可以改变速度和方向20倍,有关这些阵风的信息对普通人来说比平均值多得多。 让我提醒您,这里的速度传感器展示了每8 s周期进行四次测量的最大值,这被证明是正确的选择(实际上,我们得到了波动传感器而不是平均速度传感器)。
但是事实证明,风向标比速度传感器更令人讨厌。 根据我的气象站的初始算法(根据最大可能的节能量进行选择),该方向是每个周期测量一次的,也就是说,甚至没有脉动:从来回悬挂风向标的连续过程中随机采样的频率远大于每8个频率一次。超过16秒。
因此,决定平均每个周期的速度矢量方向,每两秒钟进行一次测量并计算平均值。 事实并非如此,因此可以通过半踢来解决-方向值不能形成可以直接加和除的偶数数组(一个单词是一个向量,不是胡说的标量)。 通常情况下,给出的示例值为1度和359度:很容易弄清楚,平均而言,它将精确地为360度(或0,无差异),但是普通算术将给出数字180度。
无需发明任何东西-您已经发明了所有东西。 通过矢量平均方法可以解决该问题,这对那些处理风或流的人来说是众所周知的。 该方法本质上非常简单:由于我们无法直接平均角度,因此让我们对向量在坐标轴上的投影进行平均,根据定义,它是一个标量值,也就是说,可以毫无疑问地进行普通算术运算。
当前风矢量W'(单引号充当上标)在X和Y轴上的投影分别为wx = Wa•cos(α)和wy = Wa•sin(α),其中Wa是矢量的模量(速度值),α -向量和零坐标轴之间的角度值。 如果我们将这些投影的值取平均值,然后将平均值转换回向量,那么我们将获得风的平均速度和风向的真实值。
注意特别腐蚀性为了以这种方式进行完全正确的平均,必须与角度值严格同时测量Wa值(速度值)。 在实践中,只有在流量幅值的明显波动周期小于或等于测量时间时,才应对此进行监视。 对于风(以及几乎所有自然水流的情况),通常无需监视,因为对我们而言,测量时间最大为一秒钟,并且明显的风脉动持续时间更长。 我们可以忽略流体的高频不均匀性,因为它们不会影响任何东西:实际物理物体(包括传感器)的惯性比这些不均匀性大得多,我们根本不会感觉到它们–一片纸屑会发抖,但仅此而已。 在极端情况下,它们会以很小的随机噪声出现,不会明显影响测量质量。
从实用的角度来看,这种出色的方法(我们称之为全矢量平均)具有一个主要的缺点:在没有测量对象的情况下(即当它完全平静时,这是很常见的情况),它给出了数学上不正确的结果:由于风速为零,因此并且两个投影都等于零,而不能为零(因为sin和cos是互补函数)。 更确切地说,可能是这样,但从根本上讲不可能从这种情况中提取信息。 您想在显示屏上显示什么? 老实说,我仍然不知道解决这种情况的正确方法(在我曾经设计的流量计中,平均周期为几小时,并且据信至少会发生一些搅拌)。
但幸运的是,在我们的情况下,任务比较容易-我们不需要平均速度,并且可以对向量进行单个投影,而无需考虑其模块的大小。 换句话说,一个人可以用纯正弦和余弦进行操作,它们永远不会一次取零:即使没有风,冻结在房地产中的风向标也显示出一定的方向。 我们称这种方法为一个方向的简化矢量平均(也许它有一些正式名称,但我不知道)。
现在只有一个困难:将计算出的平均投影值变回角度值。 为此,通常使用函数α= arctan(sin(α)/ cos(α)),但是如果我们通过反三角函数进行计算,则简单地采用arcos(cos(α))(或arcsin(sin(α))会更简单,无论如何),并且要补充此结果以获得一个完整的圆(即从0到359度),分析投影的符号,无论如何,您仍然必须:所有反函数都可以在半圆内给出结果(从0到180或从-90至+90)。 (有关此问题,请参见UPD。)
我们将以上所有内容形式化为一个真正的算法(参考Arduino)。 首先,我们将不读取每个周期的方向指示,而是读取每个测量的方向指示(在风速计的频率值之后)。 我们将把格雷码(在我们的国家中,将其指定为字节类型的wind_Gray,请参见
出版物 )中的结果转换为常规的二进制代码,然后像风速计的频率一样,将其放置在一个全局数组中,将其声明为wDirAvr [4],其中4是循环中的测量次数。 我们不会将四位数的格雷码转换为二进制码-程序员可以自行决定以几种方式完成转换,并且在任何参考文献中都有介绍。
该二进制代码的取值范围为0到15,我们同意我们将对角度进行计数,而不是像平移的地理学家/地形学家/导航员那样,而是按正常的人在学校学习三角学的方法(逆时针)。 也就是说,如果北方对应于零值,则90度不是东方(如“平移”的那样),而是西方。 由于我们有16个方向的渐变,因此我们需要将代码值乘以22.5(360/16),以弧度的普通角度获得方向。
现在,从4个代码值简化方向平均矢量的实际算法:
. . . . . float wSin=0; // sin float wCos=0; // cos float wind_Rad; // for (byte i=0; i<4; i++){ wind_Rad= ((float(wDirAvr[i])*22.5)*M_PI/180); // wSin=wSin+sin(wind_Rad);// sin wCos=wCos+cos(wind_Rad);// cos } // wSin=wSin/4;// sin – , wCos=wCos/4; // cos wind_Rad = acos(wCos); // arccos if (wSin<0) wind_Rad=2*M_PI-wind_Rad; // sin int wind_G = round ((wind_Rad*180/M_PI)/22.5); // 0-15 . . . . .
我们在最后一行将以弧度表示的平均值转换为在我们的代码中从0到15表示的平均值。您可以将其转换回格雷代码,甚至不必更改主模块中的程序即可显示方向。
实际上,这里是整个算法。 我担心余弦-arcsines的计算会减慢弱的(到今天的32位时间)Arduino控制器的速度,但是什么也没发生:它吞没了代码,甚至没有闪烁...可能是一个LED。
UPD :对于作者来说,该算法以这种形式工作了几个月,没有失败。 但是,评论员使我想到了一种可能的方法,尽管在实践中极不可能,但会犯一个错误:如果数据包含两组测量值,并且它们在零余弦值附近(即大约90度和270度)彼此相距约180度,则该算法将产生错误价值。 为避免出现这种情况,请使用atan2(wSin,wCos)函数代替acos(),该函数会立即考虑正弦和余弦符号产生正确的结果(感谢
aamonster的帮助)。 计算平均wSin值的行应该不加注释,并且不需要针对wSin符号进行调整的行。 相反,您需要将强制类型转换插入角度的正值(因为atan2给出pi到-pi的值):
if (wind_Rad<0) wind_Rad=2*M_PI+wind_Rad;