GroveStreams

Steel series Direction gauge questions189

jfels private msg quote post Address this user
The Steel Series direction gauge has two needles. One for Latest and the other for Average. I am having trouble understanding how the Average section of this gauge works. What is the source of this input? It always reads 0 for me. If I add a second source, I merely get a second gauge.

Is there any way to turn off the Average readout on this widget? I really don't need it anyway.

On the subject of average for wind direction. There does not appear to be any appropriate rollup option for wind direction. Wind direction is a Vector value rather than a Scalar value and requires a Vector Average. For example if you use a straight numerical average of two directions 30 degrees and 330 degrees, you would get 180 degrees. The correct answer is 0 degrees.
Post 1 IP   flag post
MikeMills private msg quote post Address this user
We didn't spend much time playing with this widget as we're not that knowledgeable in the science of wind . That being said, what you're saying makes sense.

You might be the first attempting to use the average feature on this control. Anyone else have a solution?

I wonder if a derived stream could do the appropriate calculation?

We'll take a look at this, in a couple of days if you or anyone else doesn't have a solution. We're a bit busy to investigate it asap.
Post 2 IP   flag post
MikeO private msg quote post Address this user
Over how many data points would you need to have the average? What is the interval of those streams (10s, 1 M, 10M, etc?).
Post 3 IP   flag post
MikeMills private msg quote post Address this user
Research, so far, indicates the formula is:

sa = sum of sines of angles
sb = sum of cosines of angles
A = ( arctan(sa/sb) ) mod 360

or

A = arctan(sum( [sin(x1) + sin(x2) ...sin(xn)] ) / sum( [cos(x1) + cos(x2) ...cos(xn)] ) ) mod 360

What is the time range you'd like to report the average over? How many direction samples will exist in that time range?

Derivation may be a solution if there are 15 or less samples and a rolling average is acceptable. You wouldn't be able to use the average pointer, but would have to have a second wind gauge and just title it "Average" and have it reference the derived stream.
Post 4 IP   flag post
jfels private msg quote post Address this user
Mike,

I was going to get back to you earlier with the formula but I have been busy getting a couple of prototypes going.

You are basically correct. To compute the Vector Average. The direction needs to be broken down into it's N-S and E-W components. The North-South is done with the Cosine function. The East-West is with the sine function.

These two components are summed separately and then the Atan function is used to get the angle. atan(Sin/Cos). In reality, the atan2 function should be used if the math library supports it. More below.

The big caveats are.
1. Almost all computer math libraries use Radians instead of degrees.
Degrees to Radians (Pi/180). Radians to degrees (180/Pi).

2. The atan() function produces values in the range -90 to +90 degrees. The Quadrant needs to be determined by the sign of the components. If Cos < 0, add 180 degrees (Quad 2 & 3). If Sin < 0 and Cos > 0 add 360 degrees (Quad 4).

The Atan2 function takes the two parameters and does all of the quadrant guessing and divide by 0 protection etc. It is called by:

dir = atan2(Cos,Sin). The output of this is -180 to 180 (-Pi to Pi). So if the result is < 0, add 360.

I have an Excel macro function that I wrote for this so I could do something like. =flDir(X,Y) in a cell.

Function flDir(flCos, flSin)
    flDirection = Application.WorksheetFunction.Atan2(flCos, flSin)
    flDirection = Application.WorksheetFunction.Degrees(flDirection)
    If (flDirection < 0) Then flDirection = flDirection + 360
    flDir = flDirection
End Function



Ideally, this Vector method would be added to the Rollup options.
Post 5 IP   flag post
MikeMills private msg quote post Address this user
We're definitely going to fix this, but we can't start on it right away. @MThomas just requested a Wind Rose Plot and it will require this solution too.

Here are a couple of other thoughts we'll need to take into consideration when we figure out the end solution:
* We have the same problem for our LATITUDE and LONGITUDE streams so we need a concept that works for those too

* We're considering adding a new stream value type called DIRECTION360. Our AVG rollup calc engine will calculate averages the correct way for DIRECTION360, LATITUDE, and LONGITUDE streams.

* The Wind direction gauge assumes:
- a value of 0 equals no wind (calm)
- values between 1 and 360 are used for direction
Is that what your sensor assumes too. If not, how does it record calm? Or does it rely on a wind speed stream to indicate calm?

We'd like DIRECTION360 to work for all direction sensors, not just wind so we need a standard range to represent direction. It appears 0-360 (360 is exclusive - it's really 0) is the one.
Post 6 IP   flag post
jfels private msg quote post Address this user
We rely on a wind speed to determine calm. In the industry, the term "Light and Variable" is typically used to indicate that the direction is to be taken with a grain of salt. Even with really good bearings, it takes a certain volume of air to move the wind vane. Even then with really light wind the direction varies around quite a bit.

You are right. 360 is really 0. In my code, I make anything > 359.9 to be 0.
Post 7 IP   flag post
MikeMills private msg quote post Address this user
What would you expect for an average with these inputs:
0
90
180
270

