From 8d86f573a5e00e2fb8026d3c31104f981d1fe7ca Mon Sep 17 00:00:00 2001 From: Oliver Lee Date: Thu, 27 Jul 2023 14:44:45 +0200 Subject: [PATCH] Remove use of `mp_units` from `//filter` (#22) Use of `mp_units` results in very long compile-times when building on the Raspberry Pi. This commit removes its use from `//filter`. Change-Id: I951300fa9db996dcc34544d780a6cf8e4f070119 --- filter/BUILD.bazel | 1 - filter/filter.hpp | 56 +++++++++++++------------------------ filter/test/filter_test.cpp | 27 ++++++++++++------ 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/filter/BUILD.bazel b/filter/BUILD.bazel index 72ed1a1..2f8fbe9 100644 --- a/filter/BUILD.bazel +++ b/filter/BUILD.bazel @@ -4,5 +4,4 @@ cc_library( name = "filter", hdrs = ["filter.hpp"], visibility = ["//:__subpackages__"], - deps = ["@mp_units"], ) diff --git a/filter/filter.hpp b/filter/filter.hpp index 6623bd1..b8e8bdf 100644 --- a/filter/filter.hpp +++ b/filter/filter.hpp @@ -1,30 +1,22 @@ #pragma once -#include #include +#include // Low and high pass filters // https://gitlab.com/mechmotum/row_filter/-/blob/master/row_filter/complementary.py namespace filter { -namespace mp = mp_units; -namespace si = mp_units::si; - -template < - auto CutoffFrequency, - auto SamplePeriod, - class Rep = double, - mp::Quantity Q = mp::quantity> +template struct lowpass { - using rep_type = Rep; + using value_type = Rep; - static constexpr auto w0 = mp::quantity{ - 2 * std::numbers::pi_v * CutoffFrequency}; - static constexpr auto dt = mp::quantity{SamplePeriod}; + static constexpr auto w0 = + 2 * std::numbers::pi_v * CutoffFrequency; + static constexpr auto dt = SamplePeriod; - using value_type = Q; using derivative_type = decltype(std::declval() / dt); struct signal @@ -41,20 +33,20 @@ struct lowpass static constexpr auto squared = [](auto x) { return x * x; }; static constexpr auto a = squared(w0); - static constexpr auto b = std::numbers::sqrt2_v * w0; + static constexpr auto b = std::numbers::sqrt2_v * w0; // Integrate the filter state equation using the midpoint Euler method with // time step h static constexpr auto h = dt; static constexpr auto h2 = squared(h); - static constexpr auto denom = 4 * mp::one + 2 * h * b + h2 * a; + static constexpr auto denom = 4 + 2 * h * b + h2 * a; - static constexpr auto A = (4 * mp::one + 2 * h * b - h2 * a) / denom; + static constexpr auto A = (4 + 2 * h * b - h2 * a) / denom; static constexpr auto B = 4 * h / denom; static constexpr auto C = -4 * h * a / denom; - static constexpr auto D = (4 * mp::one - 2 * h * b - h2 * a) / denom; + static constexpr auto D = (4 - 2 * h * b - h2 * a) / denom; static constexpr auto E = 2 * h2 * a / denom; - static constexpr auto F = 4 * mp::one * h * a / denom; + static constexpr auto F = 4 * h * a / denom; const auto x0 = value; const auto x1 = prev_unfiltered; @@ -68,24 +60,16 @@ struct lowpass } }; -template < - auto CutoffFrequency, - auto SamplePeriod, - class Rep = double, - mp::Quantity Q = mp::quantity> +template struct highpass { - using rep_type = Rep; - - static constexpr auto w0 = mp::quantity{ - 2 * std::numbers::pi_v * CutoffFrequency}; - static constexpr auto dt = mp::quantity{SamplePeriod}; + using value_type = Rep; - using value_type = Q; + static constexpr auto w0 = + 2 * std::numbers::pi_v * CutoffFrequency; + static constexpr auto dt = SamplePeriod; - using state_type = std::tuple< - mp::quantity, - mp::quantity>; + using state_type = std::tuple; value_type prev_unfiltered{}; state_type prev_state{}; @@ -106,12 +90,12 @@ struct highpass const auto xim1 = prev_unfiltered; const auto [z1im1, z2im1] = prev_state; - static constexpr auto a0 = std::numbers::sqrt2_v * h * w0; + static constexpr auto a0 = std::numbers::sqrt2_v * h * w0; static constexpr auto a1 = squared(h); static constexpr auto a2 = squared(w0); static constexpr auto a3 = a1 * a2; static constexpr auto a4 = 2 * a0; - static constexpr auto a5 = a3 + a4 + 4 * mp::one; + static constexpr auto a5 = a3 + a4 + 4; static constexpr auto a6 = 1 / a5; const auto a7 = a1 * xi + a1 * xim1 - a3 * z2im1 + a4 * z2im1 + 4 * h * z1im1 + @@ -122,7 +106,7 @@ struct highpass a6 * (a5 * (-a0 * z1im1 - a8 * z2im1 + h * xi + h * xim1 + 2 * z1im1) - a7 * a8) / - (a0 + 2 * mp::one); + (a0 + 2); const auto z2i = a6 * a7; const auto yi = (z1i - z1im1) / h; diff --git a/filter/test/filter_test.cpp b/filter/test/filter_test.cpp index fe2e227..18fc3e4 100644 --- a/filter/test/filter_test.cpp +++ b/filter/test/filter_test.cpp @@ -2,13 +2,24 @@ #include -#include +// Clang does not yet support floating point NTTP +// +template +struct constant +{ + using value_type = T; + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + const value_type value; + + consteval constant(value_type val) : value{val} {} -using namespace mp_units::si::unit_symbols; + constexpr operator T() const { return value; } +}; // NOLINTBEGIN(readability-magic-numbers) -constexpr auto cutoff_freq = 20 * Hz; -constexpr auto sample_period = 5 * ms; +constexpr auto cutoff_freq = constant{20}; // Hz; +constexpr auto sample_period = constant{0.005}; // ms; // NOLINTEND(readability-magic-numbers) auto main() -> int @@ -18,13 +29,13 @@ auto main() -> int test("high pass filter invocable") = [] { auto highpass = filter::highpass{}; - [[maybe_unused]] const auto [y0, z0] = highpass(1.0 * rad); - [[maybe_unused]] const auto _ = y0.number(); + [[maybe_unused]] const auto [y0, z0] = highpass(1.0); + [[maybe_unused]] const auto _ = y0; }; test("low pass filter invocable") = [] { auto lowpass = filter::lowpass{}; - [[maybe_unused]] const auto [y0, yd0] = lowpass(1.0 * rad); - [[maybe_unused]] const auto _ = y0.number(); + [[maybe_unused]] const auto [y0, yd0] = lowpass(1.0); + [[maybe_unused]] const auto _ = y0; }; }