mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.2.2 AverageAngle
This commit is contained in:
parent
a959b0048c
commit
b24851e77a
1
libraries/AverageAngle/.github/FUNDING.yml
vendored
1
libraries/AverageAngle/.github/FUNDING.yml
vendored
@ -1,4 +1,5 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: RobTillaart
|
||||
custom: "https://www.paypal.me/robtillaart"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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$"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -43,8 +43,8 @@ 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 |
|
||||
|:-------:|:-----------|:-----------|
|
||||
| value | name | range | notes |
|
||||
|:-------:|:-----------|:----------:|:--------|
|
||||
| 0 | DEGREES | 0 .. 360 |
|
||||
| 1 | RADIANS | 0 .. 2PI |
|
||||
| 2 | GRADIANS | 0 .. 400 | 100 GRADIANS == 90 DEGREES.
|
||||
@ -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,7 +146,7 @@ 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(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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 --
|
@ -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"
|
||||
|
@ -13,6 +13,8 @@ count KEYWORD2
|
||||
getAverage KEYWORD2
|
||||
getTotalLength KEYWORD2
|
||||
getAverageLength KEYWORD2
|
||||
getSumX KEYWORD2
|
||||
getSumY KEYWORD2
|
||||
|
||||
setType KEYWORD2
|
||||
|
||||
|
@ -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": "*",
|
||||
|
@ -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.
|
||||
|
@ -126,6 +126,25 @@ unittest(test_gradians)
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user