We're churning out 180.
Post 8 IP   flag post
jfels private msg quote post Address this user
You're evil ;-) This is a bit like trying to do a linear regression on a circular cluster of points.

Actually, it is good to test the boundary conditions. This case has 0 for the sum of the Cos as well as the sum of the Sin. When I tried this experiment in Excel, I got a divide by 0 error on the atan2() function even though it correctly handles a 0 Cos when the Sin has a value.

In my devices, I am using the atan(Sin/Cos) equation and resolving the quadrants. I have a divide by 0 protection by making the Cos .000001 if it is 0. This yields 0 degrees from the atan() and the atan2() functions.

I'm having lunch today with our retired Meteorology Product Manager. I will ask him whether he thinks that 0 or 180 is the more appropriate answer.
Post 9 IP   flag post
MikeMills private msg quote post Address this user
Yeah, writing some fringe case unit tests. It's always those fringe cases that get ya.

It's probably a java library making the decision right now. Here's a snippet of what we're doing:

Loop over data:
sumSin += Math.sin(Math.toRadians(data[j]));
sumCos += Math.cos(Math.toRadians(data[j]));

avg1 = Math.atan2(sumSin, sumCos);
avg2 = (Math.toDegrees(avg1) + 360) % 360;

For the example samples above(0,90,180,270) :
sumSin = 0
sumCos = -3.6739403974420594E-16 //really zero
avg1 = 3.141592653589793 //Looks familiar
avg2 = 180

0 or 180. Maybe it's not that important and just needs to be documented. We also have the capability to just set the result to null which would indicate a gap. It will be interesting to see what the Meterologists says. Null might be the way to go.

Also, we're working on weighing the result with time spans for interval streams. Still working on the math...
Post 10 IP   flag post
jfels private msg quote post Address this user
I talked to my guy and he says that the correct answer should be 0 degrees.

That being said, if either the sums are exactly 0 and the other one has any amplitude at all no matter how slight, you will get an answer that falls on a multiple of 90 degrees. With the conversions between degrees and radians, there is a bit of rounding going on which makes these values not be exactly zero.

You should test your atan2 function by feeding it Math.atan2(0,0) and make sure you do not get a divide by 0 error. If so, you will want to protect against that. Otherwise, I would just go with the value you get.

I would prefer to see 0 instead of NULL.

For wind direction, I am not sure if it is that critical to weight the time spans for interval streams.

As far as weighting is concerned. The formula that I gave you was for the Unit Vector Average which assumes an amplitude of 1 for each data point. This is by far the most common usage in Met. Wind is a true vector in that it has a direction and speed. The true vector average would multiply the Sin and Cos values by the Speed before summing. I didn't bother mentioning it earlier because this usage is very rare and I didn't want to confuse the issue. It is also much more complicated in that you would have to point to another feed for the speed parameter. Nevertheless, this is how weighting is done.

Are you planning on making this direction360 data type a 4 byte or 8 byte float?
Post 11 IP   flag post
MikeMills private msg quote post Address this user
0, good.

The calculation to sum the sin and cos radians in java resulted in a floating point that, in reality is zero. But, it was off enough to throw off the atan2 result. I've added this and I get the results you're requesting:
if(sum < 0.0000000000001 && sum > -0.0000000000001) {
sum = 0d;
}

Here are some test case results:
1,1,1,1,359,359,359,359 = 0
1,3 = 2
0,90 = 0
0,180 = 0
10,190 = 0
0,90,180 = 90
0,90,180,270=0

Math.atan2(0, 0) equals zero - I tested it.
Going with a double (8 byte).

"The true vector average would multiply the Sin and Cos values by the Speed before summing." Yes, I saw that in other examples. I think what we have so far is good (amplitude of 1). I'm hoping that when we get around to a wind rose graph, the direction and a speed stream (with optional cycle selections) is all that is needed. Not an expert in Wind Rose graphs, but I think that's what they plot.
Post 12 IP   flag post
jfels private msg quote post Address this user
This sounds good.

I really appreciate your effort on this. All of the major data loggers in the industry handle this but I have not seen any of the IoT services that I have reviewed handle vector averaging.

You may well be the first one on the block.

I can give you some insights on Wind Rose graphs after I dig myself out from under some stuff here. Would you prefer it in the forum or out of band?
Post 13 IP   flag post
MikeMills private msg quote post Address this user
Wind Rose - A forum discussion would be best since another user is requesting it. When you're ready, let's continue that discussion on his thread which is here.
Post 14 IP   flag post
MikeMills private msg quote post Address this user
It's in the production site:
* Enter your org and hit F5 to ensure you refresh your browser cache and pickup the latest changes
* Edit your component (right click on it and choose edit)
* Select your stream and change its value type to Direction360

We just discovered a bug in the reconcile engine for the Direction360 so you won't be able to change an existing stream type to that type and preserved the data. You have to delete all the data first until we fix the bug.
Post 15 IP   flag post
2968 15 15
Log in or sign up to compose a reply.