Skip to content

Commit aa55ba2

Browse files
committed
cleanup and replaced lookups in turbomath with math lib functions
1 parent 3fe91dc commit aa55ba2

File tree

4 files changed

+40
-247
lines changed

4 files changed

+40
-247
lines changed

CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
### project settings ###
22

3+
# Building the projects:
4+
# mkdir varmint_build && cd varmint_build && cmake .. -DBOARD_TO_BUILD=varmint && make -j
5+
# mkdir pixracer_pro_build && cd pixracer_pro_build && cmake .. -DBOARD_TO_BUILD=pixracer_pro && make -j
6+
#
7+
# alternate for make -j above is cmake --build . -j (note only one .)
8+
# make -j OR cmake --build . -j
9+
# to clean:
10+
# make clean -j OR make --build . --target clean -j
11+
#
12+
# unit test:
13+
# build:
14+
# mkdir test_build && cd test_build && cmake .. -DBOARD_TO_BUILD=test -DCMAKE_BUILD_TYPE=Release && make -j
15+
# test:
16+
# ./test/unit_tests
17+
318
cmake_minimum_required(VERSION 3.8)
419
project(rosflight_firmware C CXX ASM)
520

lib/turbomath/turbomath.cpp

Lines changed: 19 additions & 237 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3232
*/
3333

34-
#include <turbomath/turbomath.h>
34+
#include "turbomath/turbomath.h"
3535

