2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
24 #define sq(x) ((x)*(x))
27 // Undefine this for use libc sinf/cosf. Keep this defined to use fast sin/cos approximations
28 #define FAST_MATH // order 9 approximation
29 //#define VERY_FAST_MATH // order 7 approximation
31 // Use floating point M_PI instead explicitly.
32 #define M_PIf 3.14159265358979323846f
33 #define M_LN2f 0.69314718055994530942f
34 #define M_Ef 2.71828182845904523536f
36 #define RAD (M_PIf / 180.0f)
38 #define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100)
39 #define CENTIDEGREES_TO_DEGREES(angle) ((angle) / 100)
41 #define CENTIDEGREES_TO_DECIDEGREES(angle) ((angle) / 10)
42 #define DECIDEGREES_TO_CENTIDEGREES(angle) ((angle) * 10)
44 #define DEGREES_TO_DECIDEGREES(angle) ((angle) * 10)
45 #define DECIDEGREES_TO_DEGREES(angle) ((angle) / 10)
47 #define DEGREES_PER_DEKADEGREE 10
48 #define DEGREES_TO_DEKADEGREES(angle) ((angle) / DEGREES_PER_DEKADEGREE)
49 #define DEKADEGREES_TO_DEGREES(angle) ((angle) * DEGREES_PER_DEKADEGREE)
51 #define DEGREES_TO_RADIANS(angle) ((angle) * RAD)
52 #define RADIANS_TO_DEGREES(angle) ((angle) / RAD)
53 #define DECIDEGREES_TO_RADIANS(angle) (((angle) / 10.0f) * RAD)
54 #define RADIANS_TO_DECIDEGREES(angle) (((angle) * 10.0f) / RAD)
56 #define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD)
57 #define CENTIDEGREES_TO_RADIANS(angle) (((angle) / 100.0f) * RAD)
59 #define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048)
60 #define CENTIMETERS_TO_FEET(cm) (cm / 30.48)
61 #define CENTIMETERS_TO_METERS(cm) (cm / 100)
63 #define METERS_TO_CENTIMETERS(m) (m * 100)
65 #define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363)
66 #define CMSEC_TO_CENTIKPH(cms) (cms * 3.6)
67 #define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845)
69 #define C_TO_KELVIN(temp) (temp + 273.15f)
71 // Standard Sea Level values
72 // Ref:https://en.wikipedia.org/wiki/Standard_sea_level
73 #define SSL_AIR_DENSITY 1.225f // kg/m^3
74 #define SSL_AIR_PRESSURE 101325.01576f // Pascal
75 #define SSL_AIR_TEMPERATURE 288.15f // K
77 // copied from https://code.google.com/p/cxutil/source/browse/include/cxutil/utility.h#70
78 #define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
80 __typeof__(lexpr) lvar = (lexpr); \
81 __typeof__(rexpr) rvar = (rexpr); \
82 lvar binoper rvar ? lvar : rvar; \
84 #define _CHOOSE_VAR2(prefix, unique) prefix##unique
85 #define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
86 #define _CHOOSE(binoper, lexpr, rexpr) \
89 lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
90 rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
92 #define MIN(a, b) _CHOOSE(<, a, b)
93 #define MAX(a, b) _CHOOSE(>, a, b)
95 #define _ABS_II(x, var) \
97 __typeof__(x) var = (x); \
98 var < 0 ? -var : var; \
100 #define _ABS_I(x, var) _ABS_II(x, var)
101 #define ABS(x) _ABS_I(x, _CHOOSE_VAR(_abs, __COUNTER__))
103 #define power3(x) ((x)*(x)*(x))
105 // Floating point Euler angles.
106 typedef struct fp_angles
{
114 fp_angles_def angles
;
117 typedef struct stdev_s
119 float m_oldM
, m_newM
, m_oldS
, m_newS
;
123 typedef struct filterWithBufferSample_s
{
126 } filterWithBufferSample_t
;
128 typedef struct filterWithBufferState_s
{
129 uint16_t filter_size
;
130 uint16_t sample_index
;
131 filterWithBufferSample_t
* samples
;
132 } filterWithBufferState_t
;
137 } sensorCalibrationState_t
;
139 void sensorCalibrationResetState(sensorCalibrationState_t
* state
);
140 void sensorCalibrationPushSampleForOffsetCalculation(sensorCalibrationState_t
* state
, int32_t sample
[3]);
141 void sensorCalibrationPushSampleForScaleCalculation(sensorCalibrationState_t
* state
, int axis
, int32_t sample
[3], int target
);
142 bool sensorCalibrationSolveForOffset(sensorCalibrationState_t
* state
, float result
[3]);
143 bool sensorCalibrationSolveForScale(sensorCalibrationState_t
* state
, float result
[3]);
145 int gcd(int num
, int denom
);
146 int32_t applyDeadband(int32_t value
, int32_t deadband
);
147 int32_t applyDeadbandRescaled(int32_t value
, int32_t deadband
, int32_t min
, int32_t max
);
149 int32_t constrain(int32_t amt
, int32_t low
, int32_t high
);
150 float constrainf(float amt
, float low
, float high
);
152 void devClear(stdev_t
*dev
);
153 void devPush(stdev_t
*dev
, float x
);
154 float devVariance(stdev_t
*dev
);
155 float devStandardDeviation(stdev_t
*dev
);
156 float degreesToRadians(int16_t degrees
);
158 int scaleRange(int x
, int srcMin
, int srcMax
, int destMin
, int destMax
);
159 float scaleRangef(float x
, float srcMin
, float srcMax
, float destMin
, float destMax
);
161 int32_t wrap_18000(int32_t angle
);
162 int32_t wrap_36000(int32_t angle
);
164 int32_t quickMedianFilter3(int32_t * v
);
165 int32_t quickMedianFilter5(int32_t * v
);
166 int32_t quickMedianFilter7(int32_t * v
);
167 int32_t quickMedianFilter9(int32_t * v
);
169 int16_t quickMedianFilter3_16(int16_t * v
);
170 int16_t quickMedianFilter5_16(int16_t * v
);
172 #if defined(FAST_MATH) || defined(VERY_FAST_MATH)
173 float sin_approx(float x
);
174 float cos_approx(float x
);
175 float atan2_approx(float y
, float x
);
176 float acos_approx(float x
);
177 #define tan_approx(x) (sin_approx(x) / cos_approx(x))
178 #define asin_approx(x) (M_PIf / 2 - acos_approx(x))
180 #define asin_approx(x) asinf(x)
181 #define sin_approx(x) sinf(x)
182 #define cos_approx(x) cosf(x)
183 #define atan2_approx(y,x) atan2f(y,x)
184 #define acos_approx(x) acosf(x)
185 #define tan_approx(x) tanf(x)
188 void arraySubInt32(int32_t *dest
, int32_t *array1
, int32_t *array2
, int count
);
190 float bellCurve(const float x
, const float curveWidth
);
191 float fast_fsqrtf(const double value
);
192 float calc_length_pythagorean_2D(const float firstElement
, const float secondElement
);
193 float calc_length_pythagorean_3D(const float firstElement
, const float secondElement
, const float thirdElement
);