## Tuesday, November 8, 2011

### Damping AWA, TWA and heading values

Damping values is typically achieved by updating a running average of an appropriate number of past measurements.  But calculating averages of AWA, TWA and heading values presents a problem.

AWA and TWA use values between -180 and +180 deg. The problem occurs when the values to average cross the +-180 line.  For example the arithmetic average of -170 and + 160 deg is -5 deg instead of the correct average of +175 deg.

Compass headings use values between 0 and 360 deg. Here the problem arises when the values to average cross the 0 deg line. For example, the arithmetic average of 350 and 20 deg gives 185 deg instead of the correct 5 deg.

The solution developed here is to keep a double accounting of all the angles, one in the -180 to 180 range, the other in the 0 to 360 range. The average is calculated in both ranges, but only one is valid. The right value is identified and converted to original range if necessary.
Here is the algorithm used for averaging  AWA (or TWA) values.

// AWA values to average (-180 to 180)
double awa[5] = {-170.0, -170.0, 175.0, 175.0, 175.0);
// alternate list (0 to 360)
double awa_alt[5];
// build the alternate list (0 to 360)
for(i = 0; i < 5; i++)
{
if(awa[i] < 0.0)
awa_alt[i] = awa[i] + 360.0;
else awa_alt[i] = awa[i];
}
/*
Alternate list: 190, 190,  175, 175, 175
*/
// calculate the average of both lists
double awa_av = 0.0;
double awa_alt_av = 0.0;
for(i = 0; i < 5; i++)
{
awa_av += awa[i];
awa_alt_av += awa_alt[i];
}

awa_av /= 5;
awa_alt_av /= 5;
/*
awa_av = 37.0, awa_alt_av = 181.0
*/
// find min and max of original list
double minang = 999.0;
double maxang = -999.0;
for(i = 0; i < 5; i++)
{
if(awa[i] < minang)
minang = awa[i];
if(awa[i] > maxang)
maxang = awa[i];
}
/*
minang = -170, maxang = 175
*/

double minmax = minang * maxang;
/*
minmax = -29750
*/
/*
If minmax is positive, this means that the
original values were either all positive or
all negative, and the original average is
valid. If minmax is negative, this means that
the wind crossed the axis of the boat. If a front
wind crossed the axis of the boat, the original
average is valid. If a rear wind crossed the
axis of the boat, then the alternate average
(0 to 360) is valid, and must be converted back
to -180 to 180.
*/

if(minmax < 0.0) // wind crossed axis of the boat
{
if(minang < -90.0)   // rear wind, take 0-360 average
{
// convert to -180 to 180
if(awa_alt_av > 180.0)
awa_av = awa_alt_av - 360.0;
else
awa_av = awa_alt_av;
}
}
/*
At this point, the variable awa_av contains
the correct average of -179.0 deg.
*/

Some practical results using this algorithm can be seen here.