GY-63_MS5611/libraries/AverageAngle
2022-12-07 20:30:13 +01:00
..
.github add funding.yml 2022-08-03 21:56:07 +02:00
examples 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
test 0.1.8 AverageAngle 2022-10-29 13:59:29 +02:00
.arduino-ci.yml 0.1.8 AverageAngle 2022-10-29 13:59:29 +02:00
AverageAngle.cpp 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
AverageAngle.h 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
CHANGELOG.md 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
keywords.txt 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
library.json 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
library.properties 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00
LICENSE 0.1.7 AverageAngle 2021-12-13 20:51:57 +01:00
README.md 0.1.9 AverageAngle 2022-12-07 20:30:13 +01:00

Arduino CI Arduino-lint JSON check License: MIT GitHub release

AverageAngle

Arduino library to calculate correctly the average of multiple angles.

Description

AverageAngle is a class to calculate the average of angles.

This is especially useful when angles are around 0 degrees, e.g. from a compass sensor or the resultant of a track. Example, the average angle of 359 and 1 is 0, not 179 (most of the time)

Furthermore the AverageAngle can also include the length (weight) of the angle as if it is a vector. Default this length is set to 1 so all angles are by default of equal weight.

Example: The average angle of 359 (length = 2) and 1 (length = 1) is 359.something not zero.

The average angle is calculated by converting the added angle (in DEGREES, etc) to polar coordinates. These (x,y) are added to a (sumX, sumY) and divided by the number of angles added so far.

AngleType

  • enum AngleType { DEGREES, RADIANS, GRADIANS } idem.
value name range
0 DEGREES 0 .. 360
1 RADIANS 0 .. 2PI
2 GRADIANS 0 .. 400

Interface

  • AverageAngle(AngleType type = DEGREES) constructor defaults to degrees.
  • uint32_t add(float alpha, float length = 1.0) add a new angle, optional with length other than 1. Returns the number of elements (count).
  • void reset() clears internal counters.
  • uint32_t count() the amount of angles added. If count == 0, there is no average.
  • float getAverage() returns the average, unless count == 0 or the internal sums == (0,0) in which case we have a singularity ==> NAN (not a number)
  • float getTotalLength() the length of the resulting 'angle' when we see them as vectors. If count == 0 ==> total length = 0.
  • float getAverageLength() returns the average length of the angles added. If count == 0 ==> average length = 0.
  • AngleType type() returns DEGREES, RADIANS or GRADIANS.
  • void setType(AngleType type) changes type DEGREES, RADIANS or GRADIANS. Type can be changed run time and still continue to add.

Gradians

Gradians a.k.a. gon, is a less often used unit for angles. There are 100 gradians in a right angle. A full circle = 400 gradians.

https://en.wikipedia.org/wiki/Gradian

Operation

If you want to average 5 compass readings you can just add the angles and do not use the length parameter.

  AA.reset();
  for (int i = 0; i < 5; i++)
  {
    AA.add(compass.readHeading());
    delay(100);    // e.g. compass read needs some time
  }
  Serial.println(AA.getAverage());

If you want to average a track, e.g. 5 steps North, 3 steps west etc, you need to include the length of each step.

  AA.reset();
  AA.add(90, 5);     // 5 steps north
  AA.add(180, 3);    // 3 steps west
  Serial.println(AA.getAverage());
  Serial.println(AA.getTotalLength());

If you want to average an angle in DEGREES and an angle in RADIANS, just change the type runtime.

  AA.reset();
  AA.setType(DEGREES);
  AA.add(90);
  AA.setType(RADIANS);
  AA.add(PI/3);
  AA.setType(DEGREES);
  Serial.println(AA.getAverage());

Warning

As the internal representation has a limited resolution (float) it can occur that when the internal values are large, one cannot add a very small angle any more. Did not encounter it yet myself.

Future

Must

Should

Could

  • add a USER AngleType, in which the user can map 0..360 degrees to any range.
    • float userFactor = 1.0; (default)
    • can even be negative?
    • use cases? e.g 0..4 quadrant?