Skip to content

Commit

Permalink
[compatibility] mp-units support test
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoisCarouge committed Dec 14, 2024
1 parent 655830e commit cf60753
Show file tree
Hide file tree
Showing 14 changed files with 854 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ jobs:
-I support/eigen \
-I support/generator \
-I support/lazy \
-I support/mp_units \
-I support/naive \
-I support/physical \
.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This library supports various simple and extended filters. The implementation is
- [Performance](#performance)
- [Resources](#resources)
- [Definitions](#definitions)
- [Articles](#articles)
- [Related Resources](#related-resources)
- [Projects](#projects)
- [Third Party Acknowledgement](#third-party-acknowledgement)
- [Sponsors](#sponsors)
Expand Down Expand Up @@ -289,9 +289,11 @@ In theory there is no difference between theory and practice, while in practice

Design, development, and testing uncovered unexpected facets of the projects:

- The filter's state, output, and input column vectors should be type template parameters to allow the filter to participate in full compile-time verification of unit- and index-type safeties for input parameters and characteristics.
- The filter's state, output, and input column vectors should be strongly typed parameters to allow the filter to participate in full compile-time safeties verification.
- There exist Kalman filters with hundreds of state variables.
- The `float` data type has about seven significant digits. Floating point error is a loss of information to account for in design.
- The units of useful matrices are factorizable, i.e. the unit of an element is expressed as the product of the row and column indexed units. The deduced units result type of a matrix product collapses and folds the inner indexed units merely returning the outer units.
- Safe physical linear algebra not only includes types and units safety, but also coordinate axes and frames reference.

## Performance

Expand All @@ -312,16 +314,16 @@ The [benchmarks](https://github.com/FrancoisCarouge/Kalman/tree/master/benchmark

Further terms should be defined and demonstrated for completeness: CKF, EKF-IMM, EnKF, Euler-KF, Fading-Memory, Finite/Fixed-Memory, Forward-Backward, FKF, IEKF, Joseph, KF, Linearized, MEKF, MRP-EKF, MRP-UKF, MSCKF, SKF, Smoother, UKF-GSF, UKF-IMM, USQUE, UDU, and UT.

## Articles

Resources to learn about Kalman filters:
## Related Resources

- [A New Approach to Linear Filtering and Prediction Problems](https://www.cs.unc.edu/~welch/kalman/kalmanPaper.html) by Kalman, Rudolph Emil in Transactions of the ASME - Journal of Basic Engineering, Volume 82, Series D, pp 35-45, 1960 - Transcription by John Lukesh.
- [KalmanFilter.NET](https://www.kalmanfilter.net) by Alex Becker.
- [Kalman and Bayesian Filters in Python](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python) by Roger Labbe.
- [How Kalman Filters Work](https://www.anuncommonlab.com/articles/how-kalman-filters-work) by Tucker McClure of An Uncommon Lab.
- [Wikipedia Kalman filter](https://en.wikipedia.org/wiki/Kalman_filter) by Wikipedia, the free encyclopedia.
- [Applications of Kalman Filtering in Aerospace 1960 to the Present](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5466132) by Mohinder S. Grewal and Angus P. Andrews. IEEE 2010.
- [Taking Static Type-Safety to the Next Level - Physical Units for Matrices](https://www.youtube.com/watch?v=aF3samjRzD4) by Daniel Withopf at CppCon 2022 [[slides](https://meetingcpp.com/mcpp/slides/2021/Physical-units-for-matrices6397.pdf)].
- [Units Libraries and Autonomous Vehicles: Lessons from the Trenches](https://www.youtube.com/watch?v=5dhFtSu3wCo) by Chip Hogg at CppCon 2021.

## Projects

Expand All @@ -347,6 +349,7 @@ The library is designed, developed, and tested with the help of third-party tool
- [GCC](https://gcc.gnu.org) for compilation and code sanitizers.
- [Google Benchmark](https://github.com/google/benchmark) to implement the benchmarks.
- [lcov](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information.
- [mp-units](https://github.com/mpusz/mp-units) the quantities and units library for C++.
- [MSVC](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist) for compilation and code sanitizers.
- [Valgrind](https://valgrind.org) to check for correct memory management.

Expand Down
18 changes: 18 additions & 0 deletions include/fcarouge/internal/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,14 @@ struct transposer final {
[[nodiscard]] inline constexpr auto operator()(const Matrix &value) const {
return transpose(value);
}

// How to, should we force external type to provide a transposition
// implementation if the type needs to, should be transposed?
template <typename UnknownType>
[[nodiscard]] inline constexpr auto
operator()(const UnknownType &value) const {
return value;
}
};

struct matrix_deducer;
Expand All @@ -287,6 +295,16 @@ struct matrix_deducer final {
requires(eigen<Lhs> or eigen<Rhs>)
[[nodiscard]] inline constexpr auto operator()(Lhs lhs, Rhs rhs) const ->
typename decltype(lhs * transposer{}(rhs))::PlainMatrix;

template <template <typename, typename, typename> typename PhysicalMatrix,
typename Matrix1, typename RowIndexes1, typename Matrix2,
typename RowIndexes2, typename ColumnIndexes>
requires(eigen<Matrix1> or eigen<Matrix2>)
[[nodiscard]] inline constexpr auto
operator()(PhysicalMatrix<Matrix1, RowIndexes1, ColumnIndexes> lhs,
PhysicalMatrix<Matrix2, RowIndexes2, ColumnIndexes> rhs) const
-> PhysicalMatrix<deduce_matrix<Matrix1, Matrix2>, RowIndexes1,
RowIndexes2>;
};

using empty_tuple = std::tuple<>;
Expand Down
5 changes: 4 additions & 1 deletion include/fcarouge/internal/x_z_p_r_f.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ template <typename State, typename Output> struct x_z_p_r_f {
using state_transition = deduce_matrix<state, state>;
using innovation = output;
using innovation_uncertainty = output_uncertainty;
using gain = deduce_matrix<state, output>;
// Internalize gain type deduction as a quotient deducer?
using gain =
std::remove_cvref_t<decltype(std::declval<estimate_uncertainty>() /
std::declval<innovation_uncertainty>())>;

static inline const auto i{identity_v<gain>};

Expand Down
1 change: 0 additions & 1 deletion include/fcarouge/kalman.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ class kalman : public internal::conditional_member_types<Filter> {
//!
//! @todo Collapse cv-ref qualifier-aware member functions per C++23 P0847 to
//! avoid duplication: `inline constexpr auto & x(this auto&& self)`.

inline constexpr auto &&x(this auto &&self);

//! @brief Sets the state estimate column vector X.
Expand Down
2 changes: 2 additions & 0 deletions support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ For more information, please refer to <https://unlicense.org> ]]

add_subdirectory("eigen")
add_subdirectory("main")
add_subdirectory("mp_units")
add_subdirectory("naive")
add_subdirectory("physical")

add_library(kalman_options INTERFACE)

Expand Down
7 changes: 7 additions & 0 deletions support/eigen/fcarouge/linalg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,16 @@ constexpr auto operator/(const Numerator &lhs, const Denominator &rhs)
//! @brief Specialization of the standard formatter for the Eigen matrix.
template <typename Type, auto Row, auto Column, typename Char>
struct std::formatter<fcarouge::matrix<Type, Row, Column>, Char> {
// template <fcarouge::eigen Matrix, typename Char>
// struct std::formatter<Matrix, Char> {
constexpr auto parse(std::basic_format_parse_context<Char> &parse_context) {
return parse_context.begin();
}

template <typename OutputIterator>
constexpr auto
format(const fcarouge::matrix<Type, Row, Column> &value,
// format(const Matrix &value,
std::basic_format_context<OutputIterator, Char> &format_context) const
-> OutputIterator {
const Eigen::IOFormat output_format{Eigen::StreamPrecision,
Expand All @@ -124,10 +127,12 @@ struct std::formatter<fcarouge::matrix<Type, Row, Column>, Char> {
template <typename OutputIterator>
constexpr auto
format(const fcarouge::matrix<Type, Row, Column> &value,
// format(const Matrix &value,
std::basic_format_context<OutputIterator, Char> &format_context) const
-> OutputIterator
requires(fcarouge::matrix<Type, Row, Column>::RowsAtCompileTime == 1 &&
fcarouge::matrix<Type, Row, Column>::ColsAtCompileTime != 1)
// requires(Matrix::RowsAtCompileTime == 1 && Matrix::ColsAtCompileTime != 1)
{
const Eigen::IOFormat output_format{Eigen::StreamPrecision,
Eigen::DontAlignCols,
Expand All @@ -147,10 +152,12 @@ struct std::formatter<fcarouge::matrix<Type, Row, Column>, Char> {
template <typename OutputIterator>
constexpr auto
format(const fcarouge::matrix<Type, Row, Column> &value,
// format(const Matrix &value,
std::basic_format_context<OutputIterator, Char> &format_context) const
-> OutputIterator
requires(fcarouge::matrix<Type, Row, Column>::RowsAtCompileTime == 1 &&
fcarouge::matrix<Type, Row, Column>::ColsAtCompileTime == 1)
// requires(Matrix::RowsAtCompileTime == 1 && Matrix::ColsAtCompileTime == 1)
{
return std::format_to(format_context.out(), "{}", value.value());
}
Expand Down
71 changes: 71 additions & 0 deletions support/mp_units/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#[[ __ _ __ __ _ _
| |/ / /\ | | | \/ | /\ | \ | |
| ' / / \ | | | \ / | / \ | \| |
| < / /\ \ | | | |\/| | / /\ \ | . ` |
| . \ / ____ \| |____| | | |/ ____ \| |\ |
|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_|
Kalman Filter
Version 0.4.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 <https://unlicense.org> ]]

include(FetchContent)

FetchContent_Declare(
fmt
GIT_REPOSITORY "https://github.com/fmtlib/fmt"
GIT_SHALLOW TRUE
FIND_PACKAGE_ARGS NAMES fmt)
FetchContent_MakeAvailable(fmt)

FetchContent_Declare(
gsl-lite
GIT_REPOSITORY "https://github.com/gsl-lite/gsl-lite"
GIT_SHALLOW TRUE
FIND_PACKAGE_ARGS NAMES gsl-lite)
FetchContent_MakeAvailable(gsl-lite)

FetchContent_Declare(
mp-units
GIT_REPOSITORY "https://github.com/mpusz/mp-units"
GIT_SHALLOW TRUE
SOURCE_SUBDIR "src" FIND_PACKAGE_ARGS NAMES mp-units)
FetchContent_MakeAvailable(mp-units)

target_compile_options(mp-units INTERFACE $<IF:$<CXX_COMPILER_ID:MSVC>, ,
-Wno-double-promotion>)
target_compile_options(mp-units INTERFACE $<IF:$<CXX_COMPILER_ID:MSVC>, ,
-Wno-undef>)

add_library(kalman_unit_mp_units INTERFACE)
target_sources(
kalman_unit_mp_units INTERFACE FILE_SET "unit_headers" TYPE "HEADERS" FILES
"fcarouge/unit.hpp")
target_link_libraries(kalman_unit_mp_units INTERFACE mp-units::mp-units)
88 changes: 88 additions & 0 deletions support/mp_units/fcarouge/unit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* __ _ __ __ _ _
| |/ / /\ | | | \/ | /\ | \ | |
| ' / / \ | | | \ / | / \ | \| |
| < / /\ \ | | | |\/| | / /\ \ | . ` |
| . \ / ____ \| |____| | | |/ ____ \| |\ |
|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_|
Kalman Filter
Version 0.4.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 <https://unlicense.org> */

#ifndef FCAROUGE_UNIT_HPP
#define FCAROUGE_UNIT_HPP

//! @file
//! @brief Quantities and units facade for mp-units third party implementation.
//!
//! @details Supporting quantities, values, and functions.

#include <mp-units/format.h>
#include <mp-units/framework/quantity.h>
#include <mp-units/math.h>
#include <mp-units/systems/si.h>

namespace fcarouge {
//! @brief The physical unit quantity.
template <auto Reference, typename Representation>
using quantity = mp_units::quantity<Reference, Representation>;

//! @brief The singleton identity matrix specialization.
template <mp_units::Quantity Type>
inline constexpr auto identity_v<Type>{Type::one()};

//! @brief Physical linear algebra matrix unit index type.
//!
//! @todo Constraint indexes with a concept: scalar/underlying, type, conversion
//! members?
template <auto Reference> struct index {
using scalar = double;
using type = quantity<Reference, scalar>;

// Is there a more transparent yet type-safe way to convert?
//! @todo While the method is static, would it be better to handle the index
//! type properly? Or externalize this conversion?
[[nodiscard]] static constexpr auto convert(const auto &value) -> scalar {
return value.numerical_value_in(value.unit);
}
};

// Supporting using-declarations and named values.
using mp_units::si::metre;
using mp_units::si::second;
using mp_units::si::unit_symbols::m;
using mp_units::si::unit_symbols::m2;
using mp_units::si::unit_symbols::s;
using mp_units::si::unit_symbols::s2;
using mp_units::si::unit_symbols::s3;
inline constexpr auto s4 = pow<4>(second);
} // namespace fcarouge

#endif // FCAROUGE_UNIT_HPP
43 changes: 43 additions & 0 deletions support/physical/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#[[ __ _ __ __ _ _
| |/ / /\ | | | \/ | /\ | \ | |
| ' / / \ | | | \ / | / \ | \| |
| < / /\ \ | | | |\/| | / /\ \ | . ` |
| . \ / ____ \| |____| | | |/ ____ \| |\ |
|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_|
Kalman Filter
Version 0.4.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 <https://unlicense.org> ]]

add_library(kalman_physical_linalg INTERFACE)
target_sources(
kalman_physical_linalg INTERFACE FILE_SET "unit_headers" TYPE "HEADERS" FILES
"fcarouge/physical_linalg.hpp")
target_link_libraries(kalman_physical_linalg INTERFACE kalman)
Loading

0 comments on commit cf60753

Please sign in to comment.