affine-mpc 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- affine_mpc-0.2.0/.clang-format +55 -0
- affine_mpc-0.2.0/.github/workflows/build_test.yaml +65 -0
- affine_mpc-0.2.0/.github/workflows/check_stubs.yaml +51 -0
- affine_mpc-0.2.0/.github/workflows/docs.yaml +54 -0
- affine_mpc-0.2.0/.github/workflows/publish_pypi.yaml +132 -0
- affine_mpc-0.2.0/.gitignore +35 -0
- affine_mpc-0.2.0/CITATION.cff +22 -0
- affine_mpc-0.2.0/CMakeLists.txt +244 -0
- affine_mpc-0.2.0/CODE_OF_CONDUCT.md +48 -0
- affine_mpc-0.2.0/CONTRIBUTING.md +59 -0
- affine_mpc-0.2.0/LICENSE +31 -0
- affine_mpc-0.2.0/PKG-INFO +112 -0
- affine_mpc-0.2.0/README.md +60 -0
- affine_mpc-0.2.0/cmake/affine_mpcConfig.cmake.in +9 -0
- affine_mpc-0.2.0/cmake/extern_eigen.cmake +41 -0
- affine_mpc-0.2.0/cmake/extern_gtest.cmake +18 -0
- affine_mpc-0.2.0/cmake/extern_osqp.cmake +68 -0
- affine_mpc-0.2.0/docs/assets/favicon.svg +22 -0
- affine_mpc-0.2.0/docs/assets/input-parameterization/degree1-saturation.svg +1784 -0
- affine_mpc-0.2.0/docs/assets/input-parameterization/degree3-saturation.svg +1879 -0
- affine_mpc-0.2.0/docs/assets/input-parameterization/factory-methods.svg +2216 -0
- affine_mpc-0.2.0/docs/assets/input-parameterization/knot-placement.svg +1915 -0
- affine_mpc-0.2.0/docs/concepts/index.md +68 -0
- affine_mpc-0.2.0/docs/concepts/input-parameterization.md +202 -0
- affine_mpc-0.2.0/docs/concepts/nomenclature.md +53 -0
- affine_mpc-0.2.0/docs/concepts/problem-formulation.md +149 -0
- affine_mpc-0.2.0/docs/concepts/qp-formulation.md +754 -0
- affine_mpc-0.2.0/docs/concepts/runtime-updates.md +166 -0
- affine_mpc-0.2.0/docs/development.md +231 -0
- affine_mpc-0.2.0/docs/examples.md +86 -0
- affine_mpc-0.2.0/docs/getting-started/cpp.md +197 -0
- affine_mpc-0.2.0/docs/getting-started/index.md +22 -0
- affine_mpc-0.2.0/docs/getting-started/python.md +111 -0
- affine_mpc-0.2.0/docs/index.md +31 -0
- affine_mpc-0.2.0/docs/logging.md +193 -0
- affine_mpc-0.2.0/docs/usage.md +535 -0
- affine_mpc-0.2.0/examples/plot_sim.py +167 -0
- affine_mpc-0.2.0/examples/sim.cpp +86 -0
- affine_mpc-0.2.0/examples/sim.py +99 -0
- affine_mpc-0.2.0/include/affine_mpc/affine_mpc.hpp +29 -0
- affine_mpc-0.2.0/include/affine_mpc/condensed_mpc.hpp +88 -0
- affine_mpc-0.2.0/include/affine_mpc/mpc_base.hpp +511 -0
- affine_mpc-0.2.0/include/affine_mpc/mpc_logger.hpp +241 -0
- affine_mpc-0.2.0/include/affine_mpc/options.hpp +68 -0
- affine_mpc-0.2.0/include/affine_mpc/osqp_solver.hpp +237 -0
- affine_mpc-0.2.0/include/affine_mpc/parameterization.hpp +182 -0
- affine_mpc-0.2.0/include/affine_mpc/solve_status.hpp +111 -0
- affine_mpc-0.2.0/include/affine_mpc/sparse_mpc.hpp +85 -0
- affine_mpc-0.2.0/pyproject.toml +65 -0
- affine_mpc-0.2.0/python/CMakeLists.txt +164 -0
- affine_mpc-0.2.0/python/affine_mpc/__init__.py +36 -0
- affine_mpc-0.2.0/python/affine_mpc/plotter.py +5 -0
- affine_mpc-0.2.0/python/affine_mpc/py.typed +0 -0
- affine_mpc-0.2.0/python/bindings/affine_mpc_py_module.cpp +22 -0
- affine_mpc-0.2.0/python/bindings/affine_mpc_py_module.hpp +19 -0
- affine_mpc-0.2.0/python/bindings/py_condensed_mpc.cpp +58 -0
- affine_mpc-0.2.0/python/bindings/py_mpc_base.cpp +698 -0
- affine_mpc-0.2.0/python/bindings/py_mpc_logger.cpp +180 -0
- affine_mpc-0.2.0/python/bindings/py_options.cpp +107 -0
- affine_mpc-0.2.0/python/bindings/py_osqp_settings.cpp +296 -0
- affine_mpc-0.2.0/python/bindings/py_parameterization.cpp +249 -0
- affine_mpc-0.2.0/python/bindings/py_solve_status.cpp +66 -0
- affine_mpc-0.2.0/python/bindings/py_sparse_mpc.cpp +58 -0
- affine_mpc-0.2.0/python/custom_stubgen.py +139 -0
- affine_mpc-0.2.0/python/generate_parameterization_figs.py +393 -0
- affine_mpc-0.2.0/requirements/build.txt +5 -0
- affine_mpc-0.2.0/requirements/docs.txt +1 -0
- affine_mpc-0.2.0/requirements/examples.txt +3 -0
- affine_mpc-0.2.0/src/condensed_mpc.cpp +169 -0
- affine_mpc-0.2.0/src/eigen_compat.hpp +24 -0
- affine_mpc-0.2.0/src/mpc_base.cpp +720 -0
- affine_mpc-0.2.0/src/mpc_logger.cpp +596 -0
- affine_mpc-0.2.0/src/npy_writer.cpp +141 -0
- affine_mpc-0.2.0/src/npy_writer.hpp +24 -0
- affine_mpc-0.2.0/src/npz_writer.cpp +725 -0
- affine_mpc-0.2.0/src/npz_writer.hpp +69 -0
- affine_mpc-0.2.0/src/options.cpp +37 -0
- affine_mpc-0.2.0/src/osqp_solver.cpp +377 -0
- affine_mpc-0.2.0/src/parameterization.cpp +273 -0
- affine_mpc-0.2.0/src/solve_status.cpp +56 -0
- affine_mpc-0.2.0/src/sparse_mpc.cpp +186 -0
- affine_mpc-0.2.0/test/affine_mpc/condensed_mpc_tests.cpp +347 -0
- affine_mpc-0.2.0/test/affine_mpc/consistency_tests.cpp +1074 -0
- affine_mpc-0.2.0/test/affine_mpc/mpc_base_tests.cpp +1195 -0
- affine_mpc-0.2.0/test/affine_mpc/mpc_logger_tests.cpp +190 -0
- affine_mpc-0.2.0/test/affine_mpc/np_writer_fixture.cpp +120 -0
- affine_mpc-0.2.0/test/affine_mpc/npz_writer_tests.cpp +51 -0
- affine_mpc-0.2.0/test/affine_mpc/osqp_solver_tests.cpp +640 -0
- affine_mpc-0.2.0/test/affine_mpc/parameterization_tests.cpp +586 -0
- affine_mpc-0.2.0/test/affine_mpc/sparse_mpc_tests.cpp +595 -0
- affine_mpc-0.2.0/test/affine_mpc/utils.hpp +65 -0
- affine_mpc-0.2.0/test/bindings/conftest.py +129 -0
- affine_mpc-0.2.0/test/bindings/test_condensed_mpc.py +234 -0
- affine_mpc-0.2.0/test/bindings/test_mpc_base.py +84 -0
- affine_mpc-0.2.0/test/bindings/test_mpc_logger.py +229 -0
- affine_mpc-0.2.0/test/bindings/test_options.py +17 -0
- affine_mpc-0.2.0/test/bindings/test_osqp_settings.py +55 -0
- affine_mpc-0.2.0/test/bindings/test_parameterization.py +70 -0
- affine_mpc-0.2.0/test/bindings/test_solve_status.py +44 -0
- affine_mpc-0.2.0/test/bindings/test_sparse_mpc.py +118 -0
- affine_mpc-0.2.0/test/python_npz/conftest.py +65 -0
- affine_mpc-0.2.0/test/python_npz/test_np_writers.py +165 -0
- affine_mpc-0.2.0/zensical.toml +129 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# See https://clang.llvm.org/docs/ClangFormat.html
|
|
2
|
+
#
|
|
3
|
+
# Google style guide: https://google.github.io/styleguide/cppguide.html#Variable_Names
|
|
4
|
+
---
|
|
5
|
+
BasedOnStyle: LLVM
|
|
6
|
+
InsertNewlineAtEOF: true
|
|
7
|
+
---
|
|
8
|
+
Language: Cpp
|
|
9
|
+
# Standard: Cpp11
|
|
10
|
+
|
|
11
|
+
# ColumnLimit: 80
|
|
12
|
+
# AccessModifierOffset: -4
|
|
13
|
+
# IndentWidth: 4
|
|
14
|
+
# UseTab: Never
|
|
15
|
+
|
|
16
|
+
# Force pointers to the type
|
|
17
|
+
DerivePointerAlignment: false
|
|
18
|
+
PointerAlignment: Left
|
|
19
|
+
# IndentPPDirectives: AfterHash
|
|
20
|
+
|
|
21
|
+
# AlignTrailingComments: false # default is true
|
|
22
|
+
|
|
23
|
+
# AlignEscapedNewlines: Left
|
|
24
|
+
# AllowShortFunctionsOnASingleLine: Empty
|
|
25
|
+
# AllowShortLambdasOnASingleLine: Empty
|
|
26
|
+
# AlwaysBreakTemplateDeclarations: true
|
|
27
|
+
|
|
28
|
+
BreakBeforeBraces: Custom
|
|
29
|
+
BraceWrapping:
|
|
30
|
+
AfterClass: true
|
|
31
|
+
AfterFunction: true
|
|
32
|
+
AfterControlStatement: false
|
|
33
|
+
AfterEnum: true
|
|
34
|
+
AfterStruct: true
|
|
35
|
+
AfterUnion: true
|
|
36
|
+
AfterNamespace: false
|
|
37
|
+
SplitEmptyRecord: false
|
|
38
|
+
SplitEmptyFunction: false
|
|
39
|
+
# AfterInit: true
|
|
40
|
+
|
|
41
|
+
AllowAllConstructorInitializersOnNextLine: true
|
|
42
|
+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
|
43
|
+
|
|
44
|
+
BreakConstructorInitializers: AfterColon # BeforeComma
|
|
45
|
+
|
|
46
|
+
MaxEmptyLinesToKeep: 2
|
|
47
|
+
SeparateDefinitionBlocks: Leave # Always
|
|
48
|
+
|
|
49
|
+
# Bin packing fits as many items as possible on one line within column limit
|
|
50
|
+
# With it off, each item gets its own line
|
|
51
|
+
BinPackParameters: false # AlwaysOnePerLine
|
|
52
|
+
# BinPackArguments: true
|
|
53
|
+
# Cpp11BracedListStyle: false
|
|
54
|
+
# AlignAfterOpenBracket: DontAlign
|
|
55
|
+
BreakBeforeBinaryOperators: NonAssignment
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Build and Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- CMakeLists.txt
|
|
7
|
+
- cmake/**
|
|
8
|
+
- include/**
|
|
9
|
+
- src/**
|
|
10
|
+
- test/**
|
|
11
|
+
- python/CMakeLists.txt
|
|
12
|
+
- python/affine_mpc/**
|
|
13
|
+
- python/bindings/**
|
|
14
|
+
- requirements/build.txt
|
|
15
|
+
- .github/workflows/build_test.yaml
|
|
16
|
+
push:
|
|
17
|
+
branches: [main]
|
|
18
|
+
paths:
|
|
19
|
+
- CMakeLists.txt
|
|
20
|
+
- cmake/**
|
|
21
|
+
- include/**
|
|
22
|
+
- src/**
|
|
23
|
+
- test/**
|
|
24
|
+
- python/CMakeLists.txt
|
|
25
|
+
- python/affine_mpc/**
|
|
26
|
+
- python/bindings/**
|
|
27
|
+
- requirements/build.txt
|
|
28
|
+
- .github/workflows/build_test.yaml
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
build-test:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout repository
|
|
36
|
+
uses: actions/checkout@v4
|
|
37
|
+
|
|
38
|
+
- name: Set up Python
|
|
39
|
+
uses: actions/setup-python@v5
|
|
40
|
+
with:
|
|
41
|
+
python-version: "3.14"
|
|
42
|
+
|
|
43
|
+
- name: Install Linux build dependencies
|
|
44
|
+
run: |
|
|
45
|
+
sudo apt-get update
|
|
46
|
+
sudo apt-get install -y cmake build-essential libeigen3-dev zlib1g-dev
|
|
47
|
+
|
|
48
|
+
- name: Install Python build dependencies
|
|
49
|
+
run: python -m pip install -r requirements/build.txt
|
|
50
|
+
|
|
51
|
+
- name: Configure CMake
|
|
52
|
+
run: |
|
|
53
|
+
cmake -S . -B build \
|
|
54
|
+
-DAFFINE_MPC_BUILD_EXAMPLES=ON \
|
|
55
|
+
-DAFFINE_MPC_BUILD_TESTS=ON \
|
|
56
|
+
-DAFFINE_MPC_BUILD_BINDINGS=ON
|
|
57
|
+
|
|
58
|
+
- name: Build project
|
|
59
|
+
run: cmake --build build --config Release --parallel
|
|
60
|
+
|
|
61
|
+
- name: Run examples
|
|
62
|
+
run: ./build/example_sim
|
|
63
|
+
|
|
64
|
+
- name: Run tests
|
|
65
|
+
run: ctest --test-dir build --output-on-failure
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Check Stubs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- python/bindings/**
|
|
7
|
+
- python/CMakeLists.txt
|
|
8
|
+
- python/custom_stubgen.py
|
|
9
|
+
- python/affine_mpc/_bindings.pyi
|
|
10
|
+
- pyproject.toml
|
|
11
|
+
- .github/workflows/check_stubs.yaml
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
paths:
|
|
15
|
+
- python/bindings/**
|
|
16
|
+
- python/CMakeLists.txt
|
|
17
|
+
- python/custom_stubgen.py
|
|
18
|
+
- python/affine_mpc/_bindings.pyi
|
|
19
|
+
- pyproject.toml
|
|
20
|
+
- .github/workflows/check_stubs.yaml
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
check-stubs:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout repository
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.14"
|
|
34
|
+
|
|
35
|
+
- name: Install Linux build dependencies
|
|
36
|
+
run: |
|
|
37
|
+
sudo apt-get update
|
|
38
|
+
sudo apt-get install -y cmake build-essential libeigen3-dev zlib1g-dev
|
|
39
|
+
|
|
40
|
+
- name: Install package and regenerate stubs
|
|
41
|
+
run: |
|
|
42
|
+
python -m pip install ".[dev]"
|
|
43
|
+
python python/custom_stubgen.py
|
|
44
|
+
|
|
45
|
+
- name: Check committed stub file is up to date
|
|
46
|
+
run: |
|
|
47
|
+
git diff --exit-code -- python/affine_mpc/_bindings.pyi || {
|
|
48
|
+
echo "Generated bindings stub differs from python/affine_mpc/_bindings.pyi"
|
|
49
|
+
echo "Regenerate the stub locally and commit the updated file."
|
|
50
|
+
exit 1
|
|
51
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
- "zensical.toml"
|
|
9
|
+
- "requirements/docs.txt"
|
|
10
|
+
- ".github/workflows/docs.yml"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
pages: write
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
group: pages
|
|
20
|
+
cancel-in-progress: true
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout repository
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Set up Python
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.12"
|
|
33
|
+
|
|
34
|
+
- name: Install docs dependencies
|
|
35
|
+
run: python -m pip install -r requirements/docs.txt
|
|
36
|
+
|
|
37
|
+
- name: Build docs site
|
|
38
|
+
run: zensical build
|
|
39
|
+
|
|
40
|
+
- name: Upload Pages artifact
|
|
41
|
+
uses: actions/upload-pages-artifact@v3
|
|
42
|
+
with:
|
|
43
|
+
path: site
|
|
44
|
+
|
|
45
|
+
deploy:
|
|
46
|
+
needs: build
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
environment:
|
|
49
|
+
name: github-pages
|
|
50
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
51
|
+
steps:
|
|
52
|
+
- name: Deploy to GitHub Pages
|
|
53
|
+
id: deployment
|
|
54
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
env:
|
|
8
|
+
## Manually specify versions if one ever fails
|
|
9
|
+
# CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-* cp314-*"
|
|
10
|
+
CIBW_SKIP: "cp3??t-* *-win32 *-manylinux_i686 *-musllinux_i686"
|
|
11
|
+
CIBW_ARCHS_WINDOWS: AMD64
|
|
12
|
+
CIBW_TEST_REQUIRES: pytest
|
|
13
|
+
CIBW_ENVIRONMENT: AFFINE_MPC_HAS_ZLIB=1
|
|
14
|
+
CIBW_TEST_COMMAND: "python -m pytest {project}/test/bindings"
|
|
15
|
+
CIBW_BEFORE_ALL_LINUX: >-
|
|
16
|
+
bash -c 'if command -v dnf >/dev/null 2>&1; then dnf install -y zlib-devel;
|
|
17
|
+
elif command -v yum >/dev/null 2>&1; then yum install -y zlib-devel;
|
|
18
|
+
elif command -v apt-get >/dev/null 2>&1; then apt-get update && apt-get install -y zlib1g-dev;
|
|
19
|
+
elif command -v apk >/dev/null 2>&1; then apk add --no-cache zlib-dev;
|
|
20
|
+
else echo "No supported package manager found for installing zlib" >&2; exit 1; fi'
|
|
21
|
+
CIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel"
|
|
22
|
+
CIBW_ENVIRONMENT_WINDOWS: >-
|
|
23
|
+
AFFINE_MPC_HAS_ZLIB=1 CMAKE_ARGS='-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static'
|
|
24
|
+
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair -w {dest_dir} {wheel}"
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build-wheels:
|
|
28
|
+
runs-on: ${{ matrix.os }}
|
|
29
|
+
strategy:
|
|
30
|
+
matrix:
|
|
31
|
+
## Manually specify versions if one ever fails
|
|
32
|
+
# os: [ubuntu-24.04, windows-2025, macos-15]
|
|
33
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout repository
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Set up Python
|
|
40
|
+
uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
43
|
+
|
|
44
|
+
# Windows step
|
|
45
|
+
- name: Install dependencies (Windows)
|
|
46
|
+
if: runner.os == 'Windows'
|
|
47
|
+
shell: pwsh
|
|
48
|
+
run: |
|
|
49
|
+
git clone https://github.com/microsoft/vcpkg.git C:\vcpkg
|
|
50
|
+
C:\vcpkg\bootstrap-vcpkg.bat
|
|
51
|
+
C:\vcpkg\vcpkg install zlib:x64-windows-static eigen3:x64-windows-static
|
|
52
|
+
|
|
53
|
+
# macOS step
|
|
54
|
+
- name: Install dependencies (macOS)
|
|
55
|
+
if: runner.os == 'macOS'
|
|
56
|
+
run: |
|
|
57
|
+
brew update
|
|
58
|
+
brew install cmake zlib eigen
|
|
59
|
+
|
|
60
|
+
- name: Install cibuildwheel
|
|
61
|
+
run: pip install cibuildwheel
|
|
62
|
+
|
|
63
|
+
- name: Build wheels
|
|
64
|
+
run: cibuildwheel --output-dir wheelhouse
|
|
65
|
+
|
|
66
|
+
- name: List built wheels (Windows)
|
|
67
|
+
if: runner.os == 'Windows'
|
|
68
|
+
shell: pwsh
|
|
69
|
+
run: |
|
|
70
|
+
if (Test-Path wheelhouse) {
|
|
71
|
+
ls wheelhouse
|
|
72
|
+
} else {
|
|
73
|
+
Write-Host "wheelhouse folder does not exist yet."
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
- name: List built wheels (Linux/macOS)
|
|
77
|
+
if: runner.os != 'Windows'
|
|
78
|
+
run: ls -l wheelhouse
|
|
79
|
+
|
|
80
|
+
- name: Upload built wheels as artifact
|
|
81
|
+
uses: actions/upload-artifact@v4
|
|
82
|
+
with:
|
|
83
|
+
name: python-wheels-${{ matrix.os }}
|
|
84
|
+
path: wheelhouse/*.whl
|
|
85
|
+
|
|
86
|
+
build-sdist:
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
|
|
89
|
+
steps:
|
|
90
|
+
- name: Checkout repository
|
|
91
|
+
uses: actions/checkout@v4
|
|
92
|
+
with:
|
|
93
|
+
fetch-depth: 0
|
|
94
|
+
|
|
95
|
+
- name: Set up Python
|
|
96
|
+
uses: actions/setup-python@v5
|
|
97
|
+
with:
|
|
98
|
+
python-version: "3.12"
|
|
99
|
+
|
|
100
|
+
- name: Install build frontend
|
|
101
|
+
run: python -m pip install build
|
|
102
|
+
|
|
103
|
+
- name: Build sdist
|
|
104
|
+
run: python -m build --sdist
|
|
105
|
+
|
|
106
|
+
- name: Upload sdist as artifact
|
|
107
|
+
uses: actions/upload-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
name: python-sdist
|
|
110
|
+
path: dist/*.tar.gz
|
|
111
|
+
|
|
112
|
+
publish-pypi:
|
|
113
|
+
needs: [build-wheels, build-sdist]
|
|
114
|
+
runs-on: ubuntu-latest
|
|
115
|
+
environment: pypi
|
|
116
|
+
permissions:
|
|
117
|
+
id-token: write
|
|
118
|
+
steps:
|
|
119
|
+
- name: Download distribution artifacts
|
|
120
|
+
uses: actions/download-artifact@v4
|
|
121
|
+
with:
|
|
122
|
+
pattern: python-*
|
|
123
|
+
path: dist
|
|
124
|
+
merge-multiple: true
|
|
125
|
+
|
|
126
|
+
- name: List downloaded distributions
|
|
127
|
+
run: ls -l dist
|
|
128
|
+
|
|
129
|
+
- name: Publish distributions to PyPI
|
|
130
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
131
|
+
with:
|
|
132
|
+
packages_dir: dist
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
build/
|
|
2
|
+
build*/
|
|
3
|
+
install/
|
|
4
|
+
out/
|
|
5
|
+
Debug/
|
|
6
|
+
Release/
|
|
7
|
+
MinSizRel/
|
|
8
|
+
RelWithDebInfo/
|
|
9
|
+
Deployment/
|
|
10
|
+
Development/
|
|
11
|
+
|
|
12
|
+
notes/
|
|
13
|
+
|
|
14
|
+
compile_commands.json
|
|
15
|
+
.cache/
|
|
16
|
+
|
|
17
|
+
# IDE files
|
|
18
|
+
*.user
|
|
19
|
+
.vscode/
|
|
20
|
+
|
|
21
|
+
# python files
|
|
22
|
+
*.egg-info/
|
|
23
|
+
__pycache__/
|
|
24
|
+
*.so
|
|
25
|
+
*.pyd
|
|
26
|
+
*.pyi
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.cache/
|
|
29
|
+
dist/
|
|
30
|
+
|
|
31
|
+
# docs
|
|
32
|
+
site/
|
|
33
|
+
|
|
34
|
+
# generated by scikit-build-core
|
|
35
|
+
python/affine_mpc/_version.py
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
authors:
|
|
4
|
+
- family-names: "Haskell"
|
|
5
|
+
given-names: "Mathew"
|
|
6
|
+
orcid: "https://orcid.org/0000-0003-3813-7312"
|
|
7
|
+
- family-names: "Killpack"
|
|
8
|
+
given-names: "Marc"
|
|
9
|
+
orcid: "https://orcid.org/0000-0001-9372-104X"
|
|
10
|
+
title: "affine_mpc: A library for affine model predictive control with C++ and Python interfaces"
|
|
11
|
+
version: 0.2.0
|
|
12
|
+
date-released: 2026-10-07
|
|
13
|
+
url: "https://byu-rad-lab.github.io/affine_mpc"
|
|
14
|
+
license: BSD-3-Clause
|
|
15
|
+
repository-code: "https://github.com/byu-rad-lab/affine_mpc"
|
|
16
|
+
keywords:
|
|
17
|
+
- model predictive control
|
|
18
|
+
- control
|
|
19
|
+
- robotics
|
|
20
|
+
- optimization
|
|
21
|
+
- b-spline
|
|
22
|
+
- quadratic-programming
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.18)
|
|
2
|
+
project(affine_mpc
|
|
3
|
+
LANGUAGES CXX C
|
|
4
|
+
VERSION 0.2.0
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
# Default to an optimized build. Single-config generators (Makefiles, Ninja)
|
|
8
|
+
# otherwise build without optimization when no build type is given, and
|
|
9
|
+
# `cmake --build --config Release` only applies to multi-config generators.
|
|
10
|
+
# Only set when this is the top-level project so parent projects keep control.
|
|
11
|
+
get_property(AFFINE_MPC_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
12
|
+
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT AFFINE_MPC_MULTI_CONFIG)
|
|
13
|
+
if(NOT CMAKE_BUILD_TYPE)
|
|
14
|
+
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
|
15
|
+
"Build type (Debug, Release, RelWithDebInfo, MinSizeRel)" FORCE)
|
|
16
|
+
message(STATUS "No build type given; defaulting to Release")
|
|
17
|
+
endif()
|
|
18
|
+
# dropdown in cmake-gui and ccmake
|
|
19
|
+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
|
20
|
+
Debug Release RelWithDebInfo MinSizeRel)
|
|
21
|
+
endif()
|
|
22
|
+
|
|
23
|
+
# --------------------------------------------------
|
|
24
|
+
# Standard includes
|
|
25
|
+
# --------------------------------------------------
|
|
26
|
+
include(GNUInstallDirs)
|
|
27
|
+
include(CMakePackageConfigHelpers)
|
|
28
|
+
|
|
29
|
+
# --------------------------------------------------
|
|
30
|
+
# Options
|
|
31
|
+
# --------------------------------------------------
|
|
32
|
+
option(AFFINE_MPC_BUILD_TESTS "Build unit tests" OFF)
|
|
33
|
+
option(AFFINE_MPC_BUILD_EXAMPLES "Build examples" OFF)
|
|
34
|
+
|
|
35
|
+
# Internal flag for building python bindings
|
|
36
|
+
if(NOT DEFINED AFFINE_MPC_BUILD_BINDINGS)
|
|
37
|
+
set(AFFINE_MPC_BUILD_BINDINGS OFF)
|
|
38
|
+
endif()
|
|
39
|
+
|
|
40
|
+
# --------------------------------------------------
|
|
41
|
+
# Dependencies
|
|
42
|
+
# --------------------------------------------------
|
|
43
|
+
include(cmake/extern_eigen.cmake)
|
|
44
|
+
include(cmake/extern_osqp.cmake)
|
|
45
|
+
find_package(ZLIB QUIET)
|
|
46
|
+
|
|
47
|
+
# --------------------------------------------------
|
|
48
|
+
# Main library
|
|
49
|
+
# --------------------------------------------------
|
|
50
|
+
add_library(${PROJECT_NAME}
|
|
51
|
+
src/options.cpp
|
|
52
|
+
src/parameterization.cpp
|
|
53
|
+
src/solve_status.cpp
|
|
54
|
+
src/osqp_solver.cpp
|
|
55
|
+
src/mpc_base.cpp
|
|
56
|
+
src/condensed_mpc.cpp
|
|
57
|
+
src/sparse_mpc.cpp
|
|
58
|
+
src/mpc_logger.cpp
|
|
59
|
+
src/npy_writer.cpp
|
|
60
|
+
src/npz_writer.cpp
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Namespaced alias
|
|
64
|
+
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
|
65
|
+
|
|
66
|
+
# Library properties
|
|
67
|
+
set_target_properties(${PROJECT_NAME} PROPERTIES
|
|
68
|
+
POSITION_INDEPENDENT_CODE ON
|
|
69
|
+
)
|
|
70
|
+
if(NOT AFFINE_MPC_BUILD_BINDINGS)
|
|
71
|
+
set_target_properties(${PROJECT_NAME} PROPERTIES
|
|
72
|
+
VERSION ${PROJECT_VERSION}
|
|
73
|
+
SOVERSION ${PROJECT_VERSION_MAJOR}
|
|
74
|
+
)
|
|
75
|
+
endif()
|
|
76
|
+
|
|
77
|
+
# Include directories
|
|
78
|
+
target_include_directories(${PROJECT_NAME} PUBLIC
|
|
79
|
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
80
|
+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
target_include_directories(${PROJECT_NAME} PRIVATE
|
|
84
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Link dependencies
|
|
88
|
+
target_link_libraries(${PROJECT_NAME}
|
|
89
|
+
PUBLIC Eigen3::Eigen
|
|
90
|
+
PUBLIC osqp::osqp
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
if(TARGET ZLIB::ZLIB)
|
|
94
|
+
target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
|
|
95
|
+
target_compile_definitions(${PROJECT_NAME} PRIVATE AFFINE_MPC_HAS_ZLIB=1)
|
|
96
|
+
else()
|
|
97
|
+
target_compile_definitions(${PROJECT_NAME} PRIVATE AFFINE_MPC_HAS_ZLIB=0)
|
|
98
|
+
endif()
|
|
99
|
+
|
|
100
|
+
# C++ standard
|
|
101
|
+
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
|
|
102
|
+
|
|
103
|
+
# --------------------------------------------------
|
|
104
|
+
# Examples
|
|
105
|
+
# --------------------------------------------------
|
|
106
|
+
if(AFFINE_MPC_BUILD_EXAMPLES)
|
|
107
|
+
add_executable(example_sim examples/sim.cpp)
|
|
108
|
+
target_link_libraries(example_sim PRIVATE ${PROJECT_NAME}::${PROJECT_NAME})
|
|
109
|
+
# the library is C++17; the example uses C++20 designated initializers
|
|
110
|
+
target_compile_features(example_sim PRIVATE cxx_std_20)
|
|
111
|
+
endif()
|
|
112
|
+
|
|
113
|
+
# --------------------------------------------------
|
|
114
|
+
# Python Bindings
|
|
115
|
+
# --------------------------------------------------
|
|
116
|
+
if(AFFINE_MPC_BUILD_BINDINGS)
|
|
117
|
+
if(AFFINE_MPC_BUILD_TESTS)
|
|
118
|
+
set(AFFINE_MPC_PY_ADD_TESTS ON)
|
|
119
|
+
endif()
|
|
120
|
+
|
|
121
|
+
add_subdirectory(python)
|
|
122
|
+
endif()
|
|
123
|
+
|
|
124
|
+
# --------------------------------------------------
|
|
125
|
+
# Tests
|
|
126
|
+
# --------------------------------------------------
|
|
127
|
+
if(AFFINE_MPC_BUILD_TESTS)
|
|
128
|
+
enable_testing()
|
|
129
|
+
include(GoogleTest)
|
|
130
|
+
include(cmake/extern_gtest.cmake)
|
|
131
|
+
find_package(Python COMPONENTS Interpreter QUIET)
|
|
132
|
+
|
|
133
|
+
set(TEST_SOURCES
|
|
134
|
+
test/affine_mpc/osqp_solver_tests.cpp
|
|
135
|
+
test/affine_mpc/parameterization_tests.cpp
|
|
136
|
+
test/affine_mpc/mpc_base_tests.cpp
|
|
137
|
+
test/affine_mpc/condensed_mpc_tests.cpp
|
|
138
|
+
test/affine_mpc/sparse_mpc_tests.cpp
|
|
139
|
+
test/affine_mpc/consistency_tests.cpp
|
|
140
|
+
test/affine_mpc/npz_writer_tests.cpp
|
|
141
|
+
test/affine_mpc/mpc_logger_tests.cpp
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
add_executable(np_writer_fixture test/affine_mpc/np_writer_fixture.cpp)
|
|
145
|
+
set_target_properties(np_writer_fixture PROPERTIES FOLDER tests)
|
|
146
|
+
target_link_libraries(np_writer_fixture
|
|
147
|
+
PRIVATE ${PROJECT_NAME}::${PROJECT_NAME}
|
|
148
|
+
)
|
|
149
|
+
target_include_directories(np_writer_fixture
|
|
150
|
+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if(Python_Interpreter_FOUND)
|
|
154
|
+
execute_process(
|
|
155
|
+
COMMAND "${Python_EXECUTABLE}" -m pytest --version
|
|
156
|
+
RESULT_VARIABLE pytest_found
|
|
157
|
+
OUTPUT_QUIET
|
|
158
|
+
ERROR_QUIET
|
|
159
|
+
)
|
|
160
|
+
if(pytest_found EQUAL 0)
|
|
161
|
+
add_test(
|
|
162
|
+
NAME python_npz_tests
|
|
163
|
+
COMMAND "${Python_EXECUTABLE}" -m pytest
|
|
164
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/test/python_npz"
|
|
165
|
+
)
|
|
166
|
+
set(python_npz_tests_env
|
|
167
|
+
"PYTHONPATH=${CMAKE_BINARY_DIR}"
|
|
168
|
+
"AFFINE_MPC_NP_WRITER_FIXTURE=${CMAKE_BINARY_DIR}/np_writer_fixture"
|
|
169
|
+
"AFFINE_MPC_HAS_ZLIB=$<IF:$<BOOL:${ZLIB_FOUND}>,1,0>"
|
|
170
|
+
)
|
|
171
|
+
set_tests_properties(python_npz_tests PROPERTIES
|
|
172
|
+
ENVIRONMENT "${python_npz_tests_env}"
|
|
173
|
+
)
|
|
174
|
+
else()
|
|
175
|
+
message(FATAL_ERROR "pytest is required to register Python NPZ tests")
|
|
176
|
+
endif()
|
|
177
|
+
else()
|
|
178
|
+
message(FATAL_ERROR
|
|
179
|
+
"Python interpreter is required to register Python NPZ tests"
|
|
180
|
+
)
|
|
181
|
+
endif()
|
|
182
|
+
|
|
183
|
+
foreach(TEST_SRC IN LISTS TEST_SOURCES)
|
|
184
|
+
get_filename_component(TEST_NAME "${TEST_SRC}" NAME_WE)
|
|
185
|
+
add_executable(${TEST_NAME} ${TEST_SRC})
|
|
186
|
+
set_target_properties(${TEST_NAME} PROPERTIES FOLDER tests)
|
|
187
|
+
# the library is C++17; the tests use C++20 designated initializers
|
|
188
|
+
target_compile_features(${TEST_NAME} PRIVATE cxx_std_20)
|
|
189
|
+
target_link_libraries(${TEST_NAME} PRIVATE
|
|
190
|
+
GTest::gtest_main
|
|
191
|
+
${PROJECT_NAME}::${PROJECT_NAME}
|
|
192
|
+
)
|
|
193
|
+
if(TEST_NAME STREQUAL "npz_writer_tests")
|
|
194
|
+
target_include_directories(${TEST_NAME}
|
|
195
|
+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
196
|
+
)
|
|
197
|
+
endif()
|
|
198
|
+
gtest_discover_tests(${TEST_NAME})
|
|
199
|
+
endforeach()
|
|
200
|
+
endif()
|
|
201
|
+
|
|
202
|
+
# --------------------------------------------------
|
|
203
|
+
# Installation
|
|
204
|
+
# --------------------------------------------------
|
|
205
|
+
install(TARGETS ${PROJECT_NAME}
|
|
206
|
+
EXPORT ${PROJECT_NAME}Targets
|
|
207
|
+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
208
|
+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
209
|
+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
210
|
+
COMPONENT core
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
install(DIRECTORY include/
|
|
214
|
+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
|
215
|
+
COMPONENT core
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
set(config_package_location ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
|
219
|
+
|
|
220
|
+
install(EXPORT ${PROJECT_NAME}Targets
|
|
221
|
+
FILE ${PROJECT_NAME}Targets.cmake
|
|
222
|
+
NAMESPACE ${PROJECT_NAME}::
|
|
223
|
+
DESTINATION ${config_package_location}
|
|
224
|
+
COMPONENT core
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
write_basic_package_version_file(
|
|
228
|
+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
|
229
|
+
VERSION ${PROJECT_VERSION}
|
|
230
|
+
COMPATIBILITY SameMajorVersion
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
configure_package_config_file(
|
|
234
|
+
cmake/${PROJECT_NAME}Config.cmake.in
|
|
235
|
+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
|
236
|
+
INSTALL_DESTINATION ${config_package_location}
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
install(FILES
|
|
240
|
+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
|
241
|
+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
|
242
|
+
DESTINATION ${config_package_location}
|
|
243
|
+
COMPONENT core
|
|
244
|
+
)
|