Skip to content

Commit b5b4cd1

Browse files
committed
udpate fast_inv_sqrt and affected examples / code
1 parent 60b5f8d commit b5b4cd1

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

components/bldc_motor/include/bldc_motor.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@ class BldcMotor : public BaseComponent {
407407
float Uout;
408408
// a bit of optitmisation
409409
if (ud) { // only if ud and uq set
410-
// fast_sqrt is an approx of sqrt (3-4% error)
411-
Uout = fast_sqrt(ud * ud + uq * uq) / driver_->get_voltage_limit();
410+
// fast_inv_sqrt is an approx of invsqrt (3-4% error), so we need to
411+
// invert it to get the correct value (1/inv_sqrt = sqrt)
412+
Uout = 1.0f / (fast_inv_sqrt(ud * ud + uq * uq) * driver_->get_voltage_limit());
412413
// angle normalisation in between 0 and 2pi
413414
// only necessary if using fast_sin and fast_cos - approximation functions
414415
el_angle = normalize_angle(el_angle + atan2(uq, ud));

components/math/example/main/math_example.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ extern "C" void app_main(void) {
4747
//! [fast_ln example]
4848
}
4949
{
50-
//! [fast_sqrt example]
50+
//! [fast_inv_sqrt example]
5151
float x = 3.0f;
5252
auto slow = sqrt(x);
53-
auto fast = espp::fast_sqrt(x);
53+
auto fast = 1.0f / espp::fast_inv_sqrt(x);
5454
auto diff = std::abs(slow - fast);
5555
fmt::print("sqrt({}) = {} (slow), {} (fast), diff = {}\n", x, slow, fast, diff);
5656
//! [fast_sqrt example]

components/math/include/fast_math.hpp

+9-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#pragma once
22

3+
#include <bit>
34
#include <cmath>
45
#include <cstdlib>
56
#include <cstring>
7+
#include <stdfloat>
68
#include <utility>
79
#include <vector>
810

@@ -22,27 +24,16 @@ namespace espp {
2224
[[maybe_unused]] static float cube(float f) { return f * f * f; }
2325

2426
/**
25-
* @brief Fast square root approximation.
27+
* @brief Fast inverse square root approximation.
2628
* @note Using https://reprap.org/forum/read.php?147,219210 and
2729
* https://en.wikipedia.org/wiki/Fast_inverse_square_root
28-
* @param value Value to take the square root of.
29-
* @return Approximation of the square root of value.
30+
* @param value Value to take the inverse square root of.
31+
* @return Approximation of the inverse square root of value.
3032
*/
31-
[[maybe_unused]] static float fast_sqrt(float value) {
32-
uint32_t i{0};
33-
float y{0};
34-
// float x;
35-
// const float f = 1.5F; // better precision
36-
37-
// x = number * 0.5F;
38-
y = value;
39-
memcpy(&i, &y, sizeof(i));
40-
// i = * reinterpret_cast<uint32_t *>(&y);
41-
i = 0x5f375a86 - (i >> 1);
42-
// y = * reinterpret_cast<float *>(&i);
43-
memcpy(&y, &i, sizeof(y));
44-
// y = y * ( f - ( x * y * y ) ); // better precision
45-
return value * y;
33+
[[maybe_unused]] static constexpr float fast_inv_sqrt(float value) noexcept {
34+
const auto y =
35+
std::bit_cast<std::float32_t>(0x5f3759df - (std::bit_cast<std::uint32_t>(value) >> 1));
36+
return y * (1.5f - (0.5f * value * y * y));
4637
}
4738

4839
/**

0 commit comments

Comments
 (0)