A year ago, I
described a weather station with a wind speed and direction meter. According to the experience of two seasons of operation, some changes and improvements were made to it, which are partially described there in the supplements to the main text.
One of these changes concerns the calculation of the average value of the wind speed direction. To my amazement, I didn’t find anything sensible on the web, only on one of the forums the people themselves almost thought of the vector averaging method (but only almost, they didn’t solve the problem in general). Therefore, I considered it useful to bring this topic into a separate publication - suddenly someone else will come in handy. The method can be used for averaging any vector quantities, not just wind or current.
Note that the canonical method of conducting meteorological measurements of wind is as follows: to average the vector (that is, the speed and direction) for 10 minutes (in Russia and most countries of the world, this is usually the case, they say, in the USA and some other countries differently). In this case, measurements are carried out at a height of 10 m from the surface of the Earth. It is rather difficult to provide all this in knee-down conditions: you cannot reach 10 m in open space (you should not build a special tower, and far from houses and trees distorting the wind flow), and the temperature with humidity should be measured in the shade and near from the surface. From a compact device, the remote sensor transforms into a whole measuring system (see photo of the territory of the weather station in the city of Kirov).

')
And the result obtained - an average of 10 minutes - will be of little informative. Near the surface, the wind is much more gusty than at a height, in 10 minutes it can change the speed and direction twenty times, and the information about these gusts for the average person is much more informative than the average value. Let me remind you that the speed sensor we have demonstrates the maximum value of four measurements per cycle of 8 s, and this turned out to be the right choice (in fact, instead of the average speed sensor, we received a pulsation sensor).
But the weather vane turned out to be more capricious than the speed sensor. According to the initial algorithm of my meteorological station (which was chosen on the basis of the maximum possible energy saving), the direction was measured once per cycle, that is, even the pulsations did not work: there were random samples from the continuous process of wind vane rolling back and forth with a frequency much higher than every 8 and more than 16 seconds.
Therefore, it was decided to average the direction of the velocity vector per cycle, taking measurements every two seconds and calculating the average. But this is not the case in such a way that the half-ping is solved - the direction values ​​do not form a uniform array of numbers that can be directly folded and divided (one word is a vector, and not bullshit). An example is usually given with values ​​of 1 degree and 359 degrees: it is easy to figure out that on average it will be exactly 360 (or 0, no difference), but ordinary arithmetic will produce a number of 180 degrees.
There is no need to invent anything - everything has already been invented before you. The problem is solved by the vector averaging method, well known to those who dealt with measurements of winds or currents. The method is essentially very simple: if we cannot directly average the angles, then let's average the projections of the vector on the coordinate axes, which, by definition, are scalar, that is, amenable to ordinary arithmetic without questions.
The projections of the current wind vector W '(the apostrophe here plays the role of a superscript line) on the X and Y axes are wx = Wa • cos (α) and wy = Wa • sin (α), where Wa is the vector modulus (velocity value), and α - the value of the angle between the vector and the zero axis of coordinates. If we average these values ​​of the projections, and then convert the averages back into a vector, we get the true value of the average speed and direction of the wind.
Note for especially corrosiveFor a fully correct averaging in this way, it is necessary that the value of Wa (velocity value) be measured strictly simultaneously with the magnitude of the angle. In practice, this should be monitored only if the periods of significant amplitude flow pulsations are shorter or comparable to the measurement time. For the wind (and for almost all cases of the natural flow of water), it is usually not necessary to monitor, since the measurement time is at most a fraction of a second, and significant wind pulsations, of course, last longer. We may neglect the high-frequency flow irregularities, because they do not affect anything: the inertia of real physical bodies (including sensors) is much larger than these discontinuities, and we simply will not feel them - a piece of paper will tremble, but no more. In the extreme case, they will come out as a small random noise that does not significantly affect the quality of measurements.
This remarkable method (let's call it complete vector averaging) has one fundamental drawback from a practical point of view: in the absence of a measurement object (that is, when there is complete calm, which is quite a household case), it produces a mathematically incorrect result: since the wind speed is zero, and both projections are equal to zero, which cannot be (since sin and cos are complementary functions). More precisely, it can be, but it is fundamentally impossible to extract information from such a situation. And what would you order to show on the display? To be honest, I still do not know the correct way to get around this situation (in the flow meters that I once designed, the averaging cycles made up the clock, and it was believed that during this time at least some movement would occur).
But in our case, the task, fortunately, is easier - we don’t need to average the speed, and we can do with single projections of the vector, without taking into account the magnitude of its module. In other words, it is possible to operate with pure sines and cosines, which never take the zero value both at once: even when there is no wind, a weather vane frozen in real estate shows a certain direction. Let's call such a method a simplified vectorial averaging of direction (maybe it has some kind of official name, but I am not up to date).
The difficulty now remains only one: turn the calculated average values ​​of the projections back into the angle value. For this, the function α = arctan (sin (α) / cos (α)) is usually used, but if we calculate it through inverse trigonometric functions, then it is easier to take simply arcos (cos (α)) (or arcsin (sin (α)), all the same), and to supplement this result to get a full circle (ie, from 0 to 359 degrees), analyzing the signs of the projections, you still have to in any case: all inverse functions produce a result within a semicircle (from 0 to 180 or from -90 to +90). (See about this UPD at the end of the article).
We formalize everything said in the real algorithm (with reference to Arduino). To begin with, we will read the direction indications not every cycle, but every measurement (after the value of the anemometer frequency). The result obtained in the Gray code (we denoted it as wind_Gray of the byte type, see
that publication ) we convert to ordinary binary code, and, like the frequency of the anemometer, we place it in the global array, which we declare as wDirAvr [4], where 4 is the number of measurements in the cycle. We will not paint the conversion of the four-digit Gray code to binary code - this can be done in several ways at the discretion of the programmer and is described in any reference book.
This binary code will take values ​​from 0 to 15, and we will agree that we will count the angles, not as shifted geographers / topographers / navigators, but as normal people who have studied trigonometry in school - counterclockwise. That is, if the zero value corresponds to the north, then 90 degrees is not east, as in “shifted” ones, but west. Since we have 16 gradations of direction, the code value must be multiplied by 22.5 (360/16) in order to get the direction in usual degrees of arc.
Now the algorithm itself of the simplified vectorial averaging of direction from 4 code values:
. . . . . 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 . . . . .
In the last line, we convert the average, expressed in radians, into the average, expressed in our code from 0 to 15. You can then convert back to Gray code, then you don't even have to change the program in the main module to display the direction.
That's the whole algorithm. I was afraid that the calculation of cosine-arccosinuses would be slowed down by the weak (in the current 32-bit time) Arduino controller, but nothing happened: he swallowed the code without even blinking ... with a LED, I guess.
UPD : The algorithm of the author works in this form for several months without failures. However, commentators put me on a possible, though extremely unlikely error in practice: if the data contain two groups of measurements that are approximately 180 degrees apart from each other (ie, about 90 and 270 degrees), then the algorithm will produce an erroneous value. To avoid it, instead of acos (), you should use the atan2 (wSin, wCos) function, which immediately gives the correct result, taking into account the sine and cosine signs (thanks to
aamonster for the hint). The line where the mean value of wSin is calculated, should be uncommented, and the line adjusted for the wSin sign is not needed. Instead, you need to insert a cast to positive values ​​of the angle (since atan2 gives values ​​from pi to -pi):
if (wind_Rad<0) wind_Rad=2*M_PI+wind_Rad;