diff --git a/linalg/eigen/CMakeLists.txt b/linalg/eigen/CMakeLists.txt index e9be0fa871..21530ae388 100644 --- a/linalg/eigen/CMakeLists.txt +++ b/linalg/eigen/CMakeLists.txt @@ -36,6 +36,8 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to ]] +include(FetchContent) + FetchContent_Declare( eigen GIT_REPOSITORY "https://gitlab.com/libeigen/eigen" diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt index 395bd42c61..e5c1b7ad1c 100644 --- a/sample/CMakeLists.txt +++ b/sample/CMakeLists.txt @@ -36,7 +36,17 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to ]] -include(FetchContent) +add_library(kalman_utility INTERFACE) +target_sources( + kalman_utility + INTERFACE FILE_SET + "kalman_utility_headers" + TYPE + "HEADERS" + FILES + "printer.hpp" + "plotter.hpp") +target_link_libraries(kalman_utility INTERFACE kalman_print) foreach(SAMPLE "kf_1x1x0_building_height.cpp" "kf_1x1x0_liquid_temperature.cpp" "kf_1x1x1_dog_position.cpp") @@ -47,8 +57,9 @@ foreach(SAMPLE "kf_1x1x0_building_height.cpp" "kf_1x1x0_liquid_temperature.cpp" PROPERTIES CXX_STANDARD 23 CXX_EXTENSIONS OFF INTERPROCEDURAL_OPTIMIZATION TRUE) - target_link_libraries(kalman_sample_${NAME}_driver PRIVATE kalman kalman_main - kalman_options) + target_link_libraries( + kalman_sample_${NAME}_driver PRIVATE kalman kalman_main kalman_options + kalman_utility) separate_arguments(TEST_COMMAND UNIX_COMMAND $ENV{COMMAND}) add_test(NAME kalman_sample_${NAME} COMMAND ${TEST_COMMAND} $) @@ -67,7 +78,8 @@ foreach(BACKEND IN ITEMS "eigen") INTERPROCEDURAL_OPTIMIZATION TRUE) target_link_libraries( kalman_sample_${BACKEND}_${NAME}_driver - PRIVATE kalman kalman_main kalman_linalg_${BACKEND} kalman_options) + PRIVATE kalman kalman_main kalman_linalg_${BACKEND} kalman_options + kalman_utility) separate_arguments(TEST_COMMAND UNIX_COMMAND $ENV{COMMAND}) add_test(NAME kalman_sample_${BACKEND}_${NAME} COMMAND ${TEST_COMMAND} diff --git a/sample/kf_1x1x0_building_height.cpp b/sample/kf_1x1x0_building_height.cpp index 5d6c5f21b0..d83e4d512f 100644 --- a/sample/kf_1x1x0_building_height.cpp +++ b/sample/kf_1x1x0_building_height.cpp @@ -1,4 +1,6 @@ #include "fcarouge/kalman.hpp" +#include "plotter.hpp" +#include "printer.hpp" #include #include @@ -24,7 +26,7 @@ namespace { //! @example kf_1x1x0_building_height.cpp [[maybe_unused]] auto sample{[] { // A one-dimensional filter, constant system dynamic model. - kalman filter; + auto filter{plotter{printer{kalman{}}}}; // Initialization // One can estimate the building height simply by looking at it. The estimated diff --git a/sample/plotter.hpp b/sample/plotter.hpp new file mode 100644 index 0000000000..cbca3296a9 --- /dev/null +++ b/sample/plotter.hpp @@ -0,0 +1,126 @@ +/* __ _ __ __ _ _ +| |/ / /\ | | | \/ | /\ | \ | | +| ' / / \ | | | \ / | / \ | \| | +| < / /\ \ | | | |\/| | / /\ \ | . ` | +| . \ / ____ \| |____| | | |/ ____ \| |\ | +|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_| + +Kalman Filter +Version 0.3.0 +https://github.com/FrancoisCarouge/Kalman + +SPDX-License-Identifier: Unlicense + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to */ + +#ifndef FCAROUGE_PLOTTER_HPP +#define FCAROUGE_PLOTTER_HPP + +//! @file +//! @brief ... +//! +//! @details ... + +// #include "internal/utility.hpp" + +namespace fcarouge { + +// Decorator? +template class plotter final { + +public: + using state = typename KalmanFilter::state; + using output = typename KalmanFilter::output; + using input = typename KalmanFilter::input; + using estimate_uncertainty = typename KalmanFilter::estimate_uncertainty; + using process_uncertainty = typename KalmanFilter::process_uncertainty; + using output_uncertainty = typename KalmanFilter::output_uncertainty; + using state_transition = typename KalmanFilter::state_transition; + using output_model = typename KalmanFilter::output_model; + using input_control = typename KalmanFilter::input_control; + using gain = typename KalmanFilter::gain; + using innovation = typename KalmanFilter::innovation; + using innovation_uncertainty = typename KalmanFilter::innovation_uncertainty; + + inline constexpr explicit plotter(KalmanFilter &&kalman_filter) + : filter{std::forward(kalman_filter)} {} + + inline constexpr ~plotter() {} + + inline constexpr auto x() const -> const state &; + inline constexpr auto x() -> state & { return filter.x(); } + inline constexpr void x(const auto &value, const auto &...values) { + filter.x(value, values...); + } + // inline constexpr auto z() const -> const output &; + // inline constexpr auto u() const + // -> const input &requires(not std::is_same_v); + inline constexpr auto p() const -> const estimate_uncertainty &; + inline constexpr auto p() -> estimate_uncertainty & { return filter.p(); } + inline constexpr void p(const auto &value, const auto &...values) { + filter.p(value, values...); + } + inline constexpr auto q() const -> const process_uncertainty &; + inline constexpr auto q() -> process_uncertainty &; + inline constexpr void q(const auto &value, const auto &...values); + inline constexpr auto r() const -> const output_uncertainty &; + inline constexpr auto r() -> output_uncertainty &; + inline constexpr void r(const auto &value, const auto &...values) { + filter.r(value, values...); + } + // inline constexpr auto f() const -> const state_transition &; + // inline constexpr auto f() -> state_transition &; + // inline constexpr void f(const auto &value, const auto &...values); + // inline constexpr auto h() const -> const output_model &; + // inline constexpr auto h() -> output_model &; + // inline constexpr void h(const auto &value, const auto &...values); + // inline constexpr auto g() const + // -> const input_control &requires(not std::is_same_v); + // inline constexpr auto g() + // -> input_control &requires(not std::is_same_v); + // inline constexpr void g(const auto &value, const auto &...values) + // requires(not std::is_same_v); + // inline constexpr auto k() const -> const gain &; + // inline constexpr auto y() const -> const innovation &; + // inline constexpr auto s() const -> const innovation_uncertainty &; + // inline constexpr void transition(const auto &callable); + // inline constexpr void observation(const auto &callable); + inline constexpr void predict(const auto &...arguments) { + filter.predict(arguments...); + } + // template inline constexpr auto predict() const; + inline constexpr void update(const auto &...arguments) { + filter.update(arguments...); + } + // template inline constexpr auto update() const; + +private: + KalmanFilter filter; +}; + +} // namespace fcarouge + +#endif // FCAROUGE_PLOTTER_HPP diff --git a/sample/printer.hpp b/sample/printer.hpp new file mode 100644 index 0000000000..5e03936104 --- /dev/null +++ b/sample/printer.hpp @@ -0,0 +1,131 @@ +/* __ _ __ __ _ _ +| |/ / /\ | | | \/ | /\ | \ | | +| ' / / \ | | | \ / | / \ | \| | +| < / /\ \ | | | |\/| | / /\ \ | . ` | +| . \ / ____ \| |____| | | |/ ____ \| |\ | +|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_| + +Kalman Filter +Version 0.3.0 +https://github.com/FrancoisCarouge/Kalman + +SPDX-License-Identifier: Unlicense + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to */ + +#ifndef FCAROUGE_PRINTER_HPP +#define FCAROUGE_PRINTER_HPP + +//! @file +//! @brief ... +//! +//! @details ... + +// #include "internal/utility.hpp" +#include + +namespace fcarouge { + +// Decorator? +template class printer final { + +public: + using state = typename KalmanFilter::state; + using output = typename KalmanFilter::output; + using input = typename KalmanFilter::input; + using estimate_uncertainty = typename KalmanFilter::estimate_uncertainty; + using process_uncertainty = typename KalmanFilter::process_uncertainty; + using output_uncertainty = typename KalmanFilter::output_uncertainty; + using state_transition = typename KalmanFilter::state_transition; + using output_model = typename KalmanFilter::output_model; + using input_control = typename KalmanFilter::input_control; + using gain = typename KalmanFilter::gain; + using innovation = typename KalmanFilter::innovation; + using innovation_uncertainty = typename KalmanFilter::innovation_uncertainty; + + inline constexpr explicit printer(KalmanFilter &&kalman_filter) + : filter{std::forward(kalman_filter)} { + std::println("x: {}", filter.x()); + // std::println(filter.p()); + // std::println(filter.q()); + } + + inline constexpr ~printer() {} + + inline constexpr auto x() const -> const state &; + inline constexpr auto x() -> state & { return filter.x(); } + inline constexpr void x(const auto &value, const auto &...values) { + filter.x(value, values...); + } + // inline constexpr auto z() const -> const output &; + // inline constexpr auto u() const + // -> const input &requires(not std::is_same_v); + inline constexpr auto p() const -> const estimate_uncertainty &; + inline constexpr auto p() -> estimate_uncertainty & { return filter.p(); } + inline constexpr void p(const auto &value, const auto &...values) { + filter.p(value, values...); + } + inline constexpr auto q() const -> const process_uncertainty &; + inline constexpr auto q() -> process_uncertainty &; + inline constexpr void q(const auto &value, const auto &...values); + inline constexpr auto r() const -> const output_uncertainty &; + inline constexpr auto r() -> output_uncertainty &; + inline constexpr void r(const auto &value, const auto &...values) { + filter.r(value, values...); + } + // inline constexpr auto f() const -> const state_transition &; + // inline constexpr auto f() -> state_transition &; + // inline constexpr void f(const auto &value, const auto &...values); + // inline constexpr auto h() const -> const output_model &; + // inline constexpr auto h() -> output_model &; + // inline constexpr void h(const auto &value, const auto &...values); + // inline constexpr auto g() const + // -> const input_control &requires(not std::is_same_v); + // inline constexpr auto g() + // -> input_control &requires(not std::is_same_v); + // inline constexpr void g(const auto &value, const auto &...values) + // requires(not std::is_same_v); + // inline constexpr auto k() const -> const gain &; + // inline constexpr auto y() const -> const innovation &; + // inline constexpr auto s() const -> const innovation_uncertainty &; + // inline constexpr void transition(const auto &callable); + // inline constexpr void observation(const auto &callable); + inline constexpr void predict(const auto &...arguments) { + filter.predict(arguments...); + } + // template inline constexpr auto predict() const; + inline constexpr void update(const auto &...arguments) { + filter.update(arguments...); + } + // template inline constexpr auto update() const; + +private: + KalmanFilter filter; +}; + +} // namespace fcarouge + +#endif // FCAROUGE_PRINTER_HPP diff --git a/support/CMakeLists.txt b/support/CMakeLists.txt index 79795a6ba5..03280e66a4 100644 --- a/support/CMakeLists.txt +++ b/support/CMakeLists.txt @@ -109,6 +109,16 @@ endif() include(CheckSourceCompiles) include(FetchContent) +add_library(kalman_print INTERFACE) +target_sources(kalman_print INTERFACE FILE_SET "kalman_print_headers" TYPE + "HEADERS" FILES "print") + +install( + TARGETS kalman_print + EXPORT "kalman-target" + FILE_SET "kalman_print_headers" + DESTINATION "include/fcarouge") + add_library(kalman_generator INTERFACE) check_source_compiles( diff --git a/support/print b/support/print index 8492e6da4b..e33bf12a13 100644 --- a/support/print +++ b/support/print @@ -40,24 +40,15 @@ For more information, please refer to */ #define FCAROUGE_PRINT // Standard printer compiler support. Some mainstream compilers do not support -// `std::print` as of May 2023. The support is brought in through the `fmt` -// library. +// `std::print` as of October 2023. Poor man's implementation until then. -#include - -#include +#include #include namespace std { template -inline void print(std::string_view format, Types &&...arguments) { - fmt::vprint(format, fmt::make_format_args(arguments...)); -} - -template -inline void print(std::FILE *file, std::string_view format, - Types &&...arguments) { - fmt::print(file, format, fmt::make_format_args(arguments...)); +inline void println(std::string_view format, Types &&...arguments) { + std::cout << std::format(format, arguments...) << '\n'; } } // namespace std diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ea8d901aa7..15164e0c40 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -36,8 +36,6 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to ]] -include(FetchContent) - foreach( TEST "kalman_constructor_default_float_1x1x1.cpp"