3636
namespace turbomath
3737
{
@@ -47,13 +47,13 @@ Vector::Vector(float x_, float y_, float z_)
4747
, z(z_)
4848
{}
4949

50-
float Vector::norm() const { return 1.0f / inv_sqrt(x * x + y * y + z * z); }
50+
float Vector::norm() const { return sqrt(x * x + y * y + z * z); }
5151

5252
float Vector::sqrd_norm() const { return x * x + y * y + z * z; }
5353

5454
Vector & Vector::normalize()
5555
{
56-
float recip_norm = inv_sqrt(x * x + y * y + z * z);
56+
float recip_norm = 1.0 / sqrt(x * x + y * y + z * z);
5757
x *= recip_norm;
5858
y *= recip_norm;
5959
z *= recip_norm;
@@ -62,7 +62,7 @@ Vector & Vector::normalize()
6262

6363
Vector Vector::normalized() const
6464
{
65-
float recip_norm = inv_sqrt(x * x + y * y + z * z);
65+
float recip_norm = 1.0 / sqrt(x * x + y * y + z * z);
6666
Vector out(x * recip_norm, y * recip_norm, z * recip_norm);
6767
return out;
6868
}
@@ -134,7 +134,7 @@ Quaternion::Quaternion(float roll, float pitch, float yaw) { from_RPY(roll, pitc
134134

135135
Quaternion & Quaternion::normalize()
136136
{
137-
float recip_norm = inv_sqrt(w * w + x * x + y * y + z * z);
137+
float recip_norm = 1.0 / sqrt(w * w + x * x + y * y + z * z);
138138
w *= recip_norm;
139139
x *= recip_norm;
140140
y *= recip_norm;
@@ -200,7 +200,7 @@ Quaternion & Quaternion::from_two_unit_vectors(const Vector & u, const Vector &
200200
z = 0.0f;
201201
return *this;
202202
} else {
203-
float invs = inv_sqrt(2.0f * (1.0f + d));
203+
float invs = 1.0 / sqrt(2.0f * (1.0f + d));
204204
Vector xyz = u.cross(v) * invs;
205205
w = 0.5f / invs;
206206
x = xyz.x;
@@ -214,12 +214,12 @@ Quaternion & Quaternion::from_two_unit_vectors(const Vector & u, const Vector &
214214
Quaternion & Quaternion::from_RPY(float roll, float pitch, float yaw)
215215
{
216216
// p 259 of "Small unmanned aircraft: Theory and Practice" by Randy Beard and Tim McLain
217-
float cp = turbomath::cos(roll / 2.0);
218-
float sp = turbomath::sin(roll / 2.0);
219-
float ct = turbomath::cos(pitch / 2.0);
220-
float st = turbomath::sin(pitch / 2.0);
221-
float cs = turbomath::cos(yaw / 2.0);
222-
float ss = turbomath::sin(yaw / 2.0);
217+
float cp = cos(roll / 2.0);
218+
float sp = sin(roll / 2.0);
219+
float ct = cos(pitch / 2.0);
220+
float st = sin(pitch / 2.0);
221+
float cs = cos(yaw / 2.0);
222+
float ss = sin(yaw / 2.0);
223223

224224
w = cs * ct * cp + ss * st * sp;
225225
x = cs * ct * sp - ss * st * cp;
@@ -244,239 +244,21 @@ Vector Quaternion::boxminus(const Quaternion & q) const
244244

245245
void Quaternion::get_RPY(float * roll, float * pitch, float * yaw) const
246246
{
247-
*roll = turbomath::atan2(2.0f * (w * x + y * z), 1.0f - 2.0f * (x * x + y * y));
248-
*pitch = turbomath::asin(2.0f * (w * y - z * x));
249-
*yaw = turbomath::atan2(2.0f * (w * z + x * y), 1.0f - 2.0f * (y * y + z * z));
247+
*roll = atan2(2.0f * (w * x + y * z), 1.0f - 2.0f * (x * x + y * y));
248+
*pitch = asin(2.0f * (w * y - z * x));
249+
*yaw = atan2(2.0f * (w * z + x * y), 1.0f - 2.0f * (y * y + z * z));
250250
}
251251

252-
#ifndef M_PI
253-
#define M_PI 3.14159265359
254-
#endif
255-
256-
static const float atan_max_x = 1.000000;
257-
static const float atan_min_x = 0.000000;
258-
static const float atan_scale_factor = 41720.240162;
259-
static const int16_t atan_num_entries = 125;
260-
static const int16_t atan_lookup_table[125] = {
261-
0, 334, 667, 1001, 1335, 1668, 2001, 2334, 2666, 2999, 3331, 3662, 3993, 4323,
262-
4653, 4983, 5311, 5639, 5967, 6293, 6619, 6944, 7268, 7592, 7914, 8235, 8556, 8875,
263-
9194, 9511, 9827, 10142, 10456, 10768, 11080, 11390, 11699, 12006, 12313, 12617, 12921, 13223,
264-
13524, 13823, 14120, 14417, 14711, 15005, 15296, 15586, 15875, 16162, 16447, 16731, 17013, 17293,
265-
17572, 17849, 18125, 18399, 18671, 18941, 19210, 19477, 19742, 20006, 20268, 20528, 20786, 21043,
266-
21298, 21551, 21802, 22052, 22300, 22546, 22791, 23034, 23275, 23514, 23752, 23988, 24222, 24454,
267-
24685, 24914, 25142, 25367, 25591, 25814, 26034, 26253, 26471, 26686, 26900, 27113, 27324, 27533,
268-
27740, 27946, 28150, 28353, 28554, 28754, 28952, 29148, 29343, 29537, 29728, 29919, 30108, 30295,
269-
30481, 30665, 30848, 31030, 31210, 31388, 31566, 31741, 31916, 32089, 32260, 32431, 32599,
270-
};
271-
272-
static const float asin_max_x = 1.000000;
273-
static const float asin_min_x = 0.000000;
274-
static const float asin_scale_factor = 20860.120081;
275-
static const int16_t asin_num_entries = 200;
276-
static const int16_t asin_lookup_table[200] = {
277-
0, 104, 209, 313, 417, 522, 626, 730, 835, 939, 1043, 1148, 1252, 1357,
278-
1461, 1566, 1671, 1775, 1880, 1985, 2090, 2194, 2299, 2404, 2509, 2614, 2720, 2825,
279-
2930, 3035, 3141, 3246, 3352, 3458, 3564, 3669, 3775, 3881, 3988, 4094, 4200, 4307,
280-
4413, 4520, 4627, 4734, 4841, 4948, 5056, 5163, 5271, 5379, 5487, 5595, 5703, 5811,
281-
5920, 6029, 6138, 6247, 6356, 6465, 6575, 6685, 6795, 6905, 7015, 7126, 7237, 7348,
282-
7459, 7570, 7682, 7794, 7906, 8019, 8131, 8244, 8357, 8471, 8584, 8698, 8812, 8927,
283-
9042, 9157, 9272, 9388, 9504, 9620, 9737, 9854, 9971, 10089, 10207, 10325, 10444, 10563,
284-
10682, 10802, 10922, 11043, 11164, 11285, 11407, 11530, 11652, 11776, 11899, 12024, 12148, 12273,
285-
12399, 12525, 12652, 12779, 12907, 13035, 13164, 13293, 13424, 13554, 13686, 13817, 13950, 14083,
286-
14217, 14352, 14487, 14623, 14760, 14898, 15036, 15176, 15316, 15457, 15598, 15741, 15885, 16029,
287-
16175, 16321, 16469, 16618, 16767, 16918, 17070, 17224, 17378, 17534, 17691, 17849, 18009, 18170,
288-
18333, 18497, 18663, 18830, 19000, 19171, 19343, 19518, 19695, 19874, 20055, 20239, 20424, 20613,
289-
20803, 20997, 21194, 21393, 21596, 21802, 22012, 22225, 22443, 22664, 22891, 23122, 23359, 23601,
290-
23849, 24104, 24366, 24637, 24916, 25204, 25504, 25816, 26143, 26485, 26847, 27232, 27644, 28093,
291-
28588, 29149, 29814, 30680,
292-
};
293-
294-
static const float max_pressure = 106598.405011;
295-
static const float min_pressure = 69681.635473;
296-
static const float pressure_scale_factor = 10.754785;
297-
static const int16_t pressure_num_entries = 200;
298-
static const int16_t pressure_lookup_table[200] = {
299-
32767, 32544, 32321, 32098, 31876, 31655, 31434, 31213, 30993, 30773, 30554, 30335, 30117, 29899,
300-
29682, 29465, 29248, 29032, 28816, 28601, 28386, 28172, 27958, 27745, 27532, 27319, 27107, 26895,
301-
26684, 26473, 26263, 26053, 25843, 25634, 25425, 25217, 25009, 24801, 24594, 24387, 24181, 23975,
302-
23769, 23564, 23359, 23155, 22951, 22748, 22544, 22341, 22139, 21937, 21735, 21534, 21333, 21133,
303-
20932, 20733, 20533, 20334, 20135, 19937, 19739, 19542, 19344, 19148, 18951, 18755, 18559, 18364,
304-
18169, 17974, 17780, 17586, 17392, 17199, 17006, 16813, 16621, 16429, 16237, 16046, 15855, 15664,
305-
15474, 15284, 15095, 14905, 14716, 14528, 14339, 14151, 13964, 13777, 13590, 13403, 13217, 13031,
306-
12845, 12659, 12474, 12290, 12105, 11921, 11737, 11554, 11370, 11188, 11005, 10823, 10641, 10459,
307-
10278, 10096, 9916, 9735, 9555, 9375, 9195, 9016, 8837, 8658, 8480, 8302, 8124, 7946,
308-
7769, 7592, 7415, 7239, 7063, 6887, 6711, 6536, 6361, 6186, 6012, 5837, 5664, 5490,
309-
5316, 5143, 4970, 4798, 4626, 4454, 4282, 4110, 3939, 3768, 3597, 3427, 3257, 3087,
310-
2917, 2748, 2578, 2409, 2241, 2072, 1904, 1736, 1569, 1401, 1234, 1067, 901, 734,
311-
568, 402, 237, 71, -94, -259, -424, -588, -752, -916, -1080, -1243, -1407, -1570,
312-
-1732, -1895, -2057, -2219, -2381, -2543, -2704, -2865, -3026, -3187, -3347, -3507, -3667, -3827,
313-
-3987, -4146, -4305, -4464,
314-
};
315-
316-
static const float sin_max_x = 3.141593;
317-
static const float sin_min_x = 0.000000;
318-
static const float sin_scale_factor = 32767.000000;
319-
static const int16_t sin_num_entries = 125;
320-
static const int16_t sin_lookup_table[125] = {
321-
0, 823, 1646, 2468, 3289, 4107, 4922, 5735, 6544, 7349, 8149, 8944, 9733, 10516,
322-
11293, 12062, 12824, 13578, 14323, 15059, 15786, 16502, 17208, 17904, 18588, 19260, 19920, 20568,
323-
21202, 21823, 22431, 23024, 23602, 24166, 24715, 25247, 25764, 26265, 26749, 27216, 27666, 28099,
324-
28513, 28910, 29289, 29648, 29990, 30312, 30615, 30899, 31163, 31408, 31633, 31837, 32022, 32187,
325-
32331, 32454, 32558, 32640, 32702, 32744, 32764, 32764, 32744, 32702, 32640, 32558, 32454, 32331,
326-
32187, 32022, 31837, 31633, 31408, 31163, 30899, 30615, 30312, 29990, 29648, 29289, 28910, 28513,
327-
28099, 27666, 27216, 26749, 26265, 25764, 25247, 24715, 24166, 23602, 23024, 22431, 21823, 21202,
328-
20568, 19920, 19260, 18588, 17904, 17208, 16502, 15786, 15059, 14323, 13578, 12824, 12062, 11293,
329-
10516, 9733, 8944, 8149, 7349, 6544, 5735, 4922, 4107, 3289, 2468, 1646, 823};
330-
331252
float fsign(float y) { return (0.0f < y) - (y < 0.0f); }
332253

333-
float cos(float x) { return sin(M_PI / 2.0 - x); }
334-
335-
float sin(float x)
336-
{
337-
// wrap down to +/x PI
338-
while (x > M_PI) { x -= 2.0 * M_PI; }
339-
340-
while (x <= -M_PI) { x += 2.0 * M_PI; }
341-
342-
// sin is symmetric
343-
if (x < 0) { return -1.0 * sin(-x); }
344-
345-
// wrap onto (0, PI)
346-
if (x > M_PI) { return -1.0 * sin(x - M_PI); }
347-
348-
// Now, all we have left is the range 0 to PI, use the lookup table
349-
float t = (x - sin_min_x) / (sin_max_x - sin_min_x) * static_cast<float>(sin_num_entries);
350-
int16_t index = static_cast<int16_t>(t);
351-
float delta_x = t - index;
352-
353-
if (index >= sin_num_entries) {
354-
return sin_lookup_table[sin_num_entries - 1] / sin_scale_factor;
355-
} else if (index < sin_num_entries - 1) {
356-
return sin_lookup_table[index] / sin_scale_factor
357-
+ delta_x * (sin_lookup_table[index + 1] - sin_lookup_table[index]) / sin_scale_factor;
358-
} else {
359-
return sin_lookup_table[index] / sin_scale_factor
360-
+ delta_x * (sin_lookup_table[index] - sin_lookup_table[index - 1]) / sin_scale_factor;
361-
}
362-
}
363-
364-
float atan(float x)
365-
{
366-
// atan is symmetric
367-
if (x < 0) { return -1.0 * atan(-1.0 * x); }
368-
// This uses a sweet identity to wrap the domain of atan onto (0,1)
369-
if (x > 1.0) { return M_PI / 2.0 - atan(1.0 / x); }
370-
371-
float t = (x - atan_min_x) / (atan_max_x - atan_min_x) * static_cast<float>(atan_num_entries);
372-
int16_t index = static_cast<int16_t>(t);
373-
float delta_x = t - index;
374-
375-
if (index >= atan_num_entries) {
376-
return atan_lookup_table[atan_num_entries - 1] / atan_scale_factor;
377-
} else if (index < atan_num_entries - 1) {
378-
return atan_lookup_table[index] / atan_scale_factor
379-
+ delta_x * (atan_lookup_table[index + 1] - atan_lookup_table[index]) / atan_scale_factor;
380-
} else {
381-
return atan_lookup_table[index] / atan_scale_factor
382-
+ delta_x * (atan_lookup_table[index] - atan_lookup_table[index - 1]) / atan_scale_factor;
383-
}
384-
}
385-
386-
float atan2(float y, float x)
387-
{
388-
// algorithm from wikipedia: https://en.wikipedia.org/wiki/Atan2
389-
if (x == 0.0) {
390-
if (y < 0.0) {
391-
return -M_PI / 2.0;
392-
} else if (y > 0.0) {
393-
return M_PI / 2.0;
394-
} else {
395-
return 0.0;
396-
}
397-
}
398-
399-
float arctan = atan(y / x);
400-
401-
if (x < 0.0) {
402-
if (y < 0) {
403-
return arctan - M_PI;
404-
} else {
405-
return arctan + M_PI;
406-
}
407-
} else {
408-
return arctan;
409-
}
410-
}
411-
412-
float asin(float x)
413-
{
414-
if (x < 0.0) { return -1.0 * asin(-1.0 * x); }
415-
416-
float t = (x - asin_min_x) / (asin_max_x - asin_min_x) * static_cast<float>(asin_num_entries);
417-
int16_t index = static_cast<int16_t>(t);
418-
float delta_x = t - index;
419-
420-
if (index >= asin_num_entries) {
421-
return asin_lookup_table[asin_num_entries - 1] / asin_scale_factor;
422-
} else if (index < asin_num_entries - 1) {
423-
return asin_lookup_table[index] / asin_scale_factor
424-
+ delta_x * (asin_lookup_table[index + 1] - asin_lookup_table[index]) / asin_scale_factor;
425-
} else {
426-
return asin_lookup_table[index] / asin_scale_factor
427-
+ delta_x * (asin_lookup_table[index] - asin_lookup_table[index - 1]) / asin_scale_factor;
428-
}
429-
}
430-
254+
// old: alt ~ (1.0 - pow(pressure/101325.0, 0.1902631 )) * 39097.63
255+
// ISA standard atmosphere up to 11kft:
431256
float alt(float press)
432257
{
433-
if (press < max_pressure && press > min_pressure) {
434-
float t = (press - min_pressure) / (max_pressure - min_pressure)
435-
* static_cast<float>(pressure_num_entries);
436-
int16_t index = static_cast<int16_t>(t);
437-
float delta_x = t - index;
438-
439-
if (index >= pressure_num_entries) {
440-
return asin_lookup_table[pressure_num_entries - 1] / pressure_scale_factor;
441-
} else if (index < pressure_num_entries - 1) {
442-
return pressure_lookup_table[index] / pressure_scale_factor
443-
+ delta_x * (pressure_lookup_table[index + 1] - pressure_lookup_table[index])
444-
/ pressure_scale_factor;
445-
} else {
446-
return pressure_lookup_table[index] / pressure_scale_factor
447-
+ delta_x * (pressure_lookup_table[index] - pressure_lookup_table[index - 1])
448-
/ pressure_scale_factor;
449-
}
450-
} else {
451-
return 0.0;
452-
}
453-
}
454258

455-
float fabs(float x)
456-
{
457-
if (x < 0) {
458-
return -x;
459-
} else {
460-
return x;
461-
}
259+
return (1.0 - pow(press / ISA_PRESSURE, ISA_EXPONENT)) * ISA_SCALE_FACTOR;
462260
}
463261

464-
float inv_sqrt(float x)
465-
{
466-
volatile float x2;
467-
volatile float_converter_t y, i;
468-
const float threehalfs = 1.5F;
469-
470-
x2 = x * 0.5F;
471-
y.fvalue = x;
472-
i.ivalue = y.ivalue; // evil floating point bit level hacking
473-
i.ivalue = 0x5f3759df - (i.ivalue >> 1);
474-
y.fvalue = i.fvalue;
475-
y.fvalue = y.fvalue * (threehalfs - (x2 * y.fvalue * y.fvalue)); // 1st iteration
476-
y.fvalue =
477-
y.fvalue * (threehalfs - (x2 * y.fvalue * y.fvalue)); // 2nd iteration, this can be removed
478-
479-
return fabs(y.fvalue);
480-
}
262+
float inv_sqrt(float x) { return 1. / sqrt(x); }
481263

482264
} // namespace turbomath

lib/turbomath/turbomath.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,19 @@
3535
#define TURBOMATH_TURBOMATH_H
3636

3737
#include <cstdint>
38+
#include <math.h>
3839

3940
namespace turbomath
4041
{
41-
// float-based wrappers
42-
float cos(float x);
43-
float sin(float x);
44-
float asin(float x);
45-
float atan2(float y, float x);
46-
float atan(float x);
42+
#define ISA_PRESSURE (101325.0) // Pa
43+
#define ISA_EXPONENT (0.190326730028458)
44+
#define ISA_SCALE_FACTOR (44318.1386038261) //m
45+
4746
float fsign(float y);
4847

49-
// turbo-speed approximation of (1.0 - pow(pressure/101325.0, 0.1902631)) * 39097.63
5048
// Used for calculating altitude in m from atmospheric pressure in Pa
5149
float alt(float x);
52-
5350
float inv_sqrt(float x);
54-
float fabs(float x);
5551

5652
union float_converter_t
5753
{

0 commit comments

Comments
 (0)