diff --git a/xo-pykalmanfilter/.github/workflows/main.yml b/xo-pykalmanfilter/.github/workflows/main.yml new file mode 100644 index 00000000..24a0c9c7 --- /dev/null +++ b/xo-pykalmanfilter/.github/workflows/main.yml @@ -0,0 +1,663 @@ +name: build xo-optionutil + dependencies + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - name: checkout source + uses: actions/checkout@v3 + + - name: Install dependencies + run: | + echo "::group::install catch2" + # install catch2. see + # [[https://stackoverflow.com/questions/57982945/how-to-apt-get-install-in-a-github-actions-workflow]] + sudo apt-get install -y catch2 + echo "::endgroup" + + echo "::group::install eigen3" + sudo apt-get install -y libeigen3-dev + echo "::endgroup" + + echo "::group::install pybind11" + sudo apt-get install -y pybind11-dev + #echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-cmake + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-cmake + path: repo/xo-cmake + + - name: build xo-cmake + run: | + XONAME=xo-cmake + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-indentlog + uses: actions/checkout@v3 + with: + repository: Rconybea/indentlog + path: repo/xo-indentlog + + - name: build xo-indentlog + run: | + XONAME=xo-indentlog + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-refcnt + uses: actions/checkout@v3 + with: + repository: Rconybea/refcnt + path: repo/xo-refcnt + + - name: build xo-refcnt + run: | + XONAME=xo-refcnt + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-subsys + uses: actions/checkout@v3 + with: + repository: Rconybea/subsys + path: repo/xo-subsys + + - name: build xo-subsys + run: | + XONAME=xo-subsys + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-reflect + uses: actions/checkout@v3 + with: + repository: Rconybea/reflect + path: repo/xo-reflect + + - name: build xo-reflect + run: | + XONAME=xo-reflect + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-pyutil + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyutil + path: repo/xo-pyutil + + - name: build xo-pyutil + run: | + XONAME=xo-pyutil + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-pyreflect + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyreflect + path: repo/xo-pyreflect + + - name: build xo-pyreflect + run: | + XONAME=xo-pyreflect + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-callback + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-callback + path: repo/xo-callback + + - name: build xo-callback + run: | + XONAME=xo-callback + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-printjson + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-printjson + path: repo/xo-printjson + + - name: build xo-printjson + run: | + XONAME=xo-printjson + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-pyprintjson + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyprintjson + path: repo/xo-pyprintjson + + - name: build xo-pyprintjson + run: | + XONAME=xo-pyprintjson + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-webutil + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-webutil + path: repo/xo-webutil + + - name: build xo-webutil + run: | + XONAME=xo-webutil + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-randomgen + uses: actions/checkout@v3 + with: + repository: Rconybea/randomgen + path: repo/xo-randomgen + + - name: build xo-randomgen + run: | + XONAME=xo-randomgen + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-ordinaltree + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-ordinaltree + path: repo/xo-ordinaltree + + - name: build xo-ordinaltree + run: | + XONAME=xo-ordinaltree + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-reactor + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-reactor + path: repo/xo-reactor + + - name: build xo-reactor + run: | + XONAME=xo-reactor + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-pyreactor + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyreactor + path: repo/xo-pyreactor + + - name: build xo-pyreactor + run: | + XONAME=xo-pyreactor + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-statistics + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-statistics + path: repo/xo-statistics + + - name: build xo-statistics + run: | + XONAME=xo-statistics + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: clone xo-kalmanfilter + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-kalmanfilter + path: repo/xo-kalmanfilter + + - name: build xo-kalmanfilter + run: | + XONAME=xo-kalmanfilter + XOSRC=repo/${XONAME} + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${XOSRC} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} -j + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # ---------------------------------------------------------------- + + - name: Configure self (pykalmanfilter) + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: | + XONAME=xo-pykalmanfilter + BUILDDIR=${{github.workspace}}/build_${XONAME} + PREFIX=${{github.workspace}}/local + + echo "::group::repo dir tree" + tree -L 2 repo + echo "::endgroup" + + echo "::group::configure ${XONAME}" + cmake -B ${BUILDDIR} -DCMAKE_MODULE_PATH=${PREFIX}/share/cmake -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + echo "::endgroup" + + echo "::group::compile ${XONAME}" + cmake --build ${BUILDDIR} --config ${{env.BUILD_TYPE}} + echo "::endgroup" + + echo "::group::local install ${XONAME}" + cmake --install ${BUILDDIR} + echo "::endgroup" + + echo "::group::local dir tree" + tree -L 3 ${PREFIX} + echo "::endgroup" + + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + (cd ${BUILDDIR} && ctest -C ${{env.BUILD_TYPE}}) diff --git a/xo-pykalmanfilter/.gitignore b/xo-pykalmanfilter/.gitignore new file mode 100644 index 00000000..13c0afb7 --- /dev/null +++ b/xo-pykalmanfilter/.gitignore @@ -0,0 +1,6 @@ +# clangd working space (see emacs+lsp) +.cache +# typical cmake build directory (source-tree-nephew) +.build* +# symlink to builddir/compile_commands.json; should be set manually in dev sandbox +compile_commands.json diff --git a/xo-pykalmanfilter/CMakeLists.txt b/xo-pykalmanfilter/CMakeLists.txt new file mode 100644 index 00000000..15d971db --- /dev/null +++ b/xo-pykalmanfilter/CMakeLists.txt @@ -0,0 +1,26 @@ +# xo-pykalmanfilter/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_pykalmanfilter VERSION 1.0) + +include(GNUInstallDirs) +include(cmake/xo-bootstrap-macros.cmake) + +xo_cxx_toplevel_options3() + +# ---------------------------------------------------------------- +# c++ settings + +set(PROJECT_CXX_FLAGS "") +#set(PROJECT_CXX_FLAGS "-fconcepts-diagnostics-depth=2") +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- + +add_subdirectory(src/pykalmanfilter) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) diff --git a/xo-pykalmanfilter/README.md b/xo-pykalmanfilter/README.md new file mode 100644 index 00000000..7d7d1b11 --- /dev/null +++ b/xo-pykalmanfilter/README.md @@ -0,0 +1,70 @@ +# python bindings for c++ kalman filter library (xo-kalmanfilter) + +## Getting Started + +### build + install dependencies + +- [github/Rconybea/xo-kalmanfilter](https://github.com/Rconybea/xo-kalmanfilter) +- [github/Rconybea/xo-pyreactor](https://github.com/Rconybea/xo-pyreactor) + +### build + install + +``` +$ cd xo-pykalmanfilter +$ mkdir build +$ cd build +$ INSTALL_PREFIX=/usr/local # or wherever you prefer, e.g. ~/local +$ cmake \ + -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake \ + -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. +$ make +$ make install +``` +(also see .github/workflows/main.yml) + +## Examples + +Assumes `xo-pykalmanfilter` installed to `~/local2/lib` +``` +PYTHONPATH=~/local2/lib:$PYTHONPATH python +>>> import xo_pykalmanfilter +>>> dir(xo_pykalmanfilter) +['KalmanFilter', 'KalmanFilterInput', 'KalmanFilterInputToConsole', 'KalmanFilterObservable', 'KalmanFilterSpec', 'KalmanFilterState', 'KalmanFilterStateEventStore', 'KalmanFilterStateExt', 'KalmanFilterStateToConsole', 'KalmanFilterStep', 'KalmanFilterSvc', 'KalmanFilterTransition', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'kf_engine_correct', 'kf_engine_correct1', 'kf_engine_extrapolate', 'kf_engine_gain', 'kf_engine_gain1', 'make_kalman_filter', 'make_kalman_filter_input', 'make_kalman_filter_input_printer', 'make_kalman_filter_state_printer', 'print_matrix', 'print_vector'] +>>> +``` + +## Development + +### build for unit test coverage +``` +$ cd xo-pykalmanfilter +$ mkdir build-ccov +$ cd build-ccov +$ cmake \ + -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake \ + -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ + -DCODE_COVERAGE=ON \ + -DCMAKE_BUILD_TYPE=Debug .. +``` + +### LSP (language server) support + +LSP looks for compile commands in the root of the source tree; +while Cmake creates them in the root of its build directory. + +``` +$ cd xo-pykalmanfilter +$ ln -s build/compile_commands.json # supply compile commands to LSP +``` + +### display cmake variables + +- `-L` list variables +- `-A` include 'advanced' variables +- `-H` include help text + +``` +$ cd xo-pykalmanfilter/build +$ cmake -LAH +``` diff --git a/xo-pykalmanfilter/cmake/xo-bootstrap-macros.cmake b/xo-pykalmanfilter/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..aba31169 --- /dev/null +++ b/xo-pykalmanfilter/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------- +# for example: +# $ PREFIX=/usr/local # for example +# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build +# +# will get +# CMAKE_MODULE_PATH +# from xo-cmake-config --cmake-module-path +# +# and expect .cmake macros in +# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake +# ---------------------------------------------------------------- + +find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) + +if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") + message(FATAL "could not find xo-cmake-config executable") +endif() + +message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") + +if (NOT XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # default to typical install location for xo-project-macros + execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +endif() + +# needs to have been installed somewhere on CMAKE_MODULE_PATH, +# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) +# +include(xo_macros/xo_cxx) + +xo_cxx_bootstrap_message() diff --git a/xo-pykalmanfilter/cmake/xo_pykalmanfilterConfig.cmake.in b/xo-pykalmanfilter/cmake/xo_pykalmanfilterConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/xo-pykalmanfilter/cmake/xo_pykalmanfilterConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/xo-pykalmanfilter/include/README.md b/xo-pykalmanfilter/include/README.md new file mode 100644 index 00000000..4454f162 --- /dev/null +++ b/xo-pykalmanfilter/include/README.md @@ -0,0 +1 @@ +placeholder for future pyreflect #include files diff --git a/xo-pykalmanfilter/src/pykalmanfilter/CMakeLists.txt b/xo-pykalmanfilter/src/pykalmanfilter/CMakeLists.txt new file mode 100644 index 00000000..af687d48 --- /dev/null +++ b/xo-pykalmanfilter/src/pykalmanfilter/CMakeLists.txt @@ -0,0 +1,37 @@ +# xo_pykalmanfilter/src/pykalmanfilter/CMakeLists.txt + +set(SELF_LIB xo_pykalmanfilter) +set(SELF_SRCS pykalmanfilter.cpp) + +xo_pybind11_library(${SELF_LIB} ${PROJECT_NAME}Targets ${SELF_SRCS}) +xo_pybind11_dependency(${SELF_LIB} xo_kalmanfilter) +xo_pybind11_header_dependency(${SELF_LIB} xo_pyreactor) +#xo_pybind11_dependency(${SELF_LIB} xo_pyutil) + +# cmake config generated by xo-kalman filter +# (xo-kalmanfilter/cmake/xo_kalmanfilterConfig.cmake) +# doesn't work here. +# kalmanfilterConfig.cmake include path that would make +# #include +# work; we want to be able to use +# #include +# +# BTW this tells us that there's some discrepancy between what +# cmake does in response to +# +# (A) xo_kalmanfilterTarget.cmake: +# set_target_properties(xo_kalmanfilter PROPERTIES +# .. +# INTERFACE_LINK_LIBRARIES "reactor;Eigen3::Eigen") +# +# (B) xo_external_target_dependency +# (xo_kalmanfilter Eigen3 Eigen3::Eigen) +# below +# +# reminder XO_SUBMODULE_BUILD relies on +# xo_external_target_dependency() calling find_package() +# +xo_external_target_dependency(${SELF_LIB} Eigen3 Eigen3::Eigen) +#target_link_libraries(${SELF_LIB} PUBLIC Eigen3::Eigen) + +# CMakeLists.txt diff --git a/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.cpp b/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.cpp new file mode 100644 index 00000000..4255335b --- /dev/null +++ b/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.cpp @@ -0,0 +1,285 @@ +/* @file pykalmanfilter.cpp */ + +#include "pykalmanfilter.hpp" +#include "xo/pyreactor/pyreactor.hpp" +#include "xo/pyutil/pyutil.hpp" + +#include "xo/kalmanfilter/init_filter.hpp" +#include "xo/refcnt/Refcounted.hpp" +#include "xo/kalmanfilter/KalmanFilterSvc.hpp" +#include "xo/kalmanfilter/KalmanFilter.hpp" +#include "xo/kalmanfilter/KalmanFilterEngine.hpp" +#include "xo/kalmanfilter/KalmanFilterSpec.hpp" +#include "xo/kalmanfilter/KalmanFilterStep.hpp" +#include "xo/kalmanfilter/KalmanFilterStateToConsole.hpp" +#include "xo/kalmanfilter/KalmanFilterState.hpp" +#include "xo/kalmanfilter/KalmanFilterTransition.hpp" +#include "xo/kalmanfilter/KalmanFilterObservable.hpp" +#include "xo/kalmanfilter/KalmanFilterInputToConsole.hpp" +#include "xo/kalmanfilter/KalmanFilterInput.hpp" +#include "xo/reactor/EventStore.hpp" +#include "xo/subsys/Subsystem.hpp" + +#include +#include +#include +#include +#include +//#include + +namespace xo { + using xo::kalman::KalmanFilterSvc; + using xo::kalman::KalmanFilter; + using xo::kalman::KalmanFilterState; + using xo::kalman::KalmanFilterEngine; + using xo::kalman::KalmanFilterSpec; + using xo::kalman::KalmanFilterStepBase; + using xo::kalman::KalmanFilterStep; + using xo::kalman::KalmanFilterStateToConsole; + using xo::kalman::KalmanFilterState; + using xo::kalman::KalmanFilterStateExt; + using xo::kalman::KalmanFilterTransition; + using xo::kalman::KalmanFilterObservable; + using xo::kalman::KalmanFilterInputToConsole; + using xo::kalman::KalmanFilterInput; + using xo::reactor::AbstractSource; + using xo::reactor::AbstractSink; + using xo::reactor::AbstractEventStore; + using xo::reactor::ReactorSource; + using xo::reactor::PtrEventStore; + using xo::reflect::SelfTagging; + using xo::time::utc_nanos; + using Eigen::VectorXd; + using Eigen::VectorXi; + using Eigen::MatrixXd; + namespace py = pybind11; + + namespace filter { + PYBIND11_MODULE(PYKALMANFILTER_MODULE_NAME(), m) { + /* ensure filter/ will be initialized */ + InitSubsys::require(); + /* ..and immediately perform init steps + * (this 2nd step is sketchy -- want to pass an application context + * to initialize_all()) + */ + Subsystem::initialize_all(); + + /* e.g. need python wrapper for for xo::reactor::AbstractSource + */ + PYREACTOR_IMPORT_MODULE(); + + m.doc() = "pybind11 plugin for xo.filter"; + + m.def("print_matrix", + [](MatrixXd const & m) { + std::cout << m << std::endl; + }); + + m.def("print_vector", + [](VectorXd const & v) { + std::cout << v << std::endl; + }); + + // ----- xo::kalman::KalmanFilterState ----- + + py::class_>(m, "KalmanFilterState") + .def_static("make", + py::overload_cast(&KalmanFilterState::make), + py::arg("k"), py::arg("tk"), + py::arg("x"), py::arg("P"), + py::arg("transition")) + .def("step_no", &KalmanFilterState::step_no) + .def("tm", &KalmanFilterState::tm) + .def("n_state", &KalmanFilterState::n_state) + .def("state_v", &KalmanFilterState::state_v) + .def("state_cov", &KalmanFilterState::state_cov) + .def_property_readonly("k", &KalmanFilterState::step_no) + .def_property_readonly("tk", &KalmanFilterState::tm) + .def_property_readonly("x", &KalmanFilterState::state_v) + .def_property_readonly("P", &KalmanFilterState::state_cov) + .def("__repr__", &KalmanFilterState::display_string); + + // ----- xo::kalman::KalmanFilterStateExt ----- + + py::class_>(m, "KalmanFilterStateExt") + .def_static("make", + py::overload_cast>(&KalmanFilterStateExt::make), + py::arg("k"), + py::arg("tk"), + py::arg("x"), + py::arg("P"), + py::arg("transition"), + py::arg("K"), + py::arg("j"), + py::arg("zk")) + .def_property_readonly("j", &KalmanFilterStateExt::observable) + .def_property_readonly("K", &KalmanFilterStateExt::gain) + .def_property_readonly("zk", &KalmanFilterStateExt::zk); + + // ----- xo::kalman::KalmanFilterTransition ----- + + py::class_(m, "KalmanFilterTransition") + .def(py::init()) + .def("n_state", &KalmanFilterTransition::n_state) + .def("transition_mat", &KalmanFilterTransition::transition_mat) + .def("transition_cov", &KalmanFilterTransition::transition_cov) + .def("check_ok", &KalmanFilterTransition::check_ok) + .def_property_readonly("F", &KalmanFilterTransition::transition_mat) + .def_property_readonly("Q", &KalmanFilterTransition::transition_cov) + .def("__repr__", &KalmanFilterTransition::display_string); + + // ----- xo::kalman::KalmanFilterObservable ----- + + py::class_(m, "KalmanFilterObservable") + .def(py::init(), + py::arg("keep"), py::arg("H"), py::arg("R")) + .def("n_state", &KalmanFilterObservable::n_state) + .def("n_observable", &KalmanFilterObservable::n_observable) + .def("observable_mat", &KalmanFilterObservable::observable) + .def("observable_cov", &KalmanFilterObservable::observable_cov) + .def_property_readonly("H", &KalmanFilterObservable::observable) + .def_property_readonly("R", &KalmanFilterObservable::observable_cov) + .def("__repr__", &KalmanFilterObservable::display_string); + + // ----- xo::kalman::KalmanFilterInput ----- + + py::class_>(m, "KalmanFilterInput") + //.def(py::init(), + // py::arg("tkp1"), py::arg("z")) + .def("n_observable", &KalmanFilterInput::n_obs) + .def_property_readonly("tkp1", &KalmanFilterInput::tkp1) + .def_property_readonly("z", &KalmanFilterInput::z) + .def("__repr__", &KalmanFilterInput::display_string); + + m.def("make_kalman_filter_input", &KalmanFilterInput::make, + py::arg("tkp1"), py::arg("presence"), py::arg("z"), py::arg("zerr")); + + // ----- xo::kalman::KalmanFilterStep ----- + + py::class_(m, "KalmanFilterStep") + .def(py::init, KalmanFilterTransition, KalmanFilterObservable, rp>(), + py::arg("state"), py::arg("model"), py::arg("obs"), py::arg("input")) + .def_property_readonly("state", &KalmanFilterStep::state) + .def_property_readonly("model", &KalmanFilterStepBase::model) + .def_property_readonly("obs", &KalmanFilterStepBase::obs) + .def_property_readonly("input", &KalmanFilterStep::input) + .def("extrapolate", &KalmanFilterStep::extrapolate) + .def("gain", &KalmanFilterStep::gain) + .def("gain1", &KalmanFilterStep::gain1) + .def("correct", &KalmanFilterStep::correct) + .def("correct1", &KalmanFilterStep::correct1) + .def("__repr__", &KalmanFilterStep::display_string); + + // ----- xo::kalman::KalmanFilterSpec ----- + + py::class_(m, "KalmanFilterSpec") + .def(py::init, KalmanFilterSpec::MkStepFn>(), + py::arg("s0"), py::arg("mkstepfn")) + .def("start_ext", &KalmanFilterSpec::start_ext) + .def("make_step", &KalmanFilterSpec::make_step, + py::arg("sk"), py::arg("zkp1")) + .def("__repr__", &KalmanFilterSpec::display_string); + + // ----- xo::kalman::KalmanFilterEngine ----- + + m.def("kf_engine_extrapolate", + &KalmanFilterEngine::extrapolate); + m.def("kf_engine_gain", + &KalmanFilterEngine::kalman_gain); + m.def("kf_engine_gain1", + &KalmanFilterEngine::kalman_gain1); + m.def("kf_engine_correct", + &KalmanFilterEngine::correct); + m.def("kf_engine_correct1", + &KalmanFilterEngine::correct1); + + // ----- xo::kalman::KalmanFilter ----- + + py::class_(m, "KalmanFilter") + .def(py::init(), + py::arg("spec")) + .def_property_readonly("step_no", &KalmanFilter::step_no) + .def_property_readonly("tm", &KalmanFilter::tm) + .def_property_readonly("filter_spec", &KalmanFilter::filter_spec) + .def_property_readonly("step", &KalmanFilter::step) + .def_property_readonly("state_ext", &KalmanFilter::state_ext) + .def("notify_input", &KalmanFilter::notify_input) + .def("__repr__", &KalmanFilter::display_string); + + // ----- xo::kalman::KalmanFilterSvc ----- + + py::class_>(m, "KalmanFilterSvc") + .def_property_readonly("filter", &KalmanFilterSvc::filter) + .def_property_readonly("last_annexed_ev", &KalmanFilterSvc::last_annexed_ev); + + m.def("make_kalman_filter", + &KalmanFilterSvc::make, + py::arg("spec")); + + // ----- xo::kalman::KalmanFilterInputToConsole ----- + + py::class_> + (m, "KalmanFilterInputToConsole"); + + /* prints KalmanFilterInput events to console */ + m.def("make_kalman_filter_input_printer", &KalmanFilterInputToConsole::make); + + // ----- xo::kalman::KalmanFilterStateToConsole ----- + + py::class_> + (m, "KalmanFilterStateToConsole"); + + /* prints KalmanFilterStateExt events to console */ + m.def("make_kalman_filter_state_printer", &KalmanFilterStateToConsole::make); + + // ----- xo::kalman::KalmanFilterStateStore ----- + + using KalmanFilterStateEventStore + = PtrEventStore>; + + /* see also: UpxEventStore in [pyprocess/pyprocess.cpp] + * BboTickStore in [pyoption/pyoption.cpp] + */ + py::class_> + (m, "KalmanFilterStateEventStore") + .def_static("make", &KalmanFilterStateEventStore::make) + .def("last_n", &KalmanFilterStateEventStore::last_n, py::arg("n")) + .def("last_dt", &KalmanFilterStateEventStore::last_dt, py::arg("dt")); + //.def("__repr__", &KalmanFilterStateEventStore::display_string); + + +#ifdef OBSOLETE + // ----- xo::option::Pxtick ----- + + py::enum_(m, "Pxtick") + .value("nickel_dime", Pxtick::nickel_dime); + //.export_values(); // only need this for pre-c++11-style enum inside a class + + // ----- xo::option::OptionStrikeSet ----- + + py::class_>(m, "OptionStrikeSet") + .def("get_options", + [](OptionStrikeSet const & x) { + std::vector> v; + x.append_options(&v); + return v; + }) +#endif + } /*filter_py*/ + } /*namespace filter*/ +} /*namespace xo*/ + +/* end pykalmanfilter.cpp */ diff --git a/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.hpp.in b/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.hpp.in new file mode 100644 index 00000000..f2b1207d --- /dev/null +++ b/xo-pykalmanfilter/src/pykalmanfilter/pykalmanfilter.hpp.in @@ -0,0 +1,25 @@ +/* @file pykalmanfilter.hpp + * + * automatically generated from src/pykalmanfilter/pykalmanfilter.hpp.in + * see src/pykalmanfilter/CMakeLists.txt + */ + +/* python requires module name = library name + * example: + * PYBIND11_MODULE(PYKALMANFILTER_MODULE_NAME(), m) { ... } + */ +#define PYKALMANFILTER_MODULE_NAME() @SELF_LIB@ + +/* example: + * py::module_::import(PYKALMANFILTER_MODULE_NAME_STR) + */ +#define PYKALMANFILTER_MODULE_NAME_STR "@SELF_LIB@" + +/* example: + * PYKALMANFILTER_IMPORT_MODULE() + * replaces + * py::module_::import("pykalmanfilter") + */ +#define PYKALMANFILTER_IMPORT_MODULE() py::module_::import("@SELF_LIB@") + +/* end pykalmanfilter.hpp */