0.2.2 AverageAngle

This commit is contained in:
Rob Tillaart 2024-04-09 10:32:29 +02:00
parent a959b0048c
commit b24851e77a
17 changed files with 148 additions and 41 deletions

View File

@ -1,4 +1,5 @@
# These are supported funding model platforms
github: RobTillaart
custom: "https://www.paypal.me/robtillaart"

View File

@ -1,12 +1,12 @@
name: Arduino-lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -1,4 +1,3 @@
---
name: Arduino CI
on: [push, pull_request]
@ -6,9 +5,10 @@ on: [push, pull_request]
jobs:
runTest:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -9,10 +9,11 @@ on:
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
uses: limitusus/json-syntax-check@v2
with:
pattern: "\\.json$"

View File

@ -1,7 +1,7 @@
//
// FILE: AverageAngle.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// VERSION: 0.2.2
// DATE: 2017-11-21
// PURPOSE: Arduino library to calculate correctly the average of multiple angles.
// URL: https://github.com/RobTillaart/AverageAngle
@ -67,7 +67,17 @@ uint32_t AverageAngle::count()
float AverageAngle::getAverage()
{
float angle = atan2(_sumy, _sumx);
if (angle < 0) angle += TWO_PI; // (PI * 2);
if (isnan(angle))
{
_error = AVERAGE_ANGLE_SINGULARITY;
return angle;
}
_error = AVERAGE_ANGLE_OK;
if (angle < 0)
{
angle += TWO_PI; // (PI * 2);
}
if (_type == AverageAngle::DEGREES )
{
angle *= RAD_TO_DEG; // (180.0 / PI);
@ -76,16 +86,6 @@ float AverageAngle::getAverage()
{
angle *= RAD_TO_GRAD; // (200.0 / PI);
}
// error reporting
if (isnan(angle))
{
_error = AVERAGE_ANGLE_SINGULARITY;
}
else
{
_error = AVERAGE_ANGLE_OK;
}
return angle;
}
@ -104,6 +104,18 @@ float AverageAngle::getAverageLength()
}
float AverageAngle::getSumX()
{
return _sumx;
}
float AverageAngle::getSumY()
{
return _sumy;
}
AverageAngle::AngleType AverageAngle::type()
{
return _type;

View File

@ -2,15 +2,16 @@
//
// FILE: AverageAngle.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// VERSION: 0.2.2
// DATE: 2017-11-21
// PURPOSE: Arduino library to calculate correctly the average of multiple angles.
// URL: https://github.com/RobTillaart/AverageAngle
#include "math.h"
#include "Arduino.h"
#define AVERAGE_ANGLE_LIB_VERSION (F("0.2.0"))
#define AVERAGE_ANGLE_LIB_VERSION (F("0.2.2"))
#define GRAD_TO_RAD (PI / 200.0)
#define RAD_TO_GRAD (200.0 / PI)
@ -40,6 +41,8 @@ public:
float getTotalLength();
// if count == 0 average length == 0.
float getAverageLength();
float getSumX();
float getSumY();
AngleType type();
bool setType(AngleType type);

View File

@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.2] - 2024-04-08
- update GitHub actions
- fix version number
- refactored **getAverage()** early singularity detection.
- add **float getSumX()** and **float getSumY()**
- add example
- update keywords.txt
- add unit test
- minor edits
## [0.2.1] - 2023-10-17
- update readme.md
- update keywords.txt

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2023 Rob Tillaart
Copyright (c) 2017-2024 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -43,11 +43,11 @@ These (x,y) are added to a (sumX, sumY) and divided by the number of angles adde
- **enum AngleType { DEGREES, RADIANS, GRADIANS }** idem.
| value | name | range |
|:-------:|:-----------|:-----------|
| 0 | DEGREES | 0 .. 360 |
| 1 | RADIANS | 0 .. 2PI |
| 2 | GRADIANS | 0 .. 400 | 100 GRADIANS == 90 DEGREES.
| value | name | range | notes |
|:-------:|:-----------|:----------:|:--------|
| 0 | DEGREES | 0 .. 360 |
| 1 | RADIANS | 0 .. 2PI |
| 2 | GRADIANS | 0 .. 400 | 100 GRADIANS == 90 DEGREES.
## Interface
@ -69,7 +69,7 @@ Type can be changed run time and still continue to add.
- **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).
Returns the number of elements added so far (count).
If the internal sumx or sumy is >= 10000, the error **AVERAGE_ANGLE_OVERFLOW** is set.
This indicates that the internal math is near or over its accuracy limits.
- **uint32_t count()** the number of angles added.
@ -81,6 +81,8 @@ If NAN the error **AVERAGE_ANGLE_SINGULARITY** is set.
If count == 0 ==> total length = 0.
- **float getAverageLength()** returns the average length of the angles added.
If count == 0 ==> average length = 0.
- **float getSumX()** get internal sumx counter. Rectangular coordinates.
- **float getSumY()** get internal sumy counter. Rectangular coordinates.
#### Error handling
@ -94,7 +96,6 @@ If count == 0 ==> average length = 0.
| AVERAGE_ANGLE_SINGULARITY | -20 |
#### Experimental Overflow
(since 0.2.0)
@ -109,7 +110,7 @@ Note this condition is independent of the **AngleType** as the internal math
uses radians. The condition will be triggered faster when the length parameter
is used.
The overflow threshold of 10000 can be patched in the .cpp file if needed.
The overflow threshold of 10000 can be adjusted in the AverageAngle.cpp file if needed.
As this feature is **experimental**, the trigger condition for overflow will
probably be redesigned in the future. See future section below.
@ -122,7 +123,8 @@ There are 100 gradians in a right angle. A full circle = 400 gradians.
https://en.wikipedia.org/wiki/Gradian
See also AngleConvertor library.
Other less used units for measuring angles:
- https://github.com/RobTillaart/AngleConvertor
## Operation
@ -144,8 +146,8 @@ 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.
```cpp
AA.reset();
AA.add(90, 5); // 5 steps north
AA.add(180, 3); // 3 steps west
AA.add(90, 5); // 5 steps north assuming east = 0
AA.add(180, 3); // 3 steps west
Serial.println(AA.getAverage());
Serial.println(AA.getTotalLength());
```
@ -170,7 +172,7 @@ just change the type runtime.
- investigate if and how the internal math can be made more robust against overflow.
- use double instead of float (will work on certain platforms) (must) => 0.3.0
- uint32_t?
- accuracy threshold depends on float/double usage. (sizeof(double)==8)
- accuracy threshold depends on float / double usage. (sizeof(double) == 8)
- threshold depends on the units of length.
if all add's are using 10000 as length they have equal weight.
normalizing the weight? how? user responsibility?
@ -188,14 +190,19 @@ just change the type runtime.
#### Could
- **uint32_t addDegrees(float angle)** more explicit.
- **uint32_t addRadians(float angle)** idem.
- **uint32_t addGradians(float angle)** idem.
#### Wont
- 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?
- maybe better for the AngleConvertor class.
#### Wont
## Support

