diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 433a7d1f3..2d0d0eb5a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,6 +17,7 @@ foreach( tests_id_ringbuffer tests_input_transform tests_json + tests_lowpass tests_lowpass_int tests_pacing tests_quatexpmap @@ -34,6 +35,7 @@ endforeach() target_link_libraries(tests_cxx_wrappers PRIVATE xrt-interfaces) target_link_libraries(tests_history_buf PRIVATE aux_math) target_link_libraries(tests_input_transform PRIVATE st_oxr xrt-interfaces xrt-external-openxr) +target_link_libraries(tests_lowpass PRIVATE aux_tracking) target_link_libraries(tests_lowpass_int PRIVATE aux_tracking) target_link_libraries(tests_quatexpmap PRIVATE aux_math) target_link_libraries(tests_rational PRIVATE aux_math) diff --git a/tests/tests_lowpass.cpp b/tests/tests_lowpass.cpp new file mode 100644 index 000000000..f20922dd6 --- /dev/null +++ b/tests/tests_lowpass.cpp @@ -0,0 +1,75 @@ +// Copyright 2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Scalar float low pass filter tests. + * @author Ryan Pavlik + */ + +#include + +#include "catch/catch.hpp" + +using xrt::auxiliary::tracking::LowPassIIRFilter; +static constexpr float InitialState = 300; +static constexpr timepoint_ns InitialTime = 12345; +static constexpr timepoint_ns StepSize = U_TIME_1MS_IN_NS * 20; + +TEMPLATE_TEST_CASE("t_lowpass", "", float, double) +{ + LowPassIIRFilter filter(100); + + CHECK_FALSE(filter.isInitialized()); + timepoint_ns now = InitialTime; + + filter.addSample(InitialState, now); + CHECK(filter.getState() == InitialState); + CHECK(filter.getTimestampNs() == now); + CHECK(filter.isInitialized()); + + auto prev = filter.getState(); + SECTION("Increase") + { + constexpr auto newTarget = InitialState * 2; + for (int i = 0; i < 20; ++i) { + now += StepSize; + filter.addSample(newTarget, now); + REQUIRE(filter.isInitialized()); + CHECK(filter.getTimestampNs() == now); + // not going to exceed this + if (prev == newTarget) { + REQUIRE(filter.getState() == prev); + } else { + REQUIRE(filter.getState() > prev); + prev = filter.getState(); + } + } + } + + SECTION("Decrease") + { + constexpr auto newTarget = InitialState / 2; + for (int i = 0; i < 20; ++i) { + now += StepSize; + filter.addSample(newTarget, now); + REQUIRE(filter.isInitialized()); + CHECK(filter.getTimestampNs() == now); + if (prev == newTarget) { + REQUIRE(filter.getState() == newTarget); + } else { + REQUIRE(filter.getState() < prev); + prev = filter.getState(); + } + } + } + SECTION("Stay Same") + { + for (int i = 0; i < 20; ++i) { + now += StepSize; + filter.addSample(InitialState, now); + REQUIRE(filter.isInitialized()); + CHECK(filter.getTimestampNs() == now); + REQUIRE(filter.getState() == InitialState); + } + } +}