-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrunningAngle.cpp
127 lines (99 loc) · 1.92 KB
/
runningAngle.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// FILE: runningAngle.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// PURPOSE: Library to average angles by means of low pass filtering with wrapping.
// URL: https://github.com/RobTillaart/runningAngle
// RELATED: https://github.com/RobTillaart/AverageAngle
#include "runningAngle.h"
runningAngle::runningAngle(const enum AngleType type)
{
_type = type;
reset();
}
void runningAngle::reset()
{
_average = 0;
_weight = RA_DEFAULT_WEIGHT;
_reset = true;
}
float runningAngle::add(float angle)
{
if (_reset)
{
_average = wrap(angle);
_reset = false;
}
else
{
_average = wrap(_average + _weight * wrap(angle - _average));
}
if (_mode == 0) return _average;
return getAverage();
}
float runningAngle::getAverage()
{
if (_mode == 0) return _average;
if (_average >= 0) return _average;
if (_type == DEGREES) return _average + 360;
if (_type == RADIANS) return _average + TWO_PI;
// GRADIANS
return _average + 200;
}
bool runningAngle::setWeight(float w)
{
if (w < RA_MIN_WEIGHT)
{
_weight = RA_MIN_WEIGHT;
return false;
}
if (w > RA_MAX_WEIGHT)
{
_weight = RA_MAX_WEIGHT;
return false;
}
_weight = w;
return true;
}
float runningAngle::getWeight()
{
return _weight;
}
enum runningAngle::AngleType runningAngle::type()
{
return _type;
}
float runningAngle::wrap(float angle)
{
if (_type == DEGREES)
{
while (angle < -180) angle += 360;
while (angle >= +180) angle -= 360;
}
else if (_type == RADIANS)
{
while (angle < -PI) angle += TWO_PI;
while (angle >= +PI) angle -= TWO_PI;
}
else // GRADIANS
{
while (angle < -200) angle += 400;
while (angle >= +200) angle -= 400;
}
return angle;
}
// -180..180
void runningAngle::setMode0()
{
_mode = 0;
}
// 0..360
void runningAngle::setMode1()
{
_mode = 1;
}
uint8_t runningAngle::getMode()
{
return _mode;
}
// -- END OF FILE --