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
3636namespace 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
5252float Vector::sqrd_norm () const { return x * x + y * y + z * z; }
5353
5454Vector & 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
6363Vector 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
135135Quaternion & 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 &
214214Quaternion & 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
245245void 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-
331252float 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:
431256float 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
0 commit comments