Go Down

Topic: AverageAngle, a library to average of multiple headings (Read 481 times) previous topic - next topic

robtillaart

Dec 09, 2017, 06:46 pm Last Edit: Dec 09, 2017, 10:09 pm by robtillaart
In a recent project I needed to average multiple angles, sort of heading of a compass. This averaging was needed to minimize noise in the individual samples. The first straightforward code worked quite well until I got to the border case around 360 == 0 degrees. Averaging { 359, 0, 1 } did not gave the expected 0 or 360 but 120, which was a wakeup call to rethink my math.

The result is a AverageAngle library. An AverageAngle object can add multiple angles and give a correct average. The lib works both with DEGREES and RADIANS to be set in the constructor, DEGREES being the default. A simple test sketch completes the library.

The inner working is mapping the angles on a plane in X and Y coordinates and take the average of X and Y. Optionally one can add the length (weight or distance) for every angle so it can be used broader than needed within my project.

Sources on Github - https://github.com/RobTillaart/Arduino/tree/master/libraries/AverageAngle.

As always comments and remarks and improvements are welcome.

Code: (sample snippet) [Select]
void test3(int count)
{
  AverageAngle AA(AverageAngle::RADIANS);

  AA.reset();
  for (int i = 0; i < count; i++)
  {
    AA.add( PI / 180 * random(180));
  }
  int cnt = AA.count();
  float avg = AA.getAverage();

  Serial.println(__FUNCTION__);
  Serial.print("COUNT:\t");
  Serial.println(cnt);
  Serial.print("AVG:\t");
  Serial.println(avg, 6);
  Serial.println("EXPECT:\t~PI/2");
  Serial.println();
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up