Wednesday, August 28, 2013

WxService Update Available

WxMonitor ow4j130826

  • Fixed discrepancy with event intervals when wind speed and wind direction both contribute to a single composite value (wind history).  
  • Changed wind history display defaults to 120000 msec. (two minutes) interval and 3600000 msec. (one hour) length; updated config.html to document this.  
(Download...)

Tuesday, August 27, 2013

Building Your Own Computer? Important Safety Tip!

If you are building your own computer, or replacing a motherboard, or moving cables around, here is an important safety tip: Due to atrociously bad engineering, motherboard headers are physically identical for USB and firewire. However, the power and signal assignments are quite different. If you accidently connect your front panel USB ports to a firewire header on the motherboard, then any USB device that you connect to those ports will be destroyed instantly. It may also destroy the firewire port on the motherboard as well. My son and I found that out the hard way, but if you Google it, you will find that we are far from alone.

USB Header Pin Configuration

Firewire Header Pin Configuration

This is an easy mistake to make, especially if it is not the initial build, where you have the motherboard layout docs handy. The headers may not be clearly marked, and often the header nomenclature will be obscured by other components, and board real-estate for silkscreened labels sometimes puts the labels ambiguously far from the thing being labeled.

Update: It is also possible to sabotage your front panel USB jacks by plugging the internal connectors on backwards if the case uses connectors split down the middle. On such a connector, there is no key to prevent reversal, in which case the data polarity is reversed, and worse, +5 goes to GND and vice-versa. The power swap will destroy any attached USB devices. 

Tuesday, August 13, 2013

How Vector Average Would Sum to Zero

In my post Consensus Averaging vs. Vector Averaging, I mentioned that adding two opposing vectors could produce undefined results. In a wind vane data averaging scenario, this would be extremely unlikely.

Assume the following conditions: A sample interval of 1 second, an average interval of 2 minutes, yielding 120 samples per average result. Incoming data is aligned on 16 compass headings:


It is quite possible for any two vectors to sum to zero. But we have 120 vectors to sum. In order to cancel out completely, we would require one of the following:
  • 60 vectors symmetrically distributed on either yellow or violet line.
  • 30 vectors symmetrically distributed on both the yellow and violet lines.
  • 30 vectors symmetrically distributed on any red, green or blue rectangle.
  • 15 vectors symmetrically distributed on all points.
  • Other permutations of symmetrical distributions on the various lines and rectangles and their rotations.
  • Equal numbers of samples from the northeast and northwest will result in a north vector that could be canceled by some number of south vectors. 
This list goes on, but when the wind is blowing, by far the most common scenario will have chaotic or turbulent input data in which more than half of the input data will be in the general direction of the prevailing wind, providing a dithered average with good resolution.

Friday, August 9, 2013

WxService Update Available

WxMonitor ow4j130809

  • Widened Add Property dialog input field labels to display correctly on OpenJDK in Linux.

WxService ow4j130809

  • Refactored WindVane averaging algorithm to use pre-calculated sin and cos values, since we know what they are all the time. Looks up the values based on one of the 16 cardinal compass points. 

Thursday, August 8, 2013

WxService Update Available

WxMonitor ow4j130807

  • Made the WxMonitor animation speed configurable. The animation speed can be controlled by the configuration property wxmonitor.sensor.event.animation.interval. It is normally set for 38, or about one sensor event per minute (fast). You can set it as low as 1, or about 38 sensor events per minute (slow). 
  • Made the WxMonitor animation length configurable. The animation length can be set from 0 milliseconds (no event backlog) to 86,400,000 milliseconds (24 hours) as the last argument on the command line.

WxService ow4j130807

Consensus Averaging vs. Vector Averaging

One Wire Weather Service for Java has been using Consensus Averaging to smooth wind vane data and increase device resolution, from its initial implementation several years ago. I thought it gave good results, although the algorithm proved difficult for me to analyze clearly.

I was reviewing some weather data recently, and I noticed that the wind direction seemed to have slight but noticeable affinity for the sixteen primary compass points. Since nature doesn't do that, I had to suspect a problem with the hardware or software. I decided to start with the software, since that's easier to tweak. I began looking for angle averaging algorithms on the web, simply to get an idea of what kinds of solutions other people had come up with. There are several, some of them quite convoluted, home-brew algorithms. However, I found several similar examples of vector averaging. 

Vector averaging entails converting each angle (wind compass heading from the wind vane) to a vector on the unit circle, and finding the x and y coordinates, averaging the coordinates, and taking the arc tangent, converting them back to an angle. The code to do this is actually very simple.

    /**
     * Calculates the average value by converting the angles to 
     * vectors on the unit circle and averaging the Cartesian 
     * coordinates. This avoids the 360~0 wrap-around at North. 
     * Math.atan2 returns the angle between -pi and pi. Therefore, 
     * we add tau to the result to force a positive angle, mod by
     * tau and convert to degrees.
     * @param data array of sensor data to average.
     * @return average directional value.
     */
    public double averageValue(double[] data) {
        int length = data.length;
        double sin = 0, cos = 0;

        for (int ii = 0; ii < length; ii++) {
            sin += Math.sin(data[ii]);
            cos += Math.cos(data[ii]);
        }
        double theta = Math.atan2(sin / length, cos / length);

        return Math.toDegrees((tau + theta) % tau);
    }

where tau = 2π.

One of the main reasons for averaging wind vane data is that the resolution of the wind vane itself is very coarse - only 16 compass points. But wind is turbulent, so the wind vane swings back and forth over several points. This turbulence dithers the data, so the average has a much higher resolution.

I mentioned earlier that consensus averaging did increase the wind vane resolution, but some affinity remained. I had difficulty analyzing the algorithm, so it wasn't obvious to me how to modify it. But the vector averaging algorithm appears to exhibit no affinity; the output is completely de-correlated, without requiring any tweaks or tuning. It "just works".

Vector averaging does have one potential problem: if two vectors are 180 degrees out of phase, they will cancel out, yielding an undefined angle. Fortunately, we have about 40 data points for each average sample. In order for the average to be zero, all of the vectors would have to be in opposition. That would be exceedingly unlikely for a wind vane that is supposed to point into the wind, even with very low air motion. The widest wind vane swing is about 90 degrees over relatively short time periods (e.g., a two minute averaging interval).

Update: I found out from the authors of consensus averaging that the original implementation did not have the benefit of a software math library with floating point arithmetic and trigonometric functions. That makes all the difference in the world. Necessity is a mother ... ~ KU