View File

@ -1,8 +1,8 @@
//
// FILE: averageAngle.ino
// AUTHOR: Rob Tillaart
// DATE: 2017-11-21
// PURPOSE: demonstrates the usage of the AverageAngle Class
// URL: https://github.com/RobTillaart/AverageAngle
#include "AverageAngle.h"

View File

@ -1,8 +1,8 @@
//
// FILE: averageAngle.ino
// AUTHOR: Rob Tillaart
// DATE: 2017-11-21
// PURPOSE: demonstrates the usage of the AverageAngle Class
// URL: https://github.com/RobTillaart/AverageAngle
#include "AverageAngle.h"

View File

@ -0,0 +1,51 @@
//
// FILE: averageAngle_getSum.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demonstrates the usage of the AverageAngle Class
// URL: https://github.com/RobTillaart/AverageAngle
//
// view in plotter is nice.
#include "AverageAngle.h"
void setup()
{
Serial.begin(115200);
// Serial.println(__FILE__);
// Serial.print("AVERAGE_ANGLE_LIB_VERSION: ");
// Serial.println(AVERAGE_ANGLE_LIB_VERSION);
// Serial.println();
test0();
}
void loop()
{
}
void test0()
{
AverageAngle AA(AverageAngle::DEGREES);
AA.reset();
Serial.println("Degrees\tSumX\tSumY\tLength");
for (int d = 0; d <= 360; d++)
{
AA.add(d);
Serial.print(d);
Serial.print("\t");
Serial.print(AA.getSumX(), 4);
Serial.print("\t");
Serial.print(AA.getSumY(), 4);
Serial.print("\t");
Serial.print(AA.getTotalLength(), 4);
Serial.println();
}
}
// -- END OF FILE --

View File

@ -1,8 +1,8 @@
//
// FILE: AverageAngle_setType.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-10-18
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AverageAngle
#include "AverageAngle.h"

View File

@ -13,6 +13,8 @@ count KEYWORD2
getAverage KEYWORD2
getTotalLength KEYWORD2
getAverageLength KEYWORD2
getSumX KEYWORD2
getSumY KEYWORD2
setType KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/AverageAngle.git"
},
"version": "0.2.1",
"version": "0.2.2",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=AverageAngle
version=0.2.1
version=0.2.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library to calculate correctly the average of multiple angles.

View File

@ -119,13 +119,32 @@ unittest(test_gradians)
fprintf(stderr, "%f\n", aa.getTotalLength());
fprintf(stderr, "%f\n", aa.getAverageLength());
assertEqual(10, aa.count());
assertEqual(10, aa.count());
assertEqualFloat(4.5, aa.getAverage(), 0.001);
assertEqualFloat(9.98982, aa.getTotalLength(), 0.001);
assertEqualFloat(0.998982, aa.getAverageLength(), 0.001);
}
unittest(test_sumx_sumy)
{
AverageAngle aa(AverageAngle::DEGREES);
for (int i = 0; i < 10; i++)
{
int n = aa.add(i);
assertEqual(i + 1, n);
}
fprintf(stderr, "%f\n", aa.getAverage());
fprintf(stderr, "%f\n", aa.getSumX());
fprintf(stderr, "%f\n", aa.getSumY());
assertEqual(10, aa.count());
assertEqualFloat(9.95665, aa.getSumX(), 0.001);
assertEqualFloat(0.783605, aa.getSumY(), 0.001);
}
unittest_main()