AFBR-S50 API Reference Manual v1.5.6
AFBR-S50 Time-of-Flight Sensor SDK for Embedded Software
Loading...
Searching...
No Matches
fp_ema.h
Go to the documentation of this file.
1/*************************************************************************/
37#ifndef FP_EMA_H
38#define FP_EMA_H
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/*!***************************************************************************
44 * @addtogroup argus_fp
45 * @{
46 *****************************************************************************/
47
48#include "fp_def.h"
49
50#include "utility/fp_rnd.h"
51#include "utility/fp_mul.h"
52
53/*!***************************************************************************
54 * @brief Circular exponentially weighted moving average using UQ1.15 format.
55 *
56 * @details Evaluates the moving average (exponentially weighted) for circular
57 * data in UQ1.15 format.
58 * Circular data is that MAX_VALUE + 1 == MIN_VALUE. For example the
59 * usual phase information.
60 *
61 * Problem: Due to circularity of phase values, i.e. 0+x and 2PI+x are
62 * the same, the usual EMA has issues with the wrap around effect.
63 * Especially for vectors with phase around 0 (or 2PI), two values
64 * like 0 + x and PI - y are averaged to something around PI instead
65 * of 0 which would be more correct.
66 *
67 * Solution: Assume that phase jumps of more than PI are not allowed
68 * or possible. If a deviation of the new value to the smoothed signal
69 * occurs, it is clear that this stems from the wrap around effect and
70 * can be caught and correctly handled by the smoothing algorithm.
71 *
72 * Caution: If a target comes immediately into the field of view, phase
73 * jumps of > PI are indeed possible and volitional. However, the
74 * averaging break there anyway since the smoothed signal approaches
75 * only with delay to the correct values. The error made here is, that
76 * the smoothed signal approaches from the opposite direction. However,
77 * is approaches even faster since it always takes the shortest
78 * direction.
79 *
80 * @param mean The previous mean value in UQ1.15 format.
81 * @param x The current value to be added to the average UQ1.15 format.
82 * @param weight The EMA weight in UQ0.7 format.
83 * @return The new mean value in UQ1.15 format.
84 *****************************************************************************/
86{
87 if (weight == 0) return x;
88 // Heeds the wrap around effect by casting dx to int16:
89 const int16_t dx = (int16_t)(x - mean);
90 const int32_t diff = weight * dx;
91 return (uq1_15_t)fp_rnds((mean << 8U) + diff, 8U);
92}
93
94/*!***************************************************************************
95 * @brief Exponentially weighted moving average using the Q11.4 format.
96 *
97 * @details Evaluates the moving average (exponentially weighted) for data in
98 * Q11.4 format.
99 *
100 * @param mean The previous mean value in Q11.4 format.
101 * @param x The current value to be added to the average Q11.4 format.
102 * @param weight The EMA weight in UQ0.7 format.
103 * @return The new mean value in Q11.4 format.
104 *****************************************************************************/
105inline q11_4_t fp_ema4(q11_4_t mean, q11_4_t x, uq0_8_t weight)
106{
107 if (weight == 0) return x;
108 const int32_t dx = x - mean;
109 const int32_t diff = weight * dx;
110 return (q11_4_t)fp_rnds((mean << 8U) + diff, 8U);
111}
112
113/*!***************************************************************************
114 * @brief Exponentially weighted moving average using the Q7.8 format.
115 *
116 * @details Evaluates the moving average (exponentially weighted) for data in
117 * Q7.8 format.
118 *
119 * @param mean The previous mean value in Q7.8 format.
120 * @param x The current value to be added to the average Q7.8 format.
121 * @param weight The EMA weight in UQ0.7 format.
122 * @return The new mean value in Q7.8 format.
123 *****************************************************************************/
124inline q7_8_t fp_ema8(q7_8_t mean, q7_8_t x, uq0_8_t weight)
125{
126 return (q7_8_t)fp_ema4(mean, x, weight);
127}
128
129/*!***************************************************************************
130 * @brief Exponentially weighted moving average using the Q15.16 format.
131 *
132 * @details Evaluates the moving average (exponentially weighted) for data in
133 * Q15.16 format.
134 *
135 * @param mean The previous mean value in Q15.16 format.
136 * @param x The current value to be added to the average Q15.16 format.
137 * @param weight The EMA weight in UQ0.7 format.
138 * @return The new mean value in Q15.16 format.
139 *****************************************************************************/
140inline uint32_t uint_ema32(uint32_t mean, uint32_t x, uq0_8_t weight)
141{
142 if (weight == 0) return x;
143 if (x > mean)
144 {
145 const uint32_t dx = x - mean;
146 const uint32_t diff = fp_mulu(weight, dx, 8U);
147 return mean + diff;
148 }
149 else
150 {
151 const uint32_t dx = mean - x;
152 const uint32_t diff = fp_mulu(weight, dx, 8U);
153 return mean - diff;
154 }
155}
156/*!***************************************************************************
157 * @brief Exponentially weighted moving average using the Q15.16 format.
158 *
159 * @details Evaluates the moving average (exponentially weighted) for data in
160 * Q15.16 format.
161 *
162 * @param mean The previous mean value in Q15.16 format.
163 * @param x The current value to be added to the average Q15.16 format.
164 * @param weight The EMA weight in UQ0.7 format.
165 * @return The new mean value in Q15.16 format.
166 *****************************************************************************/
167inline int32_t int_ema32(int32_t mean, int32_t x, uq0_8_t weight)
168{
169 if (weight == 0) return x;
170 if (x > mean)
171 {
172 const uint32_t dx = x - mean;
173 const uint32_t diff = fp_mulu(weight, dx, 8U);
174 return mean + diff;
175 }
176 else
177 {
178 const uint32_t dx = mean - x;
179 const uint32_t diff = fp_mulu(weight, dx, 8U);
180 return mean - diff;
181 }
182}
183
184/*!***************************************************************************
185 * @brief Exponentially weighted moving average using the Q15.16 format.
186 *
187 * @details Evaluates the moving average (exponentially weighted) for data in
188 * Q15.16 format.
189 *
190 * @param mean The previous mean value in Q15.16 format.
191 * @param x The current value to be added to the average Q15.16 format.
192 * @param weight The EMA weight in UQ0.7 format.
193 * @return The new mean value in Q15.16 format.
194 *****************************************************************************/
196{
197 return (q15_16_t)int_ema32(mean, x, weight);
198}
199
201#ifdef __cplusplus
202} // extern "C"
203#endif
204#endif /* FP_EMA_H */
This file is part of the AFBR-S50 API.
This file is part of the AFBR-S50 API.
This file is part of the AFBR-S50 API.
uq1_15_t fp_ema15c(uq1_15_t mean, uq1_15_t x, uq0_8_t weight)
Circular exponentially weighted moving average using UQ1.15 format.
Definition fp_ema.h:85
q15_16_t fp_ema16(q15_16_t mean, q15_16_t x, uq0_8_t weight)
Exponentially weighted moving average using the Q15.16 format.
Definition fp_ema.h:195
uint32_t uint_ema32(uint32_t mean, uint32_t x, uq0_8_t weight)
Exponentially weighted moving average using the Q15.16 format.
Definition fp_ema.h:140
uint8_t uq0_8_t
Unsigned fixed point number: UQ0.8.
Definition fp_def.h:162
uint32_t fp_mulu(uint32_t u, uint32_t v, uint_fast8_t shift)
64-bit implementation of an unsigned multiplication with fixed point format.
Definition fp_mul.h:116
int32_t fp_rnds(int32_t Q, uint_fast8_t n)
Converting with rounding from Qx.n1 to Qx.n2.
Definition fp_rnd.h:80
int32_t int_ema32(int32_t mean, int32_t x, uq0_8_t weight)
Exponentially weighted moving average using the Q15.16 format.
Definition fp_ema.h:167
uint16_t uq1_15_t
Unsigned fixed point number: UQ1.15.
Definition fp_def.h:271
q11_4_t fp_ema4(q11_4_t mean, q11_4_t x, uq0_8_t weight)
Exponentially weighted moving average using the Q11.4 format.
Definition fp_ema.h:105
int16_t q7_8_t
Signed fixed point number: Q7.8.
Definition fp_def.h:335
int32_t q15_16_t
Signed fixed point number: Q15.16.
Definition fp_def.h:515
q7_8_t fp_ema8(q7_8_t mean, q7_8_t x, uq0_8_t weight)
Exponentially weighted moving average using the Q7.8 format.
Definition fp_ema.h:124
int16_t q11_4_t
Signed fixed point number: Q11.4.
Definition fp_def.